Farewell our code. We will switch acpica code from Intel.

This code has help us comprehence ACPI spec .

Contributors of this code is as follows(except for FreeBSD commiter):
Yasuo Yokoyama,
Munehiro Matsuda,
and ALL acpi-jp@jp.freebsd.org people.

Thanks.

R.I.P.
This commit is contained in:
Takanori Watanabe 2000-11-09 05:09:52 +00:00
parent b5a8a15c2f
commit c69ab48d38
32 changed files with 0 additions and 9906 deletions

View file

@ -182,19 +182,6 @@ 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 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
dev/acpi/aml/aml_evalobj.c optional acpi
dev/acpi/aml/aml_memman.c optional acpi
dev/acpi/aml/aml_name.c optional acpi
dev/acpi/aml/aml_obj.c optional acpi
dev/acpi/aml/aml_parse.c optional acpi
dev/acpi/aml/aml_store.c optional acpi
dev/acpi/aml/aml_region.c optional acpi
dev/acpica/acpi.c optional acpica
dev/acpica/acpi_apic.c optional acpica
dev/acpica/acpi_button.c optional acpica

View file

@ -151,7 +151,6 @@ gnu/i386/isa/dgm.c count dgm
i386/apm/apm.c count apm
i386/i386/atomic.c standard \
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
i386/i386/acpi_machdep.c optional acpi
i386/i386/autoconf.c standard
i386/i386/bios.c standard
i386/i386/bioscall.s standard

File diff suppressed because it is too large Load diff

View file

@ -1,431 +0,0 @@
/*-
* 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_disable_events(acpi_softc_t *sc)
{
u_int32_t zero;
if (sc->enabled) {
zero = 0;
acpi_io_pm1_enable(sc, ACPI_REGISTER_OUTPUT, &zero);
acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT, &zero);
acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT, &zero);
}
}
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");
}

View file

@ -1,356 +0,0 @@
/*-
* 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

@ -1,754 +0,0 @@
/*-
* Copyright (c) 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/kernel.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_evalobj.h>
#include <dev/acpi/aml/aml_name.h>
#include <dev/acpi/aml/aml_parse.h>
#include <dev/acpi/aml/aml_memman.h>
static int acpi_powerres_register(struct aml_name *name, va_list ap);
static int acpi_powerres_add_device(struct aml_name *name, va_list ap);
static void acpi_set_device_next_state(acpi_softc_t *sc,
struct acpi_powerres_device *device,
u_int8_t sleeping_state,
u_int8_t def_dstate);
static char *powerres_statestr[2] = {"_OFF", "_ON"};
/*
* 7.3.3 Evaluates to the current device state.
*/
u_int8_t
acpi_get_current_device_state(struct aml_name *name)
{
u_int8_t dstate;
struct aml_name *method;
union aml_object *ret;
struct aml_environ env;
dstate = ACPI_D_STATE_D0;
method = aml_find_from_namespace(name, "_PSC");
if (method == NULL) {
return (dstate);
}
bzero(&env, sizeof(env));
aml_local_stack_push(aml_local_stack_create());
ret = aml_eval_name(&env, method);
dstate = ret->num.number;
aml_local_stack_delete(aml_local_stack_pop());
return (dstate);
}
static __inline struct acpi_powerres_device *
acpi_powerres_get_powerres_device(acpi_softc_t *sc, struct aml_name *name)
{
struct acpi_powerres_device *device;
LIST_FOREACH(device, &sc->acpi_powerres_devlist, links) {
if (device->name == name) {
return (device);
}
}
return (NULL);
}
/*
* 7.2.2-4: For the OS to put the device in the Dx device state.
*/
void
acpi_set_device_state(acpi_softc_t *sc, struct aml_name *name, u_int8_t dstate)
{
char psx[5]; /* "_PSx" */
struct acpi_powerres_info *powerres;
struct acpi_powerres_device_ref *device_ref;
struct acpi_powerres_device *device;
struct aml_name *method;
struct aml_environ env;
if (dstate > ACPI_D_STATE_D3) {
return;
}
device = acpi_powerres_get_powerres_device(sc, name);
if (device == NULL) {
return;
}
device->state = dstate;
/*
* D3 state transition. We don't need to check PowerResource,
* just execute _PS3 control method of the device.
*/
if (dstate == ACPI_D_STATE_D3) {
goto method_execution;
}
/*
* D0 - D2 state transition.
* All Power Resources referenced by elements 1 through N
* in _PRx of the device must be in the ON state.
*
*/
LIST_FOREACH(powerres, &sc->acpi_powerres_inflist, links) {
LIST_FOREACH(device_ref, &powerres->reflist[dstate], links) {
if (device_ref->device->name != name) {
continue;
}
if (powerres->state != ACPI_POWER_RESOURCE_ON) {
acpi_set_powerres_state(sc, powerres->name,
ACPI_POWER_RESOURCE_ON);
}
break; /* already found, goto next PowerResource */
}
}
method_execution:
/*
* If present, the _PSx control method is executed to set the
* device into the Dx device state.
*/
snprintf(psx, sizeof(psx), "_PS%d", dstate);
method = aml_find_from_namespace(name, psx);
if (method == NULL) {
return;
}
bzero(&env, sizeof(env));
aml_local_stack_push(aml_local_stack_create());
aml_eval_name(&env, method);
aml_local_stack_delete(aml_local_stack_pop());
}
/*
* 7.2.1: For the OS to have the defined wake capability properly enabled
* for the device.
*/
void
acpi_set_device_wakecap(acpi_softc_t *sc, struct aml_name *name, u_int8_t cap)
{
struct acpi_powerres_info *powerres;
struct acpi_powerres_device_ref *device_ref;
struct acpi_powerres_device *device;
struct aml_name *method;
union aml_object argv[1];
if (cap != ACPI_D_WAKECAP_ENABLE && cap != ACPI_D_WAKECAP_DISABLE ) {
return;
}
device = acpi_powerres_get_powerres_device(sc, name);
if (device == NULL) {
return;
}
device->wake_cap = cap;
/*
* Disable wake capability. We don't need to check PowerResource,
* just execute _PSW control method of the device.
*/
if (cap == ACPI_D_WAKECAP_DISABLE ) {
goto method_execution;
}
/*
* Enable wake capability.
* All Power Resources referenced by elements 2 through N
* are put into the ON state.
*
*/
LIST_FOREACH(powerres, &sc->acpi_powerres_inflist, links) {
LIST_FOREACH(device_ref, &powerres->prwlist, links) {
if (device_ref->device->name != name) {
continue;
}
if (powerres->state != ACPI_POWER_RESOURCE_ON) {
acpi_set_powerres_state(sc, powerres->name,
ACPI_POWER_RESOURCE_ON);
}
break; /* already found, goto next PowerResource */
}
}
method_execution:
/*
* If present, the _PSW control method is executed to set the
* device-specific registers to enable the wake functionality
* of the device.
*/
method = aml_find_from_namespace(name, "_PSW");
if (method == NULL) {
return;
}
argv[0].type = aml_t_num;
argv[0].num.number = cap;
aml_invoke_method(method, 1, argv); /* no result code */
}
/*
* 7.4.1 Returns the current ON or OFF status for the power resource.
*/
u_int8_t
acpi_get_current_powerres_state(struct aml_name *name)
{
u_int8_t pstate;
struct aml_name *method;
union aml_object *ret;
struct aml_environ env;
pstate = ACPI_POWER_RESOURCE_ON;
method = aml_find_from_namespace(name, "_STA");
if (method == NULL) {
return (pstate); /* just in case */
}
bzero(&env, sizeof(env));
aml_local_stack_push(aml_local_stack_create());
ret = aml_eval_name(&env, method);
pstate = ret->num.number; /* OFF or ON */
aml_local_stack_delete(aml_local_stack_pop());
return (pstate);
}
static __inline struct acpi_powerres_info *
acpi_powerres_get_powerres(acpi_softc_t *sc, struct aml_name *name)
{
struct acpi_powerres_info *powerres;
LIST_FOREACH(powerres, &sc->acpi_powerres_inflist, links) {
if (powerres->name == name) {
return (powerres);
}
}
return (NULL);
}
/*
* 7.4.2,3 Puts the power resource into the ON/OFF state.
*/
void
acpi_set_powerres_state(acpi_softc_t *sc, struct aml_name *name,
u_int8_t pstate)
{
struct acpi_powerres_info *powerres;
struct aml_name *method;
struct aml_environ env;
if (pstate != ACPI_POWER_RESOURCE_ON &&
pstate != ACPI_POWER_RESOURCE_OFF) {
return;
}
powerres = acpi_powerres_get_powerres(sc, name);
if (powerres == NULL) {
return;
}
powerres->state = pstate;
method = aml_find_from_namespace(name, powerres_statestr[pstate]);
if (method == NULL) {
return; /* just in case */
}
bzero(&env, sizeof(env));
aml_local_stack_push(aml_local_stack_create());
aml_eval_name(&env, method);
aml_local_stack_delete(aml_local_stack_pop());
}
/*
* 7.1,2 Initialize the relationship of PowerResources and devices.
*/
void
acpi_powerres_init(acpi_softc_t *sc)
{
struct acpi_powerres_info *powerres;
struct acpi_powerres_device_ref *device_ref;
struct acpi_powerres_device *device;
int i;
while ((powerres = LIST_FIRST(&sc->acpi_powerres_inflist))) {
for (i = 0; i < ACPI_PR_MAX; i++) {
while ((device_ref = LIST_FIRST(&powerres->reflist[i]))) {
LIST_REMOVE(device_ref, links);
FREE(device_ref, M_TEMP);
}
LIST_INIT(&powerres->reflist[i]);
}
LIST_INIT(&powerres->prwlist);
LIST_REMOVE(powerres, links);
FREE(powerres, M_TEMP);
}
LIST_INIT(&sc->acpi_powerres_inflist);
while ((device = LIST_FIRST(&sc->acpi_powerres_devlist))) {
LIST_REMOVE(device, links);
FREE(device, M_TEMP);
}
LIST_INIT(&sc->acpi_powerres_devlist);
aml_apply_foreach_found_objects(NULL, ".",
acpi_powerres_register, sc);
aml_apply_foreach_found_objects(NULL, "_PR",
acpi_powerres_add_device, sc);
}
static __inline void
acpi_powerres_device_prw_print(struct acpi_powerres_device *device)
{
printf("[PRW:%d:", device->wake_cap);
switch (device->prw_val[0]->type) {
case aml_t_num:
/* bit index in GPEx_EN of the enable bit */
printf("0x%x", device->prw_val[0]->num.number);
break;
default:
/* XXX in ACPI 2.0, we can have additional GPE blocks */
printf("GPE block");
break;
}
/* the lowest sleeping state */
printf(":%d] ", device->prw_val[1]->num.number);
}
void
acpi_powerres_debug(acpi_softc_t *sc)
{
struct acpi_powerres_info *powerres;
struct acpi_powerres_device_ref *device_ref;
struct acpi_powerres_device *device;
int i;
LIST_FOREACH(powerres, &sc->acpi_powerres_inflist, links) {
printf("acpi_powerres_debug[powerres]:");
aml_print_curname(powerres->name);
printf("[%d:%d:%s]\n", powerres->name->property->pres.level,
powerres->name->property->pres.order,
powerres_statestr[powerres->state]);
/* for _PR[0-2] */
for (i = 0; i < ACPI_PR_MAX; i++) {
if (LIST_EMPTY(&powerres->reflist[i])) {
continue;
}
printf("\t_PR%d:", i);
LIST_FOREACH(device_ref, &powerres->reflist[i], links) {
device = device_ref->device;
aml_print_curname(device->name);
printf("[D%d] ", device->state);
}
printf("\n");
}
/* for _PRW */
if (LIST_EMPTY(&powerres->prwlist)) {
continue;
}
printf("\t_PRW:");
LIST_FOREACH(device_ref, &powerres->prwlist, links) {
device = device_ref->device;
aml_print_curname(device->name);
acpi_powerres_device_prw_print(device);
}
printf("\n");
}
LIST_FOREACH(device, &sc->acpi_powerres_devlist, links) {
printf("acpi_powerres_debug[device]:");
aml_print_curname(device->name);
if (device->state != ACPI_D_STATE_UNKNOWN) {
printf("[D%d] ", device->state);
}
if (device->wake_cap != ACPI_D_WAKECAP_UNKNOWN) {
acpi_powerres_device_prw_print(device);
}
printf("\n");
}
}
static int
acpi_powerres_register(struct aml_name *name, va_list ap)
{
int i, order;
acpi_softc_t *sc;
struct acpi_powerres_info *powerres, *other_pr, *last_pr;
sc = va_arg(ap, acpi_softc_t *);
if (name->property == NULL ||
name->property->type != aml_t_powerres) {
return (0);
}
MALLOC(powerres, struct acpi_powerres_info *,
sizeof(*powerres), M_TEMP, M_NOWAIT);
if (powerres == NULL) {
return (1);
}
powerres->name = name;
/* get the current ON or OFF status for the power resource */
powerres->state = acpi_get_current_powerres_state(name);
/* must be sorted by resource order of PowerResource */
order = powerres->name->property->pres.order;
other_pr = last_pr = NULL;
if (LIST_EMPTY(&sc->acpi_powerres_inflist)) {
LIST_INSERT_HEAD(&sc->acpi_powerres_inflist, powerres, links);
} else {
LIST_FOREACH(other_pr, &sc->acpi_powerres_inflist, links) {
if (other_pr->name->property->pres.order >= order) {
break; /* found */
}
last_pr = other_pr;
}
if (other_pr != NULL) {
LIST_INSERT_BEFORE(other_pr, powerres, links);
} else {
LIST_INSERT_AFTER(last_pr, powerres, links);
}
}
for (i = 0; i < ACPI_PR_MAX; i++) {
LIST_INIT(&powerres->reflist[i]);
}
LIST_INIT(&powerres->prwlist);
return (0);
}
static int
acpi_powerres_add_device(struct aml_name *name, va_list ap)
{
int i, offset, objtype;
int prnum;
int dev_found;
acpi_softc_t *sc;
struct acpi_powerres_device *device;
struct acpi_powerres_device_ref *device_ref;
struct acpi_powerres_info *powerres;
struct aml_name *powerres_name;
struct aml_environ env;
union aml_object **objects;
sc = va_arg(ap, acpi_softc_t *);
objtype = prnum = 0;
/* should be _PR[0-2] or _PRW */
switch (name->name[3]) {
case '0' ... '2':
objtype = ACPI_D_PM_TYPE_PRX;
prnum = name->name[3] - '0';
offset = 0;
break;
case 'W':
objtype = ACPI_D_PM_TYPE_PRW;
/* for _PRW, PowerResource reference starts from elements 2 */
offset = 2;
break;
default:
return (0);
}
if (name->property == NULL ||
name->property->type != aml_t_package) {
return (0);
}
if (name->property->package.elements == 0) {
return (0);
}
/* make the list of devices */
dev_found = 0;
LIST_FOREACH(device, &sc->acpi_powerres_devlist, links) {
if (device->name == name->parent) {
dev_found = 1;
break;
}
}
if (!dev_found) {
MALLOC(device, struct acpi_powerres_device *,
sizeof(*device), M_TEMP, M_NOWAIT);
if (device == NULL) {
return (1);
}
/* set default values */
device->state = ACPI_D_STATE_UNKNOWN;
device->wake_cap = ACPI_D_WAKECAP_UNKNOWN;
/* this is a _PR[0-2|W] object, we need the parent of this. */
device->name = name->parent;
LIST_INSERT_HEAD(&sc->acpi_powerres_devlist, device, links);
}
objects = name->property->package.objects;
switch (objtype) {
case ACPI_D_PM_TYPE_PRX:
/* get the current device state. */
if (device->state == ACPI_D_STATE_UNKNOWN) {
device->state = acpi_get_current_device_state(device->name);
}
break;
case ACPI_D_PM_TYPE_PRW:
device->wake_cap = ACPI_D_WAKECAP_DEFAULT;
for (i = 0; i < 2; i++) {
device->prw_val[i] = objects[i];
}
break;
default:
break;
}
/* find PowerResource which the device reference to */
MALLOC(device_ref, struct acpi_powerres_device_ref *,
sizeof(*device_ref), M_TEMP, M_NOWAIT);
if (device_ref == NULL) {
return (1);
}
device_ref->device = device;
env.curname = device->name;
for (i = offset; i < name->property->package.elements; i++) {
if (objects[i]->type != aml_t_namestr) {
printf("acpi_powerres_add_device: not name string\n");
continue;
}
powerres_name = aml_search_name(&env, objects[i]->nstr.dp);
if (powerres_name == NULL) {
printf("acpi_powerres_add_device: not found\n");
continue;
}
LIST_FOREACH(powerres, &sc->acpi_powerres_inflist, links) {
if (powerres->name != powerres_name) {
continue;
}
switch (objtype) {
case ACPI_D_PM_TYPE_PRX:
LIST_INSERT_HEAD(&powerres->reflist[prnum],
device_ref, links);
break;
case ACPI_D_PM_TYPE_PRW:
LIST_INSERT_HEAD(&powerres->prwlist,
device_ref, links);
break;
default:
break;
}
/* already found, go to next element... */
break;
}
}
switch (objtype) {
case ACPI_D_PM_TYPE_PRX:
/* XXX
* force to set the current device state to make
* PowerResource compatible with the device state.
*/
acpi_set_device_state(sc, device->name, device->state);
break;
case ACPI_D_PM_TYPE_PRW:
acpi_set_device_wakecap(sc, device->name, device->wake_cap);
break;
default:
break;
}
return (0);
}
static __inline void
acpi_set_device_prw_gpe(acpi_softc_t *sc, struct acpi_powerres_device *device,
boolean_t on_off)
{
u_long ef;
device->gpe_enabled = on_off;
/* The proper general-purpose register bits are enabled. */
switch (device->prw_val[0]->type) {
case aml_t_num:
/* bit index in GPEx_EN of the enable bit */
ef = read_eflags(); /* XXX should MI */
acpi_gpe_enable_bit(sc, device->prw_val[0]->num.number, on_off);
write_eflags(ef);
break;
default:
/* XXX in ACPI 2.0, we can have additional GPE blocks */
printf("ACPI 2.0 style _PRW/GPE handling is not supported\n");
break;
}
}
static void
acpi_set_device_next_state(acpi_softc_t *sc, struct acpi_powerres_device *device,
u_int8_t sleeping_state, u_int8_t def_dstate)
{
/* set given default device state */
device->next_state = def_dstate;
if (device->wake_cap != ACPI_D_WAKECAP_ENABLE) {
goto out;
}
/*
* 7.2.1 _PRW
* The sleeping state being enterted must be greater or equal to the
* power state declared in element 1 of the _PRW object.
*/
if (sleeping_state < device->prw_val[1]->num.number) {
goto out;
}
device->next_state = ACPI_D_STATE_D0; /* XXX need to refer _SxD ? */
if (sleeping_state > ACPI_S_STATE_S0 && device->gpe_enabled == 0) {
acpi_set_device_prw_gpe(sc, device, 1);
}
out:
return;
}
/*
* 7.1-5 PowerResource manipulation on the sleeping state transision.
*/
void
acpi_powerres_set_sleeping_state(acpi_softc_t *sc, u_int8_t state)
{
int i;
struct acpi_powerres_info *powerres;
struct acpi_powerres_device *device;
struct acpi_powerres_device_ref *device_ref;
if (state > ACPI_S_STATE_S4) {
return;
}
/*
* initialize the next device state to D0, then change to D3 later
* based on PowerResource state change.
*/
LIST_FOREACH(device, &sc->acpi_powerres_devlist, links) {
acpi_set_device_next_state(sc, device, state, ACPI_D_STATE_D0);
}
/*
* 7.5.2 System \_Sx state
* Power Resources are in a state compatible with the system Sx
* state. All power Resources that supply a System Level reference
* of Sn (where n < x) are in the OFF state.
*/
LIST_FOREACH(powerres, &sc->acpi_powerres_inflist, links) {
if (powerres->name->property->pres.level < state) {
/* if ON state then put it in the OFF state */
if (powerres->state == ACPI_POWER_RESOURCE_ON) {
acpi_set_powerres_state(sc, powerres->name,
ACPI_POWER_RESOURCE_OFF);
}
/*
* Device states are compatible with the current
* Power Resource states.
*/
for (i = 0; i < ACPI_PR_MAX; i++) {
LIST_FOREACH(device_ref, &powerres->reflist[i], links) {
device = device_ref->device;
acpi_set_device_next_state(sc, device,
state, ACPI_D_STATE_D3);
}
}
} else {
/* if OFF state then put it in the ON state */
if (powerres->state == ACPI_POWER_RESOURCE_OFF) {
acpi_set_powerres_state(sc, powerres->name,
ACPI_POWER_RESOURCE_ON);
}
}
}
/*
* Devices states are compatible with the current Power Resource
* states. only devices which solely reference Power Resources which
* are in the ON state for a given device state can be in that device
* state. In all other cases, the device is in the D3 (off) state.
* Note:
* Or is at least assumed to be in the D3 state by its device driver.
* For example, if the device doesn't explicitly describe how it can
* stay in some state non-off state while the system is in a sleeping
* state, the operating software must assume that the device can lose
* its power and state.
*/
LIST_FOREACH(device, &sc->acpi_powerres_devlist, links) {
if (device->next_state == ACPI_D_STATE_D3 &&
device->state != ACPI_D_STATE_D3) {
acpi_set_device_state(sc, device->name, ACPI_D_STATE_D3);
}
if (device->next_state == ACPI_D_STATE_D0 &&
device->state != ACPI_D_STATE_D0) {
acpi_set_device_state(sc, device->name, ACPI_D_STATE_D0);
}
/* XXX reset GEPx_EN enabled bit on S0 state */
if (state == ACPI_S_STATE_S0 && device->gpe_enabled &&
device->wake_cap == ACPI_D_WAKECAP_ENABLE) {
acpi_set_device_prw_gpe(sc, device, 0);
}
}
}

