Now that amldb(8) is no longer needed by acpidump, remove the last vestiges

of the original userland ACPI implementation.  amldb is still available from
the devel/acpicatools port.
This commit is contained in:
Nate Lawson 2003-08-28 03:38:18 +00:00
parent 945137d9b4
commit 1f5b6306c2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=119516
26 changed files with 0 additions and 7607 deletions

View File

@ -1,13 +0,0 @@
# $Id: Makefile,v 1.5 2000/07/14 18:16:30 iwasaki Exp $
# $FreeBSD$
PROG= amldb
MAN= amldb.8
SRCS= amldb.c debug.c region.c
SRCS+= aml_parse.c aml_name.c aml_amlmem.c aml_memman.c aml_store.c \
aml_obj.c aml_evalobj.c aml_common.c
CFLAGS+= -I${.CURDIR}
.include <bsd.prog.mk>
.PATH: ${.CURDIR}/aml

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 <aml/aml_env.h>
#include <aml/aml_memman.h>
#include <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 <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 <aml/aml_common.h>
#include <aml/aml_env.h>
#include <aml/aml_evalobj.h>
#include <aml/aml_name.h>
#include <aml/aml_obj.h>
#include <aml/aml_parse.h>
#include <aml/aml_status.h>
#include <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 <aml/aml_name.h>
#include <aml/aml_obj.h>
#include <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 <aml/aml_amlmem.h>
#include <aml/aml_common.h>
#include <aml/aml_env.h>
#include <aml/aml_evalobj.h>
#include <aml/aml_name.h>
#include <aml/aml_obj.h>
#include <aml/aml_parse.h>
#include <aml/aml_region.h>
#include <aml/aml_status.h>
#include <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 <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 <aml/aml_amlmem.h>
#include <aml/aml_common.h>
#include <aml/aml_env.h>
#include <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 <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 <aml/aml_amlmem.h>
#include <aml/aml_env.h>
#include <aml/aml_name.h>
#include <aml/aml_obj.h>
#include <aml/aml_status.h>
#include <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 <aml/aml_common.h>
#include <aml/aml_region.h>
#include <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 <aml/aml_amlmem.h>
#include <aml/aml_common.h>
#include <aml/aml_env.h>
#include <aml/aml_evalobj.h>
#include <aml/aml_name.h>
#include <aml/aml_obj.h>
#include <aml/aml_region.h>
#include <aml/aml_status.h>
#include <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,338 +0,0 @@
.\" ACPI (ACPI Package)
.\"
.\" Copyright (c) 2000 Takanori Watanabe <takawata@FreeBSD.org>
.\" Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
.\" Copyright (c) 2000 Yasuo YOKOYAMA <yokoyama@jp.FreeBSD.org>
.\" Copyright (c) 2000 Norihiro KUMAGAI <kumagai@home.com>
.\"
.\" 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 REGENTS 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 REGENTS 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$
.\"
.Dd August 31, 2000
.Dt AMLDB 8
.Os
.Sh NAME
.Nm amldb
.Nd executing and debugging AML interpreter
(with DSDT files)
.Sh SYNOPSIS
.Nm
.Op Fl dhst
.Ar dsdt_file ...
.Sh DESCRIPTION
The
.Nm
utility parses the DSDT
(Differentiated System Description Table)
files, which usually are acquired from ACPI BIOS, and executes
the sequence of ACPI Control Methods described in AML
(ACPI Machine Language)
with its AML interpreter.
The
.Nm
utility also has a simple ACPI virtual machine. During execution of the
Control Methods each access to the region, such as
SystemMemory, SystemIO, PCI_Config, does not affect the real
hardware but only the virtual machine.
Because the sequence of virtual accesses is maintained in user space,
AML interpreter developers need not worry about any effect on hardware
when they analyze DSDT data files. They can develop and debug the
interpreter, even if the machine has no ACPI BIOS.
.Pp
The developer will need to acquire a DSDT data file from any machine
with ACPI BIOS through
.Xr acpidump 8 .
The DSDT is a table, a part of the whole ACPI memory table
located in somewhere in the BIOS area
.Pq Li 0xa0000 \- 0x100000 .
It includes such information as the detailed hardware information
for PnP, and the set of procedures which perform power management from
the OS. The information is stored in AML format.
.Pp
The AML interpreter can execute any of the Control Methods specified
by users. When executed, it interprets the byte sequence in the
Control Method of DSDT, and disassembles the opcodes that it
recognizes into ASL
(ACPI Source Language)
format to be displayed.
.Pp
If it encounters one of more accesses to the region such as
SystemMemory in executing the Control Methods, its ACPI Virtual
Machine simulates the input/output operations to the resources in the
region. In writing to a certain region, the ACPI Virtual Machine
prepares a piece of memory corresponding to its address,
if necessary, and holds the specified value in the memory as the
.Em region contents .
In reading from a certain region, it fetches the value in the memory
.Pq Em region contents ,
prompts with it as the following:
.Bd -literal -offset indent
DEBUG[read(0, 0x100b6813)&mask:0x1](default: 0x1 / 1) >>
.Ed
.Pp
for users to have the opportunity to modify it, and hands it to
the AML interpreter. In case that there is no corresponding region
in the AML Virtual Machine, the value zero is handed.
.Pp
The interpreter continues to maintain all of the
.Em region contents
until
.Nm
terminates. You can specify their initial values with the file
.Pa region.ini
in the current directory. If it is executed with
.Fl d
option, it dumps the final status of all of its
.Em region contents
to the file
.Pa region.dmp
when it terminates. Each line of there files consists of the following
fields, separated by tabs; region type, address, and value.
Region types are specified as follows;
.TS H
box;
c | l.
value region type
=
0 SystemMemory
1 SystemIO
2 PCI_Concig
3 EmbeddedControl
4 SMBus
.TE
.Pp
Interactive commands are described below:
.Bl -tag -width indent
.It Cm s
.Em Single step :
Performs single-step execution of the current Control Method. If
the next instruction is an invocation of another Control Method,
the step execution will continue in the following Control Method.
.It Cm n
.Em Step program :
Performs single-step execution of the current Control Method.
Even if the next instruction is an invocation of another Control
Method, the step execution will not continue.
.It Cm c
.Em Continue program being debugged :
Resumes execution of the AML interpreter. Because the current
.Nm
has no way of breakpoint, this command might not so much useful.
.It Cm q
.Em Quit method execution :
Terminates execution of the current Control Method. If
.Nm
is not in execution, this command causes to input the next
DSDT data file. If there are no next DSDT data files, it
terminates
.Nm
itself.
.It Cm t
.Em Show local name space tree and variables :
Displays the structure of the ACPI namespace tree. If
.Nm
is in execution, this command displays the structure that relates
to the objects, arguments, and local variables below the scope of the
current Control Method.
.It Cm i
.Em Toggle region input prompt :
Switches whether the prompt for modifying the value read from the
.Em region contents
be showed or not. Default is On.
.It Cm o
.Em Toggle region output prompt :
Switches whether the prompt for modifying the value to be written
to the region contents will be shown or not. The default is Off.
.It Cm m
.Em Show memory management statistics :
Displays the current statistics of the memory management system
on the AML interpreter.
.It Cm r Ar method
.Em Run specified method :
Executes the specified Control Method. If it requires one or
more arguments, a prompt such as the following appears;
.Bd -literal
Method: Arg 1 From 0x280626ce To 0x28062775
Enter argument values (ex. number 1 / string foo). 'q' to quit.
Arg0 ?
.Ed
.Pp
For each argument, a pair of type string and value delimited by
one or more spaces can be entered. Now only
.Ic number
and
.Ic string
can be specified as the type string.
In the current implementation, only the first character of the type
string, such as
.Ic n
or
.Ic s ,
is identified. For example, we can enter as follows:
.Bd -literal
Arg0 ? n 1
.Ed
.Pp
.It Cm f Ar string
.Em Find named objects from namespace :
Lists the named objects that includes the specified string as the
terminate elements searching from the ACPI namespace. For the
namespace is expressed as the sequence of four-character elements,
appropriate number of additional underscore
.Pq Ql _
characters are necessary for specifying objects which have less than four
character string. Unless additional underscores specified, matching
occurs as the beginning of word with the specified number of characters.
.It Cm h
.Em Show help message :
Displays the command summary of
.Nm .
.El
.Sh OPTIONS
Exactly one of the following options must be specified. Otherwise,
.Nm
shows its usage and terminates.
.Bl -tag -width indent
.It Fl d
Dump the final status of all of the
.Em region contents
in the ACPI Virtual Machine to the file
.Pa region.dmp .
.It Fl h
Terminate with the usage of this command.
.It Fl s
Display the statistics of the memory management system on the
AML interpreter when
.Nm
terminates.
.It Fl t
Display the tree structure of ACPI namespace after the
DSDT data file is read.
.El
.Sh EXAMPLES
The following is an example including, invoking the
.Nm ,
searching
.Li _PRS
(Possible Resource Settings)
objects, and executing the
.Li _PTS
(Prepare To Sleep)
Control Method by the AML interpreter.
.Bd -literal -offset indent
% amldb p2b.dsdt.dat
Loading p2b.dsdt.dat...done
AML>f _PRS
\\_SB_.PCI0.ISA_.PS2M._PRS.
\\_SB_.PCI0.ISA_.IRDA._PRS.
\\_SB_.PCI0.ISA_.UAR2._PRS.
\\_SB_.PCI0.ISA_.UAR1._PRS.
\\_SB_.PCI0.ISA_.ECP_._PRS.
\\_SB_.PCI0.ISA_.LPT_._PRS.
\\_SB_.PCI0.ISA_.FDC0._PRS.
\\_SB_.LNKD._PRS.
\\_SB_.LNKC._PRS.
\\_SB_.LNKB._PRS.
\\_SB_.LNKA._PRS.
AML>r _PTS
Method: Arg 1 From 0x2805f0a3 To 0x2805f0db
Enter argument values (ex. number 1 / string foo). 'q' to quit.
Arg0 ? n 5
==== Running _PTS. ====
AML>s
[\_PTS. START]
If(LNot(LEqual(Arg0, 0x5)))
AML>
If(LEqual(Arg0, 0x1))
AML>
If(LEqual(Arg0, 0x2))
AML>
Store(One, TO12)
[aml_region_write(1, 1, 0x1, 0xe42c, 0x18, 0x1)]
amldb: region.ini: No such file or directory
[1:0x00@0xe42f]->[1:0x01@0xe42f]
[write(1, 0x1, 0xe42f)]
[aml_region_read(1, 1, 0xe42c, 0x18, 0x1)]
[1:0x01@0xe42f]
DEBUG[read(1, 0xe42f)&mask:0x1](default: 0x1 / 1) >>
[read(1, 0xe42f)->0x1]
AML>
Or(Arg0, 0xf0, Local2)[Copy number 0xf5]
AML>t
_PTS Method: Arg 1 From 0x2805f0a3 To 0x2805f0db
Arg0 Num:0x5
Local2 Num:0xf5
AML>s
Store(Local2, DBG1)
[aml_region_write(1, 1, 0xf5, 0x80, 0x0, 0x8)]
[1:0x00@0x80]->[1:0xf5@0x80]
[write(1, 0xf5, 0x80)]
[aml_region_read(1, 1, 0x80, 0x0, 0x8)]
[1:0xf5@0x80]
DEBUG[read(1, 0x80)&mask:0xf5](default: 0xf5 / 245) >>
[read(1, 0x80)->0xf5]
AML>
[\_PTS. END]
_PTS Method: Arg 1 From 0x2805f0a3 To 0x2805f0db
NO object
==== _PTS finished. ====
AML>q
%
.Ed
.Sh BUGS
The ACPI virtual machine does not completely simulate the behavior
of a machine with an ACPI BIOS. In the current implementation, the
ACPI virtual machine only reads or writes the stored values by
emulating access to regions such as SystemMemory.
.Pp
Because the AML interpreter interprets and disassembles
simultaneously, it is impossible to implement such features as setting
breakpoints with the specified line number in ASL. Setting breakpoints
at certain Control Methods, which is not very difficult, has not
yet implemented because nobody has ever needed it.
.Sh FILES
.Bl -tag -width region.ini -compact
.It Pa region.ini
.It Pa region.dmp
.El
.Sh SEE ALSO
.Xr acpi 4 ,
.Xr acpiconf 8 ,
.Xr acpidump 8
.Sh AUTHORS
.An Takanori Watanabe Aq takawata@FreeBSD.org
.An Mitsuru IWASAKI Aq iwasaki@FreeBSD.org
.An Yasuo YOKOYAMA Aq yokoyama@jp.FreeBSD.org
.Pp
Some contributions made by
.An Chitoshi Ohsawa Aq ohsawa@catv1.ccn-net.ne.jp ,
.An Takayasu IWANASHI Aq takayasu@wendy.a.perfect-liberty.or.jp ,
.An Norihiro KUMAGAI Aq kumagai@home.com ,
.An Kenneth Ingham Aq ingham@I-pi.com ,
and
.An Michael Lucas Aq mwlucas@blackhelicopters.org .
.Sh HISTORY
The
.Nm
utility appeared in
.Fx 5.0 .

