Index: head/usr.sbin/acpi/amldb/Makefile =================================================================== --- head/usr.sbin/acpi/amldb/Makefile (revision 68517) +++ head/usr.sbin/acpi/amldb/Makefile (revision 68518) @@ -1,12 +1,12 @@ # $Id: Makefile,v 1.5 2000/07/14 18:16:30 iwasaki Exp $ # $FreeBSD$ PROG= amldb 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 MAN8= amldb.8 #DEBUG_FLAGS= -g -CFLAGS+= -I${.CURDIR}/../../../sys -I${.CURDIR} +CFLAGS+= -I${.CURDIR} .include -.PATH: ${.CURDIR}/../../../sys/dev/acpi/aml +.PATH: ${.CURDIR}/aml Index: head/usr.sbin/acpi/amldb/aml/aml_amlmem.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_amlmem.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_amlmem.c (revision 68518) @@ -1,92 +1,92 @@ /*- * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include -#include -#include +#include +#include +#include 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; Index: head/usr.sbin/acpi/amldb/aml/aml_amlmem.h =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_amlmem.h (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_amlmem.h (revision 68518) @@ -1,65 +1,65 @@ /*- * Copyright (c) 1999 Mitsuru IWASAKI * 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 +#include 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_ */ Index: head/usr.sbin/acpi/amldb/aml/aml_common.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_common.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_common.c (revision 68518) @@ -1,735 +1,735 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 #ifndef _KERNEL #include #include #include #include #include #include #else /* _KERNEL */ #include "opt_acpi.h" #include #include #include #include #include #include #include #ifndef ACPI_NO_OSDFUNC_INLINE #include #endif /* !ACPI_NO_OSDFUNC_INLINE */ #endif /* !_KERNEL */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include /* 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(""); */ 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); } Index: head/usr.sbin/acpi/amldb/aml/aml_env.h =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_env.h (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_env.h (revision 68518) @@ -1,46 +1,46 @@ /*- * 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 -#include -#include +#include +#include +#include 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_ */ Index: head/usr.sbin/acpi/amldb/aml/aml_evalobj.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_evalobj.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_evalobj.c (revision 68518) @@ -1,436 +1,436 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifndef _KERNEL #include #include #include #include #include #include #include #include #include #include "debug.h" #else /* _KERNEL */ #include #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)); } Index: head/usr.sbin/acpi/amldb/aml/aml_memman.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_memman.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_memman.c (revision 68518) @@ -1,476 +1,476 @@ /*- * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include +#include #ifndef _KERNEL #include #include #include #else /* _KERNEL */ #include #include #include 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); } Index: head/usr.sbin/acpi/amldb/aml/aml_name.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_name.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_name.c (revision 68518) @@ -1,481 +1,481 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Yasuo Yokoyama * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include -#include -#include -#include +#include +#include +#include +#include #ifndef _KERNEL #include #include #include #include "debug.h" #else /* _KERNEL */ #include #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); } Index: head/usr.sbin/acpi/amldb/aml/aml_name.h =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_name.h (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_name.h (revision 68518) @@ -1,88 +1,88 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Yasuo Yokoyama * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include +#include 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_ */ Index: head/usr.sbin/acpi/amldb/aml/aml_obj.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_obj.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_obj.c (revision 68518) @@ -1,264 +1,264 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #ifndef _KERNEL #include #include #include #include #include #include #include #include #else /* _KERNEL */ #include #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; } } Index: head/usr.sbin/acpi/amldb/aml/aml_parse.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_parse.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_parse.c (revision 68518) @@ -1,2018 +1,2018 @@ /*- * Copyright (c) 1999 Doug Rabson * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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.c,v 1.32 2000/08/12 15:20:45 iwasaki Exp $ * $FreeBSD$ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifndef _KERNEL #include #include #include #include #include #include #include #include #include #include "debug.h" #else /* _KERNEL */ #include #include #include #include #include #ifndef ACPI_NO_OSDFUNC_INLINE #include #endif #endif /* !_KERNEL */ static int findsetleftbit(int num); static int findsetrightbit(int num); static int frombcd(int num); static int tobcd(int num); static u_int32_t aml_parse_pkglength(struct aml_environ *env); static u_int8_t aml_parse_bytedata(struct aml_environ *env); static u_int16_t aml_parse_worddata(struct aml_environ *env); static u_int32_t aml_parse_dworddata(struct aml_environ *env); static u_int8_t *aml_parse_namestring(struct aml_environ *env); static void aml_parse_defscope(struct aml_environ *env, int indent); static union aml_object *aml_parse_defbuffer(struct aml_environ *env, int indent); static struct aml_name *aml_parse_concat_number(struct aml_environ *env, int num1, int indent); static struct aml_name *aml_parse_concat_buffer(struct aml_environ *env, union aml_object *obj, int indent); static struct aml_name *aml_parse_concat_string(struct aml_environ *env, union aml_object *obj, int indent); static struct aml_name *aml_parse_concatop(struct aml_environ *env, int indent); static union aml_object *aml_parse_defpackage(struct aml_environ *env, int indent); static void aml_parse_defmethod(struct aml_environ *env, int indent); static void aml_parse_defopregion(struct aml_environ *env, int indent); static int aml_parse_field(struct aml_environ *env, struct aml_field *template); static void aml_parse_fieldlist(struct aml_environ *env, struct aml_field *template, int indent); static void aml_parse_deffield(struct aml_environ *env, int indent); static void aml_parse_defindexfield(struct aml_environ *env, int indent); static void aml_parse_defbankfield(struct aml_environ *env, int indent); static void aml_parse_defdevice(struct aml_environ *env, int indent); static void aml_parse_defprocessor(struct aml_environ *env, int indent); static void aml_parse_defpowerres(struct aml_environ *env, int indent); static void aml_parse_defthermalzone(struct aml_environ *env, int indent); static struct aml_name *aml_parse_defelse(struct aml_environ *env, int indent, int num); static struct aml_name *aml_parse_defif(struct aml_environ *env, int indent); static struct aml_name *aml_parse_defwhile(struct aml_environ *env, int indent); static void aml_parse_defmutex(struct aml_environ *env, int indent); static void aml_createfield_generic(struct aml_environ *env, union aml_object *srcbuf, int index, int len, char *newname); static void aml_parse_defcreatefield(struct aml_environ *env, int indent); static int findsetleftbit(int num) { int i, filter; filter = 0; for (i = 0; i < 32; i++) { filter = filter >> 1; filter |= 1 << 31; if (filter & num) { break; } } i = (i == 32) ? 0 : i + 1; return (i); } static int findsetrightbit(int num) { int i, filter; filter = 0; for (i = 0; i < 32; i++) { filter = filter << 1; filter |= 1; if (filter & num) { break; } } i = (i == 32) ? 0 : i + 1; return (i); } static int frombcd(int num) { int res, factor; res = 0; factor = 1; while (num != 0) { res += ((num & 0xf) * factor); num = num / 16; factor *= 10; } return (res); } static int tobcd(int num) { int res, factor; res = 0; factor = 1; while (num != 0) { res += ((num % 10) * factor); num = num / 10; factor *= 16; } return (res); } static u_int32_t aml_parse_pkglength(struct aml_environ *env) { u_int8_t *dp; u_int32_t pkglength; dp = env->dp; pkglength = *dp++; switch (pkglength >> 6) { case 0: break; case 1: pkglength = (pkglength & 0xf) + (dp[0] << 4); dp += 1; break; case 2: pkglength = (pkglength & 0xf) + (dp[0] << 4) + (dp[1] << 12); dp += 2; break; case 3: pkglength = (pkglength & 0xf) + (dp[0] << 4) + (dp[1] << 12) + (dp[2] << 20); dp += 3; break; } env->dp = dp; return (pkglength); } static u_int8_t aml_parse_bytedata(struct aml_environ *env) { u_int8_t data; data = env->dp[0]; env->dp++; return (data); } static u_int16_t aml_parse_worddata(struct aml_environ *env) { u_int16_t data; data = env->dp[0] + (env->dp[1] << 8); env->dp += 2; return (data); } static u_int32_t aml_parse_dworddata(struct aml_environ *env) { u_int32_t data; data = env->dp[0] + (env->dp[1] << 8) + (env->dp[2] << 16) + (env->dp[3] << 24); env->dp += 4; return (data); } static u_int8_t * aml_parse_namestring(struct aml_environ *env) { u_int8_t *name; int segcount; name = env->dp; if (env->dp[0] == '\\') env->dp++; else if (env->dp[0] == '^') while (env->dp[0] == '^') env->dp++; if (env->dp[0] == 0x00) /* NullName */ env->dp++; else if (env->dp[0] == 0x2e) /* DualNamePrefix */ env->dp += 1 + 4 + 4; /* NameSeg, NameSeg */ else if (env->dp[0] == 0x2f) { /* MultiNamePrefix */ segcount = env->dp[1]; env->dp += 1 + 1 + segcount * 4; /* segcount * NameSeg */ } else env->dp += 4; /* NameSeg */ return (name); } struct aml_name * aml_parse_objectlist(struct aml_environ *env, int indent) { union aml_object *obj; obj = NULL; while (env->dp < env->end) { aml_print_indent(indent); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); AML_DEBUGPRINT("\n"); if (env->stat == aml_stat_step) { AML_DEBUGGER(env, env); continue; } if (env->stat != aml_stat_none) { env->tempname.property = obj; return (&env->tempname); } } return (NULL); } #define AML_CREATE_NAME(amlname, env, namestr, ret) do { \ amlname = aml_create_name(env, namestr); \ if (env->stat == aml_stat_panic) \ return ret; \ } while(0) #define AML_COPY_OBJECT(dest, env, src, ret) do { \ dest = aml_copy_object(env, src); \ if (dest == NULL) { \ env->stat = aml_stat_panic; \ return ret; \ } \ } while(0) #define AML_ALLOC_OBJECT(dest, env, type, ret) do { \ dest = aml_alloc_object(type, NULL); \ if (dest == NULL) { \ env->stat= aml_stat_panic; \ return ret; \ } \ } while(0) static void aml_parse_defscope(struct aml_environ *env, int indent) { u_int8_t *start, *end, *oend; u_int8_t *name; u_int32_t pkglength; struct aml_name *oname; start = env->dp; pkglength = aml_parse_pkglength(env); AML_DEBUGPRINT("Scope("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_DEBUGPRINT(") {\n"); oname = env->curname; AML_CREATE_NAME(env->curname, env, name,); oend = env->end; env->end = end = start + pkglength; aml_parse_objectlist(env, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); AML_SYSASSERT(env->dp == env->end); env->dp = end; env->end = oend; env->curname = oname; env->stat = aml_stat_none; } static union aml_object * aml_parse_defbuffer(struct aml_environ *env, int indent) { u_int8_t *start; u_int8_t *end; u_int8_t *buffer; u_int32_t pkglength; int size1, size2, size; union aml_object *obj; start = env->dp; pkglength = aml_parse_pkglength(env); end = start + pkglength; AML_DEBUGPRINT("Buffer("); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); size1 = aml_objtonum(env, obj); size2 = end - env->dp; size = (size1 < size2) ? size1 : size2; if (size1 > 0) { buffer = memman_alloc_flexsize(aml_memman, size1); if (buffer == NULL) { AML_DEBUGPRINT("NO MEMORY\n"); env->stat = aml_stat_panic; return (NULL); } bzero(buffer, size1); bcopy(env->dp, buffer, size); } else { buffer = NULL; } obj = &env->tempobject; obj->type = aml_t_buffer; obj->buffer.size = size1; obj->buffer.data = buffer; AML_DEBUGPRINT(") "); env->dp = end; return (obj); } static struct aml_name * aml_parse_concat_number(struct aml_environ *env, int num1, int indent) { int num2; struct aml_name *destname; union aml_object *obj; num2 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(", "); destname = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); obj = &env->tempobject; obj->type = aml_t_buffer; obj->buffer.size = 2; obj->buffer.data = memman_alloc_flexsize(aml_memman, 2); if (obj->buffer.data == NULL) { env->stat = aml_stat_panic; return (NULL); } obj->buffer.data[0] = num1 & 0xff; obj->buffer.data[1] = num2 & 0xff; aml_store_to_name(env, obj, destname); return (&env->tempname); } static struct aml_name * aml_parse_concat_buffer(struct aml_environ *env, union aml_object *obj, int indent) { union aml_object *tmpobj, *tmpobj2, *resobj; struct aml_name *destname; tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent)); AML_DEBUGPRINT(", "); if (tmpobj->type != aml_t_buffer) { env->stat = aml_stat_panic; return (NULL); } AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL); destname = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); resobj = &env->tempobject; env->tempname.property = resobj; resobj->buffer.type = aml_t_buffer; resobj->buffer.size = tmpobj2->buffer.size + obj->buffer.size; if (resobj->buffer.size > 0) { resobj->buffer.data = memman_alloc_flexsize(aml_memman, resobj->buffer.size); if (resobj->buffer.data == NULL) { env->stat = aml_stat_panic; return (NULL); } bcopy(obj->buffer.data, resobj->buffer.data, obj->buffer.size); bcopy(tmpobj2->buffer.data, resobj->buffer.data + obj->buffer.size, tmpobj2->buffer.size); } else { resobj->buffer.data = NULL; } aml_free_object(&tmpobj2); aml_store_to_name(env, resobj, destname); return (&env->tempname); } static struct aml_name * aml_parse_concat_string(struct aml_environ *env, union aml_object *obj, int indent) { int len; union aml_object *tmpobj, *tmpobj2, *resobj; struct aml_name *destname; tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent)); AML_DEBUGPRINT(", "); if (tmpobj->type != aml_t_string) { env->stat = aml_stat_panic; return (NULL); } AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL); destname = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); resobj = &env->tempobject; env->tempname.property = resobj; resobj->type = aml_t_buffer; resobj->str.needfree = 1; len = strlen(obj->str.string) + strlen(tmpobj2->str.string) + 1; if (len > 0) { resobj->str.string = memman_alloc_flexsize(aml_memman, len); if (resobj->str.string == NULL) { env->stat = aml_stat_panic; return (NULL); } strncpy(resobj->str.string, obj->str.string, len); strcat(resobj->str.string, tmpobj->str.string); } else { resobj->str.string = NULL; } aml_free_object(&tmpobj2); aml_store_to_name(env, resobj, destname); return (&env->tempname); } static struct aml_name * aml_parse_concatop(struct aml_environ *env, int indent) { union aml_object *obj, *tmpobj; struct aml_name *aname; AML_DEBUGPRINT("Concat("); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); AML_DEBUGPRINT(", "); switch (obj->type) { case aml_t_num: aname = aml_parse_concat_number(env, aml_objtonum(env, obj), indent); break; case aml_t_buffer: /* obj may be temporal object */ AML_COPY_OBJECT(tmpobj, env, obj, NULL); aname = aml_parse_concat_buffer(env, obj, indent); aml_free_object(&tmpobj); break; case aml_t_string: /* obj may be temporal object */ AML_COPY_OBJECT(tmpobj, env, obj, NULL); aname = aml_parse_concat_string(env, obj, indent); aml_free_object(&tmpobj); break; default: env->stat = aml_stat_panic; aname = NULL; break; } AML_DEBUGPRINT("\n"); return (aname); } static union aml_object * aml_parse_defpackage(struct aml_environ *env, int indent) { u_int8_t numelements; u_int8_t *start; u_int32_t pkglength; int i; struct aml_environ *copy; struct aml_name *tmpname; union aml_object *obj, **objects; start = env->dp; pkglength = aml_parse_pkglength(env); numelements = aml_parse_bytedata(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return (NULL); } if (numelements > 0) { objects = memman_alloc_flexsize(aml_memman, numelements * sizeof(union aml_object *)); if (objects == NULL) { env->stat = aml_stat_panic; return (NULL); } else { bzero(objects, numelements * sizeof(union aml_object *)); } } else { objects = NULL; } *copy = *env; env->dp = copy->end = start + pkglength; AML_DEBUGPRINT("Package() {\n"); i = 0; while ((copy->dp < copy->end) && (i < numelements)) { aml_print_indent(indent + 1); tmpname = aml_parse_termobj(copy, indent + 1); if (tmpname != NULL) { objects[i] = aml_copy_object(copy, tmpname->property); } AML_DEBUGPRINT(",\n"); i++; } aml_free_objectcontent(©->tempobject); aml_print_indent(indent); AML_DEBUGPRINT("}"); obj = &env->tempobject; obj->type = aml_t_package; obj->package.elements = numelements; obj->package.objects = objects; memman_free(aml_memman, memid_aml_environ, copy); return (obj); } static void aml_parse_defmethod(struct aml_environ *env, int indent) { u_int8_t flags; u_int8_t *start; u_int32_t pkglength; char *name; struct aml_environ *copy; struct aml_method *meth; struct aml_name *aname; union aml_object *aobj; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("Method("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_CREATE_NAME(aname, env, name,); if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); goto out; } AML_ALLOC_OBJECT(aobj, env, aml_t_method,); meth = &aobj->meth; aname->property = aobj; flags = *env->dp++; if (flags) { AML_DEBUGPRINT(", %d", flags); } AML_DEBUGPRINT(") {\n"); *copy = *env; meth->argnum = flags; meth->from = env->dp; meth->to = env->dp = copy->end = start + pkglength; aml_print_indent(indent); AML_DEBUGPRINT("}"); out: memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defopregion(struct aml_environ *env, int indent) { u_int8_t *name; struct aml_name *aname; struct aml_opregion *opregion; union aml_object *obj; const char *regions[] = { "SystemMemory", "SystemIO", "PCI_Config", "EmbeddedControl", "SMBus", }; AML_DEBUGPRINT("OperationRegion("); /* Name */ name = aml_parse_namestring(env); aml_print_namestring(name); AML_CREATE_NAME(aname, env, name,); if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); return; } AML_ALLOC_OBJECT(aname->property, env, aml_t_opregion,); opregion = &aname->property->opregion; opregion->space = *env->dp; AML_DEBUGPRINT(", %s, ", regions[*env->dp]); /* Space */ env->dp++; obj = aml_eval_name(env, aml_parse_termobj(env, indent)); /* Offset */ opregion->offset = aml_objtonum(env, obj); AML_DEBUGPRINT(", "); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); /* Length */ opregion->length = aml_objtonum(env, obj); AML_DEBUGPRINT(")"); } static const char *accessnames[] = { "AnyAcc", "ByteAcc", "WordAcc", "DWordAcc", "BlockAcc", "SMBSendRecvAcc", "SMBQuickAcc" }; static int aml_parse_field(struct aml_environ *env, struct aml_field *template) { u_int8_t *name; u_int8_t access, attribute; u_int32_t width; struct aml_name *aname; struct aml_field *prop; switch (*env->dp) { case '\\': case '^': case 'A'...'Z': case '_': case '.': name = aml_parse_namestring(env); width = aml_parse_pkglength(env); template->bitlen = width; aml_print_namestring(name); AML_CREATE_NAME(aname, env, name, NULL); /* Allignment */ if (width == 16) { template->bitoffset += 15; template->bitoffset &= (~15); } if (width == 32) { template->bitoffset += 31; template->bitoffset &= (~31); } else if ((width & 7) == 0) { template->bitoffset += 7; template->bitoffset &= (~7); } else if ((width > 32) && (width & 7) != 0) { AML_DEBUGPRINT("??? Can I treat it?\n"); } if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); return (NULL); } AML_ALLOC_OBJECT(aname->property, env, aml_t_field, NULL); prop = &aname->property->field; *prop = *template; template->bitoffset += width; AML_DEBUGPRINT(",\t%d", width); break; case 0x00: env->dp++; width = aml_parse_pkglength(env); template->bitoffset += width; AML_DEBUGPRINT("Offset(0x%x)", template->bitoffset); break; case 0x01: access = env->dp[1]; attribute = env->dp[2]; env->dp += 3; AML_DEBUGPRINT("AccessAs(%s, %d)", accessnames[access], attribute); template->bitoffset = attribute; template->flags = (template->flags | 0xf0) | access; break; } return (template->bitoffset); } static void aml_parse_fieldlist(struct aml_environ *env, struct aml_field *template, int indent) { u_int32_t offset; offset = 0; while (env->dp < env->end) { aml_print_indent(indent); offset = aml_parse_field(env, template); if (env->dp < env->end) { AML_DEBUGPRINT(",\n"); } else { AML_DEBUGPRINT("\n"); } } } static void aml_parse_deffield(struct aml_environ *env, int indent) { u_int8_t flags; u_int8_t *start, *name; u_int32_t pkglength; struct aml_environ *copy; struct aml_field fieldtemplate; static const char *lockrules[] = {"NoLock", "Lock"}; static const char *updaterules[] = {"Preserve", "WriteAsOnes", "WriteAsZeros", "*Error*"}; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("Field("); aml_print_namestring(name = aml_parse_namestring(env)); fieldtemplate.type = aml_t_field; flags = aml_parse_bytedata(env); fieldtemplate.flags = fieldtemplate.flags = flags; *copy = *env; env->dp = copy->end = start + pkglength; fieldtemplate.bitoffset = 0; fieldtemplate.bitlen = 0; fieldtemplate.f.ftype = f_t_field; fieldtemplate.f.fld.regname = name; AML_DEBUGPRINT(", %s, %s, %s) {\n", accessnames[flags & 0xf], lockrules[(flags >> 4) & 1], updaterules[(flags >> 5) & 3]); aml_parse_fieldlist(copy, &fieldtemplate, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defindexfield(struct aml_environ *env, int indent) { u_int8_t flags; u_int8_t *start, *iname, *dname; u_int32_t pkglength; struct aml_environ *copy; struct aml_field template; static const char *lockrules[] = {"NoLock", "Lock"}; static const char *updaterules[] = {"Preserve", "WriteAsOnes", "WriteAsZeros", "*Error*"}; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("IndexField("); aml_print_namestring(iname = aml_parse_namestring(env)); /* Name1 */ AML_DEBUGPRINT(", "); aml_print_namestring(dname = aml_parse_namestring(env)); /* Name2 */ template.type = aml_t_field; template.flags = flags = aml_parse_bytedata(env); template.bitoffset = 0; template.bitlen = 0; template.f.ftype = f_t_index; template.f.ifld.indexname = iname; template.f.ifld.dataname = dname; AML_DEBUGPRINT(", %s, %s, %s) {\n", accessnames[flags & 0xf], lockrules[(flags >> 4) & 1], updaterules[(flags >> 5) & 3]); *copy = *env; env->dp = copy->end = start + pkglength; aml_parse_fieldlist(copy, &template, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defbankfield(struct aml_environ *env, int indent) { u_int8_t flags; u_int8_t *start, *rname, *bname; u_int32_t pkglength, bankvalue; struct aml_environ *copy; struct aml_field template; union aml_object *obj; static const char *lockrules[] = {"NoLock", "Lock"}; static const char *updaterules[] = {"Preserve", "WriteAsOnes", "WriteAsZeros", "*Error*"}; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("BankField("); aml_print_namestring(rname = aml_parse_namestring(env)); /* Name1 */ AML_DEBUGPRINT(", "); aml_print_namestring(bname = aml_parse_namestring(env)); /* Name2 */ AML_DEBUGPRINT(", "); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); /* BankValue */ bankvalue = aml_objtonum(env, obj); template.type = aml_t_field; template.flags = flags = aml_parse_bytedata(env); template.bitoffset = 0; template.bitlen = 0; template.f.ftype = f_t_bank; template.f.bfld.regname = rname; template.f.bfld.bankname = bname; template.f.bfld.bankvalue = bankvalue; *copy = *env; env->dp = copy->end = start + pkglength; AML_DEBUGPRINT(", %s, %s, %s) {\n", accessnames[flags & 0xf], lockrules[(flags >> 4) & 1], updaterules[(flags >> 5) & 3]); aml_parse_fieldlist(copy, &template, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defdevice(struct aml_environ *env, int indent) { u_int8_t *start; u_int8_t *name; u_int32_t pkglength; struct aml_environ *copy; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("Device("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_DEBUGPRINT(") {\n"); *copy = *env; AML_CREATE_NAME(copy->curname, env, name,); if (copy->curname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); goto out; } AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_device,); env->dp = copy->end = start + pkglength; aml_parse_objectlist(copy, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); out: memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defprocessor(struct aml_environ *env, int indent) { u_int8_t *start; u_int8_t *name; u_int32_t pkglength; struct aml_environ *copy; struct aml_processor *proc; union aml_object *obj; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_ALLOC_OBJECT(obj, env, aml_t_processor,); proc = &obj->proc; AML_DEBUGPRINT("Processor("); name = aml_parse_namestring(env); aml_print_namestring(name); proc->id = aml_parse_bytedata(env); proc->addr = aml_parse_dworddata(env); proc->len = aml_parse_bytedata(env); AML_DEBUGPRINT(", %d, 0x%x, 0x%x) {\n", proc->id, proc->addr, proc->len); *copy = *env; AML_CREATE_NAME(copy->curname, env, name,); if (copy->curname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); goto out; } copy->curname->property = obj; env->dp = copy->end = start + pkglength; aml_parse_objectlist(copy, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); out: memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defpowerres(struct aml_environ *env, int indent) { u_int8_t *start; u_int8_t *name; u_int32_t pkglength; struct aml_environ *copy; struct aml_powerres *pres; union aml_object *obj; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("PowerResource("); AML_ALLOC_OBJECT(obj, env, aml_t_powerres,); name = aml_parse_namestring(env); aml_print_namestring(name); pres = &obj->pres; pres->level = aml_parse_bytedata(env); pres->order = aml_parse_worddata(env); AML_DEBUGPRINT(", %d, %d) {\n", pres->level, pres->order); *copy = *env; AML_CREATE_NAME(copy->curname, env, name,); if (copy->curname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); goto out; } copy->curname->property = obj; env->dp = copy->end = start + pkglength; aml_parse_objectlist(copy, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); out: memman_free(aml_memman, memid_aml_environ, copy); } static void aml_parse_defthermalzone(struct aml_environ *env, int indent) { u_int8_t *start; u_int8_t *name; u_int32_t pkglength; struct aml_environ *copy; start = env->dp; pkglength = aml_parse_pkglength(env); copy = memman_alloc(aml_memman, memid_aml_environ); if (copy == NULL) { env->stat = aml_stat_panic; return; } AML_DEBUGPRINT("ThermalZone("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_DEBUGPRINT(") {\n"); *copy = *env; AML_CREATE_NAME(copy->curname, env, name,); if (copy->curname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); goto out; } AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_therm,); env->dp = copy->end = start + pkglength; aml_parse_objectlist(copy, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); aml_free_objectcontent(©->tempobject); AML_SYSASSERT(copy->dp == copy->end); out: memman_free(aml_memman, memid_aml_environ, copy); } static struct aml_name * aml_parse_defelse(struct aml_environ *env, int indent, int num) { u_int8_t *start, *end, *oend; u_int32_t pkglength; struct aml_name *aname; start = env->dp; pkglength = aml_parse_pkglength(env); oend = env->end; env->end = end = start + pkglength; aname = NULL; AML_DEBUGPRINT("Else {\n"); if (num == 0) { aname = aml_parse_objectlist(env, indent + 1); aml_print_indent(indent); } AML_DEBUGPRINT("}"); env->dp = end; env->end = oend; return (aname); } static struct aml_name * aml_parse_defif(struct aml_environ *env, int indent) { u_int8_t *start, *end, *oend; u_int32_t pkglength; int num; struct aml_name *aname, *aname1; start = env->dp; pkglength = aml_parse_pkglength(env); aname = NULL; AML_DEBUGPRINT("If("); num = aml_objtonum(env, aml_eval_name (env, aml_parse_termobj(env, indent))); oend = env->end; end = start + pkglength; AML_DEBUGPRINT(")"); if (num) { AML_DEBUGPRINT("{\n"); env->end = end; aname = aml_parse_objectlist(env, indent + 1); aml_print_indent(indent); AML_DEBUGPRINT("}"); } env->dp = end; env->end = oend; if ((end < oend) && *(env->dp) == 0xa1) { env->dp++; aname1 = aml_parse_defelse(env, indent, num); aname = (num == 0) ? aname1 : aname; } return (aname); } static struct aml_name * aml_parse_defwhile(struct aml_environ *env, int indent) { u_int8_t *start, *end, *oend; u_int32_t pkglength; int num; struct aml_name *aname; start = env->dp; pkglength = aml_parse_pkglength(env); oend = env->end; end = start + pkglength; aname = NULL; for (;;) { env->dp = start; aml_parse_pkglength(env); AML_DEBUGPRINT("While("); num = aml_objtonum(env, aml_eval_name (env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(")"); if (num == 0) { break; } AML_DEBUGPRINT(" {\n"); env->end = end; aname = aml_parse_objectlist(env, indent + 1); if (env->stat == aml_stat_step) { AML_DEBUGGER(env, env); continue; } if (env->stat != aml_stat_none) break; aml_print_indent(indent); AML_DEBUGPRINT("}"); } AML_DEBUGPRINT("\n"); env->dp = end; env->end = oend; if (env->stat == aml_stat_break) { env->stat = aml_stat_none; aname = NULL; } return (aname); } static void aml_parse_defmutex(struct aml_environ *env, int indent) { char *name; struct aml_name *aname; struct aml_mutex *mut; /* MutexOp */ AML_DEBUGPRINT("Mutex("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_CREATE_NAME(aname, env, name,); if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); return; } AML_ALLOC_OBJECT(aname->property, env, aml_t_mutex,); mut = &aname->property->mutex; mut->level = *env->dp++; STAILQ_INIT(&mut->queue); AML_DEBUGPRINT(", %d)", mut->level); } static void aml_createfield_generic(struct aml_environ *env, union aml_object *srcbuf, int index, int len, char *newname) { struct aml_bufferfield *field; struct aml_name *aname; if (srcbuf == NULL || srcbuf->type != aml_t_buffer) { AML_DEBUGPRINT("Not Buffer assigned,"); env->stat = aml_stat_panic; return; } AML_CREATE_NAME(aname, env, newname,); if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); return; } AML_ALLOC_OBJECT(aname->property, env, aml_t_bufferfield,); field = &aname->property->bfld; field->bitoffset = index; field->bitlen = len; field->origin = srcbuf->buffer.data; } static void aml_parse_defcreatefield(struct aml_environ *env, int indent) { int index, len; char *newname; union aml_object *obj, *srcbuf; /* CreateFieldOp */ AML_DEBUGPRINT("CreateField("); srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent)); if (srcbuf == &env->tempobject) { AML_DEBUGPRINT("NONAMED BUFFER\n"); env->stat = aml_stat_panic; return; } AML_DEBUGPRINT(", "); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); index = aml_objtonum(env, obj); AML_DEBUGPRINT(", "); obj = aml_eval_name(env, aml_parse_termobj(env, indent)); len = aml_objtonum(env, obj); AML_DEBUGPRINT(", "); newname = aml_parse_namestring(env); aml_print_namestring(newname); aml_createfield_generic(env, srcbuf, index, len, newname); AML_DEBUGPRINT(") "); } /* * Returns Named object or parser buffer. The object need not be free because * it returns preallocated buffer in env or Contain of named object. If You * need to preserve object, create a copy and then store. And The object * returned from this function is not valid after another call is * shared, tempolary buffer may be shared. */ struct aml_name * aml_parse_termobj(struct aml_environ *env, int indent) { u_int8_t opcode; u_int8_t *name; int value; int num1, num2; int len; int match1, match2, i, pkgval, start; int widthindex, index; char *newname; struct aml_name *aname; struct aml_name *destname1, *destname2; struct aml_name *tmpname, *srcname; struct aml_name *src; union aml_object *ret; union aml_object *tmpobj; union aml_object anum; union aml_object *objref; union aml_object *srcobj; union aml_object *obj; union aml_object *srcbuf; static int widthtbl[4] = {32, 16, 8, 1}; const char *opname[4] = {"CreateDWordField", "CreateWordField", "CreateByteField", "CreateBitField"}; aname = &env->tempname; ret = &env->tempobject; anum.type = aml_t_num; aname->property = ret; aml_free_objectcontent(ret); if (env->stat == aml_stat_panic) { /* * If previosuly parser panic , parsing next instruction is * prohibited. */ return (NULL); } aname = NULL; opcode = *env->dp++; switch (opcode) { case '\\': case '^': case 'A' ... 'Z': case '_': case '.': env->dp--; ret->type = aml_t_namestr; ret->nstr.dp = aml_parse_namestring(env); aml_print_namestring(ret->nstr.dp); aname = &env->tempname; break; case 0x0a: /* BytePrefix */ ret->type = aml_t_num; value = aml_parse_bytedata(env); ret->num.number = value; AML_DEBUGPRINT("0x%x", value); aname = &env->tempname; break; case 0x0b: /* WordPrefix */ ret->type = aml_t_num; value = aml_parse_worddata(env); ret->num.number = value; AML_DEBUGPRINT("0x%x", value); aname = &env->tempname; break; case 0x0c: /* DWordPrefix */ ret->type = aml_t_num; value = aml_parse_dworddata(env); ret->num.number = value; AML_DEBUGPRINT("0x%x", value); aname = &env->tempname; break; case 0x0d: /* StringPrefix */ ret->type = aml_t_string; ret->str.string = env->dp; len = strlen(env->dp); ret->str.needfree = 0; AML_DEBUGPRINT("\"%s\"", (const char *)ret->str.string); env->dp += (len + 1); aname = &env->tempname; break; case 0x00: /* ZeroOp */ ret->type = aml_t_num; ret->num.number = 0; ret->num.constant = 1; AML_DEBUGPRINT("Zero"); aname = &env->tempname; break; case 0x01: /* OneOp */ ret->type = aml_t_num; ret->num.number = 1; ret->num.constant = 1; AML_DEBUGPRINT("One"); aname = &env->tempname; break; case 0xff: /* OnesOp */ ret->type = aml_t_num; ret->num.number = 0xffffffff; ret->num.constant = 1; AML_DEBUGPRINT("Ones"); aname = &env->tempname; break; case 0x06: /* AliasOp */ AML_DEBUGPRINT("Alias("); tmpname = aml_parse_termobj(env, indent); if (env->stat == aml_stat_panic) { return (NULL); } if (tmpname->property == NULL || tmpname->property->type != aml_t_namestr) { env->stat = aml_stat_panic; return (NULL); } /* * XXX if srcname is deleted after this object, what * shall I do? */ srcname = aml_search_name(env, tmpname->property->nstr.dp); AML_DEBUGPRINT(", "); name = aml_parse_namestring(env); aml_print_namestring(name); AML_CREATE_NAME(aname, env, name, NULL); if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); aml_print_curname(aname); return (NULL); } AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL); objref = aname->property; objref->objref.nameref = srcname; objref->objref.ref = srcname->property; objref->objref.offset = -1; objref->objref.alias = 1; /* Yes, this is an alias */ AML_DEBUGPRINT(")"); /* shut the interpreter up during the namespace initializing */ return (NULL); case 0x08: /* NameOp */ AML_DEBUGPRINT("Name("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_CREATE_NAME(aname, env, name, NULL); if (env->stat == aml_stat_panic) { AML_DEBUGPRINT("Already Defined \n"); aml_print_curname(aname); return (NULL); } AML_DEBUGPRINT(", "); AML_COPY_OBJECT(aname->property, env, aml_eval_name(env, aml_parse_termobj(env, indent)), NULL); AML_DEBUGPRINT(")"); break; case 0x10: /* ScopeOp */ aml_parse_defscope(env, indent); break; case 0x11: /* BufferOp */ aname = &env->tempname; aname->property = aml_parse_defbuffer(env, indent); break; case 0x12: /* PackageOp */ aname = &env->tempname; aname->property = aml_parse_defpackage(env, indent); break; case 0x14: /* MethodOp */ aml_parse_defmethod(env, indent); break; case 0x5b: /* ExtOpPrefix */ opcode = *env->dp++; switch (opcode) { case 0x01: aml_parse_defmutex(env, indent); break; case 0x02: /* EventOp */ AML_DEBUGPRINT("Event("); name = aml_parse_namestring(env); aml_print_namestring(name); AML_CREATE_NAME(aname, env, name, NULL); if (aname->property != NULL) { env->stat = aml_stat_panic; AML_DEBUGPRINT("Already Defined \n"); return (NULL); } AML_ALLOC_OBJECT(aname->property, env, aml_t_event, NULL); AML_DEBUGPRINT(")"); return (NULL); break; case 0x12: /* CondRefOfOp */ AML_DEBUGPRINT("CondRefOf("); src = aml_parse_termobj(env, indent); AML_DEBUGPRINT(", "); if (src == &env->tempname || src == NULL) { aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); anum.num.number = 0xffffffff; env->tempobject.num = anum.num; aname = &env->tempname; break; } AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL); if (src->property == NULL || src->property->type != aml_t_namestr) { objref->objref.nameref = src; } else { objref->objref.nameref = aml_create_local_object(); } objref->objref.ref = src->property; objref->objref.offset = -1; /* different from IndexOp */ destname1 = aml_parse_termobj(env, indent); aml_store_to_name(env, objref, destname1); anum.num.number = 0; env->tempobject.num = anum.num; aname = &env->tempname; AML_DEBUGPRINT(")"); break; case 0x13: aml_parse_defcreatefield(env, indent); break; case 0x20: /* LoadOp *//* XXX Not Impremented */ AML_DEBUGPRINT("Load("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(", "); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; case 0x21: /* StallOp */ AML_DEBUGPRINT("Stall("); num1 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(")"); AML_STALL(num1); break; case 0x22: /* SleepOp */ AML_DEBUGPRINT("Sleep("); num1 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_SLEEP(0, num1); AML_DEBUGPRINT(")"); break; case 0x23: /* AcquireOp *//* XXX Not yet */ AML_DEBUGPRINT("Acquire("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(", 0x%x)", aml_parse_worddata(env)); break; case 0x24: /* SignalOp *//* XXX Not yet */ AML_DEBUGPRINT("Signal("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; case 0x25: /* WaitOp *//* XXX Not yet impremented */ AML_DEBUGPRINT("Wait("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(", "); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; case 0x26: /* ResetOp *//* XXX Not yet impremented */ AML_DEBUGPRINT("Reset("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; case 0x27: /* ReleaseOp *//* XXX Not yet impremented */ AML_DEBUGPRINT("Release("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; #define NUMOP2(opname, operation) do { \ AML_DEBUGPRINT(opname); \ AML_DEBUGPRINT("("); \ num1 = aml_objtonum(env, aml_eval_name(env, \ aml_parse_termobj(env, indent))); \ AML_DEBUGPRINT(", "); \ anum.num.number = operation (num1); \ destname1 = aml_parse_termobj(env, indent); \ AML_DEBUGPRINT(")"); \ aml_store_to_name(env, &anum, destname1); \ env->tempobject.num = anum.num; \ env->tempname.property = &env->tempobject; \ aname = &env->tempname; \ } while(0) case 0x28: /* FromBCDOp */ NUMOP2("FromBCD", frombcd); break; case 0x29: /* ToBCDOp */ NUMOP2("ToBCD", tobcd); break; case 0x2a: /* UnloadOp *//* XXX Not yet impremented */ AML_DEBUGPRINT("Unload("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; case 0x30: env->tempobject.type = aml_t_num; env->tempobject.num.number = 0; env->tempobject.num.constant = 1; AML_DEBUGPRINT("Revision"); break; case 0x31: env->tempobject.type = aml_t_debug; aname = &env->tempname; AML_DEBUGPRINT("Debug"); break; case 0x32: /* FatalOp */ AML_DEBUGPRINT("Fatal("); AML_DEBUGPRINT("0x%x, ", aml_parse_bytedata(env)); AML_DEBUGPRINT("0x%x, ", aml_parse_dworddata(env)); aml_parse_termobj(env, indent); env->stat = aml_stat_panic; AML_DEBUGPRINT(")"); break; case 0x80: /* OpRegionOp */ aml_parse_defopregion(env, indent); break; case 0x81: /* FieldOp */ aml_parse_deffield(env, indent); break; case 0x82: /* DeviceOp */ aml_parse_defdevice(env, indent); break; case 0x83: /* ProcessorOp */ aml_parse_defprocessor(env, indent); break; case 0x84: /* PowerResOp */ aml_parse_defpowerres(env, indent); break; case 0x85: /* ThermalZoneOp */ aml_parse_defthermalzone(env, indent); break; case 0x86: /* IndexFieldOp */ aml_parse_defindexfield(env, indent); break; case 0x87: /* BankFieldOp */ aml_parse_defbankfield(env, indent); break; default: AML_SYSERRX(1, "strange opcode 0x5b, 0x%x\n", opcode); AML_SYSABORT(); } break; case 0x68 ... 0x6e: /* ArgN */ AML_DEBUGPRINT("Arg%d", opcode - 0x68); return (aml_local_stack_getArgX(NULL, opcode - 0x68)); break; case 0x60 ... 0x67: AML_DEBUGPRINT("Local%d", opcode - 0x60); return (aml_local_stack_getLocalX(opcode - 0x60)); break; case 0x70: /* StoreOp */ AML_DEBUGPRINT("Store("); aname = aml_create_local_object(); AML_COPY_OBJECT(tmpobj, env, aml_eval_name(env, aml_parse_termobj(env, indent)), NULL); aname->property = tmpobj; AML_DEBUGPRINT(", "); destname1 = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); /* XXX * temporary object may change during aml_store_to_name() * operation, so we make a copy of it on stack. */ if (destname1 == &env->tempname && destname1->property == &env->tempobject) { destname1 = aml_create_local_object(); AML_COPY_OBJECT(destname1->property, env, &env->tempobject, NULL); } aml_store_to_name(env, tmpobj, destname1); if (env->stat == aml_stat_panic) { AML_DEBUGPRINT("StoreOp failed"); return (NULL); } aname = aml_create_local_object(); AML_COPY_OBJECT(tmpobj, env, destname1->property, NULL); aname->property = tmpobj; if (tmpobj == NULL) { printf("???"); break; } break; case 0x71: /* RefOfOp */ AML_DEBUGPRINT("RefOf("); src = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); aname = aml_create_local_object(); AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL); objref = aname->property; if (src->property == NULL || src->property->type != aml_t_namestr) { objref->objref.nameref = src; } else { objref->objref.nameref = aml_create_local_object(); } objref->objref.ref = src->property; objref->objref.offset = -1; /* different from IndexOp */ break; #define NUMOP3_2(opname, oparation, ope2) do { \ AML_DEBUGPRINT(opname); \ AML_DEBUGPRINT("("); \ num1 = aml_objtonum(env, aml_eval_name(env, \ aml_parse_termobj(env, indent))); \ AML_DEBUGPRINT(", "); \ num2 = aml_objtonum(env, aml_eval_name(env, \ aml_parse_termobj(env, indent))); \ AML_DEBUGPRINT(", "); \ anum.num.number = ope2(num1 oparation num2); \ destname1 = aml_parse_termobj(env, indent); \ AML_DEBUGPRINT(")"); \ aml_store_to_name(env, &anum, destname1); \ env->tempobject.num = anum.num; \ env->tempname.property = &env->tempobject; \ aname = &env->tempname; \ } while(0) #define NUMOP3(opname, operation) NUMOP3_2(opname, operation, ) #define NUMOPN3(opname, operation) NUMOP3_2(opname, operation, ~) case 0x72: /* AddOp */ NUMOP3("Add", +); break; case 0x73: /* ConcatOp */ aname = aml_parse_concatop(env, indent); break; case 0x74: /* SubtractOp */ NUMOP3("Subtract", -); break; case 0x75: /* IncrementOp */ AML_DEBUGPRINT("Increment("); aname = aml_parse_termobj(env, indent); num1 = aml_objtonum(env, aml_eval_name(env, aname)); num1++; anum.num.number = num1; AML_DEBUGPRINT(")"); aml_store_to_name(env, &anum, aname); aname = &env->tempname; env->tempobject.num = anum.num; break; case 0x76: /* DecrementOp */ AML_DEBUGPRINT("Decrement("); aname = aml_parse_termobj(env, indent); num1 = aml_objtonum(env, aml_eval_name(env, aname)); num1--; anum.num.number = num1; AML_DEBUGPRINT(")"); aml_store_to_name(env, &anum, aname); aname = &env->tempname; env->tempobject.num = anum.num; break; case 0x77: /* MultiplyOp */ NUMOP3("Multiply", *); break; case 0x78: /* DivideOp */ AML_DEBUGPRINT("Divide("); num1 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(", "); num2 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(", "); anum.num.number = num1 % num2; destname1 = aml_parse_termobj(env, indent); aml_store_to_name(env, &anum, destname1); AML_DEBUGPRINT(", "); anum.num.number = num1 / num2; destname2 = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); aml_store_to_name(env, &anum, destname2); env->tempobject.num = anum.num; aname = &env->tempname; break; case 0x79: /* ShiftLeftOp */ NUMOP3("ShiftLeft", <<); break; case 0x7a: /* ShiftRightOp */ NUMOP3("ShiftRight", >>); break; case 0x7b: /* AndOp */ NUMOP3("And", &); break; case 0x7c: /* NAndOp */ NUMOPN3("NAnd", &); break; case 0x7d: /* OrOp */ NUMOP3("Or", |); break; case 0x7e: /* NOrOp */ NUMOPN3("NOr", |); break; case 0x7f: /* XOrOp */ NUMOP3("XOr", ^); break; case 0x80: /* NotOp */ NUMOP2("Not", ~); break; case 0x81: /* FindSetLeftBitOp */ NUMOP2("FindSetLeftBit", findsetleftbit); break; case 0x82: /* FindSetRightBitOp */ NUMOP2("FindSetRightBit", findsetrightbit); break; case 0x83: /* DerefOp */ AML_DEBUGPRINT("DerefOf("); objref = aml_eval_name(env, aml_parse_termobj(env, indent)); AML_DEBUGPRINT(")"); if (objref->objref.ref == NULL) { env->tempname.property = objref->objref.ref; aname = &env->tempname; break; } switch (objref->objref.ref->type) { case aml_t_package: case aml_t_buffer: if (objref->objref.offset < 0) { env->tempname.property = objref->objref.ref; } else { objref->objref.deref = 1; env->tempname.property = objref; } break; default: env->tempname.property = objref->objref.ref; break; } aname = &env->tempname; break; case 0x86: /* NotifyOp *//* XXX Not yet impremented */ AML_DEBUGPRINT("Notify("); aml_parse_termobj(env, indent); AML_DEBUGPRINT(", "); aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; case 0x87: /* SizeOfOp */ AML_DEBUGPRINT("SizeOf("); aname = aml_parse_termobj(env, indent); tmpobj = aml_eval_name(env, aname); AML_DEBUGPRINT(")"); num1 = 0; switch (tmpobj->type) { case aml_t_buffer: num1 = tmpobj->buffer.size; break; case aml_t_string: num1 = strlen(tmpobj->str.string); break; case aml_t_package: num1 = tmpobj->package.elements; break; default: AML_DEBUGPRINT("Args of SizeOf should be " "buffer/string/package only\n"); break; } anum.num.number = num1; env->tempobject.num = anum.num; aname = &env->tempname; break; case 0x88: /* IndexOp */ AML_DEBUGPRINT("Index("); srcobj = aml_eval_name(env, aml_parse_termobj(env, indent)); AML_DEBUGPRINT(", "); num1 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(", "); destname1 = aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); aname = aml_create_local_object(); switch (srcobj->type) { case aml_t_package: case aml_t_buffer: AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL); aname->property = objref; objref->objref.ref = srcobj; objref->objref.offset = num1; objref->objref.deref = 0; break; default: AML_DEBUGPRINT("Arg0 of Index should be either " "buffer or package\n"); return (aname); } aml_store_to_name(env, objref, destname1); break; case 0x89: /* MatchOp *//* XXX Not yet Impremented */ AML_DEBUGPRINT("Match("); AML_COPY_OBJECT(obj, env, aml_eval_name(env, aml_parse_termobj(env, indent)), NULL); if (obj->type != aml_t_package) { env->stat = aml_stat_panic; return (NULL); } anum.num.number = 0xffffffff; match1 = *env->dp; AML_DEBUGPRINT(", %d", *env->dp); env->dp++; num1 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); match2 = *env->dp; AML_DEBUGPRINT(", %d", *env->dp); env->dp++; num2 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); AML_DEBUGPRINT(", "); start = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); #define MATCHOP(opnum, arg1, arg2) ((opnum == 0) ? (1) : \ (opnum == 1) ? ((arg1) == (arg2)) : \ (opnum == 2) ? ((arg1) <= (arg2)) : \ (opnum == 3) ? ((arg1) < (arg2)) : \ (opnum == 4) ? ((arg1) >= (arg2)) : \ (opnum == 5) ? ((arg1) > (arg2)) : 0 ) for (i = start; i < obj->package.elements; i++) { pkgval = aml_objtonum(env, obj->package.objects[i]); if (MATCHOP(match1, pkgval, num1) && MATCHOP(match2, pkgval, num2)) { anum.num.number = i; break; } } AML_DEBUGPRINT(")"); aml_free_object(&obj); aname = &env->tempname; env->tempname.property = &env->tempobject; env->tempobject.num = anum.num; break; #undef MATCHOP case 0x8a ... 0x8d: /* CreateDWordFieldOp */ widthindex = *(env->dp - 1) - 0x8a; AML_DEBUGPRINT("%s(", opname[widthindex]); srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent)); if (srcbuf == &env->tempobject) { AML_DEBUGPRINT("NOT NAMEDBUF\n"); env->stat = aml_stat_panic; return (NULL); } AML_DEBUGPRINT(", "); index = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); if (widthindex != 3) { index *= 8; } AML_DEBUGPRINT(", "); newname = aml_parse_namestring(env); aml_print_namestring(newname); aml_createfield_generic(env, srcbuf, index, widthtbl[widthindex], newname); AML_DEBUGPRINT(")"); break; case 0x8e: /* ObjectTypeOp */ AML_DEBUGPRINT("ObjectType("); aname = aml_parse_termobj(env, indent); if (aname == NULL) { env->tempobject.type = aml_t_num; env->tempobject.num.number = aml_t_null; } else { env->tempobject.type = aml_t_num; env->tempobject.num.number = aname->property->type; } aname = &env->tempname; AML_DEBUGPRINT(")"); break; #define CMPOP(opname,operation) do { \ AML_DEBUGPRINT(opname); \ AML_DEBUGPRINT("("); \ num1 = aml_objtonum(env, aml_eval_name(env, \ aml_parse_termobj(env, indent))); \ AML_DEBUGPRINT(", "); \ num2 = aml_objtonum(env, aml_eval_name(env, \ aml_parse_termobj(env, indent))); \ aname = &env->tempname; \ env->tempobject.type = aml_t_num; \ env->tempobject.num.number = (num1 operation num2) ? 0xffffffff : 0; \ aname->property = &env->tempobject; \ AML_DEBUGPRINT(")"); \ } while(0) case 0x90: CMPOP("LAnd", &&); break; case 0x91: CMPOP("LOr", ||); break; case 0x92: AML_DEBUGPRINT("LNot("); num1 = aml_objtonum(env, aml_eval_name(env, aml_parse_termobj(env, indent))); aname = &env->tempname; env->tempobject.type = aml_t_num; env->tempobject.num.number = (!num1) ? 0xffffffff : 0; aname->property = &env->tempobject; AML_DEBUGPRINT(")"); break; case 0x93: CMPOP("LEqual", ==); break; case 0x94: CMPOP("LGreater", >); break; case 0x95: CMPOP("LLess", <); break; case 0xa0: /* IfOp */ aname = aml_parse_defif(env, indent); break; #if 0 case 0xa1: /* ElseOp should not be treated in Main parser * But If Op */ aml_parse_defelse(env, indent); break; #endif case 0xa2: /* WhileOp */ aname = aml_parse_defwhile(env, indent); break; case 0xa3: /* NoopOp */ AML_DEBUGPRINT("Noop"); break; case 0xa5: /* BreakOp */ AML_DEBUGPRINT("Break"); env->stat = aml_stat_break; break; case 0xa4: /* ReturnOp */ AML_DEBUGPRINT("Return("); AML_COPY_OBJECT(env->tempname.property, env, aml_eval_name(env, aml_parse_termobj(env, indent)), NULL); aname = &env->tempname; env->stat = aml_stat_return; AML_DEBUGPRINT(")"); break; case 0xcc: /* BreakPointOp */ /* XXX Not Yet Impremented (Not need?) */ AML_DEBUGPRINT("BreakPoint"); break; default: AML_SYSERRX(1, "strange opcode 0x%x\n", opcode); AML_SYSABORT(); } return (aname); } Index: head/usr.sbin/acpi/amldb/aml/aml_region.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_region.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_region.c (revision 68518) @@ -1,349 +1,349 @@ /*- * Copyright (c) 2000 Mitsuru IWASAKI * Copyright (c) 2000 Munehiro Matsuda * 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 #include #include #include #include #include #include #include -#include -#include -#include +#include +#include +#include #ifndef ACPI_NO_OSDFUNC_INLINE #include #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); } Index: head/usr.sbin/acpi/amldb/aml/aml_store.c =================================================================== --- head/usr.sbin/acpi/amldb/aml/aml_store.c (revision 68517) +++ head/usr.sbin/acpi/amldb/aml/aml_store.c (revision 68518) @@ -1,349 +1,349 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifndef _KERNEL #include #include #include #include "debug.h" #else /* _KERNEL */ #include #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; } } Index: head/usr.sbin/acpi/amldb/amldb.c =================================================================== --- head/usr.sbin/acpi/amldb/amldb.c (revision 68517) +++ head/usr.sbin/acpi/amldb/amldb.c (revision 68518) @@ -1,188 +1,188 @@ /*- * Copyright (c) 1999 Mitsuru IWASAKI * 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 #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include #include #include #include #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)); /* * Microsoft asl.exe generates 0x23 byte additional info. * at the begining of the file, so just ignore it. */ if (strncmp(code, "DSDT", 4) == 0) { env.dp = code + 0x23; } 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); } Index: head/usr.sbin/acpi/amldb/debug.c =================================================================== --- head/usr.sbin/acpi/amldb/debug.c (revision 68517) +++ head/usr.sbin/acpi/amldb/debug.c (revision 68518) @@ -1,310 +1,310 @@ /*- * Copyright (c) 1999 Takanori Watanabe * Copyright (c) 1999, 2000 Mitsuru IWASAKI * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include #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; } } } Index: head/usr.sbin/acpi/amldb/region.c =================================================================== --- head/usr.sbin/acpi/amldb/region.c (revision 68517) +++ head/usr.sbin/acpi/amldb/region.c (revision 68518) @@ -1,510 +1,510 @@ /*- * Copyright (c) 1999 Mitsuru IWASAKI * 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 #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include #include #include #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(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(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); }