View file

@ -1,33 +0,0 @@
/*-
* 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

@ -1,352 +0,0 @@
/*-
* 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$
*/
/* 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 {
u_char signature[8];
u_char sum;
u_char oem[6];
u_char res;
u_int32_t addr;
} __attribute__((packed));
/* System Description Table */
struct ACPIsdt {
u_char signature[4];
u_int32_t len;
u_char rev;
u_char check;
u_char oemid[6];
u_char oemtblid[8];
u_int32_t oemrev;
u_char creator[4];
u_int32_t crerev;
#define SIZEOF_SDT_HDR 36 /* struct size except body */
u_int32_t body[1];/* This member should be casted */
} __attribute__((packed));
/* Fixed ACPI Description Table (body) */
struct FACPbody {
u_int32_t facs_ptr;
u_int32_t dsdt_ptr;
u_int8_t int_model;
#define ACPI_FACP_INTMODEL_PIC 0 /* Standard PC-AT PIC */
#define ACPI_FACP_INTMODEL_APIC 1 /* Multiple APIC */
u_char reserved1;
u_int16_t sci_int;
u_int32_t smi_cmd;
u_int8_t acpi_enable;
u_int8_t acpi_disable;
u_int8_t s4biosreq;
u_int8_t reserved2;
u_int32_t pm1a_evt_blk;
u_int32_t pm1b_evt_blk;
u_int32_t pm1a_cnt_blk;
u_int32_t pm1b_cnt_blk;
u_int32_t pm2_cnt_blk;
u_int32_t pm_tmr_blk;
u_int32_t gpe0_blk;
u_int32_t gpe1_blk;
u_int8_t pm1_evt_len;
u_int8_t pm1_cnt_len;
u_int8_t pm2_cnt_len;
u_int8_t pm_tmr_len;
u_int8_t gpe0_len;
u_int8_t gpe1_len;
u_int8_t gpe1_base;
u_int8_t reserved3;
u_int16_t p_lvl2_lat;
u_int16_t p_lvl3_lat;
u_int16_t flush_size;
u_int16_t flush_stride;
u_int8_t duty_off;
u_int8_t duty_width;
u_int8_t day_alrm;
u_int8_t mon_alrm;
u_int8_t century;
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 */
#define ACPI_FACP_FLAG_PROC_C1 4 /* C1 power state supported */
#define ACPI_FACP_FLAG_P_LVL2_UP 8 /* C2 power state works on SMP */
#define ACPI_FACP_FLAG_PWR_BUTTON 16 /* Power button uses control method */
#define ACPI_FACP_FLAG_SLP_BUTTON 32 /* Sleep button uses control method */
#define ACPI_FACP_FLAG_FIX_RTC 64 /* RTC wakeup not supported */
#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 */
struct FACS {
u_char signature[4];
u_int32_t len;
u_char hard_sig[4];
/*
* NOTE This should be filled with physical address below 1MB!!
* sigh....
*/
u_int32_t firm_wake_vec;
u_int32_t g_lock; /* bit field */
/* 5.2.6.1 Global Lock */
#define ACPI_GLOBAL_LOCK_PENDING 1
#define ACPI_GLOBAL_LOCK_OWNED 2
u_int32_t flags; /* bit field */
#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */
char reserved[40];
} __attribute__((packed));
/*
* Bits for ACPI registers
*/
/* Power Management 1 Event Regisers (4.7.3.1 Table 4-9, 4-10) */
/* these bits are for status and enable regiser */
#define ACPI_PM1_TMR_EN 0x0001
#define ACPI_PM1_GBL_EN 0x0020
#define ACPI_PM1_PWRBTN_EN 0x0100
#define ACPI_PM1_SLPBTN_EN 0x0200
#define ACPI_PM1_RTC_EN 0x0400
#define ACPI_PM1_ALL_ENABLE_BITS 0x0721
/* these bits are for status regiser only */
#define ACPI_PM1_BM_STS 0x0010
#define ACPI_PM1_WAK_STS 0x8000
/* Power Management 1 Control Regisers (4.7.3.2 Table 4-11) */
#define ACPI_CNT_SCI_EN 0x0001
#define ACPI_CNT_BM_RLD 0x0002
#define ACPI_CNT_GBL_RLS 0x0004
#define ACPI_CNT_SLP_TYPX 0x1c00
#define ACPI_CNT_SLP_EN 0x2000
#define ACPI_CNT_SET_SLP_TYP(x) (x << 10)
/* Power Management Timer (4.7.3.3 Table 4-12) */
/* Not yet */
/* Power Management 2 Control (4.7.3.4 Table 4-13) */
/* Not yet */
/* Processor Register Block (4.7.3.5 Table 4-14, 4-15, 4-16) */
/* Not yet */
/* Sleep state constants */
#define ACPI_S_STATE_S0 0
#define ACPI_S_STATE_S1 1
#define ACPI_S_STATE_S2 2
#define ACPI_S_STATE_S3 3
#define ACPI_S_STATE_S4 4
#define ACPI_S_STATE_S5 5
#ifdef _KERNEL
/*
* Structure for System State Package (7.5.2).
*/
struct acpi_system_state_package {
struct {
u_int8_t slp_typ_a; /* 3-bit only. */
u_int8_t slp_typ_b; /* (4.7.3.2.1) */
} mode[6];
};
#define ACPI_UNSUPPORTSLPTYP 0xff /* unsupported sleeping type */
/*
* ACPICA compatibility
*/
#ifdef _IA64
typedef signed char INT8;
typedef unsigned char UINT8;
typedef unsigned char UCHAR;
typedef short INT16;
typedef unsigned short UINT16;
typedef int INT32;
typedef unsigned int UINT32;
typedef long INT64;
typedef unsigned long UINT64;
typedef UINT64 NATIVE_UINT;
typedef INT64 NATIVE_INT;
typedef NATIVE_UINT ACPI_TBLPTR;
#else /* !_IA64 */
typedef signed char INT8;
typedef unsigned char UINT8;
typedef unsigned char UCHAR;
typedef short INT16;
typedef unsigned short UINT16;
typedef int INT32;
typedef unsigned int UINT32;
typedef UINT32 NATIVE_UINT;
typedef INT32 NATIVE_INT;
typedef NATIVE_UINT ACPI_TBLPTR;
#endif /* _IA64 */
/* common types */
typedef NATIVE_UINT ACPI_IO_ADDRESS;
typedef UINT32 ACPI_STATUS;
/*
* Exceptions returned by external ACPI interfaces
*/
#define ACPI_SUCCESS(a) (!(a))
#define ACPI_FAILURE(a) (a)
#define AE_OK (ACPI_STATUS) 0x0000
#define AE_CTRL_RETURN_VALUE (ACPI_STATUS) 0x0001
#define AE_CTRL_PENDING (ACPI_STATUS) 0x0002
#define AE_CTRL_TERMINATE (ACPI_STATUS) 0x0003
#define AE_CTRL_TRUE (ACPI_STATUS) 0x0004
#define AE_CTRL_FALSE (ACPI_STATUS) 0x0005
#define AE_CTRL_DEPTH (ACPI_STATUS) 0x0006
#define AE_CTRL_RESERVED (ACPI_STATUS) 0x0007
#define AE_AML_ERROR (ACPI_STATUS) 0x0008
#define AE_AML_PARSE (ACPI_STATUS) 0x0009
#define AE_AML_BAD_OPCODE (ACPI_STATUS) 0x000A
#define AE_AML_NO_OPERAND (ACPI_STATUS) 0x000B
#define AE_AML_OPERAND_TYPE (ACPI_STATUS) 0x000C
#define AE_AML_OPERAND_VALUE (ACPI_STATUS) 0x000D
#define AE_AML_UNINITIALIZED_LOCAL (ACPI_STATUS) 0x000E
#define AE_AML_UNINITIALIZED_ARG (ACPI_STATUS) 0x000F
#define AE_AML_UNINITIALIZED_ELEMENT (ACPI_STATUS) 0x0010
#define AE_AML_NUMERIC_OVERFLOW (ACPI_STATUS) 0x0011
#define AE_AML_REGION_LIMIT (ACPI_STATUS) 0x0012
#define AE_AML_BUFFER_LIMIT (ACPI_STATUS) 0x0013
#define AE_AML_PACKAGE_LIMIT (ACPI_STATUS) 0x0014
#define AE_AML_DIVIDE_BY_ZERO (ACPI_STATUS) 0x0015
#define AE_AML_BAD_NAME (ACPI_STATUS) 0x0016
#define AE_AML_NAME_NOT_FOUND (ACPI_STATUS) 0x0017
#define AE_AML_INTERNAL (ACPI_STATUS) 0x0018
#define AE_AML_RESERVED (ACPI_STATUS) 0x0019
#define AE_ERROR (ACPI_STATUS) 0x001A
#define AE_NO_ACPI_TABLES (ACPI_STATUS) 0x001B
#define AE_NO_NAMESPACE (ACPI_STATUS) 0x001C
#define AE_NO_MEMORY (ACPI_STATUS) 0x001D
#define AE_BAD_SIGNATURE (ACPI_STATUS) 0x001E
#define AE_BAD_HEADER (ACPI_STATUS) 0x001F
#define AE_BAD_CHECKSUM (ACPI_STATUS) 0x0020
#define AE_BAD_PARAMETER (ACPI_STATUS) 0x0021
#define AE_BAD_CHARACTER (ACPI_STATUS) 0x0022
#define AE_BAD_PATHNAME (ACPI_STATUS) 0x0023
#define AE_BAD_DATA (ACPI_STATUS) 0x0024
#define AE_BAD_ADDRESS (ACPI_STATUS) 0x0025
#define AE_NOT_FOUND (ACPI_STATUS) 0x0026
#define AE_NOT_EXIST (ACPI_STATUS) 0x0027
#define AE_EXIST (ACPI_STATUS) 0x0028
#define AE_TYPE (ACPI_STATUS) 0x0029
#define AE_NULL_OBJECT (ACPI_STATUS) 0x002A
#define AE_NULL_ENTRY (ACPI_STATUS) 0x002B
#define AE_BUFFER_OVERFLOW (ACPI_STATUS) 0x002C
#define AE_STACK_OVERFLOW (ACPI_STATUS) 0x002D
#define AE_STACK_UNDERFLOW (ACPI_STATUS) 0x002E
#define AE_NOT_IMPLEMENTED (ACPI_STATUS) 0x002F
#define AE_VERSION_MISMATCH (ACPI_STATUS) 0x0030
#define AE_SUPPORT (ACPI_STATUS) 0x0031
#define AE_SHARE (ACPI_STATUS) 0x0032
#define AE_LIMIT (ACPI_STATUS) 0x0033
#define AE_TIME (ACPI_STATUS) 0x0034
#define AE_UNKNOWN_STATUS (ACPI_STATUS) 0x0035
#define ACPI_MAX_STATUS (ACPI_STATUS) 0x0035
#define ACPI_NUM_STATUS (ACPI_STATUS) 0x0036
/*
* ACPICA Osd family functions
*/
#if defined(DIAGNOSTIC)
#define ACPI_NO_OSDFUNC_INLINE
#endif
#ifdef ACPI_NO_OSDFUNC_INLINE
ACPI_STATUS OsdMapMemory(void *, UINT32, void **);
void OsdUnMapMemory(void *, UINT32);
UINT8 OsdIn8(ACPI_IO_ADDRESS);
UINT16 OsdIn16(ACPI_IO_ADDRESS);
UINT32 OsdIn32(ACPI_IO_ADDRESS);
void OsdOut8(ACPI_IO_ADDRESS, UINT8);
void OsdOut16(ACPI_IO_ADDRESS, UINT16);
void OsdOut32(ACPI_IO_ADDRESS, UINT32);
ACPI_STATUS OsdReadPciCfgByte(UINT32, UINT32 , UINT32 , UINT8 *);
ACPI_STATUS OsdReadPciCfgWord(UINT32, UINT32 , UINT32 , UINT16 *);
ACPI_STATUS OsdReadPciCfgDword(UINT32, UINT32 , UINT32 , UINT32 *);
ACPI_STATUS OsdWritePciCfgByte(UINT32, UINT32 , UINT32 , UINT8);
ACPI_STATUS OsdWritePciCfgWord(UINT32, UINT32 , UINT32 , UINT16);
ACPI_STATUS OsdWritePciCfgDword(UINT32, UINT32 , UINT32 , UINT32);
ACPI_STATUS OsdSleep(UINT32, UINT32);
ACPI_STATUS OsdSleepUsec(UINT32);
#endif /* ACPI_NO_OSDFUNC_INLINE */
#else /* !_KERNEL */
void *acpi_map_physical(vm_offset_t, size_t);
struct ACPIrsdp *acpi_find_rsd_ptr(void);
int acpi_checksum(void *, size_t);
struct ACPIsdt *acpi_map_sdt(vm_offset_t);
void acpi_print_rsd_ptr(struct ACPIrsdp *);
void acpi_print_sdt(struct ACPIsdt *);
void acpi_print_rsdt(struct ACPIsdt *);
void acpi_print_facp(struct FACPbody *);
void acpi_print_dsdt(struct ACPIsdt *);
#endif /* _KERNEL */

View file

@ -1,253 +0,0 @@
/*-
* 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
* 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$
*/
/*
* PowerResource control
*/
struct acpi_powerres_device {
LIST_ENTRY(acpi_powerres_device) links;
struct aml_name *name;
/* _PR[0-2] */
u_int8_t state; /* D0 to D3 */
u_int8_t next_state; /* initialized with D0 */
#define ACPI_D_STATE_D0 0
#define ACPI_D_STATE_D1 1
#define ACPI_D_STATE_D2 2
#define ACPI_D_STATE_D3 3
#define ACPI_D_STATE_UNKNOWN 255
/* _PRW */
u_int8_t wake_cap; /* wake capability */
#define ACPI_D_WAKECAP_DISABLE 0
#define ACPI_D_WAKECAP_ENABLE 1
#define ACPI_D_WAKECAP_UNKNOWN 255
#define ACPI_D_WAKECAP_DEFAULT 1 /* XXX default enable for testing */
boolean_t gpe_enabled; /* GEPx_EN enabled/disabled */
union aml_object *prw_val[2]; /* elements of _PRW package */
};
/* Device Power Management Chained Object Type */
#define ACPI_D_PM_TYPE_IRC 0 /* _IRC */
#define ACPI_D_PM_TYPE_PRW 1 /* _PRW */
#define ACPI_D_PM_TYPE_PRX 2 /* _PR0 - _PR2 */
/* and more... */
struct acpi_powerres_device_ref {
LIST_ENTRY(acpi_powerres_device_ref) links;
struct acpi_powerres_device *device;
};
struct acpi_powerres_info {
LIST_ENTRY(acpi_powerres_info) links;
struct aml_name *name;
u_int8_t state; /* OFF or ON */
#define ACPI_POWER_RESOURCE_ON 1
#define ACPI_POWER_RESOURCE_OFF 0
#define ACPI_PR_MAX 3 /* _PR[0-2] */
LIST_HEAD(, acpi_powerres_device_ref) reflist[ACPI_PR_MAX];
LIST_HEAD(, acpi_powerres_device_ref) prwlist;
};
/*
* Event Structure
*/
struct acpi_event {
STAILQ_ENTRY (acpi_event) ae_q;
int ae_type;
#define ACPI_EVENT_TYPE_FIXEDREG 0
#define ACPI_EVENT_TYPE_GPEREG 1
#define ACPI_EVENT_TYPE_EC 2
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 acpi_io_resource iores[ACPI_RES_MAX];
struct resource *irq;
int irq_rid;
void *irq_handle;
struct ACPIsdt *rsdt;
struct ACPIsdt *facp;
struct FACPbody *facp_body;
struct ACPIsdt *dsdt;
struct FACS *facs;
int system_state;
int system_state_initialized;
int broken_wakeuplogic;
u_int32_t gpe0_mask;
u_int32_t gpe1_mask;
int enabled;
u_int32_t ignore_events;
struct acpi_system_state_package system_state_package;
struct proc *acpi_thread;
LIST_HEAD(, acpi_powerres_info) acpi_powerres_inflist;
LIST_HEAD(, acpi_powerres_device) acpi_powerres_devlist;
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
*/
extern u_int8_t acpi_get_current_device_state(struct aml_name *name);
extern void acpi_set_device_state(acpi_softc_t *sc, struct aml_name *name,
u_int8_t state);
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
*/
extern void acpi_powerres_init(acpi_softc_t *sc);
extern void acpi_powerres_debug(acpi_softc_t *sc);
extern u_int8_t acpi_get_current_powerres_state(struct aml_name *name);
extern void acpi_set_powerres_state(acpi_softc_t *sc, struct aml_name *name,
u_int8_t state);
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 *sc, u_int32_t bit, boolean_t on_off);
/*
* 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_disable_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 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)
/*
* System service interface
*/
extern int acpi_sleep(u_int32_t milli);

View file

@ -1,92 +0,0 @@
/*-
* 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.
*
* $Id: aml_amlmem.c,v 1.15 2000/08/09 14:47:43 iwasaki Exp $
* $FreeBSD$
*/
/*
* AML Namespace Memory Management
*/
#include <sys/param.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_memman.h>
#include <dev/acpi/aml/aml_name.h>
MEMMAN_INITIALSTORAGE_DESC(struct aml_namestr, _aml_namestr_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_num, _aml_num_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_string, _aml_string_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_buffer, _aml_buffer_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_package, _aml_package_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_field, _aml_field_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_method, _aml_method_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex, _aml_mutex_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_opregion, _aml_opregion_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_powerres, _aml_powerres_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_processor, _aml_processor_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_bufferfield, _aml_bufferfield_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_event, _aml_event_storage);
MEMMAN_INITIALSTORAGE_DESC(enum aml_objtype, _aml_objtype_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_name, _aml_name_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_name_group, _aml_name_group_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_objref, _aml_objref_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_regfield, _aml_regfield_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_environ, _aml_environ_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_local_stack, _aml_local_stack_storage);
MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex_queue, _aml_mutex_queue_storage);
struct memman_blockman aml_blockman[] = {
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_namestr), _aml_namestr_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_num), _aml_num_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_string), _aml_string_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_buffer), _aml_buffer_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_package), _aml_package_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_field), _aml_field_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_method), _aml_method_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex), _aml_mutex_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_opregion), _aml_opregion_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_powerres), _aml_powerres_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_processor), _aml_processor_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_bufferfield), _aml_bufferfield_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_event), _aml_event_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(enum aml_objtype), _aml_objtype_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name), _aml_name_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name_group), _aml_name_group_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_objref), _aml_objref_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_regfield), _aml_regfield_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_environ), _aml_environ_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_local_stack), _aml_local_stack_storage),
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex_queue), _aml_mutex_queue_storage),
};
struct memman_histogram aml_histogram[MEMMAN_HISTOGRAM_SIZE];
static struct memman _aml_memman = MEMMAN_MEMMANAGER_DESC(aml_blockman, 21,
aml_histogram, 1);
struct memman *aml_memman = &_aml_memman;