View File

@ -1,185 +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: amldb.c,v 1.8 2000/08/08 14:12:24 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <aml/aml_amlmem.h>
#include <aml/aml_common.h>
#include <aml/aml_env.h>
#include <aml/aml_parse.h>
#include <aml/aml_region.h>
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
int regdump_enabled = 0;
int memstat_enabled = 0;
int showtree_enabled = 0;
static void aml_init_namespace();
void
aml_init_namespace()
{
struct aml_environ env;
struct aml_name *newname;
aml_new_name_group(AML_NAME_GROUP_OS_DEFINED);
env.curname = aml_get_rootname();
newname = aml_create_name(&env, "\\_OS_");
newname->property = aml_alloc_object(aml_t_string, NULL);
newname->property->str.needfree = 0;
newname->property->str.string = "Microsoft Windows NT";
}
static int
load_dsdt(const char *dsdtfile)
{
struct aml_environ env;
u_int8_t *code;
struct stat sb;
int fd;
printf("Loading %s...", dsdtfile);
fd = open(dsdtfile, O_RDONLY, 0);
if (fd == -1) {
perror("open");
exit(-1);
}
if (fstat(fd, &sb) == -1) {
perror("fstat");
exit(-1);
}
if ((code = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == NULL) {
perror("mmap");
exit(-1);
}
aml_init_namespace();
aml_new_name_group((int)code);
bzero(&env, sizeof(env));
#define SIZEOF_SDT_HDR 36 /* struct size except body */
if (strncmp(code, "DSDT", 4) == 0) {
env.dp = code + SIZEOF_SDT_HDR;
} else {
env.dp = code;
}
env.end = code + sb.st_size;
env.curname = aml_get_rootname();
aml_local_stack_push(aml_local_stack_create());
aml_parse_objectlist(&env, 0);
aml_local_stack_delete(aml_local_stack_pop());
assert(env.dp == env.end);
env.dp = code;
env.end = code + sb.st_size;
printf("done\n");
aml_debug = 1; /* debug print enabled */
if (showtree_enabled == 1) {
aml_showtree(env.curname, 0);
}
do {
aml_dbgr(&env, &env);
} while (env.stat != aml_stat_panic);
aml_debug = 0; /* debug print disabled */
if (regdump_enabled == 1) {
aml_simulation_regdump("region.dmp");
}
while (name_group_list->id != AML_NAME_GROUP_ROOT) {
aml_delete_name_group(name_group_list);
}
if (memstat_enabled == 1) {
memman_statistics(aml_memman);
}
memman_freeall(aml_memman);
return (0);
}
static void
usage(const char *progname)
{
printf("usage: %s [-d] [-s] [-t] [-h] dsdt_files...\n", progname);
exit(1);
}
int
main(int argc, char *argv[])
{
char c, *progname;
int i;
progname = argv[0];
while ((c = getopt(argc, argv, "dsth")) != -1) {
switch (c) {
case 'd':
regdump_enabled = 1;
break;
case 's':
memstat_enabled = 1;
break;
case 't':
showtree_enabled = 1;
break;
case 'h':
default:
usage(progname);
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (argc == 0) {
usage(progname);
}
for (i = 0; i < argc; i++) {
load_dsdt(argv[i]);
}
return (0);
}

View File

@ -1,310 +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: debug.c,v 1.19 2000/08/16 18:15:00 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <aml/aml_name.h>
#include <aml/aml_amlmem.h>
#include <aml/aml_status.h>
#include <aml/aml_env.h>
#include <aml/aml_obj.h>
#include <aml/aml_evalobj.h>
#include <aml/aml_parse.h>
#include <aml/aml_region.h>
#include <aml/aml_store.h>
#include <aml/aml_common.h>
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
static int
print_named_object(struct aml_name *name, va_list ap)
{
aml_print_curname(name);
printf("\n");
return (0); /* always return success to continue the search */
}
void
aml_dbgr(struct aml_environ *env1, struct aml_environ *env2)
{
#define CMDBUFLEN 512
#define ARGBUFLEN 512
static char lastcommand[CMDBUFLEN];
char commandline[CMDBUFLEN];
char argbuf[7][ARGBUFLEN];
char *ptr, *method;
char *np, *ep;
int i;
int argnum;
struct aml_name *name;
union aml_object argv[7], *retval;
while (1) {
fputs("AML>", stderr);
fgets(commandline, 512, stdin);
commandline[512 - 1] = '\n'; /* safety */
if (feof(stdin)) {
commandline[0] = 'q';
}
if (commandline[0] == '\n') {
memcpy(commandline, lastcommand, sizeof commandline);
}
memcpy(lastcommand, commandline, sizeof commandline);
switch (commandline[0]) {
case 's':
if (env2 != NULL) {
env2->stat = aml_stat_step;
}
/* FALLTHROUGH */
case 'n':
env1->stat = aml_stat_step;
return;
case 'c':
env1->stat = aml_stat_none;
return;
case 'q':
env1->stat = aml_stat_panic;
return;
case 't':
/* NULL terminate */
ptr = &commandline[1];
while (ptr[0] != '\n')
ptr++;
ptr[0] = '\0';
/* move pointer to object name */
ptr = &commandline[1];
while (ptr[0] == ' ')
ptr++;
/* show current tree if no argument */
if (ptr[0] == '\0') {
aml_showtree(env1->curname, 0);
goto show_variables;
}
/* start from root? */
if (ptr[0] == '\\') {
if (ptr[1] == '\0') {
aml_showtree(aml_get_rootname(), 0);
goto show_variables;
}
if ((name = aml_find_from_namespace(aml_get_rootname(), ptr))) {
aml_showtree(name, 0);
goto show_variables;
}
}
if ((name = aml_find_from_namespace(env1->curname, ptr))) {
aml_showtree(name, 0);
}
show_variables:
for (i = 0; i < 7; i++) {
struct aml_name *tmp =
aml_local_stack_getArgX(NULL, i);
if (tmp == NULL || tmp->property == NULL) {
break;
}
printf(" Arg%d ", i);
aml_showobject(tmp->property);
}
for (i = 0; i < 8; i++) {
struct aml_name *tmp =
aml_local_stack_getLocalX(i);
if (tmp == NULL || tmp->property == NULL) {
continue;
}
printf(" Local%d ", i);
aml_showobject(tmp->property);
}
break;
case 'i':
aml_debug_prompt_reginput =
(aml_debug_prompt_reginput == 0) ? 1 : 0;
if (aml_debug_prompt_reginput)
fputs("REGION INPUT ON\n", stderr);
else
fputs("REGION INPUT OFF\n", stderr);
break;
case 'o':
aml_debug_prompt_regoutput =
(aml_debug_prompt_regoutput == 0) ? 1 : 0;
if (aml_debug_prompt_regoutput)
fputs("REGION OUTPUT ON\n", stderr);
else
fputs("REGION OUTPUT OFF\n", stderr);
break;
case 'm':
memman_statistics(aml_memman);
break;
case 'r':
/* NULL terminate */
ptr = &commandline[1];
while (ptr[0] != '\n')
ptr++;
ptr[0] = '\0';
/* move pointer to method name */
ptr = &commandline[1];
while (ptr[0] == ' ')
ptr++;
if (ptr[0] == '\0') {
break;
}
name = aml_find_from_namespace(aml_get_rootname(), ptr);
if (name == NULL) {
printf("%s:%d:aml_dbgr: not found name %s\n",
__FILE__, __LINE__, ptr);
break;
}
if (name->property == NULL ||
name->property->type != aml_t_method) {
printf("%s:%d:aml_dbgr: not method %s\n",
__FILE__, __LINE__, ptr);
break;
}
aml_showobject(name->property);
method = ptr;
argnum = name->property->meth.argnum & 0x07;
if (argnum) {
fputs(" Enter argument values "
"(ex. number 1 / string foo). "
"'q' to quit.\n", stderr);
}
/* get and parse argument values */
for (i = 0; i < argnum; i++) {
retry:
fprintf(stderr, " Arg%d ? ", i);
if (read(0, argbuf[i], ARGBUFLEN) == 0) {
fputs("\n", stderr);
goto retry;
}
argbuf[i][ARGBUFLEN - 1] = '\n';
if (argbuf[i][0] == 'q') {
goto finish_execution;
}
if (argbuf[i][0] == '\n') {
goto retry;
}
/* move pointer to the value */
ptr = &argbuf[i][0];
while (ptr[0] != ' ' && ptr[0] != '\n') {
ptr++;
}
while (ptr[0] == ' ') {
ptr++;
}
if (ptr[0] == '\n') {
goto retry;
}
switch (argbuf[i][0]) {
case 'n':
argv[i].type = aml_t_num;
np = ptr;
if (ptr[0] == '0' &&
ptr[1] == 'x') {
argv[i].num.number = strtoq(ptr, &ep, 16);
} else {
argv[i].num.number = strtoq(ptr, &ep, 10);
}
if (np == ep) {
fputs("Wrong value for number.\n",
stderr);
goto retry;
}
break;
case 's':
argv[i].type = aml_t_string;
argv[i].str.needfree = 0;
argv[i].str.string = ptr;
/* NULL ternimate */
while (ptr[0] != '\n') {
ptr++;
}
ptr[0] = '\0';
break;
default:
fputs("Invalid data type "
"(supports number or string only)\n",
stderr);
goto retry;
}
}
bzero(lastcommand, sizeof lastcommand);
fprintf(stderr, "==== Running %s. ====\n", method);
aml_local_stack_push(aml_local_stack_create());
retval = aml_invoke_method_by_name(method, argnum, argv);
aml_showobject(retval);
aml_local_stack_delete(aml_local_stack_pop());
fprintf(stderr, "==== %s finished. ====\n", method);
finish_execution:
break;
case 'f':
/* NULL terminate */
ptr = &commandline[1];
while (ptr[0] != '\n')
ptr++;
ptr[0] = '\0';
/* move pointer to object name */
ptr = &commandline[1];
while (ptr[0] == ' ')
ptr++;
aml_apply_foreach_found_objects(aml_get_rootname(),
ptr, print_named_object);
break;
case 'h':
fputs("s Single step\n"
"n Step program\n"
"c Continue program being debugged\n"
"q Quit method execution\n"
"t Show local name space tree and variables\n"
"i Toggle region input prompt\n"
"o Toggle region output prompt\n"
"m Show memory management statistics\n"
"r Run specified method\n"
"f Find named objects from namespace.\n"
"h Show this messsage\n", stderr);
break;
}
}
}

View File

@ -1,36 +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: debug.h,v 1.8 2000/08/09 14:47:57 iwasaki Exp $
* $FreeBSD$
*/
#ifndef _DEBUG_H_
#define _DEBUG_H_
void aml_dbgr(struct aml_environ *, struct aml_environ *);
#endif /* !_DEBUG_H_ */

View File

@ -1,510 +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: region.c,v 1.14 2000/08/08 14:12:25 iwasaki Exp $
* $FreeBSD$
*/
/*
* Region I/O subroutine
*/
#include <sys/param.h>
#include <sys/queue.h>
#include <aml/aml_amlmem.h>
#include <aml/aml_name.h>
#include <aml/aml_region.h>
#include <aml/aml_common.h>
#include <assert.h>
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
int aml_debug_prompt_regoutput = 0;
int aml_debug_prompt_reginput = 1;
static void aml_simulation_regload(const char *dumpfile);
struct ACPIRegionContent {
TAILQ_ENTRY(ACPIRegionContent) links;
int regtype;
u_int32_t addr;
u_int8_t value;
};
TAILQ_HEAD(ACPIRegionContentList, ACPIRegionContent);
struct ACPIRegionContentList RegionContentList;
static int aml_simulation_initialized = 0;
static void
aml_simulation_init()
{
aml_simulation_initialized = 1;
TAILQ_INIT(&RegionContentList);
aml_simulation_regload("region.ini");
}
static int
aml_simulate_regcontent_add(int regtype, u_int32_t addr, u_int8_t value)
{
struct ACPIRegionContent *rc;
rc = malloc(sizeof(struct ACPIRegionContent));
if (rc == NULL) {
return (-1); /* malloc fail */
}
rc->regtype = regtype;
rc->addr = addr;
rc->value = value;
TAILQ_INSERT_TAIL(&RegionContentList, rc, links);
return (0);
}
static int
aml_simulate_regcontent_read(int regtype, u_int32_t addr, u_int8_t *valuep)
{
struct ACPIRegionContent *rc;
if (!aml_simulation_initialized) {
aml_simulation_init();
}
TAILQ_FOREACH(rc, &RegionContentList, links) {
if (rc->regtype == regtype && rc->addr == addr) {
*valuep = rc->value;
return (1); /* found */
}
}
return (aml_simulate_regcontent_add(regtype, addr, 0));
}
static int
aml_simulate_regcontent_write(int regtype, u_int32_t addr, u_int8_t *valuep)
{
struct ACPIRegionContent *rc;
if (!aml_simulation_initialized) {
aml_simulation_init();
}
TAILQ_FOREACH(rc, &RegionContentList, links) {
if (rc->regtype == regtype && rc->addr == addr) {
rc->value = *valuep;
return (1); /* exists */
}
}
return (aml_simulate_regcontent_add(regtype, addr, *valuep));
}
static u_int32_t
aml_simulate_prompt(char *msg, u_int32_t def_val)
{
char buf[16], *ep;
u_int32_t val;
val = def_val;
printf("DEBUG");
if (msg != NULL) {
printf("%s", msg);
}
printf("(default: 0x%x / %u) >>", val, val);
fflush(stdout);
bzero(buf, sizeof buf);
while (1) {
if (read(0, buf, sizeof buf) == 0) {
continue;
}
if (buf[0] == '\n') {
break; /* use default value */
}
if (buf[0] == '0' && buf[1] == 'x') {
val = strtoq(buf, &ep, 16);
} else {
val = strtoq(buf, &ep, 10);
}
break;
}
return (val);
}
static void
aml_simulation_regload(const char *dumpfile)
{
char buf[256], *np, *ep;
struct ACPIRegionContent rc;
FILE *fp;
if (!aml_simulation_initialized) {
return;
}
if ((fp = fopen(dumpfile, "r")) == NULL) {
warn("%s", dumpfile);
return;
}
while (fgets(buf, sizeof buf, fp) != NULL) {
np = buf;
/* reading region type */
rc.regtype = strtoq(np, &ep, 10);
if (np == ep) {
continue;
}
np = ep;
/* reading address */
rc.addr = strtoq(np, &ep, 16);
if (np == ep) {
continue;
}
np = ep;
/* reading value */
rc.value = strtoq(np, &ep, 16);
if (np == ep) {
continue;
}
aml_simulate_regcontent_write(rc.regtype, rc.addr, &rc.value);
}
fclose(fp);
}
int
aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset,
u_int32_t *valuep)
{
int i, state;
u_int8_t val;
u_int32_t value;
state = 0;
value = val = 0;
for (i = 0; i < h->unit; i++) {
state = aml_simulate_regcontent_read(h->regtype,
h->addr + offset + i, &val);
if (state == -1) {
goto out;
}
value |= val << (i * 8);
}
*valuep = value;
out:
return (state);
}
int
aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset,
u_int32_t value)
{
int i, state;
u_int8_t val;
state = 0;
val = 0;
for (i = 0; i < h->unit; i++) {
val = value & 0xff;
state = aml_simulate_regcontent_write(h->regtype,
h->addr + offset + i, &val);
if (state == -1) {
goto out;
}
value = value >> 8;
}
out:
return (state);
}
u_int32_t
aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value)
{
u_int32_t retval;
char buf[64];
retval = value;
sprintf(buf, "[read(%d, 0x%x)&mask:0x%x]",
h->regtype, h->addr, value);
if (aml_debug_prompt_reginput) {
retval = aml_simulate_prompt(buf, value);
} else {
printf("\t%s\n", buf);
}
return (retval);
}
u_int32_t
aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value)
{
u_int32_t retval;
char buf[64];
retval = value;
if (aml_debug_prompt_regoutput) {
printf("\n");
sprintf(buf, "[write(%d, 0x%x, 0x%x)]",
h->regtype, value, h->addr);
retval = aml_simulate_prompt(buf, value);
}
return (retval);
}
int
aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value,
struct aml_region_handle *h)
{
int state;
state = 0;
if (orgval != value) {
state = aml_region_io(h->env, AML_REGION_OUTPUT, h->regtype,
h->flags, &value, h->baseaddr, h->bitoffset, h->bitlen);
if (state == -1) {
goto out;
}
}
out:
return (state);
}
static int
aml_simulate_region_io_buffer(int io, int regtype, u_int32_t flags,
u_int8_t *buffer, u_int32_t baseaddr, u_int32_t bitoffset, u_int32_t bitlen)
{
u_int8_t val;
u_int8_t offsetlow, offsethigh;
u_int32_t addr, byteoffset, bytelen;
int state, i;
val = 0;
offsetlow = offsethigh = 0;
state = 0;
byteoffset = bitoffset / 8;
bytelen = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
addr = baseaddr + byteoffset;
offsetlow = bitoffset % 8;
assert(offsetlow == 0);
if (bytelen > 1) {
offsethigh = (bitlen - (8 - offsetlow)) % 8;
}
assert(offsethigh == 0);
for (i = bytelen; i > 0; i--, addr++) {
switch (io) {
case AML_REGION_INPUT:
val = 0;
state = aml_simulate_regcontent_read(regtype, addr, &val);
if (state == -1) {
goto finish;
}
buffer[bytelen - i] = val;
break;
case AML_REGION_OUTPUT:
val = buffer[bytelen - i];
state = aml_simulate_regcontent_write(regtype,
addr, &val);
if (state == -1) {
goto finish;
}
break;
}
}
finish:
return (state);
}
static u_int32_t
aml_simulate_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;
state = aml_region_io(env, AML_REGION_INPUT, regtype, flags, &value,
addr, bitoffset, bitlen);
assert(state != -1);
return (value);
}
int
aml_simulate_region_read_into_buffer(int regtype, u_int32_t flags,
u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen, u_int8_t *buffer)
{
int state;
state = aml_simulate_region_io_buffer(AML_REGION_INPUT, regtype, flags,
buffer, addr, bitoffset, bitlen);
assert(state != -1);
return (state);
}
int
aml_simulate_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;
state = aml_region_io(env, AML_REGION_OUTPUT, regtype, flags,
&value, addr, bitoffset, bitlen);
assert(state != -1);
return (state);
}
int
aml_simulate_region_write_from_buffer(int regtype, u_int32_t flags,
u_int8_t *buffer, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
{
int state;
state = aml_simulate_region_io_buffer(AML_REGION_OUTPUT, regtype,
flags, buffer, addr, bitoffset, bitlen);
assert(state != -1);
return (state);
}
int
aml_simulate_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)
{
u_int32_t len, i;
u_int32_t value;
int state;
len = (bitlen > dbitlen) ? dbitlen : bitlen;
len = len / 8 + ((len % 8) ? 1 : 0);
for (i = 0; i < len; i++) {
state = aml_region_io(env, AML_REGION_INPUT, regtype,
flags, &value, addr, bitoffset + i * 8, 8);
assert(state != -1);
state = aml_region_io(env, AML_REGION_OUTPUT, regtype,
dflags, &value, daddr, dbitoffset + i * 8, 8);
assert(state != -1);
}
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)
{
AML_REGION_READ_DEBUG(regtype, flags, addr, bitoffset, bitlen);
return (aml_simulate_region_read(env, regtype, flags, addr,
bitoffset, bitlen));
}
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)
{
AML_REGION_READ_INTO_BUFFER_DEBUG(regtype, flags, addr, bitoffset, bitlen);
return (aml_simulate_region_read_into_buffer(regtype, flags, addr,
bitoffset, bitlen, buffer));
}
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)
{
AML_REGION_WRITE_DEBUG(regtype, flags, value, addr, bitoffset, bitlen);
return (aml_simulate_region_write(env, regtype, flags, value, addr,
bitoffset, bitlen));
}
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)
{
AML_REGION_WRITE_FROM_BUFFER_DEBUG(regtype, flags,
addr, bitoffset, bitlen);
return (aml_simulate_region_write_from_buffer(regtype, flags, buffer,
addr, bitoffset, bitlen));
}
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)
{
AML_REGION_BCOPY_DEBUG(regtype, flags, addr, bitoffset, bitlen,
dflags, daddr, dbitoffset, dbitlen);
return (aml_simulate_region_bcopy(env, regtype, flags, addr, bitoffset,
bitlen, dflags, daddr, dbitoffset, dbitlen));
}
void
aml_simulation_regdump(const char *dumpfile)
{
struct ACPIRegionContent *rc;
FILE *fp;
if (!aml_simulation_initialized) {
return;
}
if ((fp = fopen(dumpfile, "w")) == NULL) {
warn("%s", dumpfile);
return;
}
while (!TAILQ_EMPTY(&RegionContentList)) {
rc = TAILQ_FIRST(&RegionContentList);
fprintf(fp, "%d 0x%x 0x%x\n",
rc->regtype, rc->addr, rc->value);
TAILQ_REMOVE(&RegionContentList, rc, links);
free(rc);
}
fclose(fp);
TAILQ_INIT(&RegionContentList);
}