More updates to the ACPI code:

- Move all register I/O into acpi_io.c
 - Move event handling into acpi_event.c
 - Reorganise headers into acpivar/acpireg/acpiio
 - Move find-RSDT and find-ACPI-owned-memory into acpi_machdep
 - Allocate all resources (except those detailed only by AML)
   as real resources.  Add infrastructure that will make adding
   resource support to AML code easy.
 - Remove all ACPI #ifdefs in non-ACPI code
 - Removed unnecessary includes
 - Minor style and commenting fixes

Reviewed by:	iwasaki
This commit is contained in:
Mike Smith 2000-09-30 20:12:27 +00:00
parent bde5ba9dc0
commit 96f5284585
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66489
19 changed files with 1270 additions and 1064 deletions

View File

@ -31,7 +31,6 @@
* Code for dealing with the BIOS in x86 PC systems.
*/
#include "acpi.h"
#include "isa.h"
#include <sys/param.h>
@ -50,10 +49,6 @@
#include <isa/pnpreg.h>
#include <isa/pnpvar.h>
#if NACPI > 0
#include <sys/acpi.h>
#endif
#define BIOS_START 0xe0000
#define BIOS_SIZE 0x20000
@ -148,26 +143,6 @@ bios32_init(void *junk)
printf("pnpbios: Bad PnP BIOS data checksum\n");
}
}
#if NACPI > 0
/*
* ACPI BIOS
* acpi_rsdp is GLOBAL and holds RSD PTR signature
*/
if ((sigaddr = bios_sigsearch(0, "RSD PTR ", 8, 16, 0)) != 0) {
/* get a virtual pointer to the structure */
acpi_rsdp = (struct ACPIrsdp *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr);
for (cv = (u_int8_t *)acpi_rsdp, ck = 0, i = 0; i < sizeof(struct ACPIrsdp); i++) {
ck += cv[i];
}
/* If checksum is NG, disable it */
if (ck != 0) {
printf("ACPI: Bad ACPI BIOS data checksum\n");
acpi_rsdp=NULL;/* 0xa0000<=RSD_PTR<0x100000*/
}
}
#endif
if (bootverbose) {
/* look for other know signatures */
printf("Other BIOS signatures found:\n");

View File

@ -37,7 +37,6 @@
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $FreeBSD$
*/
#include "acpi.h"
#include "apm.h"
#include "npx.h"
#include "opt_atalk.h"
@ -100,6 +99,7 @@
#include <machine/ipl.h>
#include <machine/md_var.h>
#include <machine/mutex.h>
#include <machine/pc/bios.h>
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
#include <machine/globaldata.h>
#include <machine/globals.h>
@ -120,10 +120,6 @@
#include <sys/ptrace.h>
#include <machine/sigframe.h>
#if NACPI > 0
#include <sys/acpi.h>
#endif
extern void init386 __P((int first));
extern void dblfault_handler __P((void));
@ -1457,11 +1453,7 @@ getmemsize(int first)
vm_offset_t pa, physmap[PHYSMAP_SIZE];
pt_entry_t pte;
const char *cp;
struct {
u_int64_t base;
u_int64_t length;
u_int32_t type;
} *smap;
struct bios_smap *smap;
bzero(&vmf, sizeof(struct vm86frame));
bzero(physmap, sizeof(physmap));
@ -1521,22 +1513,16 @@ getmemsize(int first)
/*
* get memory map with INT 15:E820
*/
#define SMAPSIZ sizeof(*smap)
#define SMAP_SIG 0x534D4150 /* 'SMAP' */
vmc.npages = 0;
smap = (void *)vm86_addpage(&vmc, 1, KERNBASE + (1 << PAGE_SHIFT));
vm86_getptr(&vmc, (vm_offset_t)smap, &vmf.vmf_es, &vmf.vmf_di);
#if NACPI > 0
acpi_init_addr_range();
#endif
physmap_idx = 0;
vmf.vmf_ebx = 0;
do {
vmf.vmf_eax = 0xE820;
vmf.vmf_edx = SMAP_SIG;
vmf.vmf_ecx = SMAPSIZ;
vmf.vmf_ecx = sizeof(struct bios_smap);
i = vm86_datacall(0x15, &vmf, &vmc);
if (i || vmf.vmf_eax != SMAP_SIG)
break;
@ -1547,13 +1533,7 @@ getmemsize(int first)
(u_int32_t)smap->base,
*(u_int32_t *)((char *)&smap->length + 4),
(u_int32_t)smap->length);
#if NACPI > 0
/* Save ACPI related memory Info */
if (smap->type == 0x03 || smap->type == 0x04) {
acpi_register_addr_range(smap->base,
smap->length, smap->type);
}
#endif
if (smap->type != 0x01)
goto next_run;

View File

@ -218,3 +218,16 @@ extern int bios16(struct bios_args *, char *, ...);
extern int bios16_call(struct bios_regs *, char *);
extern int bios32(struct bios_regs *, u_int, u_short);
extern void set_bios_selectors(struct bios_segments *, int);
/*
* Int 15:E820 'SMAP' structure
*
* XXX add constants for type
*/
#define SMAP_SIG 0x534D4150 /* 'SMAP' */
struct bios_smap {
u_int64_t base;
u_int64_t length;
u_int32_t type;
} __attribute__ ((packed));

View File

@ -75,7 +75,9 @@ dev/aac/aac.c optional aac
#dev/aac/aac_debug.c optional aac
dev/aac/aac_disk.c optional aac
dev/aac/aac_pci.c optional aac pci
dev/acpi/acpi.c count acpi
dev/acpi/acpi.c optional acpi
dev/acpi/acpi_io.c optional acpi
dev/acpi/acpi_event.c optional acpi
dev/acpi/acpi_powerres.c optional acpi
dev/acpi/aml/aml_amlmem.c optional acpi
dev/acpi/aml/aml_common.c optional acpi

File diff suppressed because it is too large Load Diff

418
sys/dev/acpi/acpi_event.c Normal file
View File

@ -0,0 +1,418 @@
/*-
* Copyright (c) 1999 Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/ctype.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_evalobj.h>
/*
* ACPI events
*/
static void acpi_process_event(acpi_softc_t *sc, u_int32_t status_e,
u_int32_t status_0, u_int32_t status_1);
/*
* ACPI events
*/
static void
acpi_process_event(acpi_softc_t *sc, u_int32_t status_e,
u_int32_t status_0, u_int32_t status_1)
{
int i;
if (status_e & ACPI_PM1_PWRBTN_EN) {
if (sc->ignore_events & ACPI_PM1_PWRBTN_EN) {
ACPI_DEBUGPRINT("PWRBTN event ingnored\n");
} else {
#if 1
acpi_set_sleeping_state(sc, ACPI_S_STATE_S5);
#else
/*
* If there is ACPI userland daemon,
* this event should be passed to it
* so that the user can determine power policy.
*/
acpi_queue_event(sc, ACPI_EVENT_TYPE_FIXEDREG, 0);
#endif
}
}
if (status_e & ACPI_PM1_SLPBTN_EN) {
if (sc->ignore_events & ACPI_PM1_SLPBTN_EN) {
ACPI_DEBUGPRINT("SLPBTN event ingnored\n");
} else {
#if 1
acpi_set_sleeping_state(sc, ACPI_S_STATE_S1);
#else
acpi_queue_event(sc, ACPI_EVENT_TYPE_FIXEDREG, 1);
#endif
}
}
for(i = 0; i < sc->facp_body->gpe0_len * 4; i++)
if((status_0 & (1 << i)) && (sc->gpe0_mask & (1 << i)))
acpi_queue_event(sc, ACPI_EVENT_TYPE_GPEREG, i);
for(i = 0; i < sc->facp_body->gpe1_len * 4 ; i++)
if((status_1 & (1 << i)) && (sc->gpe1_mask & (1 << i)))
acpi_queue_event(sc, ACPI_EVENT_TYPE_GPEREG,
i + sc->facp_body->gpe1_base);
}
void
acpi_intr(void *data)
{
u_int32_t enable;
u_int32_t status_e, status_0, status_1;
u_int32_t val;
int debug;
acpi_softc_t *sc;
sc = (acpi_softc_t *)data;
debug = acpi_debug; /* Save debug level */
acpi_debug = 0; /* Shut up */
/*
* Power Management 1 Status Registers
*/
status_e = enable = 0;
acpi_io_pm1_status(sc, ACPI_REGISTER_INPUT, &status_e);
/*
* Get current interrupt mask
*/
acpi_io_pm1_enable(sc, ACPI_REGISTER_INPUT, &enable);
/*
* Disable events and re-enable again
*/
if ((status_e & enable) != 0) {
acpi_debug = debug; /* OK, you can speak */
ACPI_DEBUGPRINT("pm1_status intr CALLED\n");
/* Disable all interrupt generation */
val = enable & (~ACPI_PM1_ALL_ENABLE_BITS);
acpi_io_pm1_enable(sc, ACPI_REGISTER_OUTPUT, &val);
/* Clear interrupt status */
val = enable & ACPI_PM1_ALL_ENABLE_BITS;
acpi_io_pm1_status(sc, ACPI_REGISTER_OUTPUT, &val);
/* Re-enable interrupt */
acpi_io_pm1_enable(sc, ACPI_REGISTER_OUTPUT, &enable);
acpi_debug = 0; /* Shut up again */
}
/*
* General-Purpose Events 0 Status Registers
*/
status_0 = enable = 0;
acpi_io_gpe0_status(sc, ACPI_REGISTER_INPUT, &status_0);
/*
* Get current interrupt mask
*/
acpi_io_gpe0_enable(sc, ACPI_REGISTER_INPUT, &enable);
/*
* Disable events and re-enable again
*/
if ((status_0 & enable) != 0) {
acpi_debug = debug; /* OK, you can speak */
ACPI_DEBUGPRINT("gpe0_status intr CALLED\n");
/* Disable all interrupt generation */
val = enable & ~status_0;
#if 0
/* or should we disable all? */
val = 0x0;
#endif
acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT, &val);
#if 0
/* Clear interrupt status */
val = enable; /* XXX */
acpi_io_gpe0_status(sc, ACPI_REGISTER_OUTPUT, &val);
/* Re-enable interrupt */
acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT, &enable);
acpi_debug = 0; /* Shut up again */
#endif
}
/*
* General-Purpose Events 1 Status Registers
*/
status_1 = enable = 0;
acpi_io_gpe1_status(sc, ACPI_REGISTER_INPUT, &status_1);
/*
Get current interrupt mask
*/
acpi_io_gpe1_enable(sc, ACPI_REGISTER_INPUT, &enable);
/*
* Disable events and re-enable again
*/
if ((status_1 & enable) != 0) {
acpi_debug = debug; /* OK, you can speak */
ACPI_DEBUGPRINT("gpe1_status intr CALLED\n");
/* Disable all interrupt generation */
val = enable & ~status_1;
#if 0
/* or should we disable all? */
val = 0x0;
#endif
acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT, &val);
/* Clear interrupt status */
val = enable; /* XXX */
acpi_io_gpe1_status(sc, ACPI_REGISTER_OUTPUT, &val);
/* Re-enable interrupt */
acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT, &enable);
acpi_debug = 0; /* Shut up again */
}
acpi_debug = debug; /* Restore debug level */
/* do something to handle the events... */
acpi_process_event(sc, status_e, status_0, status_1);
}
static int
acpi_set_gpe_bits(struct aml_name *name, va_list ap)
{
struct acpi_softc *sc = va_arg(ap, struct acpi_softc *);
int *gpemask0 = va_arg(ap, int *);
int *gpemask1 = va_arg(ap, int *);
int gpenum;
#define XDIGITTONUM(c) ((isdigit(c)) ? ((c) - '0') : ('A' <= (c)&& (c) <= 'F') ? ((c) - 'A' + 10) : 0)
if (isxdigit(name->name[2]) && isxdigit(name->name[3])) {
gpenum = XDIGITTONUM(name->name[2]) * 16 +
XDIGITTONUM(name->name[3]);
ACPI_DEBUGPRINT("GPENUM %d %d \n", gpenum, sc->facp_body->gpe0_len * 4);
if (gpenum < (sc->facp_body->gpe0_len * 4)) {
*gpemask0 |= (1 << gpenum);
} else {
*gpemask1 |= (1 << (gpenum - sc->facp_body->gpe1_base));
}
}
ACPI_DEBUGPRINT("GPEMASK %x %x\n", *gpemask0, *gpemask1);
return 0;
}
void
acpi_enable_events(acpi_softc_t *sc)
{
u_int32_t status;
u_int32_t mask0, mask1;
u_int32_t flags;
/*
* Setup PM1 Enable Registers Fixed Feature Enable Bits (4.7.3.1.2)
* based on flags field of Fixed ACPI Description Table (5.2.5).
*/
acpi_io_pm1_enable(sc, ACPI_REGISTER_INPUT, &status);
flags = sc->facp_body->flags;
if ((flags & ACPI_FACP_FLAG_PWR_BUTTON) == 0) {
status |= ACPI_PM1_PWRBTN_EN;
}
if ((flags & ACPI_FACP_FLAG_SLP_BUTTON) == 0) {
status |= ACPI_PM1_SLPBTN_EN;
}
acpi_io_pm1_enable(sc, ACPI_REGISTER_OUTPUT, &status);
#if 1
/*
* XXX
* This should be done based on level event handlers in
* \_GPE scope (4.7.2.2.1.2).
*/
mask0 = mask1 = 0;
aml_apply_foreach_found_objects(NULL, "\\_GPE._L", acpi_set_gpe_bits,
sc, &mask0, &mask1); /* XXX correct? */
sc->gpe0_mask = mask0;
sc->gpe1_mask = mask1;
acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT, &mask0);
acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT, &mask1);
#endif
/* print all event status for debugging */
acpi_io_pm1_status(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_pm1_enable(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_gpe0_status(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_gpe0_enable(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_gpe1_status(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_gpe1_enable(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_pm1_control(sc, ACPI_REGISTER_INPUT, &mask0, &mask1);
acpi_io_pm2_control(sc, ACPI_REGISTER_INPUT, &status);
acpi_io_pm_timer(sc, ACPI_REGISTER_INPUT, &status);
}
void
acpi_clear_ignore_events(void *arg)
{
((acpi_softc_t *)arg)->ignore_events = 0;
ACPI_DEBUGPRINT("ignore events cleared\n");
}
/*
* Transition the rest of the system through state changes.
*/
int
acpi_send_pm_event(acpi_softc_t *sc, u_int8_t state)
{
int error;
error = 0;
switch (state) {
case ACPI_S_STATE_S0:
if (sc->system_state != ACPI_S_STATE_S0) {
DEVICE_RESUME(root_bus);
}
break;
case ACPI_S_STATE_S1:
case ACPI_S_STATE_S2:
case ACPI_S_STATE_S3:
case ACPI_S_STATE_S4:
error = DEVICE_SUSPEND(root_bus);
break;
default:
break;
}
return (error);
}
/*
* Event-handler thread.
*/
void
acpi_queue_event(acpi_softc_t *sc, int type, int arg)
{
struct acpi_event *ae;
int s;
ae = malloc(sizeof(*ae), M_TEMP, M_NOWAIT);
if(ae == NULL)
panic("acpi_queue_event: can't allocate event");
ae->ae_type = type;
ae->ae_arg = arg;
s = splhigh();
STAILQ_INSERT_TAIL(&sc->event, ae, ae_q);
splx(s);
wakeup(&sc->event);
}
void
acpi_event_thread(void *arg)
{
acpi_softc_t *sc = arg;
int s , gpe1_base = sc->facp_body->gpe1_base;
u_int32_t status,bit;
struct acpi_event *ae;
const char numconv[] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F',-1};
char gpemethod[] = "\\_GPE._LXX";
union aml_object argv; /* Dummy*/
while(1) {
s = splhigh();
if ((ae = STAILQ_FIRST(&sc->event)) == NULL) {
splx(s);
tsleep(&sc->event, PWAIT, "acpiev", 0);
continue;
} else {
splx(s);
}
s = splhigh();
STAILQ_REMOVE_HEAD_UNTIL(&sc->event, ae, ae_q);
splx(s);
switch(ae->ae_type) {
case ACPI_EVENT_TYPE_GPEREG:
sprintf(gpemethod, "\\_GPE._L%c%c",
numconv[(ae->ae_arg / 0x10) & 0xf],
numconv[ae->ae_arg & 0xf]);
aml_invoke_method_by_name(gpemethod, 0, &argv);
sprintf(gpemethod, "\\_GPE._E%c%c",
numconv[(ae->ae_arg / 0x10) & 0xf],
numconv[ae->ae_arg & 0xf]);
aml_invoke_method_by_name(gpemethod, 0, &argv);
s=splhigh();
if((ae->ae_arg < gpe1_base) || (gpe1_base == 0)){
bit = 1 << ae->ae_arg;
ACPI_DEBUGPRINT("GPE0%x\n", bit);
acpi_io_gpe0_status(sc, ACPI_REGISTER_OUTPUT,
&bit);
acpi_io_gpe0_enable(sc, ACPI_REGISTER_INPUT,
&status);
ACPI_DEBUGPRINT("GPE0%x\n", status);
status |= bit;
acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT,
&status);
} else {
bit = 1 << (ae->ae_arg - sc->facp_body->gpe1_base);
acpi_io_gpe1_status(sc, ACPI_REGISTER_OUTPUT,
&bit);
acpi_io_gpe1_enable(sc, ACPI_REGISTER_INPUT,
&status);
status |= bit;
acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT,
&status);
}
splx(s);
break;
}
free(ae, M_TEMP);
}
ACPI_DEVPRINTF("????\n");
}

356
sys/dev/acpi/acpi_io.c Normal file
View File

@ -0,0 +1,356 @@
/*-
* Copyright (c) 1999 Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
/*
* ACPI Register I/O
*/
static __inline void
acpi_register_input(acpi_softc_t *sc, int res, int offset, u_int32_t *value, u_int32_t size)
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
u_int32_t val;
if (sc->iores[res].rsc == NULL)
return;
bst = sc->iores[res].btag;
bsh = sc->iores[res].bhandle;
switch (size) {
case 1:
val = bus_space_read_1(bst, bsh, offset);
break;
case 2:
val = bus_space_read_2(bst, bsh, offset);
break;
case 3:
val = bus_space_read_4(bst, bsh, offset);
val &= 0x00ffffff;
break;
case 4:
val = bus_space_read_4(bst, bsh, offset);
break;
default:
ACPI_DEVPRINTF("acpi_register_input(): invalid size (%d)\n", size);
val = 0;
break;
}
*value = val;
}
static __inline void
acpi_register_output(acpi_softc_t *sc, int res, int offset, u_int32_t *value, u_int32_t size)
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
u_int32_t val;
if (sc->iores[res].rsc == NULL)
return;
val = *value;
bst = sc->iores[res].btag;
bsh = sc->iores[res].bhandle;
switch (size) {
case 1:
bus_space_write_1(bst, bsh, offset, val & 0xff);
break;
case 2:
bus_space_write_2(bst, bsh, offset, val & 0xffff);
break;
case 3:
bus_space_write_2(bst, bsh, offset, val & 0xffff);
bus_space_write_1(bst, bsh, offset + 2, (val >> 16) & 0xff);
break;
case 4:
bus_space_write_4(bst, bsh, offset, val);
break;
default:
ACPI_DEVPRINTF("acpi_register_output(): invalid size\n");
break;
}
}
static __inline void
acpi_io_mirreg(acpi_softc_t *sc, boolean_t io, u_int32_t *data,
int res, int altres, int offset, int size)
{
u_int32_t result;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, res, offset, &result, size);
*data = result;
acpi_register_input(sc, altres, offset, &result, size);
*data |= result;
} else {
acpi_register_output(sc, res, offset, data, size);
acpi_register_output(sc, altres, offset, data, size);
}
return;
}
void
acpi_enable_disable(acpi_softc_t *sc, boolean_t enable)
{
u_int8_t val;
val = enable ? sc->facp_body->acpi_enable : sc->facp_body->acpi_disable;
bus_space_write_1(sc->iores[ACPI_RES_SMI_CMD].btag,
sc->iores[ACPI_RES_SMI_CMD].bhandle,
0, val);
sc->enabled = enable;
ACPI_DEBUGPRINT("acpi_enable_disable(%d) = (%x)\n", enable, val);
}
void
acpi_io_pm1_status(acpi_softc_t *sc, boolean_t io, u_int32_t *status)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->pm1_evt_len / 2;
acpi_io_mirreg(sc, io, status, ACPI_RES_PM1A_EVT, ACPI_RES_PM1B_EVT, 0, size);
ACPI_DEBUGPRINT("acpi_io_pm1_status(%d) = (%x)\n", io, *status);
}
void
acpi_io_pm1_enable(acpi_softc_t *sc, boolean_t io, u_int32_t *enable)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->pm1_evt_len / 2;
acpi_io_mirreg(sc, io, enable, ACPI_RES_PM1A_EVT, ACPI_RES_PM1B_EVT, size, size);
ACPI_DEBUGPRINT("acpi_io_pm1_enable(%d) = (%x)\n", io, *enable);
}
/*
* PM1 is awkward because the SLP_TYP bits are not common between the two registers.
* A better interface than this might pass the SLP_TYP bits separately.
*/
void
acpi_io_pm1_control(acpi_softc_t *sc, boolean_t io, u_int32_t *value_a, u_int32_t *value_b)
{
struct FACPbody *facp;
u_int32_t result;
facp = sc->facp_body;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_PM1A_CNT, 0, &result, facp->pm1_cnt_len);
*value_a = result;
acpi_register_input(sc, ACPI_RES_PM1B_CNT, 0, &result, facp->pm1_cnt_len);
*value_a |= result;
*value_a &= ~ACPI_CNT_SLP_TYPX; /* mask the SLP_TYP bits */
} else {
acpi_register_output(sc, ACPI_RES_PM1A_CNT, 0, value_a, facp->pm1_cnt_len);
acpi_register_output(sc, ACPI_RES_PM1B_CNT, 0, value_b, facp->pm1_cnt_len);
}
ACPI_DEBUGPRINT("acpi_io_pm1_control(%d) = (%x, %x)\n", io, *value_a, *value_b);
}
void
acpi_io_pm2_control(acpi_softc_t *sc, boolean_t io, u_int32_t *val)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->pm2_cnt_len;
if (size == 0) /* port is optional */
return;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_PM2_CNT, 0, val, size);
} else {
acpi_register_output(sc, ACPI_RES_PM2_CNT, 0, val, size);
}
ACPI_DEBUGPRINT("acpi_io_pm2_control(%d) = (%x)\n", io, *val);
return;
}
void
acpi_io_pm_timer(acpi_softc_t *sc, boolean_t io, u_int32_t *val)
{
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_PM_TMR, 0, val, sizeof(u_int32_t));
ACPI_DEBUGPRINT("acpi_io_pm_timer(%d) = (%x)\n", io, *val);
}
}
void
acpi_io_gpe0_status(acpi_softc_t *sc, boolean_t io, u_int32_t *val)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->gpe0_len / 2;
if (size == 0) /* port is optional */
return;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_GPE0, 0, val, size);
} else {
acpi_register_output(sc, ACPI_RES_GPE0, 0, val, size);
}
ACPI_DEBUGPRINT("acpi_io_gpe0_status(%d) = (%x)\n", io, *val);
}
void
acpi_io_gpe0_enable(acpi_softc_t *sc, boolean_t io, u_int32_t *val)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->gpe0_len / 2;
if (size == 0) /* port is optional */
return;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_GPE0, size, val, size);
} else {
acpi_register_output(sc, ACPI_RES_GPE0, size, val, size);
}
ACPI_DEBUGPRINT("acpi_io_gpe0_enable(%d) = (%x)\n", io, *val);
}
void
acpi_io_gpe1_status(acpi_softc_t *sc, boolean_t io, u_int32_t *val)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->gpe1_len / 2;
if (size == 0) /* port is optional */
return;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_GPE1, 0, val, size);
} else {
acpi_register_output(sc, ACPI_RES_GPE1, 0, val, size);
}
ACPI_DEBUGPRINT("acpi_io_gpe1_status(%d) = (%x)\n", io, *val);
}
void
acpi_io_gpe1_enable(acpi_softc_t *sc, boolean_t io, u_int32_t *val)
{
int size;
struct FACPbody *facp;
facp = sc->facp_body;
size = facp->gpe1_len / 2;
if (size == 0) /* port is optional */
return;
if (io == ACPI_REGISTER_INPUT) {
acpi_register_input(sc, ACPI_RES_GPE1, size, val, size);
} else {
acpi_register_output(sc, ACPI_RES_GPE1, size, val, size);
}
ACPI_DEBUGPRINT("acpi_io_gpe0_enable(%d) = (%x)\n", io, *val);
}
void
acpi_gpe_enable_bit(acpi_softc_t *sc, u_int32_t bit, boolean_t on_off)
{
u_int32_t value;
int res;
/*
* Is the bit in the first GPE port?
*/
if (bit < ((sc->facp_body->gpe0_len / 2) * 8)) {
res = ACPI_RES_GPE0;
} else {
/*
* Is the bit in the second GPE port?
*/
bit -= sc->facp_body->gpe1_base;
if (bit < ((sc->facp_body->gpe1_len / 2) * 8)) {
res = ACPI_RES_GPE1;
} else {
return; /* do nothing */
}
}
switch (res) {
case ACPI_RES_GPE0:
acpi_io_gpe0_enable(sc, ACPI_REGISTER_INPUT, &value);
break;
case ACPI_RES_GPE1:
acpi_io_gpe1_enable(sc, ACPI_REGISTER_INPUT, &value);
break;
}
value = (value & ~(1 << bit)) | (on_off ? (1 << bit) : 0);
switch (res) {
case ACPI_RES_GPE0:
acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT, &value);
break;
case ACPI_RES_GPE1:
acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT, &value);
break;
}
}