View file

@ -1,65 +0,0 @@
/*-
* 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.
*
* $Id: aml_amlmem.h,v 1.12 2000/08/08 14:12:05 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_AMLMEM_H_
#define _AML_AMLMEM_H_
/*
* AML Namespace Memory Management
*/
#include <dev/acpi/aml/aml_memman.h>
enum {
memid_aml_namestr = 0,
memid_aml_num,
memid_aml_string,
memid_aml_buffer,
memid_aml_package,
memid_aml_field,
memid_aml_method,
memid_aml_mutex,
memid_aml_opregion,
memid_aml_powerres,
memid_aml_processor,
memid_aml_bufferfield,
memid_aml_event,
memid_aml_objtype,
memid_aml_name,
memid_aml_name_group,
memid_aml_objref,
memid_aml_regfield,
memid_aml_environ,
memid_aml_local_stack,
memid_aml_mutex_queue,
};
extern struct memman *aml_memman;
#endif /* !_AML_AMLMEM_H_ */

View file

@ -1,735 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_common.c,v 1.9 2000/08/09 14:47:43 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#ifndef _KERNEL
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#else /* _KERNEL */
#include "opt_acpi.h"
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#ifndef ACPI_NO_OSDFUNC_INLINE
#include <machine/acpica_osd.h>
#endif /* !ACPI_NO_OSDFUNC_INLINE */
#endif /* !_KERNEL */
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_evalobj.h>
#include <dev/acpi/aml/aml_name.h>
#include <dev/acpi/aml/aml_obj.h>
#include <dev/acpi/aml/aml_parse.h>
#include <dev/acpi/aml/aml_status.h>
#include <dev/acpi/aml/aml_store.h>
/* for debugging */
#ifdef AML_DEBUG
int aml_debug = 1;
#else /* !AML_DEBUG */
int aml_debug = 0;
#endif /* AML_DEBUG */
#ifdef _KERNEL
SYSCTL_INT(_debug, OID_AUTO, aml_debug, CTLFLAG_RW, &aml_debug, 1, "");
#endif /* _KERNEL */
static void aml_print_nameseg(u_int8_t *dp);
static void
aml_print_nameseg(u_int8_t *dp)
{
if (dp[3] != '_') {
AML_DEBUGPRINT("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]);
} else if (dp[2] != '_') {
AML_DEBUGPRINT("%c%c%c_", dp[0], dp[1], dp[2]);
} else if (dp[1] != '_') {
AML_DEBUGPRINT("%c%c__", dp[0], dp[1]);
} else if (dp[0] != '_') {
AML_DEBUGPRINT("%c___", dp[0]);
}
}
void
aml_print_namestring(u_int8_t *dp)
{
int segcount;
int i;
if (dp[0] == '\\') {
AML_DEBUGPRINT("%c", dp[0]);
dp++;
} else if (dp[0] == '^') {
while (dp[0] == '^') {
AML_DEBUGPRINT("%c", dp[0]);
dp++;
}
}
if (dp[0] == 0x00) { /* NullName */
/* AML_DEBUGPRINT("<null>"); */
dp++;
} else if (dp[0] == 0x2e) { /* DualNamePrefix */
aml_print_nameseg(dp + 1);
AML_DEBUGPRINT("%c", '.');
aml_print_nameseg(dp + 5);
} else if (dp[0] == 0x2f) { /* MultiNamePrefix */
segcount = dp[1];
for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
if (i > 0) {
AML_DEBUGPRINT("%c", '.');
}
aml_print_nameseg(dp);
}
} else /* NameSeg */
aml_print_nameseg(dp);
}
int
aml_print_curname(struct aml_name *name)
{
struct aml_name *root;
root = aml_get_rootname();
if (name == root) {
AML_DEBUGPRINT("\\");
return (0);
} else {
aml_print_curname(name->parent);
}
aml_print_nameseg(name->name);
AML_DEBUGPRINT(".");
return (0);
}
void
aml_print_indent(int indent)
{
int i;
for (i = 0; i < indent; i++)
AML_DEBUGPRINT(" ");
}
void
aml_showobject(union aml_object * obj)
{
int debug;
int i;
if (obj == NULL) {
printf("NO object\n");
return;
}
debug = aml_debug;
aml_debug = 1;
switch (obj->type) {
case aml_t_num:
printf("Num:0x%x\n", obj->num.number);
break;
case aml_t_processor:
printf("Processor:No %d,Port 0x%x length 0x%x\n",
obj->proc.id, obj->proc.addr, obj->proc.len);
break;
case aml_t_mutex:
printf("Mutex:Level %d\n", obj->mutex.level);
break;
case aml_t_powerres:
printf("PowerResource:Level %d Order %d\n",
obj->pres.level, obj->pres.order);
break;
case aml_t_opregion:
printf("OprationRegion:Busspace%d, Offset 0x%x Length 0x%x\n",
obj->opregion.space, obj->opregion.offset,
obj->opregion.length);
break;
case aml_t_field:
printf("Fieldelement:flag 0x%x offset 0x%x len 0x%x {",
obj->field.flags, obj->field.bitoffset,
obj->field.bitlen);
switch (obj->field.f.ftype) {
case f_t_field:
aml_print_namestring(obj->field.f.fld.regname);
break;
case f_t_index:
aml_print_namestring(obj->field.f.ifld.indexname);
printf(" ");
aml_print_namestring(obj->field.f.ifld.dataname);
break;
case f_t_bank:
aml_print_namestring(obj->field.f.bfld.regname);
printf(" ");
aml_print_namestring(obj->field.f.bfld.bankname);
printf("0x%x", obj->field.f.bfld.bankvalue);
break;
}
printf("}\n");
break;
case aml_t_method:
printf("Method: Arg %d From %p To %p\n", obj->meth.argnum,
obj->meth.from, obj->meth.to);
break;
case aml_t_buffer:
printf("Buffer: size:0x%x Data %p\n", obj->buffer.size,
obj->buffer.data);
break;
case aml_t_device:
printf("Device\n");
break;
case aml_t_bufferfield:
printf("Bufferfield:offset 0x%x len 0x%x Origin %p\n",
obj->bfld.bitoffset, obj->bfld.bitlen, obj->bfld.origin);
break;
case aml_t_string:
printf("String:%s\n", obj->str.string);
break;
case aml_t_package:
printf("Package:elements %d \n", obj->package.elements);
for (i = 0; i < obj->package.elements; i++) {
if (obj->package.objects[i] == NULL) {
break;
}
if (obj->package.objects[i]->type < 0) {
continue;
}
printf(" ");
aml_showobject(obj->package.objects[i]);
}
break;
case aml_t_therm:
printf("Thermalzone\n");
break;
case aml_t_event:
printf("Event\n");
break;
case aml_t_ddbhandle:
printf("DDBHANDLE\n");
break;
case aml_t_objref:
if (obj->objref.alias == 1) {
printf("Alias");
} else {
printf("Object reference");
if (obj->objref.offset >= 0) {
printf(" (offset 0x%x)", obj->objref.offset);
}
}
printf(" of ");
aml_showobject(obj->objref.ref);
break;
default:
printf("UNK ID=%d\n", obj->type);
}
aml_debug = debug;
}
void
aml_showtree(struct aml_name * aname, int lev)
{
int i;
struct aml_name *ptr;
char name[5];
for (i = 0; i < lev; i++) {
printf(" ");
}
strncpy(name, aname->name, 4);
name[4] = 0;
printf("%s ", name);
if (aname->property != NULL) {
aml_showobject(aname->property);
} else {
printf("\n");
}
for (ptr = aname->child; ptr; ptr = ptr->brother)
aml_showtree(ptr, lev + 1);
}
/*
* Common Region I/O Stuff
*/
static __inline u_int64_t
aml_adjust_bitmask(u_int32_t flags, u_int32_t bitlen)
{
u_int64_t bitmask;
switch (AML_FIELDFLAGS_ACCESSTYPE(flags)) {
case AML_FIELDFLAGS_ACCESS_ANYACC:
if (bitlen <= 8) {
bitmask = 0x000000ff;
break;
}
if (bitlen <= 16) {
bitmask = 0x0000ffff;
break;
}
bitmask = 0xffffffff;
break;
case AML_FIELDFLAGS_ACCESS_BYTEACC:
bitmask = 0x000000ff;
break;
case AML_FIELDFLAGS_ACCESS_WORDACC:
bitmask = 0x0000ffff;
break;
case AML_FIELDFLAGS_ACCESS_DWORDACC:
default:
bitmask = 0xffffffff;
break;
}
switch (bitlen) {
case 16:
bitmask |= 0x0000ffff;
break;
case 32:
bitmask |= 0xffffffff;
break;
}
return (bitmask);
}
u_int32_t
aml_adjust_readvalue(u_int32_t flags, u_int32_t bitoffset, u_int32_t bitlen,
u_int32_t orgval)
{
u_int32_t offset, retval;
u_int64_t bitmask;
offset = bitoffset; /* XXX bitoffset may change in this function! */
bitmask = aml_adjust_bitmask(flags, bitlen);
retval = (orgval >> offset) & (~(bitmask << bitlen)) & bitmask;
return (retval);
}
u_int32_t
aml_adjust_updatevalue(u_int32_t flags, u_int32_t bitoffset, u_int32_t bitlen,
u_int32_t orgval, u_int32_t value)
{
u_int32_t offset, retval;
u_int64_t bitmask;
offset = bitoffset; /* XXX bitoffset may change in this function! */
bitmask = aml_adjust_bitmask(flags, bitlen);
retval = orgval;
switch (AML_FIELDFLAGS_UPDATERULE(flags)) {
case AML_FIELDFLAGS_UPDATE_PRESERVE:
retval &= (~(((u_int64_t)1 << bitlen) - 1) << offset) |
(~(bitmask << offset));
break;
case AML_FIELDFLAGS_UPDATE_WRITEASONES:
retval = (~(((u_int64_t)1 << bitlen) - 1) << offset) |
(~(bitmask << offset));
retval &= bitmask; /* trim the upper bits */
break;
case AML_FIELDFLAGS_UPDATE_WRITEASZEROS:
retval = 0;
break;
default:
printf("illegal update rule: %d\n", flags);
return (orgval);
}
retval |= (value << (offset & bitmask));
return (retval);
}
/*
* BufferField I/O
*/
#define AML_BUFFER_INPUT 0
#define AML_BUFFER_OUTPUT 1
static int aml_bufferfield_io(int io, u_int32_t *valuep,
u_int8_t *origin, u_int32_t bitoffset,
u_int32_t bitlen);
static int
aml_bufferfield_io(int io, u_int32_t *valuep, u_int8_t *origin,
u_int32_t bitoffset, u_int32_t bitlen)
{
u_int8_t val, tmp, masklow, maskhigh;
u_int8_t offsetlow, offsethigh;
u_int8_t *addr;
int i;
u_int32_t value, readval;
u_int32_t byteoffset, bytelen;
masklow = maskhigh = 0xff;
val = readval = 0;
value = *valuep;
byteoffset = bitoffset / 8;
bytelen = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
addr = origin + byteoffset;
/* simple I/O ? */
if (bitlen <= 8 || bitlen == 16 || bitlen == 32) {
bcopy(addr, &readval, bytelen);
AML_DEBUGPRINT("\n\t[bufferfield:0x%x@%p:%d,%d]",
readval, addr, bitoffset % 8, bitlen);
switch (io) {
case AML_BUFFER_INPUT:
value = aml_adjust_readvalue(AML_FIELDFLAGS_ACCESS_BYTEACC,
bitoffset % 8, bitlen, readval);
*valuep = value;
AML_DEBUGPRINT("\n[read(bufferfield, %p)&mask:0x%x]\n",
addr, value);
break;
case AML_BUFFER_OUTPUT:
value = aml_adjust_updatevalue(AML_FIELDFLAGS_ACCESS_BYTEACC,
bitoffset % 8, bitlen, readval, value);
bcopy(&value, addr, bytelen);
AML_DEBUGPRINT("->[bufferfield:0x%x@%p:%d,%d]",
value, addr, bitoffset % 8, bitlen);
break;
}
goto out;
}
offsetlow = bitoffset % 8;
if (bytelen > 1) {
offsethigh = (bitlen - (8 - offsetlow)) % 8;
} else {
offsethigh = 0;
}
if (offsetlow) {
masklow = (~((1 << bitlen) - 1) << offsetlow) | ~(0xff << offsetlow);
AML_DEBUGPRINT("\t[offsetlow = 0x%x, masklow = 0x%x, ~masklow = 0x%x]\n",
offsetlow, masklow, ~masklow & 0xff);
}
if (offsethigh) {
maskhigh = 0xff << offsethigh;
AML_DEBUGPRINT("\t[offsethigh = 0x%x, maskhigh = 0x%x, ~maskhigh = 0x%x]\n",
offsethigh, maskhigh, ~maskhigh & 0xff);
}
for (i = bytelen; i > 0; i--, addr++) {
val = *addr;
AML_DEBUGPRINT("\t[bufferfield:0x%02x@%p]", val, addr);
switch (io) {
case AML_BUFFER_INPUT:
tmp = val;
/* the lowest byte? */
if (i == bytelen) {
if (offsetlow) {
readval = tmp & ~masklow;
} else {
readval = tmp;
}
} else {
if (i == 1 && offsethigh) {
tmp = tmp & ~maskhigh;
}
readval = (tmp << (8 * (bytelen - i))) | readval;
}
AML_DEBUGPRINT("\n");
/* goto to next byte... */
if (i > 1) {
continue;
}
/* final adjustment before finishing region access */
if (offsetlow) {
readval = readval >> offsetlow;
}
AML_DEBUGPRINT("[read(bufferfield, %p)&mask:0x%x]\n",
addr, readval);
*valuep = readval;
break;
case AML_BUFFER_OUTPUT:
tmp = value & 0xff;
/* the lowest byte? */
if (i == bytelen) {
if (offsetlow) {
tmp = (val & masklow) | tmp << offsetlow;
}
value = value >> (8 - offsetlow);
} else {
if (i == 1 && offsethigh) {
tmp = (val & maskhigh) | tmp;
}
value = value >> 8;
}
AML_DEBUGPRINT("->[bufferfield:0x%02x@%p]\n",
tmp, addr);
*addr = tmp;
}
}
out:
return (0);
}
u_int32_t
aml_bufferfield_read(u_int8_t *origin, u_int32_t bitoffset,
u_int32_t bitlen)
{
int value;
value = 0;
aml_bufferfield_io(AML_BUFFER_INPUT, &value, origin,
bitoffset, bitlen);
return (value);
}
int
aml_bufferfield_write(u_int32_t value, u_int8_t *origin,
u_int32_t bitoffset, u_int32_t bitlen)
{
int status;
status = aml_bufferfield_io(AML_BUFFER_OUTPUT, &value,
origin, bitoffset, bitlen);
return (status);
}
int
aml_region_handle_alloc(struct aml_environ *env, int regtype, u_int32_t flags,
u_int32_t baseaddr, u_int32_t bitoffset, u_int32_t bitlen,
struct aml_region_handle *h)
{
int state;
struct aml_name *pci_info;
state = 0;
pci_info = NULL;
bzero(h, sizeof(struct aml_region_handle));
h->env = env;
h->regtype = regtype;
h->flags = flags;
h->baseaddr = baseaddr;
h->bitoffset = bitoffset;
h->bitlen = bitlen;
switch (AML_FIELDFLAGS_ACCESSTYPE(flags)) {
case AML_FIELDFLAGS_ACCESS_ANYACC:
if (bitlen <= 8) {
h->unit = 1;
break;
}
if (bitlen <= 16) {
h->unit = 2;
break;
}
h->unit = 4;
break;
case AML_FIELDFLAGS_ACCESS_BYTEACC:
h->unit = 1;
break;
case AML_FIELDFLAGS_ACCESS_WORDACC:
h->unit = 2;
break;
case AML_FIELDFLAGS_ACCESS_DWORDACC:
h->unit = 4;
break;
default:
h->unit = 1;
break;
}
h->addr = baseaddr + h->unit * ((bitoffset / 8) / h->unit);
h->bytelen = baseaddr + ((bitoffset + bitlen) / 8) - h->addr +
((bitlen % 8) ? 1 : 0);
#ifdef _KERNEL
switch (h->regtype) {
case AML_REGION_SYSMEM:
OsdMapMemory((void *)h->addr, h->bytelen, (void **)&h->vaddr);
break;
case AML_REGION_PCICFG:
/* Obtain PCI bus number */
pci_info = aml_search_name(env, "_BBN");
if (pci_info == NULL || pci_info->property->type != aml_t_num) {
AML_DEBUGPRINT("Cannot locate _BBN. Using default 0\n");
h->pci_bus = 0;
} else {
AML_DEBUGPRINT("found _BBN: %d\n",
pci_info->property->num.number);
h->pci_bus = pci_info->property->num.number & 0xff;
}
/* Obtain device & function number */
pci_info = aml_search_name(env, "_ADR");
if (pci_info == NULL || pci_info->property->type != aml_t_num) {
printf("Cannot locate: _ADR\n");
state = -1;
goto out;
}
h->pci_devfunc = pci_info->property->num.number;
AML_DEBUGPRINT("[pci%d.%d]", h->pci_bus, h->pci_devfunc);
break;
default:
break;
}
out:
#endif /* _KERNEL */
return (state);
}
void
aml_region_handle_free(struct aml_region_handle *h)
{
#ifdef _KERNEL
switch (h->regtype) {
case AML_REGION_SYSMEM:
OsdUnMapMemory((void *)h->vaddr, h->bytelen);
break;
default:
break;
}
#endif /* _KERNEL */
}
static int
aml_region_io_simple(struct aml_environ *env, int io, int regtype,
u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
u_int32_t bitoffset, u_int32_t bitlen)
{
int i, state;
u_int32_t readval, value, offset, bytelen;
struct aml_region_handle handle;
state = aml_region_handle_alloc(env, regtype, flags,
baseaddr, bitoffset, bitlen, &handle);
if (state == -1) {
goto out;
}
readval = 0;
offset = bitoffset % (handle.unit * 8);
/* limitation of 32 bits alignment */
bytelen = (handle.bytelen > 4) ? 4 : handle.bytelen;
if (io == AML_REGION_INPUT ||
AML_FIELDFLAGS_UPDATERULE(flags) == AML_FIELDFLAGS_UPDATE_PRESERVE) {
for (i = 0; i < bytelen; i += handle.unit) {
state = aml_region_read_simple(&handle, i, &value);
if (state == -1) {
goto out;
}
readval |= (value << (i * 8));
}
AML_DEBUGPRINT("\t[%d:0x%x@0x%x:%d,%d]",
regtype, readval, handle.addr, offset, bitlen);
}
switch (io) {
case AML_REGION_INPUT:
AML_DEBUGPRINT("\n");
readval = aml_adjust_readvalue(flags, offset, bitlen, readval);
value = readval;
value = aml_region_prompt_read(&handle, value);
state = aml_region_prompt_update_value(readval, value, &handle);
if (state == -1) {
goto out;
}
*valuep = value;
break;
case AML_REGION_OUTPUT:
value = *valuep;
value = aml_adjust_updatevalue(flags, offset,
bitlen, readval, value);
value = aml_region_prompt_write(&handle, value);
AML_DEBUGPRINT("\t->[%d:0x%x@0x%x:%d,%d]\n", regtype, value,
handle.addr, offset, bitlen);
for (i = 0; i < bytelen; i += handle.unit) {
state = aml_region_write_simple(&handle, i, value);
if (state == -1) {
goto out;
}
value = value >> (handle.unit * 8);
}
break;
}
aml_region_handle_free(&handle);
out:
return (state);
}
int
aml_region_io(struct aml_environ *env, int io, int regtype,
u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
u_int32_t bitoffset, u_int32_t bitlen)
{
u_int32_t unit, offset;
u_int32_t offadj, bitadj;
u_int32_t value, readval;
int state, i;
readval = 0;
state = 0;
unit = 4; /* limitation of 32 bits alignment */
offset = bitoffset % (unit * 8);
offadj = 0;
bitadj = 0;
if (offset + bitlen > unit * 8) {
bitadj = bitlen - (unit * 8 - offset);
}
for (i = 0; i < offset + bitlen; i += unit * 8) {
value = (*valuep) >> offadj;
state = aml_region_io_simple(env, io, regtype, flags,
&value, baseaddr, bitoffset + offadj, bitlen - bitadj);
if (state == -1) {
goto out;
}
readval |= value << offadj;
bitadj = offadj = bitlen - bitadj;
}
*valuep = readval;
out:
return (state);
}

View file

@ -1,159 +0,0 @@
/*-
* Copyright (c) 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.
*
* $Id: aml_common.h,v 1.4 2000/08/08 14:12:05 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_COMMON_H_
#define _AML_COMMON_H_
/*
* General Stuff
*/
#ifdef _KERNEL
#define AML_SYSABORT() do { \
printf("aml: fatal errer at %s:%d\n", __FILE__, __LINE__); \
panic("panic in AML interpreter!"); \
} while(0)
#define AML_SYSASSERT(x) do { \
if (!(x)) { \
AML_SYSABORT(); \
} \
} while(0)
#define AML_SYSERRX(eval, fmt, args...) do { \
printf(fmt, args); \
} while(0)
#define AML_DEBUGGER(x, y) /* no debugger in kernel */
#define AML_STALL(micro) OsdSleepUsec(micro)
#define AML_SLEEP(sec, milli) OsdSleep(sec, milli)
#else /* !_KERNEL */
#define AML_SYSASSERT(x) assert(x)
#define AML_SYSABORT() abort()
#define AML_SYSERRX(eval, fmt, args...) errx(eval, fmt, args)
#define AML_DEBUGGER(x, y) aml_dbgr(x, y)
#define AML_STALL(micro) /* not required in userland */
#define AML_SLEEP(sec, milli) /* not required in userland */
#endif /* _KERNEL */
union aml_object;
struct aml_name;
extern int aml_debug;
#define AML_DEBUGPRINT(args...) do { \
if (aml_debug) { \
printf(args); \
} \
} while(0)
void aml_showobject(union aml_object *);
void aml_showtree(struct aml_name *, int);
int aml_print_curname(struct aml_name *);
void aml_print_namestring(u_int8_t *);
void aml_print_indent(int);
/*
* Reigion I/O Stuff for both kernel/userland.
*/
/*
* Field Flags
*/
/* bit 0 -3: AccessType */
#define AML_FIELDFLAGS_ACCESS_ANYACC 0x00
#define AML_FIELDFLAGS_ACCESS_BYTEACC 0x01
#define AML_FIELDFLAGS_ACCESS_WORDACC 0x02
#define AML_FIELDFLAGS_ACCESS_DWORDACC 0x03
#define AML_FIELDFLAGS_ACCESS_BLOCKACC 0x04
#define AML_FIELDFLAGS_ACCESS_SMBSENDRECVACC 0x05
#define AML_FIELDFLAGS_ACCESS_SMBQUICKACC 0x06
#define AML_FIELDFLAGS_ACCESSTYPE(flags) (flags & 0x0f)
/* bit 4: LockRule */
#define AML_FIELDFLAGS_LOCK_NOLOCK 0x00
#define AML_FIELDFLAGS_LOCK_LOCK 0x10
#define AML_FIELDFLAGS_LOCKRULE(flags) (flags & 0x10)
/* bit 5 - 6: UpdateRule */
#define AML_FIELDFLAGS_UPDATE_PRESERVE 0x00
#define AML_FIELDFLAGS_UPDATE_WRITEASONES 0x20
#define AML_FIELDFLAGS_UPDATE_WRITEASZEROS 0x40
#define AML_FIELDFLAGS_UPDATERULE(flags) (flags & 0x60)
/* bit 7: reserved (must be 0) */
#define AML_REGION_INPUT 0
#define AML_REGION_OUTPUT 1
#define AML_REGION_SYSMEM 0
#define AML_REGION_SYSIO 1
#define AML_REGION_PCICFG 2
#define AML_REGION_EMBCTL 3
#define AML_REGION_SMBUS 4
struct aml_region_handle {
/* These are copies of values used on initialization */
struct aml_environ *env;
int regtype;
u_int32_t flags;
u_int32_t baseaddr;
u_int32_t bitoffset;
u_int32_t bitlen;
/* following is determined on initialization */
vm_offset_t addr, bytelen;
u_int32_t unit; /* access unit in bytes */
/* region type dependant */
vm_offset_t vaddr; /* SystemMemory */
u_int32_t pci_bus, pci_devfunc; /* PCI_Config */
};
u_int32_t aml_adjust_readvalue(u_int32_t, u_int32_t, u_int32_t,
u_int32_t);
u_int32_t aml_adjust_updatevalue(u_int32_t, u_int32_t, u_int32_t,
u_int32_t, u_int32_t);
u_int32_t aml_bufferfield_read(u_int8_t *, u_int32_t, u_int32_t);
int aml_bufferfield_write(u_int32_t, u_int8_t *,
u_int32_t, u_int32_t);
int aml_region_handle_alloc(struct aml_environ *, int, u_int32_t,
u_int32_t, u_int32_t, u_int32_t,
struct aml_region_handle *);
void aml_region_handle_free(struct aml_region_handle *);
int aml_region_io(struct aml_environ *, int, int,
u_int32_t, u_int32_t *, u_int32_t,
u_int32_t, u_int32_t);
extern int aml_region_read_simple(struct aml_region_handle *, vm_offset_t,
u_int32_t *);
extern int aml_region_write_simple(struct aml_region_handle *, vm_offset_t,
u_int32_t);
extern u_int32_t aml_region_prompt_read(struct aml_region_handle *,
u_int32_t);
extern u_int32_t aml_region_prompt_write(struct aml_region_handle *,
u_int32_t);
extern int aml_region_prompt_update_value(u_int32_t, u_int32_t,
struct aml_region_handle *);
#endif /* !_AML_COMMON_H_ */

View file

@ -1,46 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_env.h,v 1.11 2000/08/08 14:12:05 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_ENV_H_
#define _AML_ENV_H_
#include <dev/acpi/aml/aml_name.h>
#include <dev/acpi/aml/aml_obj.h>
#include <dev/acpi/aml/aml_status.h>
struct aml_environ {
u_int8_t *dp;
u_int8_t *end;
enum aml_status stat;
struct aml_name *curname;
struct aml_name tempname;
union aml_object tempobject;
};
#endif /* !_AML_ENV_H_ */

View file

@ -1,436 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_evalobj.c,v 1.27 2000/08/16 18:14:53 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <dev/acpi/aml/aml_amlmem.h>
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_evalobj.h>
#include <dev/acpi/aml/aml_name.h>
#include <dev/acpi/aml/aml_obj.h>
#include <dev/acpi/aml/aml_parse.h>
#include <dev/acpi/aml/aml_region.h>
#include <dev/acpi/aml/aml_status.h>
#include <dev/acpi/aml/aml_store.h>
#ifndef _KERNEL
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#else /* _KERNEL */
#include <sys/systm.h>
#endif /* !_KERNEL */
static union aml_object *aml_eval_fieldobject(struct aml_environ *env,
struct aml_name *name);
static union aml_object *
aml_eval_fieldobject(struct aml_environ *env, struct aml_name *name)
{
int num;
struct aml_name *oname,*wname;
struct aml_field *field;
struct aml_opregion *or;
union aml_object tobj;
num = 0;
/* CANNOT OCCUR! */
if (name == NULL || name->property == NULL ||
name->property->type != aml_t_field) {
printf("????\n");
env->stat = aml_stat_panic;
return (NULL);
}
field = &name->property->field;
oname = env->curname;
if (field->bitlen > 32) {
env->tempobject.type = aml_t_regfield;
} else {
env->tempobject.type = aml_t_num;
}
env->curname = name;
if (field->f.ftype == f_t_field) {
wname = aml_search_name(env, field->f.fld.regname);
if (wname == NULL || wname->property == NULL ||
wname->property->type != aml_t_opregion) {
AML_DEBUGPRINT("Inappropreate Type\n");
env->stat = aml_stat_panic;
env->curname = oname;
return (NULL);
}
or = &wname->property->opregion;
if (env->tempobject.type == aml_t_regfield) {
env->tempobject.regfield.space = or->space;
env->tempobject.regfield.flags = field->flags;
env->tempobject.regfield.offset = or->offset;
env->tempobject.regfield.bitoffset = field->bitoffset;
env->tempobject.regfield.bitlen = field->bitlen;
} else {
env->tempobject.type = aml_t_num;
env->tempobject.num.number = aml_region_read(env,
or->space, field->flags, or->offset,
field->bitoffset, field->bitlen);
AML_DEBUGPRINT("[read(%d, 0x%x)->0x%x]",
or->space, or->offset + field->bitoffset / 8,
env->tempobject.num.number);
}
} else if (field->f.ftype == f_t_index) {
wname = aml_search_name(env, field->f.ifld.indexname);
tobj.type = aml_t_num;
tobj.num.number = field->bitoffset / 8;/* AccessType Boundary */
aml_store_to_name(env, &tobj, wname);
wname = aml_search_name(env, field->f.ifld.dataname);
num = aml_objtonum(env, aml_eval_name(env, wname));
env->tempobject.type = aml_t_num;
env->tempobject.num.number = (num >> (field->bitoffset & 7)) &
((1 << field->bitlen) - 1);
}
env->curname = oname;
return (&env->tempobject);
}
union aml_object *
aml_eval_objref(struct aml_environ *env, union aml_object *obj)
{
int offset;
union aml_object num1;
union aml_object *ref, *ret;
ret = obj;
if (obj->objref.deref == 1) {
num1.type = aml_t_num;
offset = obj->objref.offset;
ref = obj->objref.ref;
if (ref == NULL) {
goto out;
}
switch (ref->type) {
case aml_t_package:
if (ref->package.elements > offset) {
ret = ref->package.objects[offset];
} else {
num1.num.number = 0;
env->tempobject = num1;
ret = &env->tempobject;
}
break;
case aml_t_buffer:
if (ref->buffer.size > offset) {
num1.num.number = ref->buffer.data[offset] & 0xff;
} else {
num1.num.number = 0;
}
env->tempobject = num1;
ret = &env->tempobject;
break;
default:
break;
}
}
if (obj->objref.alias == 1) {
ret = aml_eval_name(env, obj->objref.nameref);
goto out;
}
out:
return (ret);
}
/*
* Eval named object.
*/
union aml_object *
aml_eval_name(struct aml_environ *env, struct aml_name *aname)
{
int argnum, i;
int num;
struct aml_name *tmp;
struct aml_environ *copy;
struct aml_local_stack *stack;
union aml_object *obj, *ret;
union aml_object *src;
ret = NULL;
if (aname == NULL || aname->property == NULL) {
return (NULL);
}
if (env->stat == aml_stat_panic) {
return (NULL);
}
copy = memman_alloc(aml_memman, memid_aml_environ);
if (copy == NULL) {
return (NULL);
}
ret = aname->property;
i = 0;
reevaluate:
if (i > 10) {
env->stat = aml_stat_panic;
printf("TOO MANY LOOP\n");
ret = NULL;
goto out;
}
switch (aname->property->type) {
case aml_t_namestr:
tmp = aname;
aname = aml_search_name(env, aname->property->nstr.dp);
if (aname == NULL) {
aname = tmp;
}
i++;
goto reevaluate;
case aml_t_objref:
ret = aml_eval_objref(env, aname->property);
goto out;
case aml_t_num:
case aml_t_string:
case aml_t_buffer:
case aml_t_package:
case aml_t_debug:
ret = aname->property;
goto out;
case aml_t_field:
aml_free_objectcontent(&env->tempobject);
ret = aml_eval_fieldobject(env, aname);
goto out;
case aml_t_method:
aml_free_objectcontent(&env->tempobject);
argnum = aname->property->meth.argnum & 7;
*copy = *env;
copy->curname = aname;
copy->dp = aname->property->meth.from;
copy->end = aname->property->meth.to;
copy->stat = aml_stat_none;
stack = aml_local_stack_create();
AML_DEBUGPRINT("(");
for (i = 0; i < argnum; i++) {
aml_local_stack_getArgX(stack, i)->property =
aml_copy_object(env,
aml_eval_name(env,
aml_parse_termobj(env, 0)));
if (i < argnum - 1)
AML_DEBUGPRINT(", ");
}
AML_DEBUGPRINT(")\n");
aml_local_stack_push(stack);
if (env->stat == aml_stat_step) {
AML_DEBUGGER(env, copy);
}
tmp = aml_execute_method(copy);
obj = aml_eval_name(env, tmp);
if (copy->stat == aml_stat_panic) {
AML_DEBUGPRINT("PANIC OCCURED IN METHOD");
env->stat = aml_stat_panic;
ret = NULL;
aml_local_stack_delete(aml_local_stack_pop());
goto out;
}
if (aml_debug) {
aml_showobject(obj);
}
if (tmp)
tmp->property = NULL;
aml_local_stack_delete(aml_local_stack_pop());
if (obj) {
aml_create_local_object()->property = obj;
ret = obj;
} else {
env->tempobject.type = aml_t_num;
env->tempobject.num.number = 0;
}
goto out;
case aml_t_bufferfield:
aml_free_objectcontent(&env->tempobject);
if (aname->property->bfld.bitlen > 32) {
ret = aname->property;
} else {
src = aname->property;
num = aml_bufferfield_read(src->bfld.origin,
src->bfld.bitoffset, src->bfld.bitlen);
env->tempobject.type = aml_t_num;
env->tempobject.num.number = num;
ret = &env->tempobject;
}
goto out;
default:
AML_DEBUGPRINT("I eval the object that I should not eval, %s%d",
aname->name, aname->property->type);
AML_SYSABORT();
ret = NULL;
goto out;
}
out:
memman_free(aml_memman, memid_aml_environ, copy);
return (ret);
}
/*
* Eval named object but env variable is not required and return
* status of evaluation (success is zero). This function is assumed
* to be called by aml_apply_foreach_found_objects().
* Note that no arguments are passed if object is a method.
*/
int
aml_eval_name_simple(struct aml_name *name, va_list ap)
{
struct aml_environ *env;
union aml_object *ret;
if (name == NULL || name->property == NULL) {
return (1);
}
env = memman_alloc(aml_memman, memid_aml_environ);
if (env == NULL) {
return (1);
}
bzero(env, sizeof(struct aml_environ));
aml_local_stack_push(aml_local_stack_create());
AML_DEBUGPRINT("Evaluating ");
aml_print_curname(name);
ret = aml_eval_name(env, name);
if (name->property->type != aml_t_method) {
AML_DEBUGPRINT("\n");
if (aml_debug) {
aml_showobject(ret);
}
}
aml_local_stack_delete(aml_local_stack_pop());
memman_free(aml_memman, memid_aml_environ, env);
return (0);
}
int
aml_objtonum(struct aml_environ *env, union aml_object *obj)
{
if (obj != NULL && obj->type == aml_t_num) {
return (obj->num.number);
} else {
env->stat = aml_stat_panic;
return (-1);
}
}
struct aml_name *
aml_execute_method(struct aml_environ *env)
{
struct aml_name *name;
struct aml_name_group *newgrp;
newgrp = aml_new_name_group(AML_NAME_GROUP_IN_METHOD);
AML_DEBUGPRINT("[");
aml_print_curname(env->curname);
AML_DEBUGPRINT(" START]\n");
name = aml_parse_objectlist(env, 0);
AML_DEBUGPRINT("[");
aml_print_curname(env->curname);
AML_DEBUGPRINT(" END]\n");
aml_delete_name_group(newgrp);
return (name);
}
union aml_object *
aml_invoke_method(struct aml_name *name, int argc, union aml_object *argv)
{
int i;
struct aml_name *tmp;
struct aml_environ *env;
struct aml_local_stack *stack;
union aml_object *retval;
union aml_object *obj;
retval = NULL;
env = memman_alloc(aml_memman, memid_aml_environ);
if (env == NULL) {
return (NULL);
}
bzero(env, sizeof(struct aml_environ));
if (name != NULL && name->property != NULL &&
name->property->type == aml_t_method) {
env->curname = name;
env->dp = name->property->meth.from;
env->end = name->property->meth.to;
AML_DEBUGGER(env, env);
stack = aml_local_stack_create();
for (i = 0; i < argc; i++) {
aml_local_stack_getArgX(stack, i)->property =
aml_alloc_object(argv[i].type, &argv[i]);
}
aml_local_stack_push(stack);
obj = aml_eval_name(env, tmp = aml_execute_method(env));
if (aml_debug) {
aml_showtree(name, 0);
}
if (tmp)
tmp->property = NULL;
aml_local_stack_delete(aml_local_stack_pop());
if (obj) {
aml_create_local_object()->property = obj;
retval = obj;
}
}
memman_free(aml_memman, memid_aml_environ, env);
return (retval);
}
union aml_object *
aml_invoke_method_by_name(char *method, int argc, union aml_object *argv)
{
struct aml_name *name;
name = aml_find_from_namespace(aml_get_rootname(), method);
if (name == NULL) {
return (NULL);
}
return (aml_invoke_method(name, argc, argv));
}