View File

@ -27,15 +27,18 @@
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/acpi.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/acpi/acpi.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#include <dev/acpi/aml/aml_amlmem.h>
#include <dev/acpi/aml/aml_common.h>

33
sys/dev/acpi/acpiio.h Normal file
View File

@ -0,0 +1,33 @@
/*-
* Copyright (c) 1999 Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
* Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#define ACPIIO_ENABLE _IO('P', 1)
#define ACPIIO_DISABLE _IO('P', 2)
#define ACPIIO_SETSLPSTATE _IOW('P', 3, int)

View File

@ -24,14 +24,23 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpi.h,v 1.9 2000/08/08 14:12:16 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _SYS_ACPI_H_
#define _SYS_ACPI_H_
#include <sys/ioccom.h>
/* Generic Address structure */
struct ACPIgas {
u_int8_t address_space_id;
#define ACPI_GAS_MEMORY 0
#define ACPI_GAS_IO 1
#define ACPI_GAS_PCI 2
#define ACPI_GAS_EMBEDDED 3
#define ACPI_GAS_SMBUS 4
#define ACPI_GAS_FIXED 0x7f
u_int8_t register_bit_width;
u_int8_t register_bit_offset;
u_int8_t res;
u_int64_t address;
} __attribute__((packed));
/* Root System Description Pointer */
struct ACPIrsdp {
@ -96,7 +105,8 @@ struct FACPbody {
u_int8_t day_alrm;
u_int8_t mon_alrm;
u_int8_t century;
u_char reserved4[3];
u_int16_t iapc_boot_arch;
u_char reserved4[1];
u_int32_t flags;
#define ACPI_FACP_FLAG_WBINVD 1 /* WBINVD is correctly supported */
#define ACPI_FACP_FLAG_WBINVD_FLUSH 2 /* WBINVD flushes caches */
@ -108,6 +118,19 @@ struct FACPbody {
#define ACPI_FACP_FLAG_RTC_S4 128 /* RTC can wakeup from S4 state */
#define ACPI_FACP_FLAG_TMR_VAL_EXT 256 /* TMR_VAL is 32bit */
#define ACPI_FACP_FLAG_DCK_CAP 512 /* Can support docking */
struct ACPIgas reset_reg;
u_int8_t reset_value;
u_int8_t reserved5[3];
u_int64_t x_firmware_ctrl;
u_int64_t x_dsdt;
struct ACPIgas x_pm1a_evt_blk;
struct ACPIgas x_pm1b_evt_blk;
struct ACPIgas x_pm1a_cnt_blk;
struct ACPIgas x_pm1b_cnt_blk;
struct ACPIgas x_pm2_cnt_blk;
struct ACPIgas x_pm_tmr_blk;
struct ACPIgas x_gpe0_blk;
struct ACPIgas x_gpe1_blk;
} __attribute__((packed));
/* Firmware ACPI Control Structure */
@ -171,10 +194,6 @@ struct FACS {
#define ACPI_S_STATE_S4 4
#define ACPI_S_STATE_S5 5
#define ACPIIO_ENABLE _IO('P', 1)
#define ACPIIO_DISABLE _IO('P', 2)
#define ACPIIO_SETSLPSTATE _IOW('P', 3, int)
#ifdef _KERNEL
/*
* Structure for System State Package (7.5.2).
@ -187,11 +206,6 @@ struct acpi_system_state_package {
};
#define ACPI_UNSUPPORTSLPTYP 0xff /* unsupported sleeping type */
extern struct ACPIrsdp *acpi_rsdp; /* ACPI Root System Description Table */
void acpi_init_addr_range(void);
void acpi_register_addr_range(u_int64_t, u_int64_t, u_int32_t);
/*
* ACPICA compatibility
*/
@ -330,4 +344,3 @@ void acpi_print_dsdt(struct ACPIsdt *);
#endif /* _KERNEL */
#endif /* _SYS_ACPI_H_ */

View File

@ -1,6 +1,8 @@
/*-
* Copyright (c) 1999 Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* Copyright (c) 2000 Michael Smith <msmith@FreeBSD.org>
* Copyright (c) 2000 BSDi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,9 +29,6 @@
* $FreeBSD$
*/
#ifndef _DEV_ACPI_ACPI_H_
#define _DEV_ACPI_ACPI_H_
/*
* PowerResource control
*/
@ -92,15 +91,40 @@ struct acpi_event {
int ae_arg;
};
/*
* I/O resource structure
*/
#define ACPI_RES_SMI_CMD 0
#define ACPI_RES_PM1A_EVT 1
#define ACPI_RES_PM1B_EVT 2
#define ACPI_RES_PM1A_CNT 3
#define ACPI_RES_PM1B_CNT 4
#define ACPI_RES_PM2_CNT 5
#define ACPI_RES_PM_TMR 6
#define ACPI_RES_GPE0 7
#define ACPI_RES_GPE1 8
#define ACPI_RES_FIRSTFREE 9
#define ACPI_RES_AUTO -1
#define ACPI_RES_MAX 64
struct acpi_io_resource {
struct resource *rsc;
int rid;
int size;
bus_space_handle_t bhandle;
bus_space_tag_t btag;
};
/*
* Softc
*/
*/
typedef struct acpi_softc {
device_t dev;
dev_t dev_t;
struct resource *port;
int port_rid;
struct acpi_io_resource iores[ACPI_RES_MAX];
struct resource *irq;
int irq_rid;
void *irq_handle;
@ -125,6 +149,23 @@ typedef struct acpi_softc {
STAILQ_HEAD(, acpi_event) event;
} acpi_softc_t;
/*
* ACPI register I/O
*/
#define ACPI_REGISTER_INPUT 0
#define ACPI_REGISTER_OUTPUT 1
extern void acpi_enable_disable(acpi_softc_t *sc, boolean_t enable);
extern void acpi_io_pm1_status(acpi_softc_t *sc, boolean_t io, u_int32_t *status);
extern void acpi_io_pm1_enable(acpi_softc_t *sc, boolean_t io, u_int32_t *enable);
extern void acpi_io_pm1_control(acpi_softc_t *sc, boolean_t io, u_int32_t *val_a, u_int32_t *val_b);
extern void acpi_io_pm2_control(acpi_softc_t *sc, boolean_t io, u_int32_t *val);
extern void acpi_io_pm_timer(acpi_softc_t *sc, boolean_t io, u_int32_t *val);
extern void acpi_io_gpe0_status(acpi_softc_t *sc, boolean_t io, u_int32_t *val);
extern void acpi_io_gpe0_enable(acpi_softc_t *sc, boolean_t io, u_int32_t *val);
extern void acpi_io_gpe1_status(acpi_softc_t *sc, boolean_t io, u_int32_t *val);
extern void acpi_io_gpe1_enable(acpi_softc_t *sc, boolean_t io, u_int32_t *val);
/*
* Device State
*/
@ -134,6 +175,11 @@ extern void acpi_set_device_state(acpi_softc_t *sc, struct aml_name *name,
extern void acpi_set_device_wakecap(acpi_softc_t *sc, struct aml_name *name,
u_int8_t cap);
/*
* System state
*/
extern void acpi_set_sleeping_state(acpi_softc_t *sc, u_int8_t state);
/*
* PowerResource State
*/
@ -147,20 +193,54 @@ extern void acpi_powerres_set_sleeping_state(acpi_softc_t *sc, u_int8_t state);
/*
* GPE enable bit manipulation
*/
extern void acpi_gpe_enable_bit(acpi_softc_t *, u_int32_t, boolean_t);
extern void acpi_gpe_enable_bit(acpi_softc_t *sc, u_int32_t bit, boolean_t on_off);
/*
* Event queue
* Event management
*/
extern void acpi_intr(void *data);
extern void acpi_queue_event(acpi_softc_t *sc, int type, int arg);
extern int acpi_send_pm_event(acpi_softc_t *sc, u_int8_t state);
extern void acpi_enable_events(acpi_softc_t *sc);
extern void acpi_clear_ignore_events(void *arg);
extern void acpi_event_thread(void *arg);
/*
* ACPI pmap subsystem
*/
#define ACPI_SMAP_MAX_SIZE 16
struct ACPIaddr {
int entries;
struct {
vm_offset_t pa_base;
vm_offset_t va_base;
vm_size_t size;
u_int32_t type;
} t [ACPI_SMAP_MAX_SIZE];
};
extern struct ACPIaddr acpi_addr;
extern struct ACPIrsdp *acpi_rsdp; /* ACPI Root System Description Table */
extern void acpi_init_addr_range(void);
extern void acpi_register_addr_range(u_int64_t base, u_int64_t size, u_int32_t type);
extern int acpi_sdt_checksum(struct ACPIsdt * sdt);
extern vm_offset_t acpi_pmap_ptv(vm_offset_t pa);
extern vm_offset_t acpi_pmap_vtp(vm_offset_t va);
/*
* Bus interface.
*/
extern int acpi_attach_resource(acpi_softc_t *sc, int type, int *wantidx,
u_long start, u_long size);
extern struct ACPIrsdp *acpi_find_rsdp(void);
extern void acpi_mapmem(void);
/*
* Debugging, console output
*
* XXX this should really be using device_printf
* XXX this should really be using device_printf or similar.
*/
extern int acpi_debug;
#define ACPI_DEVPRINTF(args...) printf("acpi0: " args)
#define ACPI_DEBUGPRINT(args...) do { if (acpi_debug) ACPI_DEVPRINTF(args);} while(0)
#endif /* !_DEV_ACPI_ACPI_H_ */

View File

@ -42,7 +42,7 @@
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/acpi.h>
#include <dev/acpi/acpireg.h>
#ifndef ACPI_NO_OSDFUNC_INLINE
#include <machine/acpica_osd.h>
#endif /* !ACPI_NO_OSDFUNC_INLINE */

View File

@ -32,10 +32,15 @@
* Region I/O subroutine
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/acpi.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_region.h>
#include <dev/acpi/aml/aml_name.h>

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,14 +23,116 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpi_machdep.c,v 1.4 2000/08/08 14:12:10 iwasaki Exp $
* $FreeBSD$
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/acpi_machdep.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#ifdef ACPI_NO_OSDFUNC_INLINE
#include <machine/acpica_osd.h>
#endif /* ACPI_NO_OSDFUNC_INLINE */
#include <machine/bus.h>
#include <machine/md_var.h>
#include <machine/vmparam.h>
#include <machine/vm86.h>
#include <machine/pc/bios.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
struct ACPIrsdp *
acpi_find_rsdp(void)
{
u_long sigaddr;
struct ACPIrsdp *rsdp;
u_int8_t ck, *cv;
int i, year;
char *dp;
/*
* Search for the RSD PTR signature.
*/
if ((sigaddr = bios_sigsearch(0, "RSD PTR ", 8, 16, 0)) == 0)
return(NULL);
/* get a virtual pointer to the structure */
rsdp = (struct ACPIrsdp *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr);
for (cv = (u_int8_t *)rsdp, ck = 0, i = 0; i < sizeof(struct ACPIrsdp); i++) {
ck += cv[i];
}
/*
* Fail if the checksum doesn't match.
*/
if (ck != 0) {
printf("ACPI: Bad ACPI BIOS data checksum\n");
return(NULL);
}
/*
* Fail if the BIOS is too old to be trustworthy.
* XXX we should check the ACPI BIOS blacklist/goodlist here.
*/
dp = (char *)(uintptr_t)BIOS_PADDRTOVADDR(0xffff5);
year = ((*(dp + 6) - '0') * 10) + (*(dp + 7) - '0');
if (year < 70)
year += 100;
if (year < 99) {
printf("ACPI: BIOS too old (%.8s < 01/01/99)\n", dp);
return(NULL);
}
return(rsdp);
}
/*
* Find and map all memory regions that are regarded as belonging to ACPI
* and let the MI code know about them. Scan the ACPI memory map as managed
* by the MI code and map it into kernel space.
*/
void
acpi_mapmem(void)
{
struct vm86frame vmf;
struct vm86context vmc;
struct bios_smap *smap;
vm_offset_t va;
int i;
bzero(&vmf, sizeof(struct vm86frame));
acpi_init_addr_range();
/*
* Scan memory map with INT 15:E820
*/
vmc.npages = 0;
smap = (void *)vm86_addpage(&vmc, 1, KERNBASE + (1 << PAGE_SHIFT));
vm86_getptr(&vmc, (vm_offset_t)smap, &vmf.vmf_es, &vmf.vmf_di);
vmf.vmf_ebx = 0;
do {
vmf.vmf_eax = 0xE820;
vmf.vmf_edx = SMAP_SIG;
vmf.vmf_ecx = sizeof(struct bios_smap);
i = vm86_datacall(0x15, &vmf, &vmc);
if (i || vmf.vmf_eax != SMAP_SIG)
break;
/* ACPI-owned memory? */
if (smap->type == 0x03 || smap->type == 0x04) {
acpi_register_addr_range(smap->base, smap->length, smap->type);
}
} while (vmf.vmf_ebx != 0);
/*
* Map the physical ranges that have been registered into the kernel.
*/
for (i = 0; i < acpi_addr.entries; i++) {
va = (vm_offset_t)pmap_mapdev(acpi_addr.t[i].pa_base, acpi_addr.t[i].size);
acpi_addr.t[i].va_base = va;
}
}

View File

@ -31,7 +31,6 @@
* Code for dealing with the BIOS in x86 PC systems.
*/
#include "acpi.h"
#include "isa.h"
#include <sys/param.h>
@ -50,10 +49,6 @@
#include <isa/pnpreg.h>
#include <isa/pnpvar.h>
#if NACPI > 0
#include <sys/acpi.h>
#endif
#define BIOS_START 0xe0000
#define BIOS_SIZE 0x20000
@ -148,26 +143,6 @@ bios32_init(void *junk)
printf("pnpbios: Bad PnP BIOS data checksum\n");
}
}
#if NACPI > 0
/*
* ACPI BIOS
* acpi_rsdp is GLOBAL and holds RSD PTR signature
*/
if ((sigaddr = bios_sigsearch(0, "RSD PTR ", 8, 16, 0)) != 0) {
/* get a virtual pointer to the structure */
acpi_rsdp = (struct ACPIrsdp *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr);
for (cv = (u_int8_t *)acpi_rsdp, ck = 0, i = 0; i < sizeof(struct ACPIrsdp); i++) {
ck += cv[i];
}
/* If checksum is NG, disable it */
if (ck != 0) {
printf("ACPI: Bad ACPI BIOS data checksum\n");
acpi_rsdp=NULL;/* 0xa0000<=RSD_PTR<0x100000*/
}
}
#endif
if (bootverbose) {
/* look for other know signatures */
printf("Other BIOS signatures found:\n");

View File

@ -37,7 +37,6 @@
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $FreeBSD$
*/
#include "acpi.h"
#include "apm.h"
#include "npx.h"
#include "opt_atalk.h"
@ -100,6 +99,7 @@
#include <machine/ipl.h>
#include <machine/md_var.h>
#include <machine/mutex.h>
#include <machine/pc/bios.h>
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
#include <machine/globaldata.h>
#include <machine/globals.h>
@ -120,10 +120,6 @@
#include <sys/ptrace.h>
#include <machine/sigframe.h>
#if NACPI > 0
#include <sys/acpi.h>
#endif
extern void init386 __P((int first));
extern void dblfault_handler __P((void));
@ -1457,11 +1453,7 @@ getmemsize(int first)
vm_offset_t pa, physmap[PHYSMAP_SIZE];
pt_entry_t pte;
const char *cp;
struct {
u_int64_t base;
u_int64_t length;
u_int32_t type;
} *smap;
struct bios_smap *smap;
bzero(&vmf, sizeof(struct vm86frame));
bzero(physmap, sizeof(physmap));
@ -1521,22 +1513,16 @@ getmemsize(int first)
/*
* get memory map with INT 15:E820
*/
#define SMAPSIZ sizeof(*smap)
#define SMAP_SIG 0x534D4150 /* 'SMAP' */
vmc.npages = 0;
smap = (void *)vm86_addpage(&vmc, 1, KERNBASE + (1 << PAGE_SHIFT));
vm86_getptr(&vmc, (vm_offset_t)smap, &vmf.vmf_es, &vmf.vmf_di);
#if NACPI > 0
acpi_init_addr_range();
#endif
physmap_idx = 0;
vmf.vmf_ebx = 0;
do {
vmf.vmf_eax = 0xE820;
vmf.vmf_edx = SMAP_SIG;
vmf.vmf_ecx = SMAPSIZ;
vmf.vmf_ecx = sizeof(struct bios_smap);
i = vm86_datacall(0x15, &vmf, &vmc);
if (i || vmf.vmf_eax != SMAP_SIG)
break;
@ -1547,13 +1533,7 @@ getmemsize(int first)
(u_int32_t)smap->base,
*(u_int32_t *)((char *)&smap->length + 4),
(u_int32_t)smap->length);
#if NACPI > 0
/* Save ACPI related memory Info */
if (smap->type == 0x03 || smap->type == 0x04) {
acpi_register_addr_range(smap->base,
smap->length, smap->type);
}
#endif
if (smap->type != 0x01)
goto next_run;

View File

@ -218,3 +218,16 @@ extern int bios16(struct bios_args *, char *, ...);
extern int bios16_call(struct bios_regs *, char *);
extern int bios32(struct bios_regs *, u_int, u_short);
extern void set_bios_selectors(struct bios_segments *, int);
/*
* Int 15:E820 'SMAP' structure
*
* XXX add constants for type
*/
#define SMAP_SIG 0x534D4150 /* 'SMAP' */
struct bios_smap {
u_int64_t base;
u_int64_t length;
u_int32_t type;
} __attribute__ ((packed));

View File

@ -42,7 +42,7 @@
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/acpi.h>
#include <dev/acpi/acpireg.h>
#ifndef ACPI_NO_OSDFUNC_INLINE
#include <machine/acpica_osd.h>
#endif /* !ACPI_NO_OSDFUNC_INLINE */

View File

@ -32,10 +32,15 @@
* Region I/O subroutine
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/acpi.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_region.h>
#include <dev/acpi/aml/aml_name.h>