View file

@ -1,48 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_evalobj.h,v 1.11 2000/08/16 18:14:53 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_EVALOBJ_H_
#define _AML_EVALOBJ_H_
#include <machine/stdarg.h>
union aml_object *aml_eval_objref(struct aml_environ *,
union aml_object *);
union aml_object *aml_eval_name(struct aml_environ *,
struct aml_name *);
int aml_eval_name_simple(struct aml_name *, va_list);
int aml_objtonum(struct aml_environ *,
union aml_object *);
struct aml_name *aml_execute_method(struct aml_environ *);
union aml_object *aml_invoke_method(struct aml_name *,
int, union aml_object *);
union aml_object *aml_invoke_method_by_name(char *,
int, union aml_object *);
#endif /* !_AML_EVALOBJ_H_ */

View file

@ -1,476 +0,0 @@
/*-
* 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.
*
* $Id: aml_memman.c,v 1.10 2000/08/09 14:47:43 iwasaki Exp $
* $FreeBSD$
*/
/*
* Generic Memory Management
*/
#include <sys/param.h>
#include <dev/acpi/aml/aml_memman.h>
#ifndef _KERNEL
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#else /* _KERNEL */
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
MALLOC_DEFINE(M_MEMMAN, "memman", "Generic and Simple Memory Management");
#endif /* !_KERNEL */
unsigned int memid_unkown = 255;
static int manage_block(struct memman *memman, unsigned int id,
void *block, unsigned static_mem,
unsigned entries);
static int blockman_init(struct memman *memman, unsigned int id);
static void memman_flexsize_add_histogram(struct memman *memman,
size_t size,
int tolerance);
static int memman_comp_histogram_size(const void *a,
const void *b);
static void memman_sort_histogram_by_size(struct memman *memman);
static unsigned int memman_guess_memid(struct memman *memman, void *chunk);
static void memman_statistics_fixedsize(struct memman *memman);
static void memman_statistics_flexsize(struct memman *memman);
static int
manage_block(struct memman *memman, unsigned int id, void *block,
unsigned static_mem, unsigned entries)
{
unsigned int i;
size_t alloc_size;
void *tmp, *realblock;
struct memman_blockman *bmp;
struct memman_block *memblock;
struct memman_node *memnodes;
bmp = &memman->blockman[id];
alloc_size = MEMMAN_BLOCKNODE_SIZE(entries);
if (static_mem) {
tmp = (void *)block;
realblock = (char *)block + alloc_size;
} else {
tmp = MEMMAN_SYSMALLOC(alloc_size);
if (!tmp) {
return (-1);
}
realblock = block;
memman->allocated_mem += alloc_size;
memman->salloc_called++;
}
memblock = (struct memman_block *)tmp;
memnodes = (struct memman_node *)((char *)tmp + sizeof(struct memman_block));
memblock->block = realblock;
memblock->static_mem = static_mem;
memblock->allocated = entries;
memblock->available = entries;
if (!static_mem) {
alloc_size += roundup(bmp->size * entries, ROUNDUP_UNIT);
}
memblock->allocated_mem = alloc_size;
LIST_INSERT_HEAD(&bmp->block_list, memblock, links);
for (i = 0; i < entries; ++i) {
memnodes[i].node = ((char *)realblock + (i * (bmp->size)));
memnodes[i].memblock = memblock;
LIST_INSERT_HEAD(&bmp->free_node_list, &memnodes[i], links);
}
bmp->available = entries;
return (0);
}
static int
blockman_init(struct memman *memman, unsigned int id)
{
int status;
struct memman_blockman *bmp;
bmp = &memman->blockman[id];
bmp->initialized = 1;
LIST_INIT(&bmp->block_list);
LIST_INIT(&bmp->free_node_list);
LIST_INIT(&bmp->occupied_node_list);
status = manage_block(memman, id, bmp->initial_block,
1, MEMMAN_INITIAL_SIZE);
return (status);
}
void *
memman_alloc(struct memman *memman, unsigned int id)
{
size_t alloc_size;
void *chunk, *block;
struct memman_blockman *bmp;
struct memman_node *memnode;
if (memman->max_memid <= id) {
printf("memman_alloc: invalid memory type id\n");
return (NULL);
}
bmp = &memman->blockman[id];
if (!bmp->initialized) {
if (blockman_init(memman, id)) {
goto malloc_fail;
}
}
memman->alloc_called++;
if (bmp->available == 0) {
alloc_size = roundup(bmp->size * MEMMAN_INCR_SIZE,
ROUNDUP_UNIT);
block = MEMMAN_SYSMALLOC(alloc_size);
if (!block) {
goto malloc_fail;
}
memman->required_mem += bmp->size * MEMMAN_INCR_SIZE;
memman->allocated_mem += alloc_size;
memman->salloc_called++;
if (manage_block(memman, id, block, 0, MEMMAN_INCR_SIZE)) {
goto malloc_fail;
}
}
memnode = LIST_FIRST(&bmp->free_node_list);
LIST_REMOVE(memnode, links);
chunk = memnode->node;
LIST_INSERT_HEAD(&bmp->occupied_node_list, memnode, links);
memnode->memblock->available--;
bmp->available--;
return (chunk);
malloc_fail:
printf("memman_alloc: could not allocate memory\n");
return (NULL);
}
static void
memman_flexsize_add_histogram(struct memman *memman, size_t size,
int tolerance)
{
int i;
int gap;
if (size == 0) {
return;
}
for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
gap = memman->flex_mem_histogram[i].mem_size - size;
if (gap >= (tolerance * -1) && gap <= tolerance) {
memman->flex_mem_histogram[i].count++;
if (memman->flex_mem_histogram[i].mem_size < size) {
memman->flex_mem_histogram[i].mem_size = size;
}
return;
}
}
if (memman->flex_mem_histogram_ptr == MEMMAN_HISTOGRAM_SIZE) {
memman_flexsize_add_histogram(memman, size, tolerance + 1);
return;
}
i = memman->flex_mem_histogram_ptr;
memman->flex_mem_histogram[i].mem_size = size;
memman->flex_mem_histogram[i].count = 1;
memman->flex_mem_histogram_ptr++;
}
static int
memman_comp_histogram_size(const void *a, const void *b)
{
int delta;
delta = ((const struct memman_histogram *)a)->mem_size -
((const struct memman_histogram *)b)->mem_size;
return (delta);
}
static void
memman_sort_histogram_by_size(struct memman *memman)
{
qsort(memman->flex_mem_histogram, memman->flex_mem_histogram_ptr,
sizeof(struct memman_histogram), memman_comp_histogram_size);
}
void *
memman_alloc_flexsize(struct memman *memman, size_t size)
{
void *mem;
struct memman_flexmem_info *info;
if (size == 0) {
return (NULL);
}
if ((mem = MEMMAN_SYSMALLOC(size)) != NULL) { /* XXX */
info = MEMMAN_SYSMALLOC(sizeof(struct memman_flexmem_info));
if (info) {
if (!memman->flex_mem_initialized) {
LIST_INIT(&memman->flexmem_info_list);
bzero(memman->flex_mem_histogram,
sizeof(struct memman_histogram));
memman->flex_mem_initialized = 1;
}
info->addr = mem;
info->mem_size = size;
LIST_INSERT_HEAD(&memman->flexmem_info_list, info, links);
}
memman->flex_alloc_called++;
memman->flex_salloc_called++;
memman->flex_required_mem += size;
memman->flex_allocated_mem += size;
if (memman->flex_mem_size_min == 0 ||
memman->flex_mem_size_min > size) {
memman->flex_mem_size_min = size;
}
if (memman->flex_mem_size_max < size) {
memman->flex_mem_size_max = size;
}
if (memman->flex_peak_mem_usage <
(memman->flex_allocated_mem - memman->flex_reclaimed_mem)) {
memman->flex_peak_mem_usage =
(memman->flex_allocated_mem - memman->flex_reclaimed_mem);
}
memman_flexsize_add_histogram(memman, size,
memman->flex_mem_histogram_initial_tolerance);
}
return (mem);
}
static unsigned int
memman_guess_memid(struct memman *memman, void *chunk)
{
unsigned int id;
struct memman_blockman *bmp;
struct memman_node *memnode;
for (id = 0; id < memman->max_memid; id++) {
bmp = &memman->blockman[id];
if (!bmp->initialized) {
if (blockman_init(memman, id)) {
printf("memman_free: could not initialized\n");
}
}
LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
if (memnode->node == chunk) {
return (id); /* got it! */
}
}
}
return (memid_unkown); /* gave up */
}
void
memman_free(struct memman *memman, unsigned int memid, void *chunk)
{
unsigned int id;
unsigned found;
void *block;
struct memman_blockman *bmp;
struct memman_block *memblock;
struct memman_node *memnode;
id = memid;
if (memid == memid_unkown) {
id = memman_guess_memid(memman, chunk);
}
if (memman->max_memid <= id) {
printf("memman_free: invalid memory type id\n");
MEMMAN_SYSABORT();
return;
}
bmp = &memman->blockman[id];
if (!bmp->initialized) {
if (blockman_init(memman, id)) {
printf("memman_free: could not initialized\n");
}
}
found = 0;
LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
if (memnode->node == chunk) {
found = 1;
break;
}
}
if (!found) {
printf("memman_free: invalid address\n");
return;
}
memman->free_called++;
LIST_REMOVE(memnode, links);
memblock = memnode->memblock;
memblock->available++;
LIST_INSERT_HEAD(&bmp->free_node_list, memnode, links);
bmp->available++;
if (!memblock->static_mem &&
memblock->available == memblock->allocated) {
LIST_FOREACH(memnode, &bmp->free_node_list, links) {
if (memnode->memblock != memblock) {
continue;
}
LIST_REMOVE(memnode, links);
bmp->available--;
}
block = memblock->block;
MEMMAN_SYSFREE(block);
memman->sfree_called++;
LIST_REMOVE(memblock, links);
memman->sfree_called++;
memman->reclaimed_mem += memblock->allocated_mem;
MEMMAN_SYSFREE(memblock);
}
}
void
memman_free_flexsize(struct memman *memman, void *chunk)
{
struct memman_flexmem_info *info;
LIST_FOREACH(info, &memman->flexmem_info_list, links) {
if (info->addr == chunk) {
memman->flex_reclaimed_mem += info->mem_size;
LIST_REMOVE(info, links);
MEMMAN_SYSFREE(info);
break;
}
}
/* XXX */
memman->flex_free_called++;
memman->flex_sfree_called++;
MEMMAN_SYSFREE(chunk);
}
void
memman_freeall(struct memman *memman)
{
int id;
void *chunk;
struct memman_blockman *bmp;
struct memman_node *memnode;
struct memman_block *memblock;
struct memman_flexmem_info *info;
for (id = 0; id < memman->max_memid; id++) {
bmp = &memman->blockman[id];
while ((memnode = LIST_FIRST(&bmp->occupied_node_list))) {
chunk = memnode->node;
printf("memman_freeall: fixed size (id = %d)\n", id);
memman_free(memman, id, chunk);
}
while ((memblock = LIST_FIRST(&bmp->block_list))) {
LIST_REMOVE(memblock, links);
if (!memblock->static_mem) {
memman->sfree_called++;
memman->reclaimed_mem += memblock->allocated_mem;
MEMMAN_SYSFREE(memblock);
}
}
bmp->initialized = 0;
}
LIST_FOREACH(info, &memman->flexmem_info_list, links) {
printf("memman_freeall: flex size (size = %d, addr = %p)\n",
info->mem_size, info->addr);
memman_free_flexsize(memman, info->addr);
}
}
static void
memman_statistics_fixedsize(struct memman *memman)
{
printf(" fixed size memory blocks\n");
printf(" alloc(): %d times\n", memman->alloc_called);
printf(" system malloc(): %d times\n", memman->salloc_called);
printf(" free(): %d times\n", memman->free_called);
printf(" system free(): %d times\n", memman->sfree_called);
printf(" required memory: %d bytes\n", memman->required_mem);
printf(" allocated memory: %d bytes\n", memman->allocated_mem);
printf(" reclaimed memory: %d bytes\n", memman->reclaimed_mem);
}
static void
memman_statistics_flexsize(struct memman *memman)
{
int i;
printf(" flexible size memory blocks\n");
printf(" alloc(): %d times\n", memman->flex_alloc_called);
printf(" system malloc(): %d times\n", memman->flex_salloc_called);
printf(" free(): %d times\n", memman->flex_free_called);
printf(" system free(): %d times\n", memman->flex_sfree_called);
printf(" required memory: %d bytes\n", memman->flex_required_mem);
printf(" allocated memory: %d bytes\n", memman->flex_allocated_mem);
printf(" reclaimed memory: %d bytes\n", memman->flex_reclaimed_mem);
printf(" peak memory usage: %d bytes\n", memman->flex_peak_mem_usage);
printf(" min memory size: %d bytes\n", memman->flex_mem_size_min);
printf(" max memory size: %d bytes\n", memman->flex_mem_size_max);
printf(" avg memory size: %d bytes\n",
(memman->flex_alloc_called) ?
memman->flex_allocated_mem / memman->flex_alloc_called : 0);
printf(" memory size histogram (%d entries):\n",
memman->flex_mem_histogram_ptr);
printf(" size count\n");
memman_sort_histogram_by_size(memman);
for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
printf(" %d %d\n",
memman->flex_mem_histogram[i].mem_size,
memman->flex_mem_histogram[i].count);
}
}
void
memman_statistics(struct memman *memman)
{
printf("memman: reporting statistics\n");
memman_statistics_fixedsize(memman);
memman_statistics_flexsize(memman);
}
size_t
memman_memid2size(struct memman *memman, unsigned int id)
{
if (memman->max_memid <= id) {
printf("memman_alloc: invalid memory type id\n");
return (0);
}
return (memman->blockman[id].size);
}

View file

@ -1,172 +0,0 @@
/*-
* 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.
*
* $Id: aml_memman.h,v 1.9 2000/08/09 14:47:43 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _MEMMAN_H_
#define _MEMMAN_H_
/*
* Generic Memory Management
*/
#include <sys/param.h>
#include <sys/queue.h>
/* memory block */
struct memman_block {
LIST_ENTRY(memman_block) links;
void *block;
unsigned static_mem; /* static memory or not */
unsigned int allocated; /* number of allocated chunks */
unsigned int available; /* number of available chunks */
unsigned int allocated_mem; /* block + misc (in bytes) */
}__attribute__((packed));
LIST_HEAD(memman_block_list, memman_block);
/* memory node in block */
struct memman_node {
LIST_ENTRY(memman_node) links;
void *node;
struct memman_block *memblock;
}__attribute__((packed));
LIST_HEAD(memman_node_list, memman_node);
/* memory type id */
extern unsigned int memid_unkown;
/* memory block manager */
struct memman_blockman {
unsigned int size; /* size of chunk */
unsigned int available; /* total # of available chunks */
void *initial_block; /* initial memory storage */
unsigned initialized; /* initialized or not */
struct memman_block_list block_list;
struct memman_node_list free_node_list;
struct memman_node_list occupied_node_list;
};
/* memory size histogram */
#define MEMMAN_HISTOGRAM_SIZE 20
struct memman_histogram {
int mem_size;
int count;
};
/* flex size memory allocation info */
struct memman_flexmem_info {
LIST_ENTRY(memman_flexmem_info) links;
void *addr;
size_t mem_size;
}__attribute__((packed));
LIST_HEAD(memman_flexmem_info_list, memman_flexmem_info);
/* memory manager */
struct memman {
struct memman_blockman *blockman;
unsigned int max_memid; /* max number of valid memid */
/* fixed size memory blocks */
unsigned int alloc_called; /* memman_alloc() calling */
unsigned int free_called; /* memman_free() calling */
unsigned int salloc_called; /* malloc() calling */
unsigned int sfree_called; /* free() calling */
size_t required_mem; /* total required memory (in bytes) */
size_t allocated_mem; /* total malloc()ed memory */
size_t reclaimed_mem; /* total free()ed memory */
/* flex size memory blocks */
unsigned int flex_alloc_called; /* memman_alloc_flexsize() calling */
unsigned int flex_free_called; /* memman_free_flexsize() calling */
unsigned int flex_salloc_called;/* malloc() calling */
unsigned int flex_sfree_called; /* free() calling */
size_t flex_required_mem; /* total required memory (in bytes) */
size_t flex_allocated_mem;/* total malloc()ed memory */
size_t flex_reclaimed_mem;/* total free()ed memory */
size_t flex_mem_size_min; /* min size of allocated memory */
size_t flex_mem_size_max; /* max size of allocated memory */
size_t flex_peak_mem_usage;/* memory usage at a peak period */
/* stuff for more detailed statistical information */
struct memman_histogram *flex_mem_histogram;
unsigned int flex_mem_histogram_ptr;
int flex_mem_histogram_initial_tolerance;
unsigned flex_mem_initialized;
struct memman_flexmem_info_list flexmem_info_list;
};
#define MEMMAN_BLOCKNODE_SIZE(entries) sizeof(struct memman_block) + \
sizeof(struct memman_node) * entries
#ifndef ROUNDUP_UNIT
#define ROUNDUP_UNIT 4
#endif
#if !defined(MEMMAN_INITIAL_SIZE) || MEMMAN_INITIAL_SIZE < 2048
#define MEMMAN_INITIAL_SIZE 2048
#endif
#if !defined(MEMMAN_INCR_SIZE) || MEMMAN_INCR_SIZE < 512
#define MEMMAN_INCR_SIZE 512
#endif
#define MEMMAN_INITIALSTORAGE_DESC(type, name) \
static struct { \
char blocknodes[MEMMAN_BLOCKNODE_SIZE(MEMMAN_INITIAL_SIZE)]; \
type realblock[MEMMAN_INITIAL_SIZE]; \
} name
#define MEMMAN_MEMBLOCK_DESC(size, initial_storage) \
{ size, MEMMAN_INITIAL_SIZE, &initial_storage, 0 }
#define MEMMAN_MEMMANAGER_DESC(blockman, max_memid, histogram, tolerance) \
{ blockman, max_memid, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, histogram, 0, tolerance, 0}
void *memman_alloc(struct memman *, unsigned int);
void *memman_alloc_flexsize(struct memman *, size_t);
void memman_free(struct memman *, unsigned int, void *);
void memman_free_flexsize(struct memman *, void *);
void memman_freeall(struct memman *);
void memman_statistics(struct memman *);
size_t memman_memid2size(struct memman *, unsigned int);
#ifdef _KERNEL
#define MEMMAN_SYSMALLOC(size) malloc(size, M_MEMMAN, M_WAITOK)
#define MEMMAN_SYSFREE(ptr) free(ptr, M_MEMMAN)
#define MEMMAN_SYSABORT() /* no abort in kernel */
#else /* !_KERNEL */
#define MEMMAN_SYSMALLOC(size) malloc(size)
#define MEMMAN_SYSFREE(ptr) free(ptr)
#define MEMMAN_SYSABORT() abort()
#endif /* _KERNEL */
#endif /* !_MEMMAN_H_ */

View file

@ -1,481 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* Copyright (c) 1999, 2000 Yasuo Yokoyama
* 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.
*
* $Id: aml_name.c,v 1.15 2000/08/16 18:14:53 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <dev/acpi/aml/aml_amlmem.h>
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_name.h>
#ifndef _KERNEL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#else /* _KERNEL */
#include <sys/systm.h>
#endif /* !_KERNEL */
static struct aml_name *aml_find_name(struct aml_name *, char *);
static struct aml_name *aml_new_name(struct aml_name *, char *);
static void aml_delete_name(struct aml_name *);
static struct aml_name rootname = {"\\", NULL, NULL, NULL, NULL, NULL};
static struct aml_name_group root_group = {
AML_NAME_GROUP_ROOT,
&rootname,
NULL
};
struct aml_name_group *name_group_list = &root_group;
struct aml_local_stack *stack_top = NULL;
struct aml_name *
aml_get_rootname()
{
return (&rootname);
}
static struct aml_name *
aml_find_name(struct aml_name *parent, char *name)
{
struct aml_name *result;
if (!parent)
parent = &rootname;
for (result = parent->child; result; result = result->brother)
if (!strncmp(result->name, name, 4))
break;
return (result);
}
/*
* Parse given namesppace expression and find a first matched object
* under given level of the tree by depth first search.
*/
struct aml_name *
aml_find_from_namespace(struct aml_name *parent, char *name)
{
char *ptr;
int len;
struct aml_name *result;
ptr = name;
if (!parent)
parent = &rootname;
if (ptr[0] == '\\') {
ptr++;
parent = &rootname;
}
for (len = 0; ptr[len] != '.' && ptr[len] != '\0'; len++)
;
for (result = parent->child; result; result = result->brother) {
if (!strncmp(result->name, ptr, len)) {
if (ptr[len] == '\0' || ptr[len + 1] == '\0') {
return (result);
}
ptr += len;
if (ptr[0] != '.') {
return (NULL);
}
ptr++;
return (aml_find_from_namespace(result, ptr));
}
}
return (NULL);
}
static void
_aml_apply_foreach_found_objects(struct aml_name *parent, char *name,
int len, int shallow, int (*func)(struct aml_name *, va_list), va_list ap)
{
struct aml_name *child, *ptr;
child = ptr = NULL;
/* function to apply must be specified */
if (func == NULL) {
return;
}
for (child = parent->child; child; child = child->brother) {
if (!strncmp(child->name, name, len)) {
/* if function call was failed, stop searching */
if (func(child, ap) != 0) {
return;
}
}
}
if (shallow == 1) {
return;
}
for (ptr = parent->child; ptr; ptr = ptr->brother) {
/* do more searching */
_aml_apply_foreach_found_objects(ptr, name, len, 0, func, ap);
}
}
/*
* Find named objects as many as possible under given level of
* namespace, and apply given callback function for each
* named objects found. If the callback function returns non-zero
* value, then the search terminates immediately.
* Note that object name expression is used as forward substring match,
* not exact match. The name expression "_L" will match for objects
* which have name starting with "_L" such as "\_SB_.LID_._LID" and
* "\_GPE._L00" and so on. The name expression can include parent object
* name in it like "\_GPE._L". In this case, GPE X level wake handlers
* will be found under "\_GPE" in shallow level.
*/
void
aml_apply_foreach_found_objects(struct aml_name *start, char *name,
int (*func)(struct aml_name *, va_list), ...)
{
int i, len, has_dot, last_is_dot, shallow;
struct aml_name *child, *parent;
va_list ap;
shallow = 0;
if (start == NULL) {
parent = &rootname;
} else {
parent = start;
}
if (name[0] == '\\') {
name++;
parent = &rootname;
shallow = 1;
}
len = strlen(name);
last_is_dot = 0;
/* the last dot should be ignored */
if (len > 0 && name[len - 1] == '.') {
len--;
last_is_dot = 1;
}
has_dot = 0;
for (i = 0; i < len - 1; i++) {
if (name[i] == '.') {
has_dot = 1;
break;
}
}
/* try to parse expression and find any matched object. */
if (has_dot == 1) {
child = aml_find_from_namespace(parent, name);
if (child == NULL) {
return;
}
/*
* we have at least one object matched, search all objects
* under upper level of the found object.
*/
parent = child->parent;
/* find the last `.' */
for (name = name + len - 1; *name != '.'; name--)
;
name++;
len = strlen(name) - last_is_dot;
shallow = 1;
}
if (len > 4) {
return;
}
va_start(ap, func);
_aml_apply_foreach_found_objects(parent, name, len, shallow, func, ap);
va_end(ap);
}
struct aml_name_group *
aml_new_name_group(int id)
{
struct aml_name_group *result;
result = memman_alloc(aml_memman, memid_aml_name_group);
result->id = id;
result->head = NULL;
result->next = name_group_list;
name_group_list = result;
return (result);
}
void
aml_delete_name_group(struct aml_name_group *target)
{
struct aml_name_group *previous;
previous = name_group_list;
if (previous == target)
name_group_list = target->next;
else {
while (previous && previous->next != target)
previous = previous->next;
if (previous)
previous->next = target->next;
}
target->next = NULL;
if (target->head)
aml_delete_name(target->head);
memman_free(aml_memman, memid_aml_name_group, target);
}
static struct aml_name *
aml_new_name(struct aml_name *parent, char *name)
{
struct aml_name *newname;
if ((newname = aml_find_name(parent, name)) != NULL)
return (newname);
newname = memman_alloc(aml_memman, memid_aml_name);
strncpy(newname->name, name, 4);
newname->parent = parent;
newname->child = NULL;
newname->property = NULL;
if (parent->child)
newname->brother = parent->child;
else
newname->brother = NULL;
parent->child = newname;
newname->chain = name_group_list->head;
name_group_list->head = newname;
return (newname);
}
/*
* NOTE:
* aml_delete_name() doesn't maintain aml_name_group::{head,tail}.
*/
static void
aml_delete_name(struct aml_name *target)
{
struct aml_name *next;
struct aml_name *ptr;
for (; target; target = next) {
next = target->chain;
if (target->child) {
target->chain = NULL;
continue;
}
if (target->brother) {
if (target->parent) {
if (target->parent->child == target) {
target->parent->child = target->brother;
} else {
ptr = target->parent->child;
while (ptr && ptr->brother != target)
ptr = ptr->brother;
if (ptr)
ptr->brother = target->brother;
}
target->brother = NULL;
}
} else if (target->parent) {
target->parent->child = NULL;
}
aml_free_object(&target->property);
memman_free(aml_memman, memid_aml_name, target);
}
}
#define AML_SEARCH_NAME 0
#define AML_CREATE_NAME 1
static struct aml_name *aml_nameman(struct aml_environ *, u_int8_t *, int);
struct aml_name *
aml_search_name(struct aml_environ *env, u_int8_t *dp)
{
return (aml_nameman(env, dp, AML_SEARCH_NAME));
}
struct aml_name *
aml_create_name(struct aml_environ *env, u_int8_t *dp)
{
return (aml_nameman(env, dp, AML_CREATE_NAME));
}
static struct aml_name *
aml_nameman(struct aml_environ *env, u_int8_t *dp, int flag)
{
int segcount;
int i;
struct aml_name *newname, *curname;
struct aml_name *(*searchfunc) (struct aml_name *, char *);
#define CREATECHECK() do { \
if (newname == NULL) { \
AML_DEBUGPRINT("ERROR CANNOT FIND NAME\n"); \
env->stat = aml_stat_panic; \
return (NULL); \
} \
} while(0)
searchfunc = (flag == AML_CREATE_NAME) ? aml_new_name : aml_find_name;
newname = env->curname;
if (dp[0] == '\\') {
newname = &rootname;
dp++;
} else if (dp[0] == '^') {
while (dp[0] == '^') {
newname = newname->parent;
CREATECHECK();
dp++;
}
}
if (dp[0] == 0x00) { /* NullName */
dp++;
} else if (dp[0] == 0x2e) { /* DualNamePrefix */
newname = (*searchfunc) (newname, dp + 1);
CREATECHECK();
newname = (*searchfunc) (newname, dp + 5);
CREATECHECK();
} else if (dp[0] == 0x2f) { /* MultiNamePrefix */
segcount = dp[1];
for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
newname = (*searchfunc) (newname, dp);
CREATECHECK();
}
} else if (flag == AML_CREATE_NAME) { /* NameSeg */
newname = aml_new_name(newname, dp);
CREATECHECK();
} else {
curname = newname;
for (;;) {
newname = aml_find_name(curname, dp);
if (newname != NULL)
break;
if (curname == &rootname)
break;
curname = curname->parent;
}
}
return (newname);
}
#undef CREATECHECK
struct aml_local_stack *
aml_local_stack_create()
{
struct aml_local_stack *result;
result = memman_alloc(aml_memman, memid_aml_local_stack);
memset(result, 0, sizeof(struct aml_local_stack));
return (result);
}
void
aml_local_stack_push(struct aml_local_stack *stack)
{
stack->next = stack_top;
stack_top = stack;
}
struct aml_local_stack *
aml_local_stack_pop()
{
struct aml_local_stack *result;
result = stack_top;
stack_top = result->next;
result->next = NULL;
return (result);
}
void
aml_local_stack_delete(struct aml_local_stack *stack)
{
int i;
for (i = 0; i < 8; i++)
aml_free_object(&stack->localvalue[i].property);
for (i = 0; i < 7; i++)
aml_free_object(&stack->argumentvalue[i].property);
aml_delete_name(stack->temporary);
memman_free(aml_memman, memid_aml_local_stack, stack);
}
struct aml_name *
aml_local_stack_getLocalX(int index)
{
if (stack_top == NULL)
return (NULL);
return (&stack_top->localvalue[index]);
}
struct aml_name *
aml_local_stack_getArgX(struct aml_local_stack *stack, int index)
{
if (!stack)
stack = stack_top;
if (stack == NULL)
return (NULL);
return (&stack->argumentvalue[index]);
}
struct aml_name *
aml_create_local_object()
{
struct aml_name *result;
result = memman_alloc(aml_memman, memid_aml_name);
result->child = result->brother = result->parent = NULL;
result->property = NULL;
result->chain = stack_top->temporary;
stack_top->temporary = result;
return (result);
}

View file

@ -1,88 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* Copyright (c) 1999, 2000 Yasuo Yokoyama
* 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.
*
* $Id: aml_name.h,v 1.17 2000/08/16 18:14:54 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_NAME_H_
#define _AML_NAME_H_
#include <machine/stdarg.h>
#include <dev/acpi/aml/aml_obj.h>
struct aml_name {
char name[4];
union aml_object *property;
struct aml_name *parent;
struct aml_name *brother;
struct aml_name *child;
struct aml_name *chain;
};
#define AML_NAME_GROUP_ROOT 0
#define AML_NAME_GROUP_OS_DEFINED 1
#define AML_NAME_GROUP_IN_METHOD 2
struct aml_name_group {
int id; /* DSDT address or DBHANDLE */
struct aml_name *head;
struct aml_name_group *next;
};
struct aml_local_stack {
struct aml_name localvalue[8];
struct aml_name argumentvalue[7];
struct aml_name *temporary;
struct aml_local_stack *next;
};
/* forward declarement */
struct aml_envrion;
struct aml_name *aml_get_rootname(void);
struct aml_name_group *aml_new_name_group(int);
void aml_delete_name_group(struct aml_name_group *);
struct aml_name *aml_find_from_namespace(struct aml_name *, char *);
void aml_apply_foreach_found_objects(struct aml_name *,
char *, int (*)(struct aml_name *, va_list), ...);
struct aml_name *aml_search_name(struct aml_environ *, u_int8_t *);
struct aml_name *aml_create_name(struct aml_environ *, u_int8_t *);
struct aml_local_stack *aml_local_stack_create(void);
void aml_local_stack_push(struct aml_local_stack *);
struct aml_local_stack *aml_local_stack_pop(void);
void aml_local_stack_delete(struct aml_local_stack *);
struct aml_name *aml_local_stack_getLocalX(int);
struct aml_name *aml_local_stack_getArgX(struct aml_local_stack *, int);
struct aml_name *aml_create_local_object(void);
extern struct aml_name_group *name_group_list;
#endif /* !_AML_NAME_H_ */

View file

@ -1,264 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_obj.c,v 1.17 2000/08/12 15:20:45 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <dev/acpi/aml/aml_amlmem.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_name.h>
#include <dev/acpi/aml/aml_obj.h>
#include <dev/acpi/aml/aml_status.h>
#include <dev/acpi/aml/aml_store.h>
#ifndef _KERNEL
#include <sys/stat.h>
#include <sys/mman.h>
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#else /* _KERNEL */
#include <sys/systm.h>
#endif /* !_KERNEL */
union aml_object *
aml_copy_object(struct aml_environ *env, union aml_object *orig)
{
int i;
union aml_object *ret;
if (orig == NULL)
return (NULL);
switch (orig->type) {
case aml_t_regfield:
ret = aml_alloc_object(aml_t_buffer, 0);
ret->buffer.size = (orig->regfield.bitlen / 8) +
((orig->regfield.bitlen % 8) ? 1 : 0);
if (ret->buffer.size == 0) {
goto out;
}
ret->buffer.data = memman_alloc_flexsize(aml_memman, ret->buffer.size);
aml_store_to_object(env, orig, ret);
break;
default:
ret = aml_alloc_object(0, orig);
break;
}
if (1 || orig != &env->tempobject) { /* XXX */
if (orig->type == aml_t_buffer) {
if (orig->buffer.size == 0) {
goto out;
}
ret->buffer.data = memman_alloc_flexsize(aml_memman,
orig->buffer.size);
bcopy(orig->buffer.data, ret->buffer.data, orig->buffer.size);
} else if (orig->type == aml_t_package) {
if (ret->package.elements == 0) {
goto out;
}
ret->package.objects = memman_alloc_flexsize(aml_memman,
ret->package.elements * sizeof(union aml_object *));
for (i = 0; i < ret->package.elements; i++) {
ret->package.objects[i] = aml_copy_object(env, orig->package.objects[i]);
}
} else if (orig->type == aml_t_string && orig->str.needfree != 0) {
ret->str.string = memman_alloc_flexsize(aml_memman,
strlen(orig->str.string) + 1);
strcpy(orig->str.string, ret->str.string);
} else if (orig->type == aml_t_num) {
ret->num.constant = 0;
}
} else {
printf("%s:%d\n", __FILE__, __LINE__);
env->tempobject.type = aml_t_null;
}
out:
return ret;
}
/*
* This function have two function: copy or allocate. if orig != NULL,
* orig is duplicated.
*/
union aml_object *
aml_alloc_object(enum aml_objtype type, union aml_object *orig)
{
unsigned int memid;
union aml_object *ret;
if (orig != NULL) {
type = orig->type;
}
switch (type) {
case aml_t_namestr:
memid = memid_aml_namestr;
break;
case aml_t_buffer:
memid = memid_aml_buffer;
break;
case aml_t_string:
memid = memid_aml_string;
break;
case aml_t_bufferfield:
memid = memid_aml_bufferfield;
break;
case aml_t_package:
memid = memid_aml_package;
break;
case aml_t_num:
memid = memid_aml_num;
break;
case aml_t_powerres:
memid = memid_aml_powerres;
break;
case aml_t_opregion:
memid = memid_aml_opregion;
break;
case aml_t_method:
memid = memid_aml_method;
break;
case aml_t_processor:
memid = memid_aml_processor;
break;
case aml_t_field:
memid = memid_aml_field;
break;
case aml_t_mutex:
memid = memid_aml_mutex;
break;
case aml_t_device:
memid = memid_aml_objtype;
break;
case aml_t_objref:
memid = memid_aml_objref;
break;
default:
memid = memid_aml_objtype;
break;
}
ret = memman_alloc(aml_memman, memid);
ret->type = type;
if (orig != NULL) {
bcopy(orig, ret, memman_memid2size(aml_memman, memid));
}
return (ret);
}
void
aml_free_objectcontent(union aml_object *obj)
{
int i;
if (obj->type == aml_t_buffer && obj->buffer.data != NULL) {
memman_free_flexsize(aml_memman, obj->buffer.data);
obj->buffer.data = NULL;
}
if (obj->type == aml_t_string && obj->str.string != NULL) {
if (obj->str.needfree != 0) {
memman_free_flexsize(aml_memman, obj->str.string);
obj->str.string = NULL;
}
}
if (obj->type == aml_t_package && obj->package.objects != NULL) {
for (i = 0; i < obj->package.elements; i++) {
aml_free_object(&obj->package.objects[i]);
}
memman_free_flexsize(aml_memman, obj->package.objects);
obj->package.objects = NULL;
}
}
void
aml_free_object(union aml_object **obj)
{
union aml_object *body;
body = *obj;
if (body == NULL) {
return;
}
aml_free_objectcontent(*obj);
memman_free(aml_memman, memid_unkown, *obj);
*obj = NULL;
}
void
aml_realloc_object(union aml_object *obj, int size)
{
int i;
enum aml_objtype type;
union aml_object tmp;
type = obj->type;
switch (type) {
case aml_t_buffer:
if (obj->buffer.size >= size) {
return;
}
tmp.buffer.size = size;
tmp.buffer.data = memman_alloc_flexsize(aml_memman, size);
bzero(tmp.buffer.data, size);
bcopy(obj->buffer.data, tmp.buffer.data, obj->buffer.size);
aml_free_objectcontent(obj);
*obj = tmp;
break;
case aml_t_string:
if (strlen(obj->str.string) >= size) {
return;
}
tmp.str.string = memman_alloc_flexsize(aml_memman, size + 1);
strcpy(tmp.str.string, obj->str.string);
aml_free_objectcontent(obj);
*obj = tmp;
break;
case aml_t_package:
if (obj->package.elements >= size) {
return;
}
tmp.package.objects = memman_alloc_flexsize(aml_memman,
size * sizeof(union aml_object *));
bzero(tmp.package.objects, size * sizeof(union aml_object *));
for (i = 0; i < obj->package.elements; i++) {
tmp.package.objects[i] = obj->package.objects[i];
}
memman_free_flexsize(aml_memman, obj->package.objects);
obj->package.objects = tmp.package.objects;
break;
default:
break;
}
}

View file

@ -1,227 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_obj.h,v 1.15 2000/08/09 14:47:43 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_OBJ_H_
#define _AML_OBJ_H_
#include <sys/queue.h>
struct aml_environ;
enum aml_objtype {
aml_t_namestr = -3,
aml_t_regfield,
aml_t_objref,
aml_t_null = 0,
aml_t_num,
aml_t_string,
aml_t_buffer,
aml_t_package,
aml_t_device,
aml_t_field,
aml_t_event,
aml_t_method,
aml_t_mutex,
aml_t_opregion,
aml_t_powerres,
aml_t_processor,
aml_t_therm,
aml_t_bufferfield,
aml_t_ddbhandle,
aml_t_debug
};
struct aml_namestr {
enum aml_objtype type; /* =aml_t_namestr */
u_int8_t *dp;
};
struct aml_opregion {
enum aml_objtype type;
int space;
int offset;
int length;
};
struct aml_num {
enum aml_objtype type; /* =aml_t_num */
int number;
int constant;
};
struct aml_package {
enum aml_objtype type;
int elements;
union aml_object **objects;
};
struct aml_string {
enum aml_objtype type; /* =aml_t_string */
int needfree;
u_int8_t *string;
};
struct aml_buffer {
enum aml_objtype type; /* =aml_t_buffer */
int size;
u_int8_t *data; /* This should be free when
* this object is free.
*/
};
enum fieldtype {
f_t_field,
f_t_index,
f_t_bank
};
struct nfieldd {
enum fieldtype ftype; /* f_t_field */
u_int8_t *regname; /* Namestring */
};
struct ifieldd {
enum fieldtype ftype; /* f_t_index */
u_int8_t *indexname;
u_int8_t *dataname;
};
struct bfieldd {
enum fieldtype ftype; /* f_t_bank */
u_int8_t *regname;
u_int8_t *bankname;
u_int32_t bankvalue;
};
struct aml_field {
enum aml_objtype type;
u_int32_t flags;
int bitoffset; /* Not Byte offset but bitoffset */
int bitlen;
union {
enum fieldtype ftype;
struct nfieldd fld;
struct ifieldd ifld;
struct bfieldd bfld;
} f;
};
struct aml_bufferfield {
enum aml_objtype type; /* aml_t_bufferfield */
int bitoffset;
int bitlen;
u_int8_t *origin; /* This should not be free
* when this object is free
* (Within Buffer object)
*/
};
struct aml_method {
enum aml_objtype type;
int argnum; /* Not argnum but argnum|frag */
u_int8_t *from;
u_int8_t *to;
};
struct aml_powerres {
enum aml_objtype type;
int level;
int order;
};
struct aml_processor {
enum aml_objtype type;
int id;
int addr;
int len;
};
struct aml_mutex_queue {
STAILQ_ENTRY(aml_mutex_queue) entry;
};
struct aml_mutex {
enum aml_objtype type;
int level;
volatile void *cookie; /* In kernel, struct proc? */
STAILQ_HEAD(, aml_mutex_queue) queue;
};
struct aml_objref {
enum aml_objtype type;
struct aml_name *nameref;
union aml_object *ref;
int offset; /* of aml_buffer.data or aml_package.objects. */
/* if negative value, not ready to dereference for element access. */
unsigned deref; /* indicates whether dereffenced or not */
unsigned alias; /* true if this is an alias object reference */
};
struct aml_regfield {
enum aml_objtype type;
int space;
u_int32_t flags;
int offset;
int bitoffset;
int bitlen;
};
struct aml_event {
enum aml_objtype type; /* aml_t_event */
int inuse;
};
union aml_object {
enum aml_objtype type;
struct aml_num num;
struct aml_processor proc;
struct aml_powerres pres;
struct aml_opregion opregion;
struct aml_method meth;
struct aml_field field;
struct aml_mutex mutex;
struct aml_namestr nstr;
struct aml_buffer buffer;
struct aml_bufferfield bfld;
struct aml_package package;
struct aml_string str;
struct aml_objref objref;
struct aml_event event;
struct aml_regfield regfield;
};
union aml_object *aml_copy_object(struct aml_environ *,
union aml_object *);
union aml_object *aml_alloc_object(enum aml_objtype,
union aml_object *);
void aml_free_objectcontent(union aml_object *);
void aml_free_object(union aml_object **);
void aml_realloc_object(union aml_object *, int);
#endif /* !_AML_OBJ_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,36 +0,0 @@
/*-
* Copyright (c) 1999 Doug Rabson
* 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.
*
* $Id: aml_parse.h,v 1.9 2000/08/08 14:12:05 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_PARSE_H_
#define _AML_PARSE_H_
struct aml_name *aml_parse_objectlist(struct aml_environ *, int);
struct aml_name *aml_parse_termobj(struct aml_environ *, int);
#endif /* !_AML_PARSE_H_ */

View file

@ -1,349 +0,0 @@
/*-
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* Copyright (c) 2000 Munehiro Matsuda <haro@tk.kubota.co.jp>
* 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.
*
* $Id: aml_region.c,v 1.10 2000/08/09 14:47:44 iwasaki Exp $
* $FreeBSD$
*/
/*
* Region I/O subroutine
*/
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_region.h>
#include <dev/acpi/aml/aml_name.h>
#ifndef ACPI_NO_OSDFUNC_INLINE
#include <machine/acpica_osd.h>
#endif
/*
* Dummy functions for aml_region_io_simple()
*/
u_int32_t
aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value)
{
return (value);
}
u_int32_t
aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value)
{
return (value);
}
int
aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value,
struct aml_region_handle *h)
{
return (0);
}
/*
* Primitive functions for aml_region_io_simple()
*/
int
aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset, u_int32_t *valuep)
{
u_int32_t value;
switch (h->regtype) {
case AML_REGION_SYSMEM:
/* XXX should be MI */
switch (h->unit) {
case 1:
value = *(volatile u_int8_t *)(h->vaddr + offset);
value &= 0xff;
break;
case 2:
value = *(volatile u_int16_t *)(h->vaddr + offset);
value &= 0xffff;
break;
case 4:
value = *(volatile u_int32_t *)(h->vaddr + offset);
break;
}
break;
case AML_REGION_SYSIO:
switch (h->unit) {
case 1:
value = OsdIn8(h->addr + offset);
value &= 0xff;
break;
case 2:
value = OsdIn16(h->addr + offset);
value &= 0xffff;
break;
case 4:
value = OsdIn32(h->addr + offset);
break;
}
break;
case AML_REGION_PCICFG:
switch (h->unit) {
case 1:
OsdReadPciCfgByte(h->pci_bus, h->pci_devfunc,
h->addr + offset, (UINT8 *)&value);
value &= 0xff;
break;
case 2:
OsdReadPciCfgWord(h->pci_bus, h->pci_devfunc,
h->addr + offset, (UINT16 *)&value);
value &= 0xffff;
break;
case 4:
OsdReadPciCfgDword(h->pci_bus, h->pci_devfunc,
h->addr + offset, &value);
break;
}
break;
default:
printf("aml_region_read_simple: not supported yet (%d)\n",
h->regtype);
value = 0;
break;
}
*valuep = value;
return (0);
}
int
aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset, u_int32_t value)
{
switch (h->regtype) {
case AML_REGION_SYSMEM:
/* XXX should be MI */
switch (h->unit) {
case 1:
value &= 0xff;
*(volatile u_int8_t *)(h->vaddr + offset) = value;
break;
case 2:
value &= 0xffff;
*(volatile u_int16_t *)(h->vaddr + offset) = value;
break;
case 4:
*(volatile u_int32_t *)(h->vaddr + offset) = value;
break;
}
break;
case AML_REGION_SYSIO:
switch (h->unit) {
case 1:
value &= 0xff;
OsdOut8(h->addr + offset, value);
break;
case 2:
value &= 0xffff;
OsdOut16(h->addr + offset, value);
break;
case 4:
OsdOut32(h->addr + offset, value);
break;
}
break;
case AML_REGION_PCICFG:
switch (h->unit) {
case 1:
OsdWritePciCfgByte(h->pci_bus, h->pci_devfunc,
h->addr + offset, value);
break;
case 2:
OsdWritePciCfgWord(h->pci_bus, h->pci_devfunc,
h->addr + offset, value);
break;
case 4:
OsdWritePciCfgDword(h->pci_bus, h->pci_devfunc,
h->addr + offset, value);
break;
}
break;
default:
printf("aml_region_write_simple: not supported yet (%d)\n",
h->regtype);
break;
}
return (0);
}
static int
aml_region_io_buffer(boolean_t io, int regtype, u_int32_t flags,
u_int8_t *buffer, u_int32_t baseaddr, u_int32_t bitoffset, u_int32_t bitlen)
{
vm_offset_t addr, vaddr;
size_t len;
const char *funcname[] = {
"aml_region_read_into_buffer",
"aml_region_write_from_buffer"
};
if (regtype != AML_REGION_SYSMEM) {
printf("%s: region type isn't system memory!\n", funcname[io]);
return (-1);
}
if (bitlen % 8) {
printf("%s: bit length isn't a multiple of 8!\n", funcname[io]);
}
if (bitoffset % 8) {
printf("%s: bit offset isn't a multiple of 8!\n", funcname[io]);
}
addr = baseaddr + bitoffset / 8;
len = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
OsdMapMemory((void *)addr, len, (void **)&vaddr);
switch (io) {
case AML_REGION_INPUT:
bcopy((void *)vaddr, (void *)buffer, len);
break;
case AML_REGION_OUTPUT:
bcopy((void *)buffer, (void *)vaddr, len);
break;
}
OsdUnMapMemory((void *)vaddr, len);
return (0);
}
u_int32_t
aml_region_read(struct aml_environ *env, int regtype, u_int32_t flags,
u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
{
int value;
int state;
AML_REGION_READ_DEBUG(regtype, flags, addr, bitoffset, bitlen);
state = aml_region_io(env, AML_REGION_INPUT, regtype,
flags, &value, addr, bitoffset, bitlen);
AML_SYSASSERT(state != -1);
return (value);
}
int
aml_region_read_into_buffer(struct aml_environ *env, int regtype,
u_int32_t flags, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen,
u_int8_t *buffer)
{
int state;
AML_REGION_READ_INTO_BUFFER_DEBUG(regtype, flags, addr, bitoffset, bitlen);
state = aml_region_io_buffer(AML_REGION_INPUT, regtype, flags,
buffer, addr, bitoffset, bitlen);
return (state);
}
int
aml_region_write(struct aml_environ *env, int regtype, u_int32_t flags,
u_int32_t value, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
{
int state;
AML_REGION_WRITE_DEBUG(regtype, flags, value, addr, bitoffset, bitlen);
state = aml_region_io(env, AML_REGION_OUTPUT, regtype,
flags, &value, addr, bitoffset, bitlen);
AML_SYSASSERT(state != -1);
return (state);
}
int
aml_region_write_from_buffer(struct aml_environ *env, int regtype,
u_int32_t flags, u_int8_t *buffer, u_int32_t addr, u_int32_t bitoffset,
u_int32_t bitlen)
{
int state;
AML_REGION_WRITE_FROM_BUFFER_DEBUG(regtype, flags,
addr, bitoffset, bitlen);
state = aml_region_io_buffer(AML_REGION_OUTPUT, regtype, flags,
buffer, addr, bitoffset, bitlen);
return (state);
}
int
aml_region_bcopy(struct aml_environ *env, int regtype,
u_int32_t flags, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen,
u_int32_t dflags, u_int32_t daddr, u_int32_t dbitoffset, u_int32_t dbitlen)
{
vm_offset_t from_addr, from_vaddr;
vm_offset_t to_addr, to_vaddr;
size_t len;
AML_REGION_BCOPY_DEBUG(regtype, flags, addr, bitoffset, bitlen,
dflags, daddr, dbitoffset, dbitlen);
if (regtype != AML_REGION_SYSMEM) {
printf("aml_region_bcopy: region type isn't system memory!\n");
return (-1);
}
if ((bitlen % 8) || (dbitlen % 8)) {
printf("aml_region_bcopy: bit length isn't a multiple of 8!\n");
}
if ((bitoffset % 8) || (dbitoffset % 8)) {
printf("aml_region_bcopy: bit offset isn't a multiple of 8!\n");
}
from_addr = addr + bitoffset / 8;
to_addr = daddr + dbitoffset / 8;
len = (bitlen > dbitlen) ? dbitlen : bitlen;
len = len / 8 + ((len % 8) ? 1 : 0);
OsdMapMemory((void *)from_addr, len, (void **)&from_vaddr);
OsdMapMemory((void *)to_addr, len, (void **)&to_vaddr);
bcopy((void *)from_vaddr, (void *)to_vaddr, len);
OsdUnMapMemory((void *)from_vaddr, len);
OsdUnMapMemory((void *)to_vaddr, len);
return (0);
}

View file

@ -1,92 +0,0 @@
/*-
* Copyright (c) 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.
*
* $Id: aml_region.h,v 1.5 2000/08/08 14:12:05 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_REGION_H_
#define _AML_REGION_H_
/*
* Note that common part of region I/O is implemented in aml_common.c.
*/
/*
* Debug macros for region I/O
*/
#define AML_REGION_READ_DEBUG(regtype, flags, addr, bitoffset, bitlen) \
AML_DEBUGPRINT("\n[aml_region_read(%d, %d, 0x%x, 0x%x, 0x%x)]\n",\
regtype, flags, addr, bitoffset, bitlen)
#define AML_REGION_READ_INTO_BUFFER_DEBUG(regtype, flags, \
addr, bitoffset, bitlen) \
AML_DEBUGPRINT("\n[aml_region_read_into_buffer(%d, %d, 0x%x, 0x%x, 0x%x)]\n",\
regtype, flags, addr, bitoffset, bitlen)
#define AML_REGION_WRITE_DEBUG(regtype, flags, value, \
addr, bitoffset, bitlen) \
AML_DEBUGPRINT("\n[aml_region_write(%d, %d, 0x%x, 0x%x, 0x%x, 0x%x)]\n",\
regtype, flags, value, addr, bitoffset, bitlen)
#define AML_REGION_WRITE_FROM_BUFFER_DEBUG(regtype, flags, \
addr, bitoffset, bitlen) \
AML_DEBUGPRINT("\n[aml_region_write_from_buffer(%d, %d, 0x%x, 0x%x, 0x%x)]\n",\
regtype, flags, addr, bitoffset, bitlen)
#define AML_REGION_BCOPY_DEBUG(regtype, flags, addr, bitoffset, bitlen, \
dflags, daddr, dbitoffset, dbitlen) \
AML_DEBUGPRINT("\n[aml_region_bcopy(%d, %d, 0x%x, 0x%x, 0x%x, %d, 0x%x, 0x%x, 0x%x)]\n",\
regtype, flags, addr, bitoffset, bitlen, \
dflags, daddr, dbitoffset, dbitlen)
/*
* Region I/O subroutine
*/
struct aml_environ;
u_int32_t aml_region_read(struct aml_environ *, int, u_int32_t,
u_int32_t, u_int32_t, u_int32_t);
int aml_region_write(struct aml_environ *, int, u_int32_t,
u_int32_t, u_int32_t, u_int32_t, u_int32_t);
int aml_region_read_into_buffer(struct aml_environ *, int,
u_int32_t, u_int32_t, u_int32_t,
u_int32_t, u_int8_t *);
int aml_region_write_from_buffer(struct aml_environ *, int,
u_int32_t, u_int8_t *, u_int32_t,
u_int32_t, u_int32_t);
int aml_region_bcopy(struct aml_environ *, int,
u_int32_t, u_int32_t, u_int32_t, u_int32_t,
u_int32_t, u_int32_t, u_int32_t, u_int32_t);
#ifndef _KERNEL
void aml_simulation_regdump(const char *);
extern int aml_debug_prompt_regoutput;
extern int aml_debug_prompt_reginput;
#endif /* !_KERNEL */
#endif /* !_AML_REGION_H_ */

View file

@ -1,41 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_status.h,v 1.6 2000/08/08 14:12:05 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_STATUS_H_
#define _AML_STATUS_H_
enum aml_status {
aml_stat_none = 0,
aml_stat_return,
aml_stat_break,
aml_stat_panic,
aml_stat_step
};
#endif /* !_AML_STATUS_H_ */

View file

@ -1,349 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_store.c,v 1.22 2000/08/09 14:47:44 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <dev/acpi/aml/aml_amlmem.h>
#include <dev/acpi/aml/aml_common.h>
#include <dev/acpi/aml/aml_env.h>
#include <dev/acpi/aml/aml_evalobj.h>
#include <dev/acpi/aml/aml_name.h>
#include <dev/acpi/aml/aml_obj.h>
#include <dev/acpi/aml/aml_region.h>
#include <dev/acpi/aml/aml_status.h>
#include <dev/acpi/aml/aml_store.h>
#ifndef _KERNEL
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "debug.h"
#else /* _KERNEL */
#include <sys/systm.h>
#endif /* !_KERNEL */
static void
aml_store_to_fieldname(struct aml_environ *env, union aml_object *obj,
struct aml_name *name)
{
char *buffer;
struct aml_name *wname, *oname, *iname;
struct aml_field *field;
struct aml_opregion *or;
union aml_object tobj, iobj, *tmpobj;
field = &name->property->field;
oname = env->curname;
iname = NULL;
env->curname = name->parent;
if (field->f.ftype == f_t_field) {
wname = aml_search_name(env, field->f.fld.regname);
if (wname == NULL ||
wname->property == NULL ||
wname->property->type != aml_t_opregion) {
AML_DEBUGPRINT("Inappropreate Type\n");
env->stat = aml_stat_panic;
env->curname = oname;
return;
}
or = &wname->property->opregion;
switch (obj->type) {
case aml_t_num:
aml_region_write(env, or->space, field->flags,
obj->num.number, or->offset,
field->bitoffset, field->bitlen);
AML_DEBUGPRINT("[write(%d, 0x%x, 0x%x)]",
or->space, obj->num.number,
or->offset + field->bitoffset / 8);
break;
case aml_t_buffer:
case aml_t_bufferfield:
if (obj->type == aml_t_buffer) {
buffer = obj->buffer.data;
} else {
buffer = obj->bfld.origin;
buffer += obj->bfld.bitoffset / 8;
}
aml_region_write_from_buffer(env, or->space,
field->flags, buffer, or->offset, field->bitoffset,
field->bitlen);
break;
case aml_t_regfield:
if (or->space != obj->regfield.space) {
AML_DEBUGPRINT("aml_store_to_fieldname: "
"Different type of space\n");
break;
}
aml_region_bcopy(env, obj->regfield.space,
obj->regfield.flags, obj->regfield.offset,
obj->regfield.bitoffset, obj->regfield.bitlen,
field->flags, or->offset, field->bitoffset,
field->bitlen);
break;
default:
AML_DEBUGPRINT("aml_store_to_fieldname: "
"Inappropreate Type of src object\n");
break;
}
} else if (field->f.ftype == f_t_index) {
iname = aml_search_name(env, field->f.ifld.indexname);
wname = aml_search_name(env, field->f.ifld.dataname);
iobj.type = aml_t_num;
iobj.num.number = field->bitoffset / 8; /* AccessType Boundary */
/* read whole values of IndexField */
aml_store_to_name(env, &iobj, iname);
tmpobj = aml_eval_name(env, wname);
/* make the values to be written */
tobj.num = obj->num;
tobj.num.number = aml_adjust_updatevalue(field->flags,
field->bitoffset & 7, field->bitlen,
tmpobj->num.number, obj->num.number);
/* write the values to IndexField */
aml_store_to_name(env, &iobj, iname);
aml_store_to_name(env, &tobj, wname);
}
env->curname = oname;
}
static void
aml_store_to_buffer(struct aml_environ *env, union aml_object *obj,
union aml_object *buf, int offset)
{
int size;
int bitlen;
switch (obj->type) {
case aml_t_num:
if (offset > buf->buffer.size) {
aml_realloc_object(buf, offset);
}
buf->buffer.data[offset] = obj->num.number & 0xff;
AML_DEBUGPRINT("[Store number 0x%x to buffer]",
obj->num.number & 0xff);
break;
case aml_t_string:
size = strlen(obj->str.string);
if (buf->buffer.size - offset < size) {
aml_realloc_object(buf, offset + size + 1);
}
strcpy(&buf->buffer.data[offset], obj->str.string);
AML_DEBUGPRINT("[Store string to buffer]");
break;
case aml_t_buffer:
bzero(buf->buffer.data, buf->buffer.size);
if (obj->buffer.size > buf->buffer.size) {
size = buf->buffer.size;
} else {
size = obj->buffer.size;
}
bcopy(obj->buffer.data, buf->buffer.data, size);
break;
case aml_t_regfield:
bitlen = (buf->buffer.size - offset) * 8;
if (bitlen > obj->regfield.bitlen) {
bitlen = obj->regfield.bitlen;
}
aml_region_read_into_buffer(env, obj->regfield.space,
obj->regfield.flags, obj->regfield.offset,
obj->regfield.bitoffset, bitlen,
buf->buffer.data + offset);
break;
default:
goto not_yet;
}
return;
not_yet:
AML_DEBUGPRINT("[XXX not supported yet]");
}
void
aml_store_to_object(struct aml_environ *env, union aml_object *src,
union aml_object * dest)
{
char *buffer, *srcbuf;
int offset, bitlen;
switch (dest->type) {
case aml_t_num:
if (src->type == aml_t_num) {
dest->num = src->num;
AML_DEBUGPRINT("[Store number 0x%x]", src->num.number);
} else {
env->stat = aml_stat_panic;
}
break;
case aml_t_string:
case aml_t_package:
break;
case aml_t_buffer:
aml_store_to_buffer(env, src, dest, 0);
break;
case aml_t_bufferfield:
buffer = dest->bfld.origin;
offset = dest->bfld.bitoffset;
bitlen = dest->bfld.bitlen;
switch (src->type) {
case aml_t_num:
if (aml_bufferfield_write(src->num.number, buffer, offset, bitlen)) {
AML_DEBUGPRINT("aml_bufferfield_write() failed\n");
}
break;
case aml_t_buffer:
case aml_t_bufferfield:
if (src->type == aml_t_buffer) {
srcbuf = src->buffer.data;
} else {
srcbuf = src->bfld.origin;
srcbuf += src->bfld.bitoffset / 8;
}
bcopy(srcbuf, buffer, bitlen / 8);
break;
case aml_t_regfield:
aml_region_read_into_buffer(env, src->regfield.space,
src->regfield.flags, src->regfield.offset,
src->regfield.bitoffset, src->regfield.bitlen,
buffer);
break;
default:
AML_DEBUGPRINT("not implemented yet");
break;
}
break;
case aml_t_debug:
aml_showobject(src);
break;
default:
AML_DEBUGPRINT("[Unimplemented %d]", dest->type);
break;
}
}
static void
aml_store_to_objref(struct aml_environ *env, union aml_object *obj,
union aml_object *r)
{
int offset;
union aml_object *ref;
if (r->objref.ref == NULL) {
r->objref.ref = aml_alloc_object(obj->type, NULL); /* XXX */
r->objref.nameref->property = r->objref.ref;
}
ref = r->objref.ref;
switch (ref->type) {
case aml_t_buffer:
offset = r->objref.offset;
aml_store_to_buffer(env, obj, ref, r->objref.offset);
break;
case aml_t_package:
offset = r->objref.offset;
if (r->objref.ref->package.elements < offset) {
aml_realloc_object(ref, offset);
}
if (ref->package.objects[offset] == NULL) {
ref->package.objects[offset] = aml_copy_object(env, obj);
} else {
aml_store_to_object(env, obj, ref->package.objects[offset]);
}
break;
default:
aml_store_to_object(env, obj, ref);
break;
}
}
/*
* Store to Named object
*/
void
aml_store_to_name(struct aml_environ *env, union aml_object *obj,
struct aml_name *name)
{
struct aml_name *wname;
if (env->stat == aml_stat_panic) {
return;
}
if (name == NULL || obj == NULL) {
AML_DEBUGPRINT("[Try to store no existant name ]");
return;
}
if (name->property == NULL) {
name->property = aml_copy_object(env, obj);
AML_DEBUGPRINT("[Copy number 0x%x]", obj->num.number);
return;
}
if (name->property->type == aml_t_namestr) {
wname = aml_search_name(env, name->property->nstr.dp);
name = wname;
}
if (name == NULL) {
env->stat = aml_stat_panic;
return;
}
if (name->property == NULL || name->property->type == aml_t_null) {
name->property = aml_copy_object(env, obj);
AML_DEBUGPRINT("[Copy number 0x%x]", obj->num.number);
return;
}
/* Writes to constant object are not allowed */
if (name->property != NULL && name->property->type == aml_t_num &&
name->property->num.constant == 1) {
return;
}
/* try to dereference */
if (obj->type == aml_t_objref && obj->objref.deref == 0) {
AML_DEBUGPRINT("Source object isn't dereferenced yet, "
"try to dereference anyway\n");
obj->objref.deref = 1;
obj = aml_eval_objref(env, obj);
}
switch (name->property->type) {
case aml_t_field:
aml_store_to_fieldname(env, obj, name);
break;
case aml_t_objref:
aml_store_to_objref(env, obj, name->property);
break;
case aml_t_num:
if (name == &env->tempname)
break;
default:
aml_store_to_object(env, obj, name->property);
break;
}
}

View file

@ -1,39 +0,0 @@
/*-
* Copyright (c) 1999 Takanori Watanabe
* 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.
*
* $Id: aml_store.h,v 1.8 2000/08/09 14:47:44 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _AML_STORE_H_
#define _AML_STORE_H_
void aml_store_to_name(struct aml_environ *, union aml_object *,
struct aml_name *);
void aml_store_to_object(struct aml_environ *, union aml_object *,
union aml_object *);
#endif /* _AML_STORE_H_ */

View file

@ -1,142 +0,0 @@
/*-
* Copyright (c) 2000 Michael Smith <msmith@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 <vm/vm.h>
#include <vm/pmap.h>
#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>
#ifdef ACPI_NO_OSDFUNC_INLINE
#include <machine/acpica_osd.h>
#endif
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

@ -1,35 +0,0 @@
/*-
* Copyright (c) 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$
*/
#ifndef _MACHINE_ACPI_MACHDEP_H_
#define _MACHINE_ACPI_MACHDEP_H_
#define ACPI_BUS_SPACE_IO I386_BUS_SPACE_IO
#define ACPI_BUS_SPACE_MEM I386_BUS_SPACE_MEM
#endif /* ! _MACHINE_ACPI_MACHDEP_H_ */

View file

@ -1,321 +0,0 @@
/*-
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* Copyright (c) 2000 Munehiro Matsuda <haro@tk.kubota.co.jp>
* 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.
*
* $Id: acpica_osd.h,v 1.3 2000/08/09 14:47:48 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/clock.h>
#include <machine/acpi_machdep.h>
#include <machine/vmparam.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include "pcib_if.h"
#ifdef ACPI_NO_OSDFUNC_INLINE
#define _ACPICA_INLINE_
#else
#define _ACPICA_INLINE_ static __inline
#endif
/*
* ACPICA compatibility
*/
static UINT32 OsdInX(ACPI_IO_ADDRESS, int);
static void OsdOutX(ACPI_IO_ADDRESS, UINT32, int);
/*
* New-bus dependent code
*/
static device_t get_pcib_device(void);
static __inline device_t
get_pcib_device()
{
device_t nexus, pcib;
if ((nexus = device_find_child(root_bus, "nexus", 0)) == NULL) {
return (NULL);
}
if ((pcib = device_find_child(nexus, "pcib", 0)) == NULL) {
return (NULL);
}
return (pcib);
}
/*
* Platform/Hardware independent I/O interfaces
*/
static __inline UINT32
OsdInX(ACPI_IO_ADDRESS InPort, int bytes)
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
UINT32 retval;
bst = ACPI_BUS_SPACE_IO;
bsh = InPort;
switch (bytes) {
case 1:
retval = bus_space_read_1(bst, bsh, 0);
break;
case 2:
retval = bus_space_read_2(bst, bsh, 0);
break;
case 4:
retval = bus_space_read_4(bst, bsh, 0);
break;
default:
printf("OsdInX: wrong length to read\n");
retval = 0;
}
return (retval);
}
_ACPICA_INLINE_ UINT8
OsdIn8(ACPI_IO_ADDRESS InPort)
{
return (OsdInX(InPort, 1) & 0xff);
}
_ACPICA_INLINE_ UINT16
OsdIn16(ACPI_IO_ADDRESS InPort)
{
return (OsdInX(InPort, 2) & 0xffff);
}
_ACPICA_INLINE_ UINT32
OsdIn32(ACPI_IO_ADDRESS InPort)
{
return (OsdInX(InPort, 4));
}
static __inline void
OsdOutX(ACPI_IO_ADDRESS OutPort, UINT32 Value, int bytes)
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
bst = ACPI_BUS_SPACE_IO;
bsh = OutPort;
switch (bytes) {
case 1:
bus_space_write_1(bst, bsh, 0, Value & 0xff);
break;
case 2:
bus_space_write_2(bst, bsh, 0, Value & 0xffff);
break;
case 4:
bus_space_write_4(bst, bsh, 0, Value);
break;
default:
printf("OsdOutX: wrong length to write\n");
}
}
_ACPICA_INLINE_ void
OsdOut8(ACPI_IO_ADDRESS OutPort, UINT8 Value)
{
OsdOutX(OutPort, Value, 1);
}
_ACPICA_INLINE_ void
OsdOut16(ACPI_IO_ADDRESS OutPort, UINT16 Value)
{
OsdOutX(OutPort, Value, 2);
}
_ACPICA_INLINE_ void
OsdOut32(ACPI_IO_ADDRESS OutPort, UINT32 Value)
{
OsdOutX(OutPort, Value, 4);
}
_ACPICA_INLINE_ ACPI_STATUS
OsdMapMemory(void *PhysicalAddress, UINT32 Length, void **LogicalAddress)
{
vm_offset_t PhysicalEnd;
vm_offset_t PhysicalOffs;
PhysicalEnd = (vm_offset_t)PhysicalAddress + Length;
if (PhysicalEnd < 1024 * 1024) {
/*
* The first 1Mb is mapped at KERNBASE.
*/
*LogicalAddress = (void *)(uintptr_t)
(KERNBASE + (vm_offset_t)PhysicalAddress);
} else {
PhysicalOffs = (vm_offset_t)PhysicalAddress -
trunc_page((vm_offset_t)PhysicalAddress);
*LogicalAddress = (caddr_t)
pmap_mapdev((vm_offset_t)PhysicalAddress - PhysicalOffs,
Length + PhysicalOffs) +
PhysicalOffs;
}
return (AE_OK);
}
_ACPICA_INLINE_ void
OsdUnMapMemory(void *LogicalAddress, UINT32 Length)
{
if ((vm_offset_t)LogicalAddress + Length - KERNBASE >= 1024 * 1024) {
pmap_unmapdev((vm_offset_t)LogicalAddress, Length);
}
}
/*
* Standard access to PCI configuration space
*/
static __inline ACPI_STATUS
OsdReadPciCfg(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 *Value, int bytes)
{
static device_t pcib = NULL;
if (pcib == NULL && (pcib = get_pcib_device()) == NULL) {
return (AE_ERROR);
}
*Value = PCIB_READ_CONFIG(pcib, Bus, (DeviceFunction >> 16) & 0xff,
DeviceFunction & 0xff, Register, bytes);
return (AE_OK);
}
_ACPICA_INLINE_ ACPI_STATUS
OsdReadPciCfgByte(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT8 *Value)
{
ACPI_STATUS status;
UINT32 tmp;
status = OsdReadPciCfg(Bus, DeviceFunction, Register, &tmp, 1);
*Value = tmp & 0xff;
return (status);
}
_ACPICA_INLINE_ ACPI_STATUS
OsdReadPciCfgWord(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT16 *Value)
{
ACPI_STATUS status;
UINT32 tmp;
status = OsdReadPciCfg(Bus, DeviceFunction, Register, &tmp, 2);
*Value = tmp & 0xffff;
return (status);
}
_ACPICA_INLINE_ ACPI_STATUS
OsdReadPciCfgDword(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 *Value)
{
ACPI_STATUS status;
UINT32 tmp;
status = OsdReadPciCfg(Bus, DeviceFunction, Register, &tmp, 2);
*Value = tmp;
return (status);
}
static __inline ACPI_STATUS
OsdWritePciCfg(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 Value, int bytes)
{
static device_t pcib = NULL;
if (pcib == NULL && (pcib = get_pcib_device()) == NULL) {
return (AE_ERROR);
}
PCIB_WRITE_CONFIG(pcib, Bus, (DeviceFunction >> 16) & 0xff,
DeviceFunction & 0xff, Register, Value, bytes);
return (AE_OK);
}
_ACPICA_INLINE_ ACPI_STATUS
OsdWritePciCfgByte(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT8 Value)
{
return (OsdWritePciCfg(Bus, DeviceFunction, Register, (UINT32) Value, 1));
}
_ACPICA_INLINE_ ACPI_STATUS
OsdWritePciCfgWord(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT16 Value)
{
return (OsdWritePciCfg(Bus, DeviceFunction, Register, (UINT32) Value, 2));
}
_ACPICA_INLINE_ ACPI_STATUS
OsdWritePciCfgDword(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 Value)
{
return (OsdWritePciCfg(Bus, DeviceFunction, Register, Value, 4));
}
_ACPICA_INLINE_ ACPI_STATUS
OsdSleep(UINT32 Seconds, UINT32 Milliseconds)
{
int error;
ACPI_STATUS status;
error = acpi_sleep(Seconds * 1000 + Milliseconds);
switch (error) {
case 0:
/* The running thread slept for the time specified */
status = AE_OK;
break;
case 1:
/* TBD!!!! */
status = AE_BAD_PARAMETER;
break;
case 2:
default:
/* The running thread did not slept because of a host OS error */
status = AE_ERROR;
break;
}
return (status);
}
_ACPICA_INLINE_ ACPI_STATUS
OsdSleepUsec(UINT32 Microseconds)
{
if (Microseconds == 0) {
return (AE_BAD_PARAMETER);
}
DELAY(Microseconds);
return (AE_OK);
}