mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
Add orthogonal part of ACPI support code.
This does not come effect until non-orthogonal part is commited. Approved by: jkh Obtained from: ACPI for FreeBSD CVS repository.
This commit is contained in:
parent
01819900ae
commit
681cfb39e1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65047
1339
sys/dev/acpi/acpi.c
Normal file
1339
sys/dev/acpi/acpi.c
Normal file
File diff suppressed because it is too large
Load Diff
92
sys/dev/acpi/aml/aml_amlmem.c
Normal file
92
sys/dev/acpi/aml/aml_amlmem.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_amlmem.c,v 1.15 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* AML Namespace Memory Management
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_memman.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_namestr, _aml_namestr_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_num, _aml_num_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_string, _aml_string_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_buffer, _aml_buffer_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_package, _aml_package_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_field, _aml_field_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_method, _aml_method_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex, _aml_mutex_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_opregion, _aml_opregion_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_powerres, _aml_powerres_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_processor, _aml_processor_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_bufferfield, _aml_bufferfield_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_event, _aml_event_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(enum aml_objtype, _aml_objtype_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_name, _aml_name_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_name_group, _aml_name_group_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_objref, _aml_objref_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_regfield, _aml_regfield_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_environ, _aml_environ_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_local_stack, _aml_local_stack_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex_queue, _aml_mutex_queue_storage);
|
||||
|
||||
struct memman_blockman aml_blockman[] = {
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_namestr), _aml_namestr_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_num), _aml_num_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_string), _aml_string_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_buffer), _aml_buffer_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_package), _aml_package_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_field), _aml_field_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_method), _aml_method_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex), _aml_mutex_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_opregion), _aml_opregion_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_powerres), _aml_powerres_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_processor), _aml_processor_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_bufferfield), _aml_bufferfield_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_event), _aml_event_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(enum aml_objtype), _aml_objtype_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name), _aml_name_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name_group), _aml_name_group_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_objref), _aml_objref_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_regfield), _aml_regfield_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_environ), _aml_environ_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_local_stack), _aml_local_stack_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex_queue), _aml_mutex_queue_storage),
|
||||
};
|
||||
|
||||
struct memman_histogram aml_histogram[MEMMAN_HISTOGRAM_SIZE];
|
||||
|
||||
static struct memman _aml_memman = MEMMAN_MEMMANAGER_DESC(aml_blockman, 21,
|
||||
aml_histogram, 1);
|
||||
|
||||
struct memman *aml_memman = &_aml_memman;
|
||||
|
65
sys/dev/acpi/aml/aml_amlmem.h
Normal file
65
sys/dev/acpi/aml/aml_amlmem.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_amlmem.h,v 1.12 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_AMLMEM_H_
|
||||
#define _AML_AMLMEM_H_
|
||||
|
||||
/*
|
||||
* AML Namespace Memory Management
|
||||
*/
|
||||
|
||||
#include <dev/acpi/aml/aml_memman.h>
|
||||
|
||||
enum {
|
||||
memid_aml_namestr = 0,
|
||||
memid_aml_num,
|
||||
memid_aml_string,
|
||||
memid_aml_buffer,
|
||||
memid_aml_package,
|
||||
memid_aml_field,
|
||||
memid_aml_method,
|
||||
memid_aml_mutex,
|
||||
memid_aml_opregion,
|
||||
memid_aml_powerres,
|
||||
memid_aml_processor,
|
||||
memid_aml_bufferfield,
|
||||
memid_aml_event,
|
||||
memid_aml_objtype,
|
||||
memid_aml_name,
|
||||
memid_aml_name_group,
|
||||
memid_aml_objref,
|
||||
memid_aml_regfield,
|
||||
memid_aml_environ,
|
||||
memid_aml_local_stack,
|
||||
memid_aml_mutex_queue,
|
||||
};
|
||||
|
||||
extern struct memman *aml_memman;
|
||||
|
||||
#endif /* !_AML_AMLMEM_H_ */
|
406
sys/dev/acpi/aml/aml_common.c
Normal file
406
sys/dev/acpi/aml/aml_common.c
Normal file
@ -0,0 +1,406 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_common.c,v 1.9 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#else /* _KERNEL */
|
||||
#include "opt_acpi.h"
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_evalobj.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_parse.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
/* for debugging */
|
||||
#ifdef AML_DEBUG
|
||||
int aml_debug = 1;
|
||||
#else /* !AML_DEBUG */
|
||||
int aml_debug = 0;
|
||||
#endif /* AML_DEBUG */
|
||||
#ifdef _KERNEL
|
||||
SYSCTL_INT(_debug, OID_AUTO, aml_debug, CTLFLAG_RW, &aml_debug, 1, "");
|
||||
#endif /* _KERNEL */
|
||||
|
||||
static void aml_print_nameseg(u_int8_t *dp);
|
||||
|
||||
static void
|
||||
aml_print_nameseg(u_int8_t *dp)
|
||||
{
|
||||
|
||||
if (dp[3] != '_') {
|
||||
AML_DEBUGPRINT("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]);
|
||||
} else if (dp[2] != '_') {
|
||||
AML_DEBUGPRINT("%c%c%c_", dp[0], dp[1], dp[2]);
|
||||
} else if (dp[1] != '_') {
|
||||
AML_DEBUGPRINT("%c%c__", dp[0], dp[1]);
|
||||
} else if (dp[0] != '_') {
|
||||
AML_DEBUGPRINT("%c___", dp[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aml_print_namestring(u_int8_t *dp)
|
||||
{
|
||||
int segcount;
|
||||
int i;
|
||||
|
||||
if (dp[0] == '\\') {
|
||||
AML_DEBUGPRINT("%c", dp[0]);
|
||||
dp++;
|
||||
} else if (dp[0] == '^') {
|
||||
while (dp[0] == '^') {
|
||||
AML_DEBUGPRINT("%c", dp[0]);
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
if (dp[0] == 0x00) { /* NullName */
|
||||
/* AML_DEBUGPRINT("<null>"); */
|
||||
dp++;
|
||||
} else if (dp[0] == 0x2e) { /* DualNamePrefix */
|
||||
aml_print_nameseg(dp + 1);
|
||||
AML_DEBUGPRINT("%c", '.');
|
||||
aml_print_nameseg(dp + 5);
|
||||
} else if (dp[0] == 0x2f) { /* MultiNamePrefix */
|
||||
segcount = dp[1];
|
||||
for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
|
||||
if (i > 0) {
|
||||
AML_DEBUGPRINT("%c", '.');
|
||||
}
|
||||
aml_print_nameseg(dp);
|
||||
}
|
||||
} else /* NameSeg */
|
||||
aml_print_nameseg(dp);
|
||||
}
|
||||
|
||||
int
|
||||
aml_print_curname(struct aml_name *name)
|
||||
{
|
||||
struct aml_name *root;
|
||||
|
||||
root = aml_get_rootname();
|
||||
if (name == root) {
|
||||
AML_DEBUGPRINT("\\");
|
||||
return (0);
|
||||
} else {
|
||||
aml_print_curname(name->parent);
|
||||
}
|
||||
aml_print_nameseg(name->name);
|
||||
AML_DEBUGPRINT(".");
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
aml_print_indent(int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
AML_DEBUGPRINT(" ");
|
||||
}
|
||||
|
||||
void
|
||||
aml_showobject(union aml_object * obj)
|
||||
{
|
||||
int debug;
|
||||
int i;
|
||||
|
||||
if (obj == NULL) {
|
||||
printf("NO object\n");
|
||||
return;
|
||||
}
|
||||
debug = aml_debug;
|
||||
aml_debug = 1;
|
||||
switch (obj->type) {
|
||||
case aml_t_num:
|
||||
printf("Num:0x%x\n", obj->num.number);
|
||||
break;
|
||||
case aml_t_processor:
|
||||
printf("Processor:No %d,Port 0x%x length 0x%x\n",
|
||||
obj->proc.id, obj->proc.addr, obj->proc.len);
|
||||
break;
|
||||
case aml_t_mutex:
|
||||
printf("Mutex:Level %d\n", obj->mutex.level);
|
||||
break;
|
||||
case aml_t_powerres:
|
||||
printf("PowerResource:Level %d Order %d\n",
|
||||
obj->pres.level, obj->pres.order);
|
||||
break;
|
||||
case aml_t_opregion:
|
||||
printf("OprationRegion:Busspace%d, Offset 0x%x Length 0x%x\n",
|
||||
obj->opregion.space, obj->opregion.offset,
|
||||
obj->opregion.length);
|
||||
break;
|
||||
case aml_t_field:
|
||||
printf("Fieldelement:flag 0x%x offset 0x%x len 0x%x {",
|
||||
obj->field.flags, obj->field.bitoffset,
|
||||
obj->field.bitlen);
|
||||
switch (obj->field.f.ftype) {
|
||||
case f_t_field:
|
||||
aml_print_namestring(obj->field.f.fld.regname);
|
||||
break;
|
||||
case f_t_index:
|
||||
aml_print_namestring(obj->field.f.ifld.indexname);
|
||||
printf(" ");
|
||||
aml_print_namestring(obj->field.f.ifld.dataname);
|
||||
break;
|
||||
case f_t_bank:
|
||||
aml_print_namestring(obj->field.f.bfld.regname);
|
||||
printf(" ");
|
||||
aml_print_namestring(obj->field.f.bfld.bankname);
|
||||
printf("0x%x", obj->field.f.bfld.bankvalue);
|
||||
break;
|
||||
}
|
||||
printf("}\n");
|
||||
break;
|
||||
case aml_t_method:
|
||||
printf("Method: Arg %d From %p To %p\n", obj->meth.argnum,
|
||||
obj->meth.from, obj->meth.to);
|
||||
break;
|
||||
case aml_t_buffer:
|
||||
printf("Buffer: size:0x%x Data %p\n", obj->buffer.size,
|
||||
obj->buffer.data);
|
||||
break;
|
||||
case aml_t_device:
|
||||
printf("Device\n");
|
||||
break;
|
||||
case aml_t_bufferfield:
|
||||
printf("Bufferfield:offset 0x%x len 0x%x Origin %p\n",
|
||||
obj->bfld.bitoffset, obj->bfld.bitlen, obj->bfld.origin);
|
||||
break;
|
||||
case aml_t_string:
|
||||
printf("String:%s\n", obj->str.string);
|
||||
break;
|
||||
case aml_t_package:
|
||||
printf("Package:elements %d \n", obj->package.elements);
|
||||
for (i = 0; i < obj->package.elements; i++) {
|
||||
if (obj->package.objects[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
if (obj->package.objects[i]->type < 0) {
|
||||
continue;
|
||||
}
|
||||
printf(" ");
|
||||
aml_showobject(obj->package.objects[i]);
|
||||
}
|
||||
break;
|
||||
case aml_t_therm:
|
||||
printf("Thermalzone\n");
|
||||
break;
|
||||
case aml_t_event:
|
||||
printf("Event\n");
|
||||
break;
|
||||
case aml_t_ddbhandle:
|
||||
printf("DDBHANDLE\n");
|
||||
break;
|
||||
case aml_t_objref:
|
||||
if (obj->objref.alias == 1) {
|
||||
printf("Alias");
|
||||
} else {
|
||||
printf("Object reference");
|
||||
if (obj->objref.offset >= 0) {
|
||||
printf(" (offset 0x%x)", obj->objref.offset);
|
||||
}
|
||||
}
|
||||
printf(" of ");
|
||||
aml_showobject(obj->objref.ref);
|
||||
break;
|
||||
default:
|
||||
printf("UNK ID=%d\n", obj->type);
|
||||
}
|
||||
|
||||
aml_debug = debug;
|
||||
}
|
||||
|
||||
void
|
||||
aml_showtree(struct aml_name * aname, int lev)
|
||||
{
|
||||
int i;
|
||||
struct aml_name *ptr;
|
||||
char name[5];
|
||||
|
||||
for (i = 0; i < lev; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
strncpy(name, aname->name, 4);
|
||||
name[4] = 0;
|
||||
printf("%s ", name);
|
||||
if (aname->property != NULL) {
|
||||
aml_showobject(aname->property);
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
for (ptr = aname->child; ptr; ptr = ptr->brother)
|
||||
aml_showtree(ptr, lev + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 value = *valuep, readval;
|
||||
int i;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
75
sys/dev/acpi/aml/aml_common.h
Normal file
75
sys/dev/acpi/aml/aml_common.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_common.h,v 1.4 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_COMMON_H_
|
||||
#define _AML_COMMON_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define AML_SYSABORT() do { \
|
||||
printf("aml: fatal errer at %s:%d\n", __FILE__, __LINE__); \
|
||||
panic("panic in AML interpreter!"); \
|
||||
} while(0)
|
||||
#define AML_SYSASSERT(x) do { \
|
||||
if (!(x)) { \
|
||||
AML_SYSABORT(); \
|
||||
} \
|
||||
} while(0)
|
||||
#define AML_SYSERRX(eval, fmt, args...) do { \
|
||||
printf(fmt, args); \
|
||||
} while(0)
|
||||
#define AML_DEBUGGER(x, y) /* no debugger in kernel */
|
||||
#else /* !_KERNEL */
|
||||
#define AML_SYSASSERT(x) assert(x)
|
||||
#define AML_SYSABORT() abort()
|
||||
#define AML_SYSERRX(eval, fmt, args...) errx(eval, fmt, args)
|
||||
#define AML_DEBUGGER(x, y) aml_dbgr(x, y)
|
||||
#endif /* _KERNEL */
|
||||
|
||||
union aml_object;
|
||||
struct aml_name;
|
||||
|
||||
extern int aml_debug;
|
||||
|
||||
#define AML_DEBUGPRINT(args...) do { \
|
||||
if (aml_debug) { \
|
||||
printf(args); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
void aml_showobject(union aml_object *);
|
||||
void aml_showtree(struct aml_name *, int);
|
||||
int aml_print_curname(struct aml_name *);
|
||||
void aml_print_namestring(u_int8_t *);
|
||||
void aml_print_indent(int);
|
||||
|
||||
u_int32_t aml_bufferfield_read(u_int8_t *, u_int32_t, u_int32_t);
|
||||
int aml_bufferfield_write(u_int32_t, u_int8_t *,
|
||||
u_int32_t, u_int32_t);
|
||||
|
||||
#endif /* !_AML_COMMON_H_ */
|
46
sys/dev/acpi/aml/aml_env.h
Normal file
46
sys/dev/acpi/aml/aml_env.h
Normal file
@ -0,0 +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 <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
|
||||
struct aml_environ {
|
||||
u_int8_t *dp;
|
||||
u_int8_t *end;
|
||||
enum aml_status stat;
|
||||
struct aml_name *curname;
|
||||
struct aml_name tempname;
|
||||
union aml_object tempobject;
|
||||
};
|
||||
|
||||
#endif /* !_AML_ENV_H_ */
|
421
sys/dev/acpi/aml/aml_evalobj.c
Normal file
421
sys/dev/acpi/aml/aml_evalobj.c
Normal file
@ -0,0 +1,421 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_evalobj.c,v 1.27 2000/08/16 18:14:53 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_evalobj.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_parse.h>
|
||||
#include <dev/acpi/aml/aml_region.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#else /* _KERNEL */
|
||||
#include <sys/bus.h>
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static union aml_object *aml_eval_fieldobject(struct aml_environ *env,
|
||||
struct aml_name *name);
|
||||
|
||||
static union aml_object *
|
||||
aml_eval_fieldobject(struct aml_environ *env, struct aml_name *name)
|
||||
{
|
||||
struct aml_name *oname,*wname;
|
||||
struct aml_field *field;
|
||||
struct aml_opregion *or;
|
||||
union aml_object tobj;
|
||||
|
||||
/* 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);
|
||||
aml_eval_name(env, wname);
|
||||
}
|
||||
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_by_name(char *method, int argc, union aml_object *argv)
|
||||
{
|
||||
int i;
|
||||
struct aml_name *name;
|
||||
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));
|
||||
name = aml_find_from_namespace(aml_get_rootname(), method);
|
||||
|
||||
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);
|
||||
}
|
46
sys/dev/acpi/aml/aml_evalobj.h
Normal file
46
sys/dev/acpi/aml/aml_evalobj.h
Normal file
@ -0,0 +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_evalobj.h,v 1.11 2000/08/16 18:14:53 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_EVALOBJ_H_
|
||||
#define _AML_EVALOBJ_H_
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
union aml_object *aml_eval_objref(struct aml_environ *,
|
||||
union aml_object *);
|
||||
union aml_object *aml_eval_name(struct aml_environ *,
|
||||
struct aml_name *);
|
||||
int aml_eval_name_simple(struct aml_name *, va_list);
|
||||
int aml_objtonum(struct aml_environ *,
|
||||
union aml_object *);
|
||||
struct aml_name *aml_execute_method(struct aml_environ *);
|
||||
union aml_object *aml_invoke_method_by_name(char *,
|
||||
int, union aml_object *);
|
||||
|
||||
#endif /* !_AML_EVALOBJ_H_ */
|
476
sys/dev/acpi/aml/aml_memman.c
Normal file
476
sys/dev/acpi/aml/aml_memman.c
Normal file
@ -0,0 +1,476 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_memman.c,v 1.10 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic Memory Management
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_memman.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#else /* _KERNEL */
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
MALLOC_DEFINE(M_MEMMAN, "memman", "Generic and Simple Memory Management");
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
unsigned int memid_unkown = 255;
|
||||
|
||||
static int manage_block(struct memman *memman, unsigned int id,
|
||||
void *block, unsigned static_mem,
|
||||
unsigned entries);
|
||||
static int blockman_init(struct memman *memman, unsigned int id);
|
||||
static void memman_flexsize_add_histogram(struct memman *memman,
|
||||
size_t size,
|
||||
int tolerance);
|
||||
static int memman_comp_histogram_size(const void *a,
|
||||
const void *b);
|
||||
static void memman_sort_histogram_by_size(struct memman *memman);
|
||||
static unsigned int memman_guess_memid(struct memman *memman, void *chunk);
|
||||
static void memman_statistics_fixedsize(struct memman *memman);
|
||||
static void memman_statistics_flexsize(struct memman *memman);
|
||||
|
||||
static int
|
||||
manage_block(struct memman *memman, unsigned int id, void *block,
|
||||
unsigned static_mem, unsigned entries)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t alloc_size;
|
||||
void *tmp, *realblock;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_block *memblock;
|
||||
struct memman_node *memnodes;
|
||||
|
||||
bmp = &memman->blockman[id];
|
||||
alloc_size = MEMMAN_BLOCKNODE_SIZE(entries);
|
||||
|
||||
if (static_mem) {
|
||||
tmp = (void *)block;
|
||||
realblock = (char *)block + alloc_size;
|
||||
} else {
|
||||
tmp = MEMMAN_SYSMALLOC(alloc_size);
|
||||
if (!tmp) {
|
||||
return (-1);
|
||||
}
|
||||
realblock = block;
|
||||
|
||||
memman->allocated_mem += alloc_size;
|
||||
memman->salloc_called++;
|
||||
}
|
||||
|
||||
memblock = (struct memman_block *)tmp;
|
||||
memnodes = (struct memman_node *)((char *)tmp + sizeof(struct memman_block));
|
||||
|
||||
memblock->block = realblock;
|
||||
memblock->static_mem = static_mem;
|
||||
memblock->allocated = entries;
|
||||
memblock->available = entries;
|
||||
if (!static_mem) {
|
||||
alloc_size += roundup(bmp->size * entries, ROUNDUP_UNIT);
|
||||
}
|
||||
memblock->allocated_mem = alloc_size;
|
||||
LIST_INSERT_HEAD(&bmp->block_list, memblock, links);
|
||||
|
||||
for (i = 0; i < entries; ++i) {
|
||||
memnodes[i].node = ((char *)realblock + (i * (bmp->size)));
|
||||
memnodes[i].memblock = memblock;
|
||||
LIST_INSERT_HEAD(&bmp->free_node_list, &memnodes[i], links);
|
||||
}
|
||||
bmp->available = entries;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
blockman_init(struct memman *memman, unsigned int id)
|
||||
{
|
||||
int status;
|
||||
struct memman_blockman *bmp;
|
||||
|
||||
bmp = &memman->blockman[id];
|
||||
bmp->initialized = 1;
|
||||
LIST_INIT(&bmp->block_list);
|
||||
LIST_INIT(&bmp->free_node_list);
|
||||
LIST_INIT(&bmp->occupied_node_list);
|
||||
status = manage_block(memman, id, bmp->initial_block,
|
||||
1, MEMMAN_INITIAL_SIZE);
|
||||
return (status);
|
||||
}
|
||||
|
||||
void *
|
||||
memman_alloc(struct memman *memman, unsigned int id)
|
||||
{
|
||||
size_t alloc_size;
|
||||
void *chunk, *block;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_node *memnode;
|
||||
|
||||
if (memman->max_memid <= id) {
|
||||
printf("memman_alloc: invalid memory type id\n");
|
||||
return (NULL);
|
||||
}
|
||||
bmp = &memman->blockman[id];
|
||||
if (!bmp->initialized) {
|
||||
if (blockman_init(memman, id)) {
|
||||
goto malloc_fail;
|
||||
}
|
||||
}
|
||||
memman->alloc_called++;
|
||||
|
||||
if (bmp->available == 0) {
|
||||
alloc_size = roundup(bmp->size * MEMMAN_INCR_SIZE,
|
||||
ROUNDUP_UNIT);
|
||||
block = MEMMAN_SYSMALLOC(alloc_size);
|
||||
if (!block) {
|
||||
goto malloc_fail;
|
||||
}
|
||||
memman->required_mem += bmp->size * MEMMAN_INCR_SIZE;
|
||||
memman->allocated_mem += alloc_size;
|
||||
memman->salloc_called++;
|
||||
|
||||
if (manage_block(memman, id, block, 0, MEMMAN_INCR_SIZE)) {
|
||||
goto malloc_fail;
|
||||
}
|
||||
}
|
||||
memnode = LIST_FIRST(&bmp->free_node_list);
|
||||
LIST_REMOVE(memnode, links);
|
||||
chunk = memnode->node;
|
||||
LIST_INSERT_HEAD(&bmp->occupied_node_list, memnode, links);
|
||||
memnode->memblock->available--;
|
||||
bmp->available--;
|
||||
|
||||
return (chunk);
|
||||
|
||||
malloc_fail:
|
||||
printf("memman_alloc: could not allocate memory\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
memman_flexsize_add_histogram(struct memman *memman, size_t size,
|
||||
int tolerance)
|
||||
{
|
||||
int i;
|
||||
int gap;
|
||||
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
|
||||
gap = memman->flex_mem_histogram[i].mem_size - size;
|
||||
if (gap >= (tolerance * -1) && gap <= tolerance) {
|
||||
memman->flex_mem_histogram[i].count++;
|
||||
if (memman->flex_mem_histogram[i].mem_size < size) {
|
||||
memman->flex_mem_histogram[i].mem_size = size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (memman->flex_mem_histogram_ptr == MEMMAN_HISTOGRAM_SIZE) {
|
||||
memman_flexsize_add_histogram(memman, size, tolerance + 1);
|
||||
return;
|
||||
}
|
||||
i = memman->flex_mem_histogram_ptr;
|
||||
memman->flex_mem_histogram[i].mem_size = size;
|
||||
memman->flex_mem_histogram[i].count = 1;
|
||||
memman->flex_mem_histogram_ptr++;
|
||||
}
|
||||
|
||||
static int
|
||||
memman_comp_histogram_size(const void *a, const void *b)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = ((const struct memman_histogram *)a)->mem_size -
|
||||
((const struct memman_histogram *)b)->mem_size;
|
||||
return (delta);
|
||||
}
|
||||
|
||||
static void
|
||||
memman_sort_histogram_by_size(struct memman *memman)
|
||||
{
|
||||
qsort(memman->flex_mem_histogram, memman->flex_mem_histogram_ptr,
|
||||
sizeof(struct memman_histogram), memman_comp_histogram_size);
|
||||
}
|
||||
|
||||
void *
|
||||
memman_alloc_flexsize(struct memman *memman, size_t size)
|
||||
{
|
||||
void *mem;
|
||||
struct memman_flexmem_info *info;
|
||||
|
||||
if (size == 0) {
|
||||
return (NULL);
|
||||
}
|
||||
if ((mem = MEMMAN_SYSMALLOC(size)) != NULL) { /* XXX */
|
||||
|
||||
info = MEMMAN_SYSMALLOC(sizeof(struct memman_flexmem_info));
|
||||
if (info) {
|
||||
if (!memman->flex_mem_initialized) {
|
||||
LIST_INIT(&memman->flexmem_info_list);
|
||||
bzero(memman->flex_mem_histogram,
|
||||
sizeof(struct memman_histogram));
|
||||
memman->flex_mem_initialized = 1;
|
||||
}
|
||||
info->addr = mem;
|
||||
info->mem_size = size;
|
||||
LIST_INSERT_HEAD(&memman->flexmem_info_list, info, links);
|
||||
}
|
||||
memman->flex_alloc_called++;
|
||||
memman->flex_salloc_called++;
|
||||
memman->flex_required_mem += size;
|
||||
memman->flex_allocated_mem += size;
|
||||
if (memman->flex_mem_size_min == 0 ||
|
||||
memman->flex_mem_size_min > size) {
|
||||
memman->flex_mem_size_min = size;
|
||||
}
|
||||
if (memman->flex_mem_size_max < size) {
|
||||
memman->flex_mem_size_max = size;
|
||||
}
|
||||
if (memman->flex_peak_mem_usage <
|
||||
(memman->flex_allocated_mem - memman->flex_reclaimed_mem)) {
|
||||
memman->flex_peak_mem_usage =
|
||||
(memman->flex_allocated_mem - memman->flex_reclaimed_mem);
|
||||
}
|
||||
memman_flexsize_add_histogram(memman, size,
|
||||
memman->flex_mem_histogram_initial_tolerance);
|
||||
}
|
||||
return (mem);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
memman_guess_memid(struct memman *memman, void *chunk)
|
||||
{
|
||||
unsigned int id;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_node *memnode;
|
||||
|
||||
for (id = 0; id < memman->max_memid; id++) {
|
||||
bmp = &memman->blockman[id];
|
||||
if (!bmp->initialized) {
|
||||
if (blockman_init(memman, id)) {
|
||||
printf("memman_free: could not initialized\n");
|
||||
}
|
||||
}
|
||||
LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
|
||||
if (memnode->node == chunk) {
|
||||
return (id); /* got it! */
|
||||
}
|
||||
}
|
||||
}
|
||||
return (memid_unkown); /* gave up */
|
||||
}
|
||||
|
||||
void
|
||||
memman_free(struct memman *memman, unsigned int memid, void *chunk)
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned found;
|
||||
void *block;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_block *memblock;
|
||||
struct memman_node *memnode;
|
||||
|
||||
id = memid;
|
||||
if (memid == memid_unkown) {
|
||||
id = memman_guess_memid(memman, chunk);
|
||||
}
|
||||
if (memman->max_memid <= id) {
|
||||
printf("memman_free: invalid memory type id\n");
|
||||
MEMMAN_SYSABORT();
|
||||
return;
|
||||
}
|
||||
bmp = &memman->blockman[id];
|
||||
if (!bmp->initialized) {
|
||||
if (blockman_init(memman, id)) {
|
||||
printf("memman_free: could not initialized\n");
|
||||
}
|
||||
}
|
||||
found = 0;
|
||||
LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
|
||||
if (memnode->node == chunk) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
printf("memman_free: invalid address\n");
|
||||
return;
|
||||
}
|
||||
memman->free_called++;
|
||||
|
||||
LIST_REMOVE(memnode, links);
|
||||
memblock = memnode->memblock;
|
||||
memblock->available++;
|
||||
LIST_INSERT_HEAD(&bmp->free_node_list, memnode, links);
|
||||
bmp->available++;
|
||||
|
||||
if (!memblock->static_mem &&
|
||||
memblock->available == memblock->allocated) {
|
||||
LIST_FOREACH(memnode, &bmp->free_node_list, links) {
|
||||
if (memnode->memblock != memblock) {
|
||||
continue;
|
||||
}
|
||||
LIST_REMOVE(memnode, links);
|
||||
bmp->available--;
|
||||
}
|
||||
block = memblock->block;
|
||||
MEMMAN_SYSFREE(block);
|
||||
memman->sfree_called++;
|
||||
|
||||
LIST_REMOVE(memblock, links);
|
||||
memman->sfree_called++;
|
||||
memman->reclaimed_mem += memblock->allocated_mem;
|
||||
MEMMAN_SYSFREE(memblock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
memman_free_flexsize(struct memman *memman, void *chunk)
|
||||
{
|
||||
struct memman_flexmem_info *info;
|
||||
|
||||
LIST_FOREACH(info, &memman->flexmem_info_list, links) {
|
||||
if (info->addr == chunk) {
|
||||
memman->flex_reclaimed_mem += info->mem_size;
|
||||
LIST_REMOVE(info, links);
|
||||
MEMMAN_SYSFREE(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* XXX */
|
||||
memman->flex_free_called++;
|
||||
memman->flex_sfree_called++;
|
||||
MEMMAN_SYSFREE(chunk);
|
||||
}
|
||||
|
||||
void
|
||||
memman_freeall(struct memman *memman)
|
||||
{
|
||||
int id;
|
||||
void *chunk;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_node *memnode;
|
||||
struct memman_block *memblock;
|
||||
struct memman_flexmem_info *info;
|
||||
|
||||
for (id = 0; id < memman->max_memid; id++) {
|
||||
bmp = &memman->blockman[id];
|
||||
|
||||
while ((memnode = LIST_FIRST(&bmp->occupied_node_list))) {
|
||||
chunk = memnode->node;
|
||||
printf("memman_freeall: fixed size (id = %d)\n", id);
|
||||
memman_free(memman, id, chunk);
|
||||
}
|
||||
while ((memblock = LIST_FIRST(&bmp->block_list))) {
|
||||
LIST_REMOVE(memblock, links);
|
||||
if (!memblock->static_mem) {
|
||||
memman->sfree_called++;
|
||||
memman->reclaimed_mem += memblock->allocated_mem;
|
||||
MEMMAN_SYSFREE(memblock);
|
||||
}
|
||||
}
|
||||
bmp->initialized = 0;
|
||||
}
|
||||
|
||||
LIST_FOREACH(info, &memman->flexmem_info_list, links) {
|
||||
printf("memman_freeall: flex size (size = %d, addr = %p)\n",
|
||||
info->mem_size, info->addr);
|
||||
memman_free_flexsize(memman, info->addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
memman_statistics_fixedsize(struct memman *memman)
|
||||
{
|
||||
printf(" fixed size memory blocks\n");
|
||||
printf(" alloc(): %d times\n", memman->alloc_called);
|
||||
printf(" system malloc(): %d times\n", memman->salloc_called);
|
||||
printf(" free(): %d times\n", memman->free_called);
|
||||
printf(" system free(): %d times\n", memman->sfree_called);
|
||||
printf(" required memory: %d bytes\n", memman->required_mem);
|
||||
printf(" allocated memory: %d bytes\n", memman->allocated_mem);
|
||||
printf(" reclaimed memory: %d bytes\n", memman->reclaimed_mem);
|
||||
}
|
||||
|
||||
static void
|
||||
memman_statistics_flexsize(struct memman *memman)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf(" flexible size memory blocks\n");
|
||||
printf(" alloc(): %d times\n", memman->flex_alloc_called);
|
||||
printf(" system malloc(): %d times\n", memman->flex_salloc_called);
|
||||
printf(" free(): %d times\n", memman->flex_free_called);
|
||||
printf(" system free(): %d times\n", memman->flex_sfree_called);
|
||||
printf(" required memory: %d bytes\n", memman->flex_required_mem);
|
||||
printf(" allocated memory: %d bytes\n", memman->flex_allocated_mem);
|
||||
printf(" reclaimed memory: %d bytes\n", memman->flex_reclaimed_mem);
|
||||
printf(" peak memory usage: %d bytes\n", memman->flex_peak_mem_usage);
|
||||
printf(" min memory size: %d bytes\n", memman->flex_mem_size_min);
|
||||
printf(" max memory size: %d bytes\n", memman->flex_mem_size_max);
|
||||
printf(" avg memory size: %d bytes\n",
|
||||
(memman->flex_alloc_called) ?
|
||||
memman->flex_allocated_mem / memman->flex_alloc_called : 0);
|
||||
|
||||
printf(" memory size histogram (%d entries):\n",
|
||||
memman->flex_mem_histogram_ptr);
|
||||
printf(" size count\n");
|
||||
memman_sort_histogram_by_size(memman);
|
||||
for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
|
||||
printf(" %d %d\n",
|
||||
memman->flex_mem_histogram[i].mem_size,
|
||||
memman->flex_mem_histogram[i].count);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
memman_statistics(struct memman *memman)
|
||||
{
|
||||
printf("memman: reporting statistics\n");
|
||||
memman_statistics_fixedsize(memman);
|
||||
memman_statistics_flexsize(memman);
|
||||
}
|
||||
|
||||
size_t
|
||||
memman_memid2size(struct memman *memman, unsigned int id)
|
||||
{
|
||||
if (memman->max_memid <= id) {
|
||||
printf("memman_alloc: invalid memory type id\n");
|
||||
return (0);
|
||||
}
|
||||
return (memman->blockman[id].size);
|
||||
}
|
172
sys/dev/acpi/aml/aml_memman.h
Normal file
172
sys/dev/acpi/aml/aml_memman.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_memman.h,v 1.9 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MEMMAN_H_
|
||||
#define _MEMMAN_H_
|
||||
|
||||
/*
|
||||
* Generic Memory Management
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
/* memory block */
|
||||
struct memman_block {
|
||||
LIST_ENTRY(memman_block) links;
|
||||
void *block;
|
||||
unsigned static_mem; /* static memory or not */
|
||||
unsigned int allocated; /* number of allocated chunks */
|
||||
unsigned int available; /* number of available chunks */
|
||||
unsigned int allocated_mem; /* block + misc (in bytes) */
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
LIST_HEAD(memman_block_list, memman_block);
|
||||
|
||||
/* memory node in block */
|
||||
struct memman_node {
|
||||
LIST_ENTRY(memman_node) links;
|
||||
void *node;
|
||||
struct memman_block *memblock;
|
||||
}__attribute__((packed));
|
||||
|
||||
LIST_HEAD(memman_node_list, memman_node);
|
||||
|
||||
/* memory type id */
|
||||
extern unsigned int memid_unkown;
|
||||
|
||||
/* memory block manager */
|
||||
struct memman_blockman {
|
||||
unsigned int size; /* size of chunk */
|
||||
unsigned int available; /* total # of available chunks */
|
||||
void *initial_block; /* initial memory storage */
|
||||
unsigned initialized; /* initialized or not */
|
||||
|
||||
struct memman_block_list block_list;
|
||||
struct memman_node_list free_node_list;
|
||||
struct memman_node_list occupied_node_list;
|
||||
};
|
||||
|
||||
/* memory size histogram */
|
||||
#define MEMMAN_HISTOGRAM_SIZE 20
|
||||
struct memman_histogram {
|
||||
int mem_size;
|
||||
int count;
|
||||
};
|
||||
|
||||
/* flex size memory allocation info */
|
||||
struct memman_flexmem_info {
|
||||
LIST_ENTRY(memman_flexmem_info) links;
|
||||
void *addr;
|
||||
size_t mem_size;
|
||||
}__attribute__((packed));
|
||||
|
||||
LIST_HEAD(memman_flexmem_info_list, memman_flexmem_info);
|
||||
|
||||
/* memory manager */
|
||||
struct memman {
|
||||
struct memman_blockman *blockman;
|
||||
unsigned int max_memid; /* max number of valid memid */
|
||||
|
||||
/* fixed size memory blocks */
|
||||
unsigned int alloc_called; /* memman_alloc() calling */
|
||||
unsigned int free_called; /* memman_free() calling */
|
||||
unsigned int salloc_called; /* malloc() calling */
|
||||
unsigned int sfree_called; /* free() calling */
|
||||
size_t required_mem; /* total required memory (in bytes) */
|
||||
size_t allocated_mem; /* total malloc()ed memory */
|
||||
size_t reclaimed_mem; /* total free()ed memory */
|
||||
/* flex size memory blocks */
|
||||
unsigned int flex_alloc_called; /* memman_alloc_flexsize() calling */
|
||||
unsigned int flex_free_called; /* memman_free_flexsize() calling */
|
||||
unsigned int flex_salloc_called;/* malloc() calling */
|
||||
unsigned int flex_sfree_called; /* free() calling */
|
||||
size_t flex_required_mem; /* total required memory (in bytes) */
|
||||
size_t flex_allocated_mem;/* total malloc()ed memory */
|
||||
size_t flex_reclaimed_mem;/* total free()ed memory */
|
||||
size_t flex_mem_size_min; /* min size of allocated memory */
|
||||
size_t flex_mem_size_max; /* max size of allocated memory */
|
||||
size_t flex_peak_mem_usage;/* memory usage at a peak period */
|
||||
|
||||
/* stuff for more detailed statistical information */
|
||||
struct memman_histogram *flex_mem_histogram;
|
||||
unsigned int flex_mem_histogram_ptr;
|
||||
int flex_mem_histogram_initial_tolerance;
|
||||
unsigned flex_mem_initialized;
|
||||
struct memman_flexmem_info_list flexmem_info_list;
|
||||
};
|
||||
|
||||
#define MEMMAN_BLOCKNODE_SIZE(entries) sizeof(struct memman_block) + \
|
||||
sizeof(struct memman_node) * entries
|
||||
|
||||
#ifndef ROUNDUP_UNIT
|
||||
#define ROUNDUP_UNIT 4
|
||||
#endif
|
||||
|
||||
#if !defined(MEMMAN_INITIAL_SIZE) || MEMMAN_INITIAL_SIZE < 2048
|
||||
#define MEMMAN_INITIAL_SIZE 2048
|
||||
#endif
|
||||
|
||||
#if !defined(MEMMAN_INCR_SIZE) || MEMMAN_INCR_SIZE < 512
|
||||
#define MEMMAN_INCR_SIZE 512
|
||||
#endif
|
||||
|
||||
#define MEMMAN_INITIALSTORAGE_DESC(type, name) \
|
||||
static struct { \
|
||||
char blocknodes[MEMMAN_BLOCKNODE_SIZE(MEMMAN_INITIAL_SIZE)]; \
|
||||
type realblock[MEMMAN_INITIAL_SIZE]; \
|
||||
} name
|
||||
|
||||
#define MEMMAN_MEMBLOCK_DESC(size, initial_storage) \
|
||||
{ size, MEMMAN_INITIAL_SIZE, &initial_storage, 0 }
|
||||
|
||||
#define MEMMAN_MEMMANAGER_DESC(blockman, max_memid, histogram, tolerance) \
|
||||
{ blockman, max_memid, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, histogram, 0, tolerance, 0}
|
||||
|
||||
void *memman_alloc(struct memman *, unsigned int);
|
||||
void *memman_alloc_flexsize(struct memman *, size_t);
|
||||
void memman_free(struct memman *, unsigned int, void *);
|
||||
void memman_free_flexsize(struct memman *, void *);
|
||||
void memman_freeall(struct memman *);
|
||||
void memman_statistics(struct memman *);
|
||||
size_t memman_memid2size(struct memman *, unsigned int);
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define MEMMAN_SYSMALLOC(size) malloc(size, M_MEMMAN, M_WAITOK)
|
||||
#define MEMMAN_SYSFREE(ptr) free(ptr, M_MEMMAN)
|
||||
#define MEMMAN_SYSABORT() /* no abort in kernel */
|
||||
#else /* !_KERNEL */
|
||||
#define MEMMAN_SYSMALLOC(size) malloc(size)
|
||||
#define MEMMAN_SYSFREE(ptr) free(ptr)
|
||||
#define MEMMAN_SYSABORT() abort()
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MEMMAN_H_ */
|
477
sys/dev/acpi/aml/aml_name.c
Normal file
477
sys/dev/acpi/aml/aml_name.c
Normal file
@ -0,0 +1,477 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Yasuo Yokoyama
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_name.c,v 1.15 2000/08/16 18:14:53 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#else /* _KERNEL */
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static struct aml_name *aml_find_name(struct aml_name *, char *);
|
||||
static struct aml_name *aml_new_name(struct aml_name *, char *);
|
||||
static void aml_delete_name(struct aml_name *);
|
||||
|
||||
static struct aml_name rootname = {"\\", NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
static struct aml_name_group root_group = {
|
||||
AML_NAME_GROUP_ROOT,
|
||||
&rootname,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct aml_name_group *name_group_list = &root_group;
|
||||
struct aml_local_stack *stack_top = NULL;
|
||||
|
||||
struct aml_name *
|
||||
aml_get_rootname()
|
||||
{
|
||||
|
||||
return (&rootname);
|
||||
}
|
||||
|
||||
static struct aml_name *
|
||||
aml_find_name(struct aml_name *parent, char *name)
|
||||
{
|
||||
struct aml_name *result;
|
||||
|
||||
if (!parent)
|
||||
parent = &rootname;
|
||||
for (result = parent->child; result; result = result->brother)
|
||||
if (!strncmp(result->name, name, 4))
|
||||
break;
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse given namesppace expression and find a first matched object
|
||||
* under given level of the tree by depth first search.
|
||||
*/
|
||||
|
||||
struct aml_name *
|
||||
aml_find_from_namespace(struct aml_name *parent, char *name)
|
||||
{
|
||||
char *ptr;
|
||||
int len;
|
||||
struct aml_name *result;
|
||||
|
||||
ptr = name;
|
||||
if (!parent)
|
||||
parent = &rootname;
|
||||
|
||||
if (ptr[0] == '\\') {
|
||||
ptr++;
|
||||
parent = &rootname;
|
||||
}
|
||||
for (len = 0; ptr[len] != '.' && ptr[len] != '\0'; len++)
|
||||
;
|
||||
|
||||
for (result = parent->child; result; result = result->brother) {
|
||||
if (!strncmp(result->name, ptr, len)) {
|
||||
if (ptr[len] == '\0' || ptr[len + 1] == '\0') {
|
||||
return (result);
|
||||
}
|
||||
ptr += len;
|
||||
if (ptr[0] != '.') {
|
||||
return (NULL);
|
||||
}
|
||||
ptr++;
|
||||
return (aml_find_from_namespace(result, ptr));
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_aml_apply_foreach_found_objects(struct aml_name *parent, char *name,
|
||||
int len, int shallow, int (*func)(struct aml_name *, va_list), va_list ap)
|
||||
{
|
||||
struct aml_name *child, *ptr;
|
||||
|
||||
child = ptr = NULL;
|
||||
|
||||
/* function to apply must be specified */
|
||||
if (func == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (child = parent->child; child; child = child->brother) {
|
||||
if (!strncmp(child->name, name, len)) {
|
||||
/* if function call was failed, stop searching */
|
||||
if (func(child, ap) != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shallow == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ptr = parent->child; ptr; ptr = ptr->brother) {
|
||||
/* do more searching */
|
||||
_aml_apply_foreach_found_objects(ptr, name, len, 0, func, ap);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find named objects as many as possible under given level of
|
||||
* namespace, and apply given callback function for each
|
||||
* named objects found. If the callback function returns non-zero
|
||||
* value, then the search terminates immediately.
|
||||
* Note that object name expression is used as forward substring match,
|
||||
* not exact match. The name expression "_L" will match for objects
|
||||
* which have name starting with "_L" such as "\_SB_.LID_._LID" and
|
||||
* "\_GPE._L00" and so on. The name expression can include parent object
|
||||
* name in it like "\_GPE._L". In this case, GPE X level wake handlers
|
||||
* will be found under "\_GPE" in shallow level.
|
||||
*/
|
||||
|
||||
void
|
||||
aml_apply_foreach_found_objects(struct aml_name *start, char *name,
|
||||
int (*func)(struct aml_name *, va_list), ...)
|
||||
{
|
||||
int i, len, has_dot, last_is_dot, shallow;
|
||||
struct aml_name *child, *parent;
|
||||
va_list ap;
|
||||
|
||||
shallow = 0;
|
||||
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);
|
||||
}
|
88
sys/dev/acpi/aml/aml_name.h
Normal file
88
sys/dev/acpi/aml/aml_name.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Yasuo Yokoyama
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_name.h,v 1.17 2000/08/16 18:14:54 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_NAME_H_
|
||||
#define _AML_NAME_H_
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
|
||||
struct aml_name {
|
||||
char name[4];
|
||||
union aml_object *property;
|
||||
struct aml_name *parent;
|
||||
struct aml_name *brother;
|
||||
struct aml_name *child;
|
||||
struct aml_name *chain;
|
||||
};
|
||||
|
||||
#define AML_NAME_GROUP_ROOT 0
|
||||
#define AML_NAME_GROUP_OS_DEFINED 1
|
||||
#define AML_NAME_GROUP_IN_METHOD 2
|
||||
|
||||
struct aml_name_group {
|
||||
int id; /* DSDT address or DBHANDLE */
|
||||
struct aml_name *head;
|
||||
struct aml_name_group *next;
|
||||
};
|
||||
|
||||
struct aml_local_stack {
|
||||
struct aml_name localvalue[8];
|
||||
struct aml_name argumentvalue[7];
|
||||
struct aml_name *temporary;
|
||||
struct aml_local_stack *next;
|
||||
};
|
||||
|
||||
/* forward declarement */
|
||||
struct aml_envrion;
|
||||
|
||||
struct aml_name *aml_get_rootname(void);
|
||||
struct aml_name_group *aml_new_name_group(int);
|
||||
void aml_delete_name_group(struct aml_name_group *);
|
||||
|
||||
struct aml_name *aml_find_from_namespace(struct aml_name *, char *);
|
||||
void aml_apply_foreach_found_objects(struct aml_name *,
|
||||
char *, int (*)(struct aml_name *, va_list), ...);
|
||||
struct aml_name *aml_search_name(struct aml_environ *, u_int8_t *);
|
||||
struct aml_name *aml_create_name(struct aml_environ *, u_int8_t *);
|
||||
|
||||
struct aml_local_stack *aml_local_stack_create(void);
|
||||
void aml_local_stack_push(struct aml_local_stack *);
|
||||
struct aml_local_stack *aml_local_stack_pop(void);
|
||||
void aml_local_stack_delete(struct aml_local_stack *);
|
||||
struct aml_name *aml_local_stack_getLocalX(int);
|
||||
struct aml_name *aml_local_stack_getArgX(struct aml_local_stack *, int);
|
||||
struct aml_name *aml_create_local_object(void);
|
||||
|
||||
extern struct aml_name_group *name_group_list;
|
||||
|
||||
#endif /* !_AML_NAME_H_ */
|
265
sys/dev/acpi/aml/aml_obj.c
Normal file
265
sys/dev/acpi/aml/aml_obj.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_obj.c,v 1.17 2000/08/12 15:20:45 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#else /* _KERNEL */
|
||||
#include <sys/bus.h>
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
union aml_object *
|
||||
aml_copy_object(struct aml_environ *env, union aml_object *orig)
|
||||
{
|
||||
int i;
|
||||
union aml_object *ret;
|
||||
|
||||
if (orig == NULL)
|
||||
return (NULL);
|
||||
switch (orig->type) {
|
||||
case aml_t_regfield:
|
||||
ret = aml_alloc_object(aml_t_buffer, 0);
|
||||
ret->buffer.size = (orig->regfield.bitlen / 8) +
|
||||
((orig->regfield.bitlen % 8) ? 1 : 0);
|
||||
if (ret->buffer.size == 0) {
|
||||
goto out;
|
||||
}
|
||||
ret->buffer.data = memman_alloc_flexsize(aml_memman, ret->buffer.size);
|
||||
aml_store_to_object(env, orig, ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = aml_alloc_object(0, orig);
|
||||
break;
|
||||
}
|
||||
|
||||
if (1 || orig != &env->tempobject) { /* XXX */
|
||||
if (orig->type == aml_t_buffer) {
|
||||
if (orig->buffer.size == 0) {
|
||||
goto out;
|
||||
}
|
||||
ret->buffer.data = memman_alloc_flexsize(aml_memman,
|
||||
orig->buffer.size);
|
||||
bcopy(orig->buffer.data, ret->buffer.data, orig->buffer.size);
|
||||
} else if (orig->type == aml_t_package) {
|
||||
if (ret->package.elements == 0) {
|
||||
goto out;
|
||||
}
|
||||
ret->package.objects = memman_alloc_flexsize(aml_memman,
|
||||
ret->package.elements * sizeof(union aml_object *));
|
||||
for (i = 0; i < ret->package.elements; i++) {
|
||||
ret->package.objects[i] = aml_copy_object(env, orig->package.objects[i]);
|
||||
}
|
||||
} else if (orig->type == aml_t_string && orig->str.needfree != 0) {
|
||||
ret->str.string = memman_alloc_flexsize(aml_memman,
|
||||
strlen(orig->str.string) + 1);
|
||||
strcpy(orig->str.string, ret->str.string);
|
||||
} else if (orig->type == aml_t_num) {
|
||||
ret->num.constant = 0;
|
||||
}
|
||||
} else {
|
||||
printf("%s:%d\n", __FILE__, __LINE__);
|
||||
env->tempobject.type = aml_t_null;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function have two function: copy or allocate. if orig != NULL,
|
||||
* orig is duplicated.
|
||||
*/
|
||||
|
||||
union aml_object *
|
||||
aml_alloc_object(enum aml_objtype type, union aml_object *orig)
|
||||
{
|
||||
unsigned int memid;
|
||||
union aml_object *ret;
|
||||
|
||||
if (orig != NULL) {
|
||||
type = orig->type;
|
||||
}
|
||||
switch (type) {
|
||||
case aml_t_namestr:
|
||||
memid = memid_aml_namestr;
|
||||
break;
|
||||
case aml_t_buffer:
|
||||
memid = memid_aml_buffer;
|
||||
break;
|
||||
case aml_t_string:
|
||||
memid = memid_aml_string;
|
||||
break;
|
||||
case aml_t_bufferfield:
|
||||
memid = memid_aml_bufferfield;
|
||||
break;
|
||||
case aml_t_package:
|
||||
memid = memid_aml_package;
|
||||
break;
|
||||
case aml_t_num:
|
||||
memid = memid_aml_num;
|
||||
break;
|
||||
case aml_t_powerres:
|
||||
memid = memid_aml_powerres;
|
||||
break;
|
||||
case aml_t_opregion:
|
||||
memid = memid_aml_opregion;
|
||||
break;
|
||||
case aml_t_method:
|
||||
memid = memid_aml_method;
|
||||
break;
|
||||
case aml_t_processor:
|
||||
memid = memid_aml_processor;
|
||||
break;
|
||||
case aml_t_field:
|
||||
memid = memid_aml_field;
|
||||
break;
|
||||
case aml_t_mutex:
|
||||
memid = memid_aml_mutex;
|
||||
break;
|
||||
case aml_t_device:
|
||||
memid = memid_aml_objtype;
|
||||
break;
|
||||
case aml_t_objref:
|
||||
memid = memid_aml_objref;
|
||||
break;
|
||||
default:
|
||||
memid = memid_aml_objtype;
|
||||
break;
|
||||
}
|
||||
ret = memman_alloc(aml_memman, memid);
|
||||
ret->type = type;
|
||||
|
||||
if (orig != NULL) {
|
||||
bcopy(orig, ret, memman_memid2size(aml_memman, memid));
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
aml_free_objectcontent(union aml_object *obj)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (obj->type == aml_t_buffer && obj->buffer.data != NULL) {
|
||||
memman_free_flexsize(aml_memman, obj->buffer.data);
|
||||
obj->buffer.data = NULL;
|
||||
}
|
||||
if (obj->type == aml_t_string && obj->str.string != NULL) {
|
||||
if (obj->str.needfree != 0) {
|
||||
memman_free_flexsize(aml_memman, obj->str.string);
|
||||
obj->str.string = NULL;
|
||||
}
|
||||
}
|
||||
if (obj->type == aml_t_package && obj->package.objects != NULL) {
|
||||
for (i = 0; i < obj->package.elements; i++) {
|
||||
aml_free_object(&obj->package.objects[i]);
|
||||
}
|
||||
memman_free_flexsize(aml_memman, obj->package.objects);
|
||||
obj->package.objects = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aml_free_object(union aml_object **obj)
|
||||
{
|
||||
union aml_object *body;
|
||||
|
||||
body = *obj;
|
||||
if (body == NULL) {
|
||||
return;
|
||||
}
|
||||
aml_free_objectcontent(*obj);
|
||||
memman_free(aml_memman, memid_unkown, *obj);
|
||||
*obj = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aml_realloc_object(union aml_object *obj, int size)
|
||||
{
|
||||
int i;
|
||||
enum aml_objtype type;
|
||||
union aml_object tmp;
|
||||
|
||||
type = obj->type;
|
||||
switch (type) {
|
||||
case aml_t_buffer:
|
||||
if (obj->buffer.size >= size) {
|
||||
return;
|
||||
}
|
||||
tmp.buffer.size = size;
|
||||
tmp.buffer.data = memman_alloc_flexsize(aml_memman, size);
|
||||
bzero(tmp.buffer.data, size);
|
||||
bcopy(obj->buffer.data, tmp.buffer.data, obj->buffer.size);
|
||||
aml_free_objectcontent(obj);
|
||||
*obj = tmp;
|
||||
break;
|
||||
case aml_t_string:
|
||||
if (strlen(obj->str.string) >= size) {
|
||||
return;
|
||||
}
|
||||
tmp.str.string = memman_alloc_flexsize(aml_memman, size + 1);
|
||||
strcpy(tmp.str.string, obj->str.string);
|
||||
aml_free_objectcontent(obj);
|
||||
*obj = tmp;
|
||||
break;
|
||||
case aml_t_package:
|
||||
if (obj->package.elements >= size) {
|
||||
return;
|
||||
}
|
||||
tmp.package.objects = memman_alloc_flexsize(aml_memman,
|
||||
size * sizeof(union aml_object *));
|
||||
bzero(tmp.package.objects, size * sizeof(union aml_object *));
|
||||
for (i = 0; i < obj->package.elements; i++) {
|
||||
tmp.package.objects[i] = obj->package.objects[i];
|
||||
}
|
||||
memman_free_flexsize(aml_memman, obj->package.objects);
|
||||
obj->package.objects = tmp.package.objects;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
227
sys/dev/acpi/aml/aml_obj.h
Normal file
227
sys/dev/acpi/aml/aml_obj.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_obj.h,v 1.15 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_OBJ_H_
|
||||
#define _AML_OBJ_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct aml_environ;
|
||||
enum aml_objtype {
|
||||
aml_t_namestr = -3,
|
||||
aml_t_regfield,
|
||||
aml_t_objref,
|
||||
aml_t_null = 0,
|
||||
aml_t_num,
|
||||
aml_t_string,
|
||||
aml_t_buffer,
|
||||
aml_t_package,
|
||||
aml_t_device,
|
||||
aml_t_field,
|
||||
aml_t_event,
|
||||
aml_t_method,
|
||||
aml_t_mutex,
|
||||
aml_t_opregion,
|
||||
aml_t_powerres,
|
||||
aml_t_processor,
|
||||
aml_t_therm,
|
||||
aml_t_bufferfield,
|
||||
aml_t_ddbhandle,
|
||||
aml_t_debug
|
||||
};
|
||||
|
||||
struct aml_namestr {
|
||||
enum aml_objtype type; /* =aml_t_namestr */
|
||||
u_int8_t *dp;
|
||||
};
|
||||
|
||||
struct aml_opregion {
|
||||
enum aml_objtype type;
|
||||
int space;
|
||||
int offset;
|
||||
int length;
|
||||
};
|
||||
|
||||
struct aml_num {
|
||||
enum aml_objtype type; /* =aml_t_num */
|
||||
int number;
|
||||
int constant;
|
||||
};
|
||||
|
||||
struct aml_package {
|
||||
enum aml_objtype type;
|
||||
int elements;
|
||||
union aml_object **objects;
|
||||
};
|
||||
|
||||
struct aml_string {
|
||||
enum aml_objtype type; /* =aml_t_string */
|
||||
int needfree;
|
||||
u_int8_t *string;
|
||||
};
|
||||
|
||||
struct aml_buffer {
|
||||
enum aml_objtype type; /* =aml_t_buffer */
|
||||
int size;
|
||||
u_int8_t *data; /* This should be free when
|
||||
* this object is free.
|
||||
*/
|
||||
};
|
||||
|
||||
enum fieldtype {
|
||||
f_t_field,
|
||||
f_t_index,
|
||||
f_t_bank
|
||||
};
|
||||
|
||||
struct nfieldd {
|
||||
enum fieldtype ftype; /* f_t_field */
|
||||
u_int8_t *regname; /* Namestring */
|
||||
};
|
||||
|
||||
struct ifieldd {
|
||||
enum fieldtype ftype; /* f_t_index */
|
||||
u_int8_t *indexname;
|
||||
u_int8_t *dataname;
|
||||
};
|
||||
|
||||
struct bfieldd {
|
||||
enum fieldtype ftype; /* f_t_bank */
|
||||
u_int8_t *regname;
|
||||
u_int8_t *bankname;
|
||||
u_int32_t bankvalue;
|
||||
};
|
||||
|
||||
struct aml_field {
|
||||
enum aml_objtype type;
|
||||
u_int32_t flags;
|
||||
int bitoffset; /* Not Byte offset but bitoffset */
|
||||
int bitlen;
|
||||
union {
|
||||
enum fieldtype ftype;
|
||||
struct nfieldd fld;
|
||||
struct ifieldd ifld;
|
||||
struct bfieldd bfld;
|
||||
} f;
|
||||
};
|
||||
|
||||
struct aml_bufferfield {
|
||||
enum aml_objtype type; /* aml_t_bufferfield */
|
||||
int bitoffset;
|
||||
int bitlen;
|
||||
u_int8_t *origin; /* This should not be free
|
||||
* when this object is free
|
||||
* (Within Buffer object)
|
||||
*/
|
||||
};
|
||||
|
||||
struct aml_method {
|
||||
enum aml_objtype type;
|
||||
int argnum; /* Not argnum but argnum|frag */
|
||||
u_int8_t *from;
|
||||
u_int8_t *to;
|
||||
};
|
||||
|
||||
struct aml_powerres {
|
||||
enum aml_objtype type;
|
||||
int level;
|
||||
int order;
|
||||
};
|
||||
|
||||
struct aml_processor {
|
||||
enum aml_objtype type;
|
||||
int id;
|
||||
int addr;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct aml_mutex_queue {
|
||||
STAILQ_ENTRY(aml_mutex_queue) entry;
|
||||
};
|
||||
|
||||
struct aml_mutex {
|
||||
enum aml_objtype type;
|
||||
int level;
|
||||
volatile void *cookie; /* In kernel, struct proc? */
|
||||
STAILQ_HEAD(, aml_mutex_queue) queue;
|
||||
};
|
||||
|
||||
struct aml_objref {
|
||||
enum aml_objtype type;
|
||||
struct aml_name *nameref;
|
||||
union aml_object *ref;
|
||||
int offset; /* of aml_buffer.data or aml_package.objects. */
|
||||
/* if negative value, not ready to dereference for element access. */
|
||||
unsigned deref; /* indicates whether dereffenced or not */
|
||||
unsigned alias; /* true if this is an alias object reference */
|
||||
};
|
||||
|
||||
struct aml_regfield {
|
||||
enum aml_objtype type;
|
||||
int space;
|
||||
u_int32_t flags;
|
||||
int offset;
|
||||
int bitoffset;
|
||||
int bitlen;
|
||||
};
|
||||
|
||||
struct aml_event {
|
||||
enum aml_objtype type; /* aml_t_event */
|
||||
int inuse;
|
||||
};
|
||||
|
||||
union aml_object {
|
||||
enum aml_objtype type;
|
||||
struct aml_num num;
|
||||
struct aml_processor proc;
|
||||
struct aml_powerres pres;
|
||||
struct aml_opregion opregion;
|
||||
struct aml_method meth;
|
||||
struct aml_field field;
|
||||
struct aml_mutex mutex;
|
||||
struct aml_namestr nstr;
|
||||
struct aml_buffer buffer;
|
||||
struct aml_bufferfield bfld;
|
||||
struct aml_package package;
|
||||
struct aml_string str;
|
||||
struct aml_objref objref;
|
||||
struct aml_event event;
|
||||
struct aml_regfield regfield;
|
||||
};
|
||||
|
||||
union aml_object *aml_copy_object(struct aml_environ *,
|
||||
union aml_object *);
|
||||
union aml_object *aml_alloc_object(enum aml_objtype,
|
||||
union aml_object *);
|
||||
void aml_free_objectcontent(union aml_object *);
|
||||
void aml_free_object(union aml_object **);
|
||||
void aml_realloc_object(union aml_object *, int);
|
||||
|
||||
#endif /* !_AML_OBJ_H_ */
|
1998
sys/dev/acpi/aml/aml_parse.c
Normal file
1998
sys/dev/acpi/aml/aml_parse.c
Normal file
File diff suppressed because it is too large
Load Diff
36
sys/dev/acpi/aml/aml_parse.h
Normal file
36
sys/dev/acpi/aml/aml_parse.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_parse.h,v 1.9 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_PARSE_H_
|
||||
#define _AML_PARSE_H_
|
||||
|
||||
struct aml_name *aml_parse_objectlist(struct aml_environ *, int);
|
||||
struct aml_name *aml_parse_termobj(struct aml_environ *, int);
|
||||
|
||||
#endif /* !_AML_PARSE_H_ */
|
490
sys/dev/acpi/aml/aml_region.c
Normal file
490
sys/dev/acpi/aml/aml_region.c
Normal file
@ -0,0 +1,490 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* Copyright (c) 2000 Munehiro Matsuda <haro@tk.kubota.co.jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_region.c,v 1.10 2000/08/09 14:47:44 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Region I/O subroutine
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/acpi.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_region.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
|
||||
#ifndef ACPI_NO_OSDFUNC_INLINE
|
||||
#include <machine/acpica_osd.h>
|
||||
#endif
|
||||
|
||||
#define AML_REGION_INPUT 0
|
||||
#define AML_REGION_OUTPUT 1
|
||||
|
||||
#define AML_REGION_SYSMEM 0
|
||||
#define AML_REGION_SYSIO 1
|
||||
#define AML_REGION_PCICFG 2
|
||||
#define AML_REGION_EMBCTL 3
|
||||
#define AML_REGION_SMBUS 4
|
||||
|
||||
static int
|
||||
aml_region_io_system(struct aml_environ *env, boolean_t io, int regtype,
|
||||
u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
|
||||
u_int32_t bitoffset, u_int32_t bitlen)
|
||||
{
|
||||
u_int8_t val, tmp, masklow, maskhigh;
|
||||
u_int8_t offsetlow, offsethigh;
|
||||
vm_offset_t addr, vaddr, byteoffset, bytelen;
|
||||
u_int32_t pci_bus;
|
||||
u_int32_t pci_devfunc;
|
||||
int value, readval;
|
||||
int state, i;
|
||||
int debug;
|
||||
|
||||
/* save debug level and shut it up */
|
||||
debug = aml_debug;
|
||||
aml_debug = 0;
|
||||
|
||||
value = *valuep;
|
||||
val = readval = 0;
|
||||
masklow = maskhigh = 0xff;
|
||||
state = 0;
|
||||
vaddr = 0;
|
||||
pci_bus = pci_devfunc = 0;
|
||||
|
||||
byteoffset = bitoffset / 8;
|
||||
bytelen = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
|
||||
addr = baseaddr + byteoffset;
|
||||
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);
|
||||
}
|
||||
|
||||
if (regtype == AML_REGION_SYSMEM) {
|
||||
OsdMapMemory((void *)addr, bytelen, (void **)&vaddr);
|
||||
}
|
||||
if (regtype == AML_REGION_PCICFG) {
|
||||
/* Access to PCI Config space */
|
||||
struct aml_name *pci_info;
|
||||
|
||||
/* Obtain PCI bus number */
|
||||
pci_info = aml_search_name(env, "_BBN");
|
||||
if (!pci_info || pci_info->property->type != aml_t_num) {
|
||||
AML_DEBUGPRINT("Cannot locate _BBN. Using default 0\n");
|
||||
pci_bus = 0;
|
||||
} else {
|
||||
AML_DEBUGPRINT("found _BBN: %d\n",
|
||||
pci_info->property->num.number);
|
||||
pci_bus = pci_info->property->num.number & 0xff;
|
||||
}
|
||||
|
||||
/* Obtain device & function number */
|
||||
pci_info = aml_search_name(env, "_ADR");
|
||||
if (!pci_info || pci_info->property->type != aml_t_num) {
|
||||
printf("Cannot locate: _ADR\n");
|
||||
state = -1;
|
||||
goto io_done;
|
||||
}
|
||||
pci_devfunc = pci_info->property->num.number;
|
||||
|
||||
AML_DEBUGPRINT("[pci%d.%d]", pci_bus, pci_devfunc);
|
||||
}
|
||||
|
||||
/* simple I/O ? */
|
||||
if (offsetlow == 0 && offsethigh == 0 &&
|
||||
(bitlen == 8 || bitlen == 16 || bitlen == 32)) {
|
||||
switch (io) {
|
||||
case AML_REGION_INPUT:
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
/* XXX should be MI */
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value = *(volatile u_int8_t *)(vaddr);
|
||||
value &= 0xff;
|
||||
break;
|
||||
case 16:
|
||||
value = *(volatile u_int16_t *)(vaddr);
|
||||
value &= 0xffff;
|
||||
break;
|
||||
case 32:
|
||||
value = *(volatile u_int32_t *)(vaddr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value = OsdIn8(addr);
|
||||
value &= 0xff;
|
||||
break;
|
||||
case 16:
|
||||
value = OsdIn16(addr);
|
||||
value &= 0xffff;
|
||||
break;
|
||||
case 32:
|
||||
value = OsdIn32(addr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
OsdReadPciCfgByte(pci_bus, pci_devfunc,
|
||||
addr, (UINT8 *)&value);
|
||||
value &= 0xff;
|
||||
break;
|
||||
case 16:
|
||||
OsdReadPciCfgWord(pci_bus, pci_devfunc,
|
||||
addr, (UINT16 *)&value);
|
||||
value &= 0xffff;
|
||||
break;
|
||||
case 32:
|
||||
OsdReadPciCfgDword(pci_bus, pci_devfunc,
|
||||
addr, &value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
value = 0;
|
||||
break;
|
||||
}
|
||||
*valuep = value;
|
||||
break;
|
||||
case AML_REGION_OUTPUT:
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
/* XXX should be MI */
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value &= 0xff;
|
||||
*(volatile u_int8_t *)(vaddr) = value;
|
||||
break;
|
||||
case 16:
|
||||
value &= 0xffff;
|
||||
*(volatile u_int16_t *)(vaddr) = value;
|
||||
break;
|
||||
case 32:
|
||||
*(volatile u_int32_t *)(vaddr) = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value &= 0xff;
|
||||
OsdOut8(addr, value);
|
||||
break;
|
||||
case 16:
|
||||
value &= 0xffff;
|
||||
OsdOut16(addr, value);
|
||||
break;
|
||||
case 32:
|
||||
OsdOut32(addr, value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
OsdWritePciCfgByte(pci_bus, pci_devfunc,
|
||||
addr, value);
|
||||
break;
|
||||
case 16:
|
||||
OsdWritePciCfgWord(pci_bus, pci_devfunc,
|
||||
addr, value);
|
||||
break;
|
||||
case 32:
|
||||
OsdWritePciCfgDword(pci_bus, pci_devfunc,
|
||||
addr, value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto io_done;
|
||||
}
|
||||
|
||||
for (i = 0; i < bytelen; i++) {
|
||||
/* XXX */
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
val = *(volatile u_int8_t *)(vaddr + i);
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
val = OsdIn8(addr + i);
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
OsdReadPciCfgByte(pci_bus, pci_devfunc, addr + i, &val);
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
AML_DEBUGPRINT("\t[%d:0x%02x@0x%x]", regtype, val, addr + i);
|
||||
|
||||
switch (io) {
|
||||
case AML_REGION_INPUT:
|
||||
tmp = val;
|
||||
/* the lowest byte? */
|
||||
if (i == 0) {
|
||||
if (offsetlow) {
|
||||
readval = tmp & ~masklow;
|
||||
} else {
|
||||
readval = tmp;
|
||||
}
|
||||
} else {
|
||||
if (i == bytelen - 1 && offsethigh) {
|
||||
tmp = tmp & ~maskhigh;
|
||||
}
|
||||
readval = (tmp << (8 * i)) | readval;
|
||||
}
|
||||
|
||||
AML_DEBUGPRINT("\n");
|
||||
/* goto to next byte... */
|
||||
if (i < bytelen - 1) {
|
||||
continue;
|
||||
}
|
||||
/* final adjustment before finishing region access */
|
||||
if (offsetlow) {
|
||||
readval = readval >> offsetlow;
|
||||
}
|
||||
AML_DEBUGPRINT("\t[read(%d, 0x%x)&mask:0x%x]\n",
|
||||
regtype, addr + i, readval);
|
||||
value = readval;
|
||||
*valuep = value;
|
||||
|
||||
break;
|
||||
case AML_REGION_OUTPUT:
|
||||
tmp = value & 0xff;
|
||||
/* the lowest byte? */
|
||||
if (i == 0) {
|
||||
if (offsetlow) {
|
||||
tmp = (val & masklow) | tmp << offsetlow;
|
||||
}
|
||||
value = value >> (8 - offsetlow);
|
||||
} else {
|
||||
if (i == bytelen - 1 && offsethigh) {
|
||||
tmp = (val & maskhigh) | tmp;
|
||||
}
|
||||
value = value >> 8;
|
||||
}
|
||||
|
||||
AML_DEBUGPRINT("->[%d:0x%02x@0x%x]\n",
|
||||
regtype, tmp, addr + i);
|
||||
val = tmp;
|
||||
|
||||
/* XXX */
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
*(volatile u_int8_t *)(vaddr + i) = val;
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
OsdOut8(addr + i, val);
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
OsdWritePciCfgByte(pci_bus, pci_devfunc,
|
||||
addr + i, val);
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
io_done:
|
||||
if (regtype == AML_REGION_SYSMEM) {
|
||||
OsdUnMapMemory((void *)vaddr, bytelen);
|
||||
}
|
||||
|
||||
aml_debug = debug; /* restore debug devel */
|
||||
|
||||
return (state);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
state = aml_region_io_system(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;
|
||||
|
||||
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;
|
||||
|
||||
state = aml_region_io_system(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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
58
sys/dev/acpi/aml/aml_region.h
Normal file
58
sys/dev/acpi/aml/aml_region.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_region.h,v 1.5 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_REGION_H_
|
||||
#define _AML_REGION_H_
|
||||
|
||||
/*
|
||||
* Region I/O subroutine
|
||||
*/
|
||||
struct aml_environ;
|
||||
|
||||
u_int32_t aml_region_read(struct aml_environ *, int, u_int32_t,
|
||||
u_int32_t, u_int32_t, u_int32_t);
|
||||
int aml_region_write(struct aml_environ *, int, u_int32_t,
|
||||
u_int32_t, u_int32_t, u_int32_t, u_int32_t);
|
||||
int aml_region_read_into_buffer(struct aml_environ *, int,
|
||||
u_int32_t, u_int32_t, u_int32_t,
|
||||
u_int32_t, u_int8_t *);
|
||||
int aml_region_write_from_buffer(struct aml_environ *, int,
|
||||
u_int32_t, u_int8_t *, u_int32_t,
|
||||
u_int32_t, u_int32_t);
|
||||
int aml_region_bcopy(struct aml_environ *, int,
|
||||
u_int32_t, u_int32_t, u_int32_t, u_int32_t,
|
||||
u_int32_t, u_int32_t, u_int32_t, u_int32_t);
|
||||
|
||||
#ifndef _KERNEL
|
||||
void aml_simulation_regdump(const char *);
|
||||
extern int aml_debug_prompt_regoutput;
|
||||
extern int aml_debug_prompt_reginput;
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* !_AML_REGION_H_ */
|
41
sys/dev/acpi/aml/aml_status.h
Normal file
41
sys/dev/acpi/aml/aml_status.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_status.h,v 1.6 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_STATUS_H_
|
||||
#define _AML_STATUS_H_
|
||||
|
||||
enum aml_status {
|
||||
aml_stat_none = 0,
|
||||
aml_stat_return,
|
||||
aml_stat_break,
|
||||
aml_stat_panic,
|
||||
aml_stat_step
|
||||
};
|
||||
|
||||
#endif /* !_AML_STATUS_H_ */
|
338
sys/dev/acpi/aml/aml_store.c
Normal file
338
sys/dev/acpi/aml/aml_store.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_store.c,v 1.22 2000/08/09 14:47:44 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_evalobj.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_region.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#else /* _KERNEL */
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static void
|
||||
aml_store_to_fieldname(struct aml_environ *env, union aml_object *obj,
|
||||
struct aml_name *name)
|
||||
{
|
||||
char *buffer;
|
||||
struct aml_name *wname, *oname;
|
||||
struct aml_field *field;
|
||||
struct aml_opregion *or;
|
||||
union aml_object tobj;
|
||||
|
||||
field = &name->property->field;
|
||||
oname = env->curname;
|
||||
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) {
|
||||
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);
|
||||
tobj.num = obj->num;
|
||||
tobj.num.number = tobj.num.number << (field->bitoffset & 7);
|
||||
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;
|
||||
}
|
||||
}
|
39
sys/dev/acpi/aml/aml_store.h
Normal file
39
sys/dev/acpi/aml/aml_store.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_store.h,v 1.8 2000/08/09 14:47:44 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_STORE_H_
|
||||
#define _AML_STORE_H_
|
||||
|
||||
void aml_store_to_name(struct aml_environ *, union aml_object *,
|
||||
struct aml_name *);
|
||||
void aml_store_to_object(struct aml_environ *, union aml_object *,
|
||||
union aml_object *);
|
||||
|
||||
#endif /* _AML_STORE_H_ */
|
34
sys/i386/i386/acpi_machdep.c
Normal file
34
sys/i386/i386/acpi_machdep.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: acpi_machdep.c,v 1.4 2000/08/08 14:12:10 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_acpi.h"
|
||||
|
||||
#ifdef ACPI_NO_OSDFUNC_INLINE
|
||||
#include <machine/acpica_osd.h>
|
||||
#endif /* ACPI_NO_OSDFUNC_INLINE */
|
325
sys/sys/acpi.h
Normal file
325
sys/sys/acpi.h
Normal file
@ -0,0 +1,325 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
|
||||
* Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: acpi.h,v 1.9 2000/08/08 14:12:16 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ACPI_H_
|
||||
#define _SYS_ACPI_H_
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/* Root System Description Pointer */
|
||||
struct ACPIrsdp {
|
||||
u_char signature[8];
|
||||
u_char sum;
|
||||
u_char oem[6];
|
||||
u_char res;
|
||||
u_int32_t addr;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* System Description Table */
|
||||
struct ACPIsdt {
|
||||
u_char signature[4];
|
||||
u_int32_t len;
|
||||
u_char rev;
|
||||
u_char check;
|
||||
u_char oemid[6];
|
||||
u_char oemtblid[8];
|
||||
u_int32_t oemrev;
|
||||
u_char creator[4];
|
||||
u_int32_t crerev;
|
||||
#define SIZEOF_SDT_HDR 36 /* struct size except body */
|
||||
u_int32_t body[1];/* This member should be casted */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Fixed ACPI Description Table (body) */
|
||||
struct FACPbody {
|
||||
u_int32_t facs_ptr;
|
||||
u_int32_t dsdt_ptr;
|
||||
u_int8_t int_model;
|
||||
#define ACPI_FACP_INTMODEL_PIC 0 /* Standard PC-AT PIC */
|
||||
#define ACPI_FACP_INTMODEL_APIC 1 /* Multiple APIC */
|
||||
u_char reserved1;
|
||||
u_int16_t sci_int;
|
||||
u_int32_t smi_cmd;
|
||||
u_int8_t acpi_enable;
|
||||
u_int8_t acpi_disable;
|
||||
u_int8_t s4biosreq;
|
||||
u_int8_t reserved2;
|
||||
u_int32_t pm1a_evt_blk;
|
||||
u_int32_t pm1b_evt_blk;
|
||||
u_int32_t pm1a_cnt_blk;
|
||||
u_int32_t pm1b_cnt_blk;
|
||||
u_int32_t pm2_cnt_blk;
|
||||
u_int32_t pm_tmr_blk;
|
||||
u_int32_t gpe0_blk;
|
||||
u_int32_t gpe1_blk;
|
||||
u_int8_t pm1_evt_len;
|
||||
u_int8_t pm1_cnt_len;
|
||||
u_int8_t pm2_cnt_len;
|
||||
u_int8_t pm_tmr_len;
|
||||
u_int8_t gpe0_len;
|
||||
u_int8_t gpe1_len;
|
||||
u_int8_t gpe1_base;
|
||||
u_int8_t reserved3;
|
||||
u_int16_t p_lvl2_lat;
|
||||
u_int16_t p_lvl3_lat;
|
||||
u_int16_t flush_size;
|
||||
u_int16_t flush_stride;
|
||||
u_int8_t duty_off;
|
||||
u_int8_t duty_width;
|
||||
u_int8_t day_alrm;
|
||||
u_int8_t mon_alrm;
|
||||
u_int8_t century;
|
||||
u_char reserved4[3];
|
||||
u_int32_t flags;
|
||||
#define ACPI_FACP_FLAG_WBINVD 1 /* WBINVD is correctly supported */
|
||||
#define ACPI_FACP_FLAG_WBINVD_FLUSH 2 /* WBINVD flushes caches */
|
||||
#define ACPI_FACP_FLAG_PROC_C1 4 /* C1 power state supported */
|
||||
#define ACPI_FACP_FLAG_P_LVL2_UP 8 /* C2 power state works on SMP */
|
||||
#define ACPI_FACP_FLAG_PWR_BUTTON 16 /* Power button uses control method */
|
||||
#define ACPI_FACP_FLAG_SLP_BUTTON 32 /* Sleep button uses control method */
|
||||
#define ACPI_FACP_FLAG_FIX_RTC 64 /* RTC wakeup not supported */
|
||||
#define ACPI_FACP_FLAG_RTC_S4 128 /* RTC can wakeup from S4 state */
|
||||
#define ACPI_FACP_FLAG_TMR_VAL_EXT 256 /* TMR_VAL is 32bit */
|
||||
#define ACPI_FACP_FLAG_DCK_CAP 512 /* Can support docking */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Firmware ACPI Control Structure */
|
||||
struct FACS {
|
||||
u_char signature[4];
|
||||
u_int32_t len;
|
||||
u_char hard_sig[4];
|
||||
/*
|
||||
* NOTE This should be filled with physical address below 1MB!!
|
||||
* sigh....
|
||||
*/
|
||||
u_int32_t firm_wake_vec;
|
||||
u_int32_t g_lock; /* bit field */
|
||||
/* 5.2.6.1 Global Lock */
|
||||
#define ACPI_GLOBAL_LOCK_PENDING 1
|
||||
#define ACPI_GLOBAL_LOCK_OWNED 2
|
||||
u_int32_t flags; /* bit field */
|
||||
#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */
|
||||
char reserved[40];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Bits for ACPI registers
|
||||
*/
|
||||
|
||||
/* Power Management 1 Event Regisers (4.7.3.1 Table 4-9, 4-10) */
|
||||
/* these bits are for status and enable regiser */
|
||||
#define ACPI_PM1_TMR_EN 0x0001
|
||||
#define ACPI_PM1_GBL_EN 0x0020
|
||||
#define ACPI_PM1_PWRBTN_EN 0x0100
|
||||
#define ACPI_PM1_SLPBTN_EN 0x0200
|
||||
#define ACPI_PM1_RTC_EN 0x0400
|
||||
#define ACPI_PM1_ALL_ENABLE_BITS 0x0721
|
||||
/* these bits are for status regiser only */
|
||||
#define ACPI_PM1_BM_STS 0x0010
|
||||
#define ACPI_PM1_WAK_STS 0x8000
|
||||
|
||||
/* Power Management 1 Control Regisers (4.7.3.2 Table 4-11) */
|
||||
#define ACPI_CNT_SCI_EN 0x0001
|
||||
#define ACPI_CNT_BM_RLD 0x0002
|
||||
#define ACPI_CNT_GBL_RLS 0x0004
|
||||
#define ACPI_CNT_SLP_TYPX 0x1c00
|
||||
#define ACPI_CNT_SLP_EN 0x2000
|
||||
|
||||
#define ACPI_CNT_SET_SLP_TYP(x) (x << 10)
|
||||
|
||||
/* Power Management Timer (4.7.3.3 Table 4-12) */
|
||||
/* Not yet */
|
||||
|
||||
/* Power Management 2 Control (4.7.3.4 Table 4-13) */
|
||||
/* Not yet */
|
||||
|
||||
/* Processor Register Block (4.7.3.5 Table 4-14, 4-15, 4-16) */
|
||||
/* Not yet */
|
||||
|
||||
#define ACPIIO_ENABLE _IO('P', 1)
|
||||
#define ACPIIO_DISABLE _IO('P', 2)
|
||||
#define ACPIIO_SETSLPSTATE _IOW('P', 3, int)
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Structure for System State Package (7.5.2).
|
||||
*/
|
||||
struct acpi_system_state_package {
|
||||
struct {
|
||||
u_int8_t slp_typ_a; /* 3-bit only. */
|
||||
u_int8_t slp_typ_b; /* (4.7.3.2.1) */
|
||||
} mode[6];
|
||||
};
|
||||
#define ACPI_UNSUPPORTSLPTYP 0xff /* unsupported sleeping type */
|
||||
|
||||
extern struct ACPIrsdp *acpi_rsdp; /* ACPI Root System Description Table */
|
||||
|
||||
void acpi_init_addr_range(void);
|
||||
void acpi_register_addr_range(u_int64_t, u_int64_t, u_int32_t);
|
||||
|
||||
/*
|
||||
* ACPICA compatibility
|
||||
*/
|
||||
#ifdef _IA64
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef int INT32;
|
||||
typedef unsigned int UINT32;
|
||||
typedef long INT64;
|
||||
typedef unsigned long UINT64;
|
||||
|
||||
typedef UINT64 NATIVE_UINT;
|
||||
typedef INT64 NATIVE_INT;
|
||||
|
||||
typedef NATIVE_UINT ACPI_TBLPTR;
|
||||
#else /* !_IA64 */
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef int INT32;
|
||||
typedef unsigned int UINT32;
|
||||
|
||||
typedef UINT32 NATIVE_UINT;
|
||||
typedef INT32 NATIVE_INT;
|
||||
|
||||
typedef NATIVE_UINT ACPI_TBLPTR;
|
||||
#endif /* _IA64 */
|
||||
|
||||
/* common types */
|
||||
typedef NATIVE_UINT ACPI_IO_ADDRESS;
|
||||
typedef UINT32 ACPI_STATUS;
|
||||
|
||||
/*
|
||||
* Exceptions returned by external ACPI interfaces
|
||||
*/
|
||||
|
||||
#define ACPI_SUCCESS(a) (!(a))
|
||||
#define ACPI_FAILURE(a) (a)
|
||||
|
||||
#define AE_OK (ACPI_STATUS) 0x0000
|
||||
#define AE_CTRL_RETURN_VALUE (ACPI_STATUS) 0x0001
|
||||
#define AE_CTRL_PENDING (ACPI_STATUS) 0x0002
|
||||
#define AE_CTRL_TERMINATE (ACPI_STATUS) 0x0003
|
||||
#define AE_CTRL_TRUE (ACPI_STATUS) 0x0004
|
||||
#define AE_CTRL_FALSE (ACPI_STATUS) 0x0005
|
||||
#define AE_CTRL_DEPTH (ACPI_STATUS) 0x0006
|
||||
#define AE_CTRL_RESERVED (ACPI_STATUS) 0x0007
|
||||
#define AE_AML_ERROR (ACPI_STATUS) 0x0008
|
||||
#define AE_AML_PARSE (ACPI_STATUS) 0x0009
|
||||
#define AE_AML_BAD_OPCODE (ACPI_STATUS) 0x000A
|
||||
#define AE_AML_NO_OPERAND (ACPI_STATUS) 0x000B
|
||||
#define AE_AML_OPERAND_TYPE (ACPI_STATUS) 0x000C
|
||||
#define AE_AML_OPERAND_VALUE (ACPI_STATUS) 0x000D
|
||||
#define AE_AML_UNINITIALIZED_LOCAL (ACPI_STATUS) 0x000E
|
||||
#define AE_AML_UNINITIALIZED_ARG (ACPI_STATUS) 0x000F
|
||||
#define AE_AML_UNINITIALIZED_ELEMENT (ACPI_STATUS) 0x0010
|
||||
#define AE_AML_NUMERIC_OVERFLOW (ACPI_STATUS) 0x0011
|
||||
#define AE_AML_REGION_LIMIT (ACPI_STATUS) 0x0012
|
||||
#define AE_AML_BUFFER_LIMIT (ACPI_STATUS) 0x0013
|
||||
#define AE_AML_PACKAGE_LIMIT (ACPI_STATUS) 0x0014
|
||||
#define AE_AML_DIVIDE_BY_ZERO (ACPI_STATUS) 0x0015
|
||||
#define AE_AML_BAD_NAME (ACPI_STATUS) 0x0016
|
||||
#define AE_AML_NAME_NOT_FOUND (ACPI_STATUS) 0x0017
|
||||
#define AE_AML_INTERNAL (ACPI_STATUS) 0x0018
|
||||
#define AE_AML_RESERVED (ACPI_STATUS) 0x0019
|
||||
#define AE_ERROR (ACPI_STATUS) 0x001A
|
||||
#define AE_NO_ACPI_TABLES (ACPI_STATUS) 0x001B
|
||||
#define AE_NO_NAMESPACE (ACPI_STATUS) 0x001C
|
||||
#define AE_NO_MEMORY (ACPI_STATUS) 0x001D
|
||||
#define AE_BAD_SIGNATURE (ACPI_STATUS) 0x001E
|
||||
#define AE_BAD_HEADER (ACPI_STATUS) 0x001F
|
||||
#define AE_BAD_CHECKSUM (ACPI_STATUS) 0x0020
|
||||
#define AE_BAD_PARAMETER (ACPI_STATUS) 0x0021
|
||||
#define AE_BAD_CHARACTER (ACPI_STATUS) 0x0022
|
||||
#define AE_BAD_PATHNAME (ACPI_STATUS) 0x0023
|
||||
#define AE_BAD_DATA (ACPI_STATUS) 0x0024
|
||||
#define AE_BAD_ADDRESS (ACPI_STATUS) 0x0025
|
||||
#define AE_NOT_FOUND (ACPI_STATUS) 0x0026
|
||||
#define AE_NOT_EXIST (ACPI_STATUS) 0x0027
|
||||
#define AE_EXIST (ACPI_STATUS) 0x0028
|
||||
#define AE_TYPE (ACPI_STATUS) 0x0029
|
||||
#define AE_NULL_OBJECT (ACPI_STATUS) 0x002A
|
||||
#define AE_NULL_ENTRY (ACPI_STATUS) 0x002B
|
||||
#define AE_BUFFER_OVERFLOW (ACPI_STATUS) 0x002C
|
||||
#define AE_STACK_OVERFLOW (ACPI_STATUS) 0x002D
|
||||
#define AE_STACK_UNDERFLOW (ACPI_STATUS) 0x002E
|
||||
#define AE_NOT_IMPLEMENTED (ACPI_STATUS) 0x002F
|
||||
#define AE_VERSION_MISMATCH (ACPI_STATUS) 0x0030
|
||||
#define AE_SUPPORT (ACPI_STATUS) 0x0031
|
||||
#define AE_SHARE (ACPI_STATUS) 0x0032
|
||||
#define AE_LIMIT (ACPI_STATUS) 0x0033
|
||||
#define AE_TIME (ACPI_STATUS) 0x0034
|
||||
#define AE_UNKNOWN_STATUS (ACPI_STATUS) 0x0035
|
||||
#define ACPI_MAX_STATUS (ACPI_STATUS) 0x0035
|
||||
#define ACPI_NUM_STATUS (ACPI_STATUS) 0x0036
|
||||
|
||||
/*
|
||||
* ACPICA Osd family functions
|
||||
*/
|
||||
|
||||
#ifdef ACPI_NO_OSDFUNC_INLINE
|
||||
ACPI_STATUS OsdMapMemory(void *, UINT32, void **);
|
||||
void OsdUnMapMemory(void *, UINT32);
|
||||
|
||||
UINT8 OsdIn8(ACPI_IO_ADDRESS);
|
||||
UINT16 OsdIn16(ACPI_IO_ADDRESS);
|
||||
UINT32 OsdIn32(ACPI_IO_ADDRESS);
|
||||
void OsdOut8(ACPI_IO_ADDRESS, UINT8);
|
||||
void OsdOut16(ACPI_IO_ADDRESS, UINT16);
|
||||
void OsdOut32(ACPI_IO_ADDRESS, UINT32);
|
||||
|
||||
ACPI_STATUS OsdReadPciCfgByte(UINT32, UINT32 , UINT32 , UINT8 *);
|
||||
ACPI_STATUS OsdReadPciCfgWord(UINT32, UINT32 , UINT32 , UINT16 *);
|
||||
ACPI_STATUS OsdReadPciCfgDword(UINT32, UINT32 , UINT32 , UINT32 *);
|
||||
ACPI_STATUS OsdWritePciCfgByte(UINT32, UINT32 , UINT32 , UINT8);
|
||||
ACPI_STATUS OsdWritePciCfgWord(UINT32, UINT32 , UINT32 , UINT16);
|
||||
ACPI_STATUS OsdWritePciCfgDword(UINT32, UINT32 , UINT32 , UINT32);
|
||||
#endif /* ACPI_NO_OSDFUNC_INLINE */
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
void *acpi_map_physical(vm_offset_t, size_t);
|
||||
struct ACPIrsdp *acpi_find_rsd_ptr(void);
|
||||
int acpi_checksum(void *, size_t);
|
||||
struct ACPIsdt *acpi_map_sdt(vm_offset_t);
|
||||
void acpi_print_rsd_ptr(struct ACPIrsdp *);
|
||||
void acpi_print_sdt(struct ACPIsdt *);
|
||||
void acpi_print_rsdt(struct ACPIsdt *);
|
||||
void acpi_print_facp(struct FACPbody *);
|
||||
void acpi_print_dsdt(struct ACPIsdt *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _SYS_ACPI_H_ */
|
92
usr.sbin/acpi/amldb/aml/aml_amlmem.c
Normal file
92
usr.sbin/acpi/amldb/aml/aml_amlmem.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_amlmem.c,v 1.15 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* AML Namespace Memory Management
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_memman.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_namestr, _aml_namestr_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_num, _aml_num_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_string, _aml_string_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_buffer, _aml_buffer_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_package, _aml_package_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_field, _aml_field_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_method, _aml_method_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex, _aml_mutex_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_opregion, _aml_opregion_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_powerres, _aml_powerres_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_processor, _aml_processor_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_bufferfield, _aml_bufferfield_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_event, _aml_event_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(enum aml_objtype, _aml_objtype_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_name, _aml_name_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_name_group, _aml_name_group_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_objref, _aml_objref_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_regfield, _aml_regfield_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_environ, _aml_environ_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_local_stack, _aml_local_stack_storage);
|
||||
MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex_queue, _aml_mutex_queue_storage);
|
||||
|
||||
struct memman_blockman aml_blockman[] = {
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_namestr), _aml_namestr_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_num), _aml_num_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_string), _aml_string_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_buffer), _aml_buffer_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_package), _aml_package_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_field), _aml_field_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_method), _aml_method_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex), _aml_mutex_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_opregion), _aml_opregion_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_powerres), _aml_powerres_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_processor), _aml_processor_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_bufferfield), _aml_bufferfield_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_event), _aml_event_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(enum aml_objtype), _aml_objtype_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name), _aml_name_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name_group), _aml_name_group_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_objref), _aml_objref_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_regfield), _aml_regfield_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_environ), _aml_environ_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_local_stack), _aml_local_stack_storage),
|
||||
MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex_queue), _aml_mutex_queue_storage),
|
||||
};
|
||||
|
||||
struct memman_histogram aml_histogram[MEMMAN_HISTOGRAM_SIZE];
|
||||
|
||||
static struct memman _aml_memman = MEMMAN_MEMMANAGER_DESC(aml_blockman, 21,
|
||||
aml_histogram, 1);
|
||||
|
||||
struct memman *aml_memman = &_aml_memman;
|
||||
|
65
usr.sbin/acpi/amldb/aml/aml_amlmem.h
Normal file
65
usr.sbin/acpi/amldb/aml/aml_amlmem.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_amlmem.h,v 1.12 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_AMLMEM_H_
|
||||
#define _AML_AMLMEM_H_
|
||||
|
||||
/*
|
||||
* AML Namespace Memory Management
|
||||
*/
|
||||
|
||||
#include <dev/acpi/aml/aml_memman.h>
|
||||
|
||||
enum {
|
||||
memid_aml_namestr = 0,
|
||||
memid_aml_num,
|
||||
memid_aml_string,
|
||||
memid_aml_buffer,
|
||||
memid_aml_package,
|
||||
memid_aml_field,
|
||||
memid_aml_method,
|
||||
memid_aml_mutex,
|
||||
memid_aml_opregion,
|
||||
memid_aml_powerres,
|
||||
memid_aml_processor,
|
||||
memid_aml_bufferfield,
|
||||
memid_aml_event,
|
||||
memid_aml_objtype,
|
||||
memid_aml_name,
|
||||
memid_aml_name_group,
|
||||
memid_aml_objref,
|
||||
memid_aml_regfield,
|
||||
memid_aml_environ,
|
||||
memid_aml_local_stack,
|
||||
memid_aml_mutex_queue,
|
||||
};
|
||||
|
||||
extern struct memman *aml_memman;
|
||||
|
||||
#endif /* !_AML_AMLMEM_H_ */
|
406
usr.sbin/acpi/amldb/aml/aml_common.c
Normal file
406
usr.sbin/acpi/amldb/aml/aml_common.c
Normal file
@ -0,0 +1,406 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_common.c,v 1.9 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#else /* _KERNEL */
|
||||
#include "opt_acpi.h"
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_evalobj.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_parse.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
/* for debugging */
|
||||
#ifdef AML_DEBUG
|
||||
int aml_debug = 1;
|
||||
#else /* !AML_DEBUG */
|
||||
int aml_debug = 0;
|
||||
#endif /* AML_DEBUG */
|
||||
#ifdef _KERNEL
|
||||
SYSCTL_INT(_debug, OID_AUTO, aml_debug, CTLFLAG_RW, &aml_debug, 1, "");
|
||||
#endif /* _KERNEL */
|
||||
|
||||
static void aml_print_nameseg(u_int8_t *dp);
|
||||
|
||||
static void
|
||||
aml_print_nameseg(u_int8_t *dp)
|
||||
{
|
||||
|
||||
if (dp[3] != '_') {
|
||||
AML_DEBUGPRINT("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]);
|
||||
} else if (dp[2] != '_') {
|
||||
AML_DEBUGPRINT("%c%c%c_", dp[0], dp[1], dp[2]);
|
||||
} else if (dp[1] != '_') {
|
||||
AML_DEBUGPRINT("%c%c__", dp[0], dp[1]);
|
||||
} else if (dp[0] != '_') {
|
||||
AML_DEBUGPRINT("%c___", dp[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aml_print_namestring(u_int8_t *dp)
|
||||
{
|
||||
int segcount;
|
||||
int i;
|
||||
|
||||
if (dp[0] == '\\') {
|
||||
AML_DEBUGPRINT("%c", dp[0]);
|
||||
dp++;
|
||||
} else if (dp[0] == '^') {
|
||||
while (dp[0] == '^') {
|
||||
AML_DEBUGPRINT("%c", dp[0]);
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
if (dp[0] == 0x00) { /* NullName */
|
||||
/* AML_DEBUGPRINT("<null>"); */
|
||||
dp++;
|
||||
} else if (dp[0] == 0x2e) { /* DualNamePrefix */
|
||||
aml_print_nameseg(dp + 1);
|
||||
AML_DEBUGPRINT("%c", '.');
|
||||
aml_print_nameseg(dp + 5);
|
||||
} else if (dp[0] == 0x2f) { /* MultiNamePrefix */
|
||||
segcount = dp[1];
|
||||
for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
|
||||
if (i > 0) {
|
||||
AML_DEBUGPRINT("%c", '.');
|
||||
}
|
||||
aml_print_nameseg(dp);
|
||||
}
|
||||
} else /* NameSeg */
|
||||
aml_print_nameseg(dp);
|
||||
}
|
||||
|
||||
int
|
||||
aml_print_curname(struct aml_name *name)
|
||||
{
|
||||
struct aml_name *root;
|
||||
|
||||
root = aml_get_rootname();
|
||||
if (name == root) {
|
||||
AML_DEBUGPRINT("\\");
|
||||
return (0);
|
||||
} else {
|
||||
aml_print_curname(name->parent);
|
||||
}
|
||||
aml_print_nameseg(name->name);
|
||||
AML_DEBUGPRINT(".");
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
aml_print_indent(int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
AML_DEBUGPRINT(" ");
|
||||
}
|
||||
|
||||
void
|
||||
aml_showobject(union aml_object * obj)
|
||||
{
|
||||
int debug;
|
||||
int i;
|
||||
|
||||
if (obj == NULL) {
|
||||
printf("NO object\n");
|
||||
return;
|
||||
}
|
||||
debug = aml_debug;
|
||||
aml_debug = 1;
|
||||
switch (obj->type) {
|
||||
case aml_t_num:
|
||||
printf("Num:0x%x\n", obj->num.number);
|
||||
break;
|
||||
case aml_t_processor:
|
||||
printf("Processor:No %d,Port 0x%x length 0x%x\n",
|
||||
obj->proc.id, obj->proc.addr, obj->proc.len);
|
||||
break;
|
||||
case aml_t_mutex:
|
||||
printf("Mutex:Level %d\n", obj->mutex.level);
|
||||
break;
|
||||
case aml_t_powerres:
|
||||
printf("PowerResource:Level %d Order %d\n",
|
||||
obj->pres.level, obj->pres.order);
|
||||
break;
|
||||
case aml_t_opregion:
|
||||
printf("OprationRegion:Busspace%d, Offset 0x%x Length 0x%x\n",
|
||||
obj->opregion.space, obj->opregion.offset,
|
||||
obj->opregion.length);
|
||||
break;
|
||||
case aml_t_field:
|
||||
printf("Fieldelement:flag 0x%x offset 0x%x len 0x%x {",
|
||||
obj->field.flags, obj->field.bitoffset,
|
||||
obj->field.bitlen);
|
||||
switch (obj->field.f.ftype) {
|
||||
case f_t_field:
|
||||
aml_print_namestring(obj->field.f.fld.regname);
|
||||
break;
|
||||
case f_t_index:
|
||||
aml_print_namestring(obj->field.f.ifld.indexname);
|
||||
printf(" ");
|
||||
aml_print_namestring(obj->field.f.ifld.dataname);
|
||||
break;
|
||||
case f_t_bank:
|
||||
aml_print_namestring(obj->field.f.bfld.regname);
|
||||
printf(" ");
|
||||
aml_print_namestring(obj->field.f.bfld.bankname);
|
||||
printf("0x%x", obj->field.f.bfld.bankvalue);
|
||||
break;
|
||||
}
|
||||
printf("}\n");
|
||||
break;
|
||||
case aml_t_method:
|
||||
printf("Method: Arg %d From %p To %p\n", obj->meth.argnum,
|
||||
obj->meth.from, obj->meth.to);
|
||||
break;
|
||||
case aml_t_buffer:
|
||||
printf("Buffer: size:0x%x Data %p\n", obj->buffer.size,
|
||||
obj->buffer.data);
|
||||
break;
|
||||
case aml_t_device:
|
||||
printf("Device\n");
|
||||
break;
|
||||
case aml_t_bufferfield:
|
||||
printf("Bufferfield:offset 0x%x len 0x%x Origin %p\n",
|
||||
obj->bfld.bitoffset, obj->bfld.bitlen, obj->bfld.origin);
|
||||
break;
|
||||
case aml_t_string:
|
||||
printf("String:%s\n", obj->str.string);
|
||||
break;
|
||||
case aml_t_package:
|
||||
printf("Package:elements %d \n", obj->package.elements);
|
||||
for (i = 0; i < obj->package.elements; i++) {
|
||||
if (obj->package.objects[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
if (obj->package.objects[i]->type < 0) {
|
||||
continue;
|
||||
}
|
||||
printf(" ");
|
||||
aml_showobject(obj->package.objects[i]);
|
||||
}
|
||||
break;
|
||||
case aml_t_therm:
|
||||
printf("Thermalzone\n");
|
||||
break;
|
||||
case aml_t_event:
|
||||
printf("Event\n");
|
||||
break;
|
||||
case aml_t_ddbhandle:
|
||||
printf("DDBHANDLE\n");
|
||||
break;
|
||||
case aml_t_objref:
|
||||
if (obj->objref.alias == 1) {
|
||||
printf("Alias");
|
||||
} else {
|
||||
printf("Object reference");
|
||||
if (obj->objref.offset >= 0) {
|
||||
printf(" (offset 0x%x)", obj->objref.offset);
|
||||
}
|
||||
}
|
||||
printf(" of ");
|
||||
aml_showobject(obj->objref.ref);
|
||||
break;
|
||||
default:
|
||||
printf("UNK ID=%d\n", obj->type);
|
||||
}
|
||||
|
||||
aml_debug = debug;
|
||||
}
|
||||
|
||||
void
|
||||
aml_showtree(struct aml_name * aname, int lev)
|
||||
{
|
||||
int i;
|
||||
struct aml_name *ptr;
|
||||
char name[5];
|
||||
|
||||
for (i = 0; i < lev; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
strncpy(name, aname->name, 4);
|
||||
name[4] = 0;
|
||||
printf("%s ", name);
|
||||
if (aname->property != NULL) {
|
||||
aml_showobject(aname->property);
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
for (ptr = aname->child; ptr; ptr = ptr->brother)
|
||||
aml_showtree(ptr, lev + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 value = *valuep, readval;
|
||||
int i;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
75
usr.sbin/acpi/amldb/aml/aml_common.h
Normal file
75
usr.sbin/acpi/amldb/aml/aml_common.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_common.h,v 1.4 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_COMMON_H_
|
||||
#define _AML_COMMON_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define AML_SYSABORT() do { \
|
||||
printf("aml: fatal errer at %s:%d\n", __FILE__, __LINE__); \
|
||||
panic("panic in AML interpreter!"); \
|
||||
} while(0)
|
||||
#define AML_SYSASSERT(x) do { \
|
||||
if (!(x)) { \
|
||||
AML_SYSABORT(); \
|
||||
} \
|
||||
} while(0)
|
||||
#define AML_SYSERRX(eval, fmt, args...) do { \
|
||||
printf(fmt, args); \
|
||||
} while(0)
|
||||
#define AML_DEBUGGER(x, y) /* no debugger in kernel */
|
||||
#else /* !_KERNEL */
|
||||
#define AML_SYSASSERT(x) assert(x)
|
||||
#define AML_SYSABORT() abort()
|
||||
#define AML_SYSERRX(eval, fmt, args...) errx(eval, fmt, args)
|
||||
#define AML_DEBUGGER(x, y) aml_dbgr(x, y)
|
||||
#endif /* _KERNEL */
|
||||
|
||||
union aml_object;
|
||||
struct aml_name;
|
||||
|
||||
extern int aml_debug;
|
||||
|
||||
#define AML_DEBUGPRINT(args...) do { \
|
||||
if (aml_debug) { \
|
||||
printf(args); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
void aml_showobject(union aml_object *);
|
||||
void aml_showtree(struct aml_name *, int);
|
||||
int aml_print_curname(struct aml_name *);
|
||||
void aml_print_namestring(u_int8_t *);
|
||||
void aml_print_indent(int);
|
||||
|
||||
u_int32_t aml_bufferfield_read(u_int8_t *, u_int32_t, u_int32_t);
|
||||
int aml_bufferfield_write(u_int32_t, u_int8_t *,
|
||||
u_int32_t, u_int32_t);
|
||||
|
||||
#endif /* !_AML_COMMON_H_ */
|
46
usr.sbin/acpi/amldb/aml/aml_env.h
Normal file
46
usr.sbin/acpi/amldb/aml/aml_env.h
Normal file
@ -0,0 +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 <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
|
||||
struct aml_environ {
|
||||
u_int8_t *dp;
|
||||
u_int8_t *end;
|
||||
enum aml_status stat;
|
||||
struct aml_name *curname;
|
||||
struct aml_name tempname;
|
||||
union aml_object tempobject;
|
||||
};
|
||||
|
||||
#endif /* !_AML_ENV_H_ */
|
421
usr.sbin/acpi/amldb/aml/aml_evalobj.c
Normal file
421
usr.sbin/acpi/amldb/aml/aml_evalobj.c
Normal file
@ -0,0 +1,421 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_evalobj.c,v 1.27 2000/08/16 18:14:53 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_evalobj.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_parse.h>
|
||||
#include <dev/acpi/aml/aml_region.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#else /* _KERNEL */
|
||||
#include <sys/bus.h>
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static union aml_object *aml_eval_fieldobject(struct aml_environ *env,
|
||||
struct aml_name *name);
|
||||
|
||||
static union aml_object *
|
||||
aml_eval_fieldobject(struct aml_environ *env, struct aml_name *name)
|
||||
{
|
||||
struct aml_name *oname,*wname;
|
||||
struct aml_field *field;
|
||||
struct aml_opregion *or;
|
||||
union aml_object tobj;
|
||||
|
||||
/* 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);
|
||||
aml_eval_name(env, wname);
|
||||
}
|
||||
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_by_name(char *method, int argc, union aml_object *argv)
|
||||
{
|
||||
int i;
|
||||
struct aml_name *name;
|
||||
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));
|
||||
name = aml_find_from_namespace(aml_get_rootname(), method);
|
||||
|
||||
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);
|
||||
}
|
46
usr.sbin/acpi/amldb/aml/aml_evalobj.h
Normal file
46
usr.sbin/acpi/amldb/aml/aml_evalobj.h
Normal file
@ -0,0 +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_evalobj.h,v 1.11 2000/08/16 18:14:53 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_EVALOBJ_H_
|
||||
#define _AML_EVALOBJ_H_
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
union aml_object *aml_eval_objref(struct aml_environ *,
|
||||
union aml_object *);
|
||||
union aml_object *aml_eval_name(struct aml_environ *,
|
||||
struct aml_name *);
|
||||
int aml_eval_name_simple(struct aml_name *, va_list);
|
||||
int aml_objtonum(struct aml_environ *,
|
||||
union aml_object *);
|
||||
struct aml_name *aml_execute_method(struct aml_environ *);
|
||||
union aml_object *aml_invoke_method_by_name(char *,
|
||||
int, union aml_object *);
|
||||
|
||||
#endif /* !_AML_EVALOBJ_H_ */
|
476
usr.sbin/acpi/amldb/aml/aml_memman.c
Normal file
476
usr.sbin/acpi/amldb/aml/aml_memman.c
Normal file
@ -0,0 +1,476 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_memman.c,v 1.10 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic Memory Management
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_memman.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#else /* _KERNEL */
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
MALLOC_DEFINE(M_MEMMAN, "memman", "Generic and Simple Memory Management");
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
unsigned int memid_unkown = 255;
|
||||
|
||||
static int manage_block(struct memman *memman, unsigned int id,
|
||||
void *block, unsigned static_mem,
|
||||
unsigned entries);
|
||||
static int blockman_init(struct memman *memman, unsigned int id);
|
||||
static void memman_flexsize_add_histogram(struct memman *memman,
|
||||
size_t size,
|
||||
int tolerance);
|
||||
static int memman_comp_histogram_size(const void *a,
|
||||
const void *b);
|
||||
static void memman_sort_histogram_by_size(struct memman *memman);
|
||||
static unsigned int memman_guess_memid(struct memman *memman, void *chunk);
|
||||
static void memman_statistics_fixedsize(struct memman *memman);
|
||||
static void memman_statistics_flexsize(struct memman *memman);
|
||||
|
||||
static int
|
||||
manage_block(struct memman *memman, unsigned int id, void *block,
|
||||
unsigned static_mem, unsigned entries)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t alloc_size;
|
||||
void *tmp, *realblock;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_block *memblock;
|
||||
struct memman_node *memnodes;
|
||||
|
||||
bmp = &memman->blockman[id];
|
||||
alloc_size = MEMMAN_BLOCKNODE_SIZE(entries);
|
||||
|
||||
if (static_mem) {
|
||||
tmp = (void *)block;
|
||||
realblock = (char *)block + alloc_size;
|
||||
} else {
|
||||
tmp = MEMMAN_SYSMALLOC(alloc_size);
|
||||
if (!tmp) {
|
||||
return (-1);
|
||||
}
|
||||
realblock = block;
|
||||
|
||||
memman->allocated_mem += alloc_size;
|
||||
memman->salloc_called++;
|
||||
}
|
||||
|
||||
memblock = (struct memman_block *)tmp;
|
||||
memnodes = (struct memman_node *)((char *)tmp + sizeof(struct memman_block));
|
||||
|
||||
memblock->block = realblock;
|
||||
memblock->static_mem = static_mem;
|
||||
memblock->allocated = entries;
|
||||
memblock->available = entries;
|
||||
if (!static_mem) {
|
||||
alloc_size += roundup(bmp->size * entries, ROUNDUP_UNIT);
|
||||
}
|
||||
memblock->allocated_mem = alloc_size;
|
||||
LIST_INSERT_HEAD(&bmp->block_list, memblock, links);
|
||||
|
||||
for (i = 0; i < entries; ++i) {
|
||||
memnodes[i].node = ((char *)realblock + (i * (bmp->size)));
|
||||
memnodes[i].memblock = memblock;
|
||||
LIST_INSERT_HEAD(&bmp->free_node_list, &memnodes[i], links);
|
||||
}
|
||||
bmp->available = entries;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
blockman_init(struct memman *memman, unsigned int id)
|
||||
{
|
||||
int status;
|
||||
struct memman_blockman *bmp;
|
||||
|
||||
bmp = &memman->blockman[id];
|
||||
bmp->initialized = 1;
|
||||
LIST_INIT(&bmp->block_list);
|
||||
LIST_INIT(&bmp->free_node_list);
|
||||
LIST_INIT(&bmp->occupied_node_list);
|
||||
status = manage_block(memman, id, bmp->initial_block,
|
||||
1, MEMMAN_INITIAL_SIZE);
|
||||
return (status);
|
||||
}
|
||||
|
||||
void *
|
||||
memman_alloc(struct memman *memman, unsigned int id)
|
||||
{
|
||||
size_t alloc_size;
|
||||
void *chunk, *block;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_node *memnode;
|
||||
|
||||
if (memman->max_memid <= id) {
|
||||
printf("memman_alloc: invalid memory type id\n");
|
||||
return (NULL);
|
||||
}
|
||||
bmp = &memman->blockman[id];
|
||||
if (!bmp->initialized) {
|
||||
if (blockman_init(memman, id)) {
|
||||
goto malloc_fail;
|
||||
}
|
||||
}
|
||||
memman->alloc_called++;
|
||||
|
||||
if (bmp->available == 0) {
|
||||
alloc_size = roundup(bmp->size * MEMMAN_INCR_SIZE,
|
||||
ROUNDUP_UNIT);
|
||||
block = MEMMAN_SYSMALLOC(alloc_size);
|
||||
if (!block) {
|
||||
goto malloc_fail;
|
||||
}
|
||||
memman->required_mem += bmp->size * MEMMAN_INCR_SIZE;
|
||||
memman->allocated_mem += alloc_size;
|
||||
memman->salloc_called++;
|
||||
|
||||
if (manage_block(memman, id, block, 0, MEMMAN_INCR_SIZE)) {
|
||||
goto malloc_fail;
|
||||
}
|
||||
}
|
||||
memnode = LIST_FIRST(&bmp->free_node_list);
|
||||
LIST_REMOVE(memnode, links);
|
||||
chunk = memnode->node;
|
||||
LIST_INSERT_HEAD(&bmp->occupied_node_list, memnode, links);
|
||||
memnode->memblock->available--;
|
||||
bmp->available--;
|
||||
|
||||
return (chunk);
|
||||
|
||||
malloc_fail:
|
||||
printf("memman_alloc: could not allocate memory\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
memman_flexsize_add_histogram(struct memman *memman, size_t size,
|
||||
int tolerance)
|
||||
{
|
||||
int i;
|
||||
int gap;
|
||||
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
|
||||
gap = memman->flex_mem_histogram[i].mem_size - size;
|
||||
if (gap >= (tolerance * -1) && gap <= tolerance) {
|
||||
memman->flex_mem_histogram[i].count++;
|
||||
if (memman->flex_mem_histogram[i].mem_size < size) {
|
||||
memman->flex_mem_histogram[i].mem_size = size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (memman->flex_mem_histogram_ptr == MEMMAN_HISTOGRAM_SIZE) {
|
||||
memman_flexsize_add_histogram(memman, size, tolerance + 1);
|
||||
return;
|
||||
}
|
||||
i = memman->flex_mem_histogram_ptr;
|
||||
memman->flex_mem_histogram[i].mem_size = size;
|
||||
memman->flex_mem_histogram[i].count = 1;
|
||||
memman->flex_mem_histogram_ptr++;
|
||||
}
|
||||
|
||||
static int
|
||||
memman_comp_histogram_size(const void *a, const void *b)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = ((const struct memman_histogram *)a)->mem_size -
|
||||
((const struct memman_histogram *)b)->mem_size;
|
||||
return (delta);
|
||||
}
|
||||
|
||||
static void
|
||||
memman_sort_histogram_by_size(struct memman *memman)
|
||||
{
|
||||
qsort(memman->flex_mem_histogram, memman->flex_mem_histogram_ptr,
|
||||
sizeof(struct memman_histogram), memman_comp_histogram_size);
|
||||
}
|
||||
|
||||
void *
|
||||
memman_alloc_flexsize(struct memman *memman, size_t size)
|
||||
{
|
||||
void *mem;
|
||||
struct memman_flexmem_info *info;
|
||||
|
||||
if (size == 0) {
|
||||
return (NULL);
|
||||
}
|
||||
if ((mem = MEMMAN_SYSMALLOC(size)) != NULL) { /* XXX */
|
||||
|
||||
info = MEMMAN_SYSMALLOC(sizeof(struct memman_flexmem_info));
|
||||
if (info) {
|
||||
if (!memman->flex_mem_initialized) {
|
||||
LIST_INIT(&memman->flexmem_info_list);
|
||||
bzero(memman->flex_mem_histogram,
|
||||
sizeof(struct memman_histogram));
|
||||
memman->flex_mem_initialized = 1;
|
||||
}
|
||||
info->addr = mem;
|
||||
info->mem_size = size;
|
||||
LIST_INSERT_HEAD(&memman->flexmem_info_list, info, links);
|
||||
}
|
||||
memman->flex_alloc_called++;
|
||||
memman->flex_salloc_called++;
|
||||
memman->flex_required_mem += size;
|
||||
memman->flex_allocated_mem += size;
|
||||
if (memman->flex_mem_size_min == 0 ||
|
||||
memman->flex_mem_size_min > size) {
|
||||
memman->flex_mem_size_min = size;
|
||||
}
|
||||
if (memman->flex_mem_size_max < size) {
|
||||
memman->flex_mem_size_max = size;
|
||||
}
|
||||
if (memman->flex_peak_mem_usage <
|
||||
(memman->flex_allocated_mem - memman->flex_reclaimed_mem)) {
|
||||
memman->flex_peak_mem_usage =
|
||||
(memman->flex_allocated_mem - memman->flex_reclaimed_mem);
|
||||
}
|
||||
memman_flexsize_add_histogram(memman, size,
|
||||
memman->flex_mem_histogram_initial_tolerance);
|
||||
}
|
||||
return (mem);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
memman_guess_memid(struct memman *memman, void *chunk)
|
||||
{
|
||||
unsigned int id;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_node *memnode;
|
||||
|
||||
for (id = 0; id < memman->max_memid; id++) {
|
||||
bmp = &memman->blockman[id];
|
||||
if (!bmp->initialized) {
|
||||
if (blockman_init(memman, id)) {
|
||||
printf("memman_free: could not initialized\n");
|
||||
}
|
||||
}
|
||||
LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
|
||||
if (memnode->node == chunk) {
|
||||
return (id); /* got it! */
|
||||
}
|
||||
}
|
||||
}
|
||||
return (memid_unkown); /* gave up */
|
||||
}
|
||||
|
||||
void
|
||||
memman_free(struct memman *memman, unsigned int memid, void *chunk)
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned found;
|
||||
void *block;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_block *memblock;
|
||||
struct memman_node *memnode;
|
||||
|
||||
id = memid;
|
||||
if (memid == memid_unkown) {
|
||||
id = memman_guess_memid(memman, chunk);
|
||||
}
|
||||
if (memman->max_memid <= id) {
|
||||
printf("memman_free: invalid memory type id\n");
|
||||
MEMMAN_SYSABORT();
|
||||
return;
|
||||
}
|
||||
bmp = &memman->blockman[id];
|
||||
if (!bmp->initialized) {
|
||||
if (blockman_init(memman, id)) {
|
||||
printf("memman_free: could not initialized\n");
|
||||
}
|
||||
}
|
||||
found = 0;
|
||||
LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
|
||||
if (memnode->node == chunk) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
printf("memman_free: invalid address\n");
|
||||
return;
|
||||
}
|
||||
memman->free_called++;
|
||||
|
||||
LIST_REMOVE(memnode, links);
|
||||
memblock = memnode->memblock;
|
||||
memblock->available++;
|
||||
LIST_INSERT_HEAD(&bmp->free_node_list, memnode, links);
|
||||
bmp->available++;
|
||||
|
||||
if (!memblock->static_mem &&
|
||||
memblock->available == memblock->allocated) {
|
||||
LIST_FOREACH(memnode, &bmp->free_node_list, links) {
|
||||
if (memnode->memblock != memblock) {
|
||||
continue;
|
||||
}
|
||||
LIST_REMOVE(memnode, links);
|
||||
bmp->available--;
|
||||
}
|
||||
block = memblock->block;
|
||||
MEMMAN_SYSFREE(block);
|
||||
memman->sfree_called++;
|
||||
|
||||
LIST_REMOVE(memblock, links);
|
||||
memman->sfree_called++;
|
||||
memman->reclaimed_mem += memblock->allocated_mem;
|
||||
MEMMAN_SYSFREE(memblock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
memman_free_flexsize(struct memman *memman, void *chunk)
|
||||
{
|
||||
struct memman_flexmem_info *info;
|
||||
|
||||
LIST_FOREACH(info, &memman->flexmem_info_list, links) {
|
||||
if (info->addr == chunk) {
|
||||
memman->flex_reclaimed_mem += info->mem_size;
|
||||
LIST_REMOVE(info, links);
|
||||
MEMMAN_SYSFREE(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* XXX */
|
||||
memman->flex_free_called++;
|
||||
memman->flex_sfree_called++;
|
||||
MEMMAN_SYSFREE(chunk);
|
||||
}
|
||||
|
||||
void
|
||||
memman_freeall(struct memman *memman)
|
||||
{
|
||||
int id;
|
||||
void *chunk;
|
||||
struct memman_blockman *bmp;
|
||||
struct memman_node *memnode;
|
||||
struct memman_block *memblock;
|
||||
struct memman_flexmem_info *info;
|
||||
|
||||
for (id = 0; id < memman->max_memid; id++) {
|
||||
bmp = &memman->blockman[id];
|
||||
|
||||
while ((memnode = LIST_FIRST(&bmp->occupied_node_list))) {
|
||||
chunk = memnode->node;
|
||||
printf("memman_freeall: fixed size (id = %d)\n", id);
|
||||
memman_free(memman, id, chunk);
|
||||
}
|
||||
while ((memblock = LIST_FIRST(&bmp->block_list))) {
|
||||
LIST_REMOVE(memblock, links);
|
||||
if (!memblock->static_mem) {
|
||||
memman->sfree_called++;
|
||||
memman->reclaimed_mem += memblock->allocated_mem;
|
||||
MEMMAN_SYSFREE(memblock);
|
||||
}
|
||||
}
|
||||
bmp->initialized = 0;
|
||||
}
|
||||
|
||||
LIST_FOREACH(info, &memman->flexmem_info_list, links) {
|
||||
printf("memman_freeall: flex size (size = %d, addr = %p)\n",
|
||||
info->mem_size, info->addr);
|
||||
memman_free_flexsize(memman, info->addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
memman_statistics_fixedsize(struct memman *memman)
|
||||
{
|
||||
printf(" fixed size memory blocks\n");
|
||||
printf(" alloc(): %d times\n", memman->alloc_called);
|
||||
printf(" system malloc(): %d times\n", memman->salloc_called);
|
||||
printf(" free(): %d times\n", memman->free_called);
|
||||
printf(" system free(): %d times\n", memman->sfree_called);
|
||||
printf(" required memory: %d bytes\n", memman->required_mem);
|
||||
printf(" allocated memory: %d bytes\n", memman->allocated_mem);
|
||||
printf(" reclaimed memory: %d bytes\n", memman->reclaimed_mem);
|
||||
}
|
||||
|
||||
static void
|
||||
memman_statistics_flexsize(struct memman *memman)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf(" flexible size memory blocks\n");
|
||||
printf(" alloc(): %d times\n", memman->flex_alloc_called);
|
||||
printf(" system malloc(): %d times\n", memman->flex_salloc_called);
|
||||
printf(" free(): %d times\n", memman->flex_free_called);
|
||||
printf(" system free(): %d times\n", memman->flex_sfree_called);
|
||||
printf(" required memory: %d bytes\n", memman->flex_required_mem);
|
||||
printf(" allocated memory: %d bytes\n", memman->flex_allocated_mem);
|
||||
printf(" reclaimed memory: %d bytes\n", memman->flex_reclaimed_mem);
|
||||
printf(" peak memory usage: %d bytes\n", memman->flex_peak_mem_usage);
|
||||
printf(" min memory size: %d bytes\n", memman->flex_mem_size_min);
|
||||
printf(" max memory size: %d bytes\n", memman->flex_mem_size_max);
|
||||
printf(" avg memory size: %d bytes\n",
|
||||
(memman->flex_alloc_called) ?
|
||||
memman->flex_allocated_mem / memman->flex_alloc_called : 0);
|
||||
|
||||
printf(" memory size histogram (%d entries):\n",
|
||||
memman->flex_mem_histogram_ptr);
|
||||
printf(" size count\n");
|
||||
memman_sort_histogram_by_size(memman);
|
||||
for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
|
||||
printf(" %d %d\n",
|
||||
memman->flex_mem_histogram[i].mem_size,
|
||||
memman->flex_mem_histogram[i].count);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
memman_statistics(struct memman *memman)
|
||||
{
|
||||
printf("memman: reporting statistics\n");
|
||||
memman_statistics_fixedsize(memman);
|
||||
memman_statistics_flexsize(memman);
|
||||
}
|
||||
|
||||
size_t
|
||||
memman_memid2size(struct memman *memman, unsigned int id)
|
||||
{
|
||||
if (memman->max_memid <= id) {
|
||||
printf("memman_alloc: invalid memory type id\n");
|
||||
return (0);
|
||||
}
|
||||
return (memman->blockman[id].size);
|
||||
}
|
172
usr.sbin/acpi/amldb/aml/aml_memman.h
Normal file
172
usr.sbin/acpi/amldb/aml/aml_memman.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_memman.h,v 1.9 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MEMMAN_H_
|
||||
#define _MEMMAN_H_
|
||||
|
||||
/*
|
||||
* Generic Memory Management
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
/* memory block */
|
||||
struct memman_block {
|
||||
LIST_ENTRY(memman_block) links;
|
||||
void *block;
|
||||
unsigned static_mem; /* static memory or not */
|
||||
unsigned int allocated; /* number of allocated chunks */
|
||||
unsigned int available; /* number of available chunks */
|
||||
unsigned int allocated_mem; /* block + misc (in bytes) */
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
LIST_HEAD(memman_block_list, memman_block);
|
||||
|
||||
/* memory node in block */
|
||||
struct memman_node {
|
||||
LIST_ENTRY(memman_node) links;
|
||||
void *node;
|
||||
struct memman_block *memblock;
|
||||
}__attribute__((packed));
|
||||
|
||||
LIST_HEAD(memman_node_list, memman_node);
|
||||
|
||||
/* memory type id */
|
||||
extern unsigned int memid_unkown;
|
||||
|
||||
/* memory block manager */
|
||||
struct memman_blockman {
|
||||
unsigned int size; /* size of chunk */
|
||||
unsigned int available; /* total # of available chunks */
|
||||
void *initial_block; /* initial memory storage */
|
||||
unsigned initialized; /* initialized or not */
|
||||
|
||||
struct memman_block_list block_list;
|
||||
struct memman_node_list free_node_list;
|
||||
struct memman_node_list occupied_node_list;
|
||||
};
|
||||
|
||||
/* memory size histogram */
|
||||
#define MEMMAN_HISTOGRAM_SIZE 20
|
||||
struct memman_histogram {
|
||||
int mem_size;
|
||||
int count;
|
||||
};
|
||||
|
||||
/* flex size memory allocation info */
|
||||
struct memman_flexmem_info {
|
||||
LIST_ENTRY(memman_flexmem_info) links;
|
||||
void *addr;
|
||||
size_t mem_size;
|
||||
}__attribute__((packed));
|
||||
|
||||
LIST_HEAD(memman_flexmem_info_list, memman_flexmem_info);
|
||||
|
||||
/* memory manager */
|
||||
struct memman {
|
||||
struct memman_blockman *blockman;
|
||||
unsigned int max_memid; /* max number of valid memid */
|
||||
|
||||
/* fixed size memory blocks */
|
||||
unsigned int alloc_called; /* memman_alloc() calling */
|
||||
unsigned int free_called; /* memman_free() calling */
|
||||
unsigned int salloc_called; /* malloc() calling */
|
||||
unsigned int sfree_called; /* free() calling */
|
||||
size_t required_mem; /* total required memory (in bytes) */
|
||||
size_t allocated_mem; /* total malloc()ed memory */
|
||||
size_t reclaimed_mem; /* total free()ed memory */
|
||||
/* flex size memory blocks */
|
||||
unsigned int flex_alloc_called; /* memman_alloc_flexsize() calling */
|
||||
unsigned int flex_free_called; /* memman_free_flexsize() calling */
|
||||
unsigned int flex_salloc_called;/* malloc() calling */
|
||||
unsigned int flex_sfree_called; /* free() calling */
|
||||
size_t flex_required_mem; /* total required memory (in bytes) */
|
||||
size_t flex_allocated_mem;/* total malloc()ed memory */
|
||||
size_t flex_reclaimed_mem;/* total free()ed memory */
|
||||
size_t flex_mem_size_min; /* min size of allocated memory */
|
||||
size_t flex_mem_size_max; /* max size of allocated memory */
|
||||
size_t flex_peak_mem_usage;/* memory usage at a peak period */
|
||||
|
||||
/* stuff for more detailed statistical information */
|
||||
struct memman_histogram *flex_mem_histogram;
|
||||
unsigned int flex_mem_histogram_ptr;
|
||||
int flex_mem_histogram_initial_tolerance;
|
||||
unsigned flex_mem_initialized;
|
||||
struct memman_flexmem_info_list flexmem_info_list;
|
||||
};
|
||||
|
||||
#define MEMMAN_BLOCKNODE_SIZE(entries) sizeof(struct memman_block) + \
|
||||
sizeof(struct memman_node) * entries
|
||||
|
||||
#ifndef ROUNDUP_UNIT
|
||||
#define ROUNDUP_UNIT 4
|
||||
#endif
|
||||
|
||||
#if !defined(MEMMAN_INITIAL_SIZE) || MEMMAN_INITIAL_SIZE < 2048
|
||||
#define MEMMAN_INITIAL_SIZE 2048
|
||||
#endif
|
||||
|
||||
#if !defined(MEMMAN_INCR_SIZE) || MEMMAN_INCR_SIZE < 512
|
||||
#define MEMMAN_INCR_SIZE 512
|
||||
#endif
|
||||
|
||||
#define MEMMAN_INITIALSTORAGE_DESC(type, name) \
|
||||
static struct { \
|
||||
char blocknodes[MEMMAN_BLOCKNODE_SIZE(MEMMAN_INITIAL_SIZE)]; \
|
||||
type realblock[MEMMAN_INITIAL_SIZE]; \
|
||||
} name
|
||||
|
||||
#define MEMMAN_MEMBLOCK_DESC(size, initial_storage) \
|
||||
{ size, MEMMAN_INITIAL_SIZE, &initial_storage, 0 }
|
||||
|
||||
#define MEMMAN_MEMMANAGER_DESC(blockman, max_memid, histogram, tolerance) \
|
||||
{ blockman, max_memid, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, histogram, 0, tolerance, 0}
|
||||
|
||||
void *memman_alloc(struct memman *, unsigned int);
|
||||
void *memman_alloc_flexsize(struct memman *, size_t);
|
||||
void memman_free(struct memman *, unsigned int, void *);
|
||||
void memman_free_flexsize(struct memman *, void *);
|
||||
void memman_freeall(struct memman *);
|
||||
void memman_statistics(struct memman *);
|
||||
size_t memman_memid2size(struct memman *, unsigned int);
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define MEMMAN_SYSMALLOC(size) malloc(size, M_MEMMAN, M_WAITOK)
|
||||
#define MEMMAN_SYSFREE(ptr) free(ptr, M_MEMMAN)
|
||||
#define MEMMAN_SYSABORT() /* no abort in kernel */
|
||||
#else /* !_KERNEL */
|
||||
#define MEMMAN_SYSMALLOC(size) malloc(size)
|
||||
#define MEMMAN_SYSFREE(ptr) free(ptr)
|
||||
#define MEMMAN_SYSABORT() abort()
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MEMMAN_H_ */
|
477
usr.sbin/acpi/amldb/aml/aml_name.c
Normal file
477
usr.sbin/acpi/amldb/aml/aml_name.c
Normal file
@ -0,0 +1,477 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Yasuo Yokoyama
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_name.c,v 1.15 2000/08/16 18:14:53 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#else /* _KERNEL */
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static struct aml_name *aml_find_name(struct aml_name *, char *);
|
||||
static struct aml_name *aml_new_name(struct aml_name *, char *);
|
||||
static void aml_delete_name(struct aml_name *);
|
||||
|
||||
static struct aml_name rootname = {"\\", NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
static struct aml_name_group root_group = {
|
||||
AML_NAME_GROUP_ROOT,
|
||||
&rootname,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct aml_name_group *name_group_list = &root_group;
|
||||
struct aml_local_stack *stack_top = NULL;
|
||||
|
||||
struct aml_name *
|
||||
aml_get_rootname()
|
||||
{
|
||||
|
||||
return (&rootname);
|
||||
}
|
||||
|
||||
static struct aml_name *
|
||||
aml_find_name(struct aml_name *parent, char *name)
|
||||
{
|
||||
struct aml_name *result;
|
||||
|
||||
if (!parent)
|
||||
parent = &rootname;
|
||||
for (result = parent->child; result; result = result->brother)
|
||||
if (!strncmp(result->name, name, 4))
|
||||
break;
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse given namesppace expression and find a first matched object
|
||||
* under given level of the tree by depth first search.
|
||||
*/
|
||||
|
||||
struct aml_name *
|
||||
aml_find_from_namespace(struct aml_name *parent, char *name)
|
||||
{
|
||||
char *ptr;
|
||||
int len;
|
||||
struct aml_name *result;
|
||||
|
||||
ptr = name;
|
||||
if (!parent)
|
||||
parent = &rootname;
|
||||
|
||||
if (ptr[0] == '\\') {
|
||||
ptr++;
|
||||
parent = &rootname;
|
||||
}
|
||||
for (len = 0; ptr[len] != '.' && ptr[len] != '\0'; len++)
|
||||
;
|
||||
|
||||
for (result = parent->child; result; result = result->brother) {
|
||||
if (!strncmp(result->name, ptr, len)) {
|
||||
if (ptr[len] == '\0' || ptr[len + 1] == '\0') {
|
||||
return (result);
|
||||
}
|
||||
ptr += len;
|
||||
if (ptr[0] != '.') {
|
||||
return (NULL);
|
||||
}
|
||||
ptr++;
|
||||
return (aml_find_from_namespace(result, ptr));
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_aml_apply_foreach_found_objects(struct aml_name *parent, char *name,
|
||||
int len, int shallow, int (*func)(struct aml_name *, va_list), va_list ap)
|
||||
{
|
||||
struct aml_name *child, *ptr;
|
||||
|
||||
child = ptr = NULL;
|
||||
|
||||
/* function to apply must be specified */
|
||||
if (func == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (child = parent->child; child; child = child->brother) {
|
||||
if (!strncmp(child->name, name, len)) {
|
||||
/* if function call was failed, stop searching */
|
||||
if (func(child, ap) != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shallow == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ptr = parent->child; ptr; ptr = ptr->brother) {
|
||||
/* do more searching */
|
||||
_aml_apply_foreach_found_objects(ptr, name, len, 0, func, ap);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find named objects as many as possible under given level of
|
||||
* namespace, and apply given callback function for each
|
||||
* named objects found. If the callback function returns non-zero
|
||||
* value, then the search terminates immediately.
|
||||
* Note that object name expression is used as forward substring match,
|
||||
* not exact match. The name expression "_L" will match for objects
|
||||
* which have name starting with "_L" such as "\_SB_.LID_._LID" and
|
||||
* "\_GPE._L00" and so on. The name expression can include parent object
|
||||
* name in it like "\_GPE._L". In this case, GPE X level wake handlers
|
||||
* will be found under "\_GPE" in shallow level.
|
||||
*/
|
||||
|
||||
void
|
||||
aml_apply_foreach_found_objects(struct aml_name *start, char *name,
|
||||
int (*func)(struct aml_name *, va_list), ...)
|
||||
{
|
||||
int i, len, has_dot, last_is_dot, shallow;
|
||||
struct aml_name *child, *parent;
|
||||
va_list ap;
|
||||
|
||||
shallow = 0;
|
||||
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);
|
||||
}
|
88
usr.sbin/acpi/amldb/aml/aml_name.h
Normal file
88
usr.sbin/acpi/amldb/aml/aml_name.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Yasuo Yokoyama
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_name.h,v 1.17 2000/08/16 18:14:54 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_NAME_H_
|
||||
#define _AML_NAME_H_
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
|
||||
struct aml_name {
|
||||
char name[4];
|
||||
union aml_object *property;
|
||||
struct aml_name *parent;
|
||||
struct aml_name *brother;
|
||||
struct aml_name *child;
|
||||
struct aml_name *chain;
|
||||
};
|
||||
|
||||
#define AML_NAME_GROUP_ROOT 0
|
||||
#define AML_NAME_GROUP_OS_DEFINED 1
|
||||
#define AML_NAME_GROUP_IN_METHOD 2
|
||||
|
||||
struct aml_name_group {
|
||||
int id; /* DSDT address or DBHANDLE */
|
||||
struct aml_name *head;
|
||||
struct aml_name_group *next;
|
||||
};
|
||||
|
||||
struct aml_local_stack {
|
||||
struct aml_name localvalue[8];
|
||||
struct aml_name argumentvalue[7];
|
||||
struct aml_name *temporary;
|
||||
struct aml_local_stack *next;
|
||||
};
|
||||
|
||||
/* forward declarement */
|
||||
struct aml_envrion;
|
||||
|
||||
struct aml_name *aml_get_rootname(void);
|
||||
struct aml_name_group *aml_new_name_group(int);
|
||||
void aml_delete_name_group(struct aml_name_group *);
|
||||
|
||||
struct aml_name *aml_find_from_namespace(struct aml_name *, char *);
|
||||
void aml_apply_foreach_found_objects(struct aml_name *,
|
||||
char *, int (*)(struct aml_name *, va_list), ...);
|
||||
struct aml_name *aml_search_name(struct aml_environ *, u_int8_t *);
|
||||
struct aml_name *aml_create_name(struct aml_environ *, u_int8_t *);
|
||||
|
||||
struct aml_local_stack *aml_local_stack_create(void);
|
||||
void aml_local_stack_push(struct aml_local_stack *);
|
||||
struct aml_local_stack *aml_local_stack_pop(void);
|
||||
void aml_local_stack_delete(struct aml_local_stack *);
|
||||
struct aml_name *aml_local_stack_getLocalX(int);
|
||||
struct aml_name *aml_local_stack_getArgX(struct aml_local_stack *, int);
|
||||
struct aml_name *aml_create_local_object(void);
|
||||
|
||||
extern struct aml_name_group *name_group_list;
|
||||
|
||||
#endif /* !_AML_NAME_H_ */
|
265
usr.sbin/acpi/amldb/aml/aml_obj.c
Normal file
265
usr.sbin/acpi/amldb/aml/aml_obj.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_obj.c,v 1.17 2000/08/12 15:20:45 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#else /* _KERNEL */
|
||||
#include <sys/bus.h>
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
union aml_object *
|
||||
aml_copy_object(struct aml_environ *env, union aml_object *orig)
|
||||
{
|
||||
int i;
|
||||
union aml_object *ret;
|
||||
|
||||
if (orig == NULL)
|
||||
return (NULL);
|
||||
switch (orig->type) {
|
||||
case aml_t_regfield:
|
||||
ret = aml_alloc_object(aml_t_buffer, 0);
|
||||
ret->buffer.size = (orig->regfield.bitlen / 8) +
|
||||
((orig->regfield.bitlen % 8) ? 1 : 0);
|
||||
if (ret->buffer.size == 0) {
|
||||
goto out;
|
||||
}
|
||||
ret->buffer.data = memman_alloc_flexsize(aml_memman, ret->buffer.size);
|
||||
aml_store_to_object(env, orig, ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = aml_alloc_object(0, orig);
|
||||
break;
|
||||
}
|
||||
|
||||
if (1 || orig != &env->tempobject) { /* XXX */
|
||||
if (orig->type == aml_t_buffer) {
|
||||
if (orig->buffer.size == 0) {
|
||||
goto out;
|
||||
}
|
||||
ret->buffer.data = memman_alloc_flexsize(aml_memman,
|
||||
orig->buffer.size);
|
||||
bcopy(orig->buffer.data, ret->buffer.data, orig->buffer.size);
|
||||
} else if (orig->type == aml_t_package) {
|
||||
if (ret->package.elements == 0) {
|
||||
goto out;
|
||||
}
|
||||
ret->package.objects = memman_alloc_flexsize(aml_memman,
|
||||
ret->package.elements * sizeof(union aml_object *));
|
||||
for (i = 0; i < ret->package.elements; i++) {
|
||||
ret->package.objects[i] = aml_copy_object(env, orig->package.objects[i]);
|
||||
}
|
||||
} else if (orig->type == aml_t_string && orig->str.needfree != 0) {
|
||||
ret->str.string = memman_alloc_flexsize(aml_memman,
|
||||
strlen(orig->str.string) + 1);
|
||||
strcpy(orig->str.string, ret->str.string);
|
||||
} else if (orig->type == aml_t_num) {
|
||||
ret->num.constant = 0;
|
||||
}
|
||||
} else {
|
||||
printf("%s:%d\n", __FILE__, __LINE__);
|
||||
env->tempobject.type = aml_t_null;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function have two function: copy or allocate. if orig != NULL,
|
||||
* orig is duplicated.
|
||||
*/
|
||||
|
||||
union aml_object *
|
||||
aml_alloc_object(enum aml_objtype type, union aml_object *orig)
|
||||
{
|
||||
unsigned int memid;
|
||||
union aml_object *ret;
|
||||
|
||||
if (orig != NULL) {
|
||||
type = orig->type;
|
||||
}
|
||||
switch (type) {
|
||||
case aml_t_namestr:
|
||||
memid = memid_aml_namestr;
|
||||
break;
|
||||
case aml_t_buffer:
|
||||
memid = memid_aml_buffer;
|
||||
break;
|
||||
case aml_t_string:
|
||||
memid = memid_aml_string;
|
||||
break;
|
||||
case aml_t_bufferfield:
|
||||
memid = memid_aml_bufferfield;
|
||||
break;
|
||||
case aml_t_package:
|
||||
memid = memid_aml_package;
|
||||
break;
|
||||
case aml_t_num:
|
||||
memid = memid_aml_num;
|
||||
break;
|
||||
case aml_t_powerres:
|
||||
memid = memid_aml_powerres;
|
||||
break;
|
||||
case aml_t_opregion:
|
||||
memid = memid_aml_opregion;
|
||||
break;
|
||||
case aml_t_method:
|
||||
memid = memid_aml_method;
|
||||
break;
|
||||
case aml_t_processor:
|
||||
memid = memid_aml_processor;
|
||||
break;
|
||||
case aml_t_field:
|
||||
memid = memid_aml_field;
|
||||
break;
|
||||
case aml_t_mutex:
|
||||
memid = memid_aml_mutex;
|
||||
break;
|
||||
case aml_t_device:
|
||||
memid = memid_aml_objtype;
|
||||
break;
|
||||
case aml_t_objref:
|
||||
memid = memid_aml_objref;
|
||||
break;
|
||||
default:
|
||||
memid = memid_aml_objtype;
|
||||
break;
|
||||
}
|
||||
ret = memman_alloc(aml_memman, memid);
|
||||
ret->type = type;
|
||||
|
||||
if (orig != NULL) {
|
||||
bcopy(orig, ret, memman_memid2size(aml_memman, memid));
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
aml_free_objectcontent(union aml_object *obj)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (obj->type == aml_t_buffer && obj->buffer.data != NULL) {
|
||||
memman_free_flexsize(aml_memman, obj->buffer.data);
|
||||
obj->buffer.data = NULL;
|
||||
}
|
||||
if (obj->type == aml_t_string && obj->str.string != NULL) {
|
||||
if (obj->str.needfree != 0) {
|
||||
memman_free_flexsize(aml_memman, obj->str.string);
|
||||
obj->str.string = NULL;
|
||||
}
|
||||
}
|
||||
if (obj->type == aml_t_package && obj->package.objects != NULL) {
|
||||
for (i = 0; i < obj->package.elements; i++) {
|
||||
aml_free_object(&obj->package.objects[i]);
|
||||
}
|
||||
memman_free_flexsize(aml_memman, obj->package.objects);
|
||||
obj->package.objects = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aml_free_object(union aml_object **obj)
|
||||
{
|
||||
union aml_object *body;
|
||||
|
||||
body = *obj;
|
||||
if (body == NULL) {
|
||||
return;
|
||||
}
|
||||
aml_free_objectcontent(*obj);
|
||||
memman_free(aml_memman, memid_unkown, *obj);
|
||||
*obj = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aml_realloc_object(union aml_object *obj, int size)
|
||||
{
|
||||
int i;
|
||||
enum aml_objtype type;
|
||||
union aml_object tmp;
|
||||
|
||||
type = obj->type;
|
||||
switch (type) {
|
||||
case aml_t_buffer:
|
||||
if (obj->buffer.size >= size) {
|
||||
return;
|
||||
}
|
||||
tmp.buffer.size = size;
|
||||
tmp.buffer.data = memman_alloc_flexsize(aml_memman, size);
|
||||
bzero(tmp.buffer.data, size);
|
||||
bcopy(obj->buffer.data, tmp.buffer.data, obj->buffer.size);
|
||||
aml_free_objectcontent(obj);
|
||||
*obj = tmp;
|
||||
break;
|
||||
case aml_t_string:
|
||||
if (strlen(obj->str.string) >= size) {
|
||||
return;
|
||||
}
|
||||
tmp.str.string = memman_alloc_flexsize(aml_memman, size + 1);
|
||||
strcpy(tmp.str.string, obj->str.string);
|
||||
aml_free_objectcontent(obj);
|
||||
*obj = tmp;
|
||||
break;
|
||||
case aml_t_package:
|
||||
if (obj->package.elements >= size) {
|
||||
return;
|
||||
}
|
||||
tmp.package.objects = memman_alloc_flexsize(aml_memman,
|
||||
size * sizeof(union aml_object *));
|
||||
bzero(tmp.package.objects, size * sizeof(union aml_object *));
|
||||
for (i = 0; i < obj->package.elements; i++) {
|
||||
tmp.package.objects[i] = obj->package.objects[i];
|
||||
}
|
||||
memman_free_flexsize(aml_memman, obj->package.objects);
|
||||
obj->package.objects = tmp.package.objects;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
227
usr.sbin/acpi/amldb/aml/aml_obj.h
Normal file
227
usr.sbin/acpi/amldb/aml/aml_obj.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_obj.h,v 1.15 2000/08/09 14:47:43 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_OBJ_H_
|
||||
#define _AML_OBJ_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct aml_environ;
|
||||
enum aml_objtype {
|
||||
aml_t_namestr = -3,
|
||||
aml_t_regfield,
|
||||
aml_t_objref,
|
||||
aml_t_null = 0,
|
||||
aml_t_num,
|
||||
aml_t_string,
|
||||
aml_t_buffer,
|
||||
aml_t_package,
|
||||
aml_t_device,
|
||||
aml_t_field,
|
||||
aml_t_event,
|
||||
aml_t_method,
|
||||
aml_t_mutex,
|
||||
aml_t_opregion,
|
||||
aml_t_powerres,
|
||||
aml_t_processor,
|
||||
aml_t_therm,
|
||||
aml_t_bufferfield,
|
||||
aml_t_ddbhandle,
|
||||
aml_t_debug
|
||||
};
|
||||
|
||||
struct aml_namestr {
|
||||
enum aml_objtype type; /* =aml_t_namestr */
|
||||
u_int8_t *dp;
|
||||
};
|
||||
|
||||
struct aml_opregion {
|
||||
enum aml_objtype type;
|
||||
int space;
|
||||
int offset;
|
||||
int length;
|
||||
};
|
||||
|
||||
struct aml_num {
|
||||
enum aml_objtype type; /* =aml_t_num */
|
||||
int number;
|
||||
int constant;
|
||||
};
|
||||
|
||||
struct aml_package {
|
||||
enum aml_objtype type;
|
||||
int elements;
|
||||
union aml_object **objects;
|
||||
};
|
||||
|
||||
struct aml_string {
|
||||
enum aml_objtype type; /* =aml_t_string */
|
||||
int needfree;
|
||||
u_int8_t *string;
|
||||
};
|
||||
|
||||
struct aml_buffer {
|
||||
enum aml_objtype type; /* =aml_t_buffer */
|
||||
int size;
|
||||
u_int8_t *data; /* This should be free when
|
||||
* this object is free.
|
||||
*/
|
||||
};
|
||||
|
||||
enum fieldtype {
|
||||
f_t_field,
|
||||
f_t_index,
|
||||
f_t_bank
|
||||
};
|
||||
|
||||
struct nfieldd {
|
||||
enum fieldtype ftype; /* f_t_field */
|
||||
u_int8_t *regname; /* Namestring */
|
||||
};
|
||||
|
||||
struct ifieldd {
|
||||
enum fieldtype ftype; /* f_t_index */
|
||||
u_int8_t *indexname;
|
||||
u_int8_t *dataname;
|
||||
};
|
||||
|
||||
struct bfieldd {
|
||||
enum fieldtype ftype; /* f_t_bank */
|
||||
u_int8_t *regname;
|
||||
u_int8_t *bankname;
|
||||
u_int32_t bankvalue;
|
||||
};
|
||||
|
||||
struct aml_field {
|
||||
enum aml_objtype type;
|
||||
u_int32_t flags;
|
||||
int bitoffset; /* Not Byte offset but bitoffset */
|
||||
int bitlen;
|
||||
union {
|
||||
enum fieldtype ftype;
|
||||
struct nfieldd fld;
|
||||
struct ifieldd ifld;
|
||||
struct bfieldd bfld;
|
||||
} f;
|
||||
};
|
||||
|
||||
struct aml_bufferfield {
|
||||
enum aml_objtype type; /* aml_t_bufferfield */
|
||||
int bitoffset;
|
||||
int bitlen;
|
||||
u_int8_t *origin; /* This should not be free
|
||||
* when this object is free
|
||||
* (Within Buffer object)
|
||||
*/
|
||||
};
|
||||
|
||||
struct aml_method {
|
||||
enum aml_objtype type;
|
||||
int argnum; /* Not argnum but argnum|frag */
|
||||
u_int8_t *from;
|
||||
u_int8_t *to;
|
||||
};
|
||||
|
||||
struct aml_powerres {
|
||||
enum aml_objtype type;
|
||||
int level;
|
||||
int order;
|
||||
};
|
||||
|
||||
struct aml_processor {
|
||||
enum aml_objtype type;
|
||||
int id;
|
||||
int addr;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct aml_mutex_queue {
|
||||
STAILQ_ENTRY(aml_mutex_queue) entry;
|
||||
};
|
||||
|
||||
struct aml_mutex {
|
||||
enum aml_objtype type;
|
||||
int level;
|
||||
volatile void *cookie; /* In kernel, struct proc? */
|
||||
STAILQ_HEAD(, aml_mutex_queue) queue;
|
||||
};
|
||||
|
||||
struct aml_objref {
|
||||
enum aml_objtype type;
|
||||
struct aml_name *nameref;
|
||||
union aml_object *ref;
|
||||
int offset; /* of aml_buffer.data or aml_package.objects. */
|
||||
/* if negative value, not ready to dereference for element access. */
|
||||
unsigned deref; /* indicates whether dereffenced or not */
|
||||
unsigned alias; /* true if this is an alias object reference */
|
||||
};
|
||||
|
||||
struct aml_regfield {
|
||||
enum aml_objtype type;
|
||||
int space;
|
||||
u_int32_t flags;
|
||||
int offset;
|
||||
int bitoffset;
|
||||
int bitlen;
|
||||
};
|
||||
|
||||
struct aml_event {
|
||||
enum aml_objtype type; /* aml_t_event */
|
||||
int inuse;
|
||||
};
|
||||
|
||||
union aml_object {
|
||||
enum aml_objtype type;
|
||||
struct aml_num num;
|
||||
struct aml_processor proc;
|
||||
struct aml_powerres pres;
|
||||
struct aml_opregion opregion;
|
||||
struct aml_method meth;
|
||||
struct aml_field field;
|
||||
struct aml_mutex mutex;
|
||||
struct aml_namestr nstr;
|
||||
struct aml_buffer buffer;
|
||||
struct aml_bufferfield bfld;
|
||||
struct aml_package package;
|
||||
struct aml_string str;
|
||||
struct aml_objref objref;
|
||||
struct aml_event event;
|
||||
struct aml_regfield regfield;
|
||||
};
|
||||
|
||||
union aml_object *aml_copy_object(struct aml_environ *,
|
||||
union aml_object *);
|
||||
union aml_object *aml_alloc_object(enum aml_objtype,
|
||||
union aml_object *);
|
||||
void aml_free_objectcontent(union aml_object *);
|
||||
void aml_free_object(union aml_object **);
|
||||
void aml_realloc_object(union aml_object *, int);
|
||||
|
||||
#endif /* !_AML_OBJ_H_ */
|
1998
usr.sbin/acpi/amldb/aml/aml_parse.c
Normal file
1998
usr.sbin/acpi/amldb/aml/aml_parse.c
Normal file
File diff suppressed because it is too large
Load Diff
36
usr.sbin/acpi/amldb/aml/aml_parse.h
Normal file
36
usr.sbin/acpi/amldb/aml/aml_parse.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_parse.h,v 1.9 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_PARSE_H_
|
||||
#define _AML_PARSE_H_
|
||||
|
||||
struct aml_name *aml_parse_objectlist(struct aml_environ *, int);
|
||||
struct aml_name *aml_parse_termobj(struct aml_environ *, int);
|
||||
|
||||
#endif /* !_AML_PARSE_H_ */
|
490
usr.sbin/acpi/amldb/aml/aml_region.c
Normal file
490
usr.sbin/acpi/amldb/aml/aml_region.c
Normal file
@ -0,0 +1,490 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* Copyright (c) 2000 Munehiro Matsuda <haro@tk.kubota.co.jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_region.c,v 1.10 2000/08/09 14:47:44 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Region I/O subroutine
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/acpi.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_region.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
|
||||
#ifndef ACPI_NO_OSDFUNC_INLINE
|
||||
#include <machine/acpica_osd.h>
|
||||
#endif
|
||||
|
||||
#define AML_REGION_INPUT 0
|
||||
#define AML_REGION_OUTPUT 1
|
||||
|
||||
#define AML_REGION_SYSMEM 0
|
||||
#define AML_REGION_SYSIO 1
|
||||
#define AML_REGION_PCICFG 2
|
||||
#define AML_REGION_EMBCTL 3
|
||||
#define AML_REGION_SMBUS 4
|
||||
|
||||
static int
|
||||
aml_region_io_system(struct aml_environ *env, boolean_t io, int regtype,
|
||||
u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
|
||||
u_int32_t bitoffset, u_int32_t bitlen)
|
||||
{
|
||||
u_int8_t val, tmp, masklow, maskhigh;
|
||||
u_int8_t offsetlow, offsethigh;
|
||||
vm_offset_t addr, vaddr, byteoffset, bytelen;
|
||||
u_int32_t pci_bus;
|
||||
u_int32_t pci_devfunc;
|
||||
int value, readval;
|
||||
int state, i;
|
||||
int debug;
|
||||
|
||||
/* save debug level and shut it up */
|
||||
debug = aml_debug;
|
||||
aml_debug = 0;
|
||||
|
||||
value = *valuep;
|
||||
val = readval = 0;
|
||||
masklow = maskhigh = 0xff;
|
||||
state = 0;
|
||||
vaddr = 0;
|
||||
pci_bus = pci_devfunc = 0;
|
||||
|
||||
byteoffset = bitoffset / 8;
|
||||
bytelen = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
|
||||
addr = baseaddr + byteoffset;
|
||||
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);
|
||||
}
|
||||
|
||||
if (regtype == AML_REGION_SYSMEM) {
|
||||
OsdMapMemory((void *)addr, bytelen, (void **)&vaddr);
|
||||
}
|
||||
if (regtype == AML_REGION_PCICFG) {
|
||||
/* Access to PCI Config space */
|
||||
struct aml_name *pci_info;
|
||||
|
||||
/* Obtain PCI bus number */
|
||||
pci_info = aml_search_name(env, "_BBN");
|
||||
if (!pci_info || pci_info->property->type != aml_t_num) {
|
||||
AML_DEBUGPRINT("Cannot locate _BBN. Using default 0\n");
|
||||
pci_bus = 0;
|
||||
} else {
|
||||
AML_DEBUGPRINT("found _BBN: %d\n",
|
||||
pci_info->property->num.number);
|
||||
pci_bus = pci_info->property->num.number & 0xff;
|
||||
}
|
||||
|
||||
/* Obtain device & function number */
|
||||
pci_info = aml_search_name(env, "_ADR");
|
||||
if (!pci_info || pci_info->property->type != aml_t_num) {
|
||||
printf("Cannot locate: _ADR\n");
|
||||
state = -1;
|
||||
goto io_done;
|
||||
}
|
||||
pci_devfunc = pci_info->property->num.number;
|
||||
|
||||
AML_DEBUGPRINT("[pci%d.%d]", pci_bus, pci_devfunc);
|
||||
}
|
||||
|
||||
/* simple I/O ? */
|
||||
if (offsetlow == 0 && offsethigh == 0 &&
|
||||
(bitlen == 8 || bitlen == 16 || bitlen == 32)) {
|
||||
switch (io) {
|
||||
case AML_REGION_INPUT:
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
/* XXX should be MI */
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value = *(volatile u_int8_t *)(vaddr);
|
||||
value &= 0xff;
|
||||
break;
|
||||
case 16:
|
||||
value = *(volatile u_int16_t *)(vaddr);
|
||||
value &= 0xffff;
|
||||
break;
|
||||
case 32:
|
||||
value = *(volatile u_int32_t *)(vaddr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value = OsdIn8(addr);
|
||||
value &= 0xff;
|
||||
break;
|
||||
case 16:
|
||||
value = OsdIn16(addr);
|
||||
value &= 0xffff;
|
||||
break;
|
||||
case 32:
|
||||
value = OsdIn32(addr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
OsdReadPciCfgByte(pci_bus, pci_devfunc,
|
||||
addr, (UINT8 *)&value);
|
||||
value &= 0xff;
|
||||
break;
|
||||
case 16:
|
||||
OsdReadPciCfgWord(pci_bus, pci_devfunc,
|
||||
addr, (UINT16 *)&value);
|
||||
value &= 0xffff;
|
||||
break;
|
||||
case 32:
|
||||
OsdReadPciCfgDword(pci_bus, pci_devfunc,
|
||||
addr, &value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
value = 0;
|
||||
break;
|
||||
}
|
||||
*valuep = value;
|
||||
break;
|
||||
case AML_REGION_OUTPUT:
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
/* XXX should be MI */
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value &= 0xff;
|
||||
*(volatile u_int8_t *)(vaddr) = value;
|
||||
break;
|
||||
case 16:
|
||||
value &= 0xffff;
|
||||
*(volatile u_int16_t *)(vaddr) = value;
|
||||
break;
|
||||
case 32:
|
||||
*(volatile u_int32_t *)(vaddr) = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
value &= 0xff;
|
||||
OsdOut8(addr, value);
|
||||
break;
|
||||
case 16:
|
||||
value &= 0xffff;
|
||||
OsdOut16(addr, value);
|
||||
break;
|
||||
case 32:
|
||||
OsdOut32(addr, value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
switch (bitlen) {
|
||||
case 8:
|
||||
OsdWritePciCfgByte(pci_bus, pci_devfunc,
|
||||
addr, value);
|
||||
break;
|
||||
case 16:
|
||||
OsdWritePciCfgWord(pci_bus, pci_devfunc,
|
||||
addr, value);
|
||||
break;
|
||||
case 32:
|
||||
OsdWritePciCfgDword(pci_bus, pci_devfunc,
|
||||
addr, value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto io_done;
|
||||
}
|
||||
|
||||
for (i = 0; i < bytelen; i++) {
|
||||
/* XXX */
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
val = *(volatile u_int8_t *)(vaddr + i);
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
val = OsdIn8(addr + i);
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
OsdReadPciCfgByte(pci_bus, pci_devfunc, addr + i, &val);
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
AML_DEBUGPRINT("\t[%d:0x%02x@0x%x]", regtype, val, addr + i);
|
||||
|
||||
switch (io) {
|
||||
case AML_REGION_INPUT:
|
||||
tmp = val;
|
||||
/* the lowest byte? */
|
||||
if (i == 0) {
|
||||
if (offsetlow) {
|
||||
readval = tmp & ~masklow;
|
||||
} else {
|
||||
readval = tmp;
|
||||
}
|
||||
} else {
|
||||
if (i == bytelen - 1 && offsethigh) {
|
||||
tmp = tmp & ~maskhigh;
|
||||
}
|
||||
readval = (tmp << (8 * i)) | readval;
|
||||
}
|
||||
|
||||
AML_DEBUGPRINT("\n");
|
||||
/* goto to next byte... */
|
||||
if (i < bytelen - 1) {
|
||||
continue;
|
||||
}
|
||||
/* final adjustment before finishing region access */
|
||||
if (offsetlow) {
|
||||
readval = readval >> offsetlow;
|
||||
}
|
||||
AML_DEBUGPRINT("\t[read(%d, 0x%x)&mask:0x%x]\n",
|
||||
regtype, addr + i, readval);
|
||||
value = readval;
|
||||
*valuep = value;
|
||||
|
||||
break;
|
||||
case AML_REGION_OUTPUT:
|
||||
tmp = value & 0xff;
|
||||
/* the lowest byte? */
|
||||
if (i == 0) {
|
||||
if (offsetlow) {
|
||||
tmp = (val & masklow) | tmp << offsetlow;
|
||||
}
|
||||
value = value >> (8 - offsetlow);
|
||||
} else {
|
||||
if (i == bytelen - 1 && offsethigh) {
|
||||
tmp = (val & maskhigh) | tmp;
|
||||
}
|
||||
value = value >> 8;
|
||||
}
|
||||
|
||||
AML_DEBUGPRINT("->[%d:0x%02x@0x%x]\n",
|
||||
regtype, tmp, addr + i);
|
||||
val = tmp;
|
||||
|
||||
/* XXX */
|
||||
switch (regtype) {
|
||||
case AML_REGION_SYSMEM:
|
||||
*(volatile u_int8_t *)(vaddr + i) = val;
|
||||
break;
|
||||
case AML_REGION_SYSIO:
|
||||
OsdOut8(addr + i, val);
|
||||
break;
|
||||
case AML_REGION_PCICFG:
|
||||
OsdWritePciCfgByte(pci_bus, pci_devfunc,
|
||||
addr + i, val);
|
||||
break;
|
||||
default:
|
||||
printf("aml_region_io_system: not supported yet (%d)\n",
|
||||
regtype);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
io_done:
|
||||
if (regtype == AML_REGION_SYSMEM) {
|
||||
OsdUnMapMemory((void *)vaddr, bytelen);
|
||||
}
|
||||
|
||||
aml_debug = debug; /* restore debug devel */
|
||||
|
||||
return (state);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
state = aml_region_io_system(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;
|
||||
|
||||
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;
|
||||
|
||||
state = aml_region_io_system(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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
58
usr.sbin/acpi/amldb/aml/aml_region.h
Normal file
58
usr.sbin/acpi/amldb/aml/aml_region.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_region.h,v 1.5 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_REGION_H_
|
||||
#define _AML_REGION_H_
|
||||
|
||||
/*
|
||||
* Region I/O subroutine
|
||||
*/
|
||||
struct aml_environ;
|
||||
|
||||
u_int32_t aml_region_read(struct aml_environ *, int, u_int32_t,
|
||||
u_int32_t, u_int32_t, u_int32_t);
|
||||
int aml_region_write(struct aml_environ *, int, u_int32_t,
|
||||
u_int32_t, u_int32_t, u_int32_t, u_int32_t);
|
||||
int aml_region_read_into_buffer(struct aml_environ *, int,
|
||||
u_int32_t, u_int32_t, u_int32_t,
|
||||
u_int32_t, u_int8_t *);
|
||||
int aml_region_write_from_buffer(struct aml_environ *, int,
|
||||
u_int32_t, u_int8_t *, u_int32_t,
|
||||
u_int32_t, u_int32_t);
|
||||
int aml_region_bcopy(struct aml_environ *, int,
|
||||
u_int32_t, u_int32_t, u_int32_t, u_int32_t,
|
||||
u_int32_t, u_int32_t, u_int32_t, u_int32_t);
|
||||
|
||||
#ifndef _KERNEL
|
||||
void aml_simulation_regdump(const char *);
|
||||
extern int aml_debug_prompt_regoutput;
|
||||
extern int aml_debug_prompt_reginput;
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* !_AML_REGION_H_ */
|
41
usr.sbin/acpi/amldb/aml/aml_status.h
Normal file
41
usr.sbin/acpi/amldb/aml/aml_status.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_status.h,v 1.6 2000/08/08 14:12:05 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_STATUS_H_
|
||||
#define _AML_STATUS_H_
|
||||
|
||||
enum aml_status {
|
||||
aml_stat_none = 0,
|
||||
aml_stat_return,
|
||||
aml_stat_break,
|
||||
aml_stat_panic,
|
||||
aml_stat_step
|
||||
};
|
||||
|
||||
#endif /* !_AML_STATUS_H_ */
|
338
usr.sbin/acpi/amldb/aml/aml_store.c
Normal file
338
usr.sbin/acpi/amldb/aml/aml_store.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_store.c,v 1.22 2000/08/09 14:47:44 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/acpi/aml/aml_amlmem.h>
|
||||
#include <dev/acpi/aml/aml_common.h>
|
||||
#include <dev/acpi/aml/aml_env.h>
|
||||
#include <dev/acpi/aml/aml_evalobj.h>
|
||||
#include <dev/acpi/aml/aml_name.h>
|
||||
#include <dev/acpi/aml/aml_obj.h>
|
||||
#include <dev/acpi/aml/aml_region.h>
|
||||
#include <dev/acpi/aml/aml_status.h>
|
||||
#include <dev/acpi/aml/aml_store.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#else /* _KERNEL */
|
||||
#include <sys/systm.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static void
|
||||
aml_store_to_fieldname(struct aml_environ *env, union aml_object *obj,
|
||||
struct aml_name *name)
|
||||
{
|
||||
char *buffer;
|
||||
struct aml_name *wname, *oname;
|
||||
struct aml_field *field;
|
||||
struct aml_opregion *or;
|
||||
union aml_object tobj;
|
||||
|
||||
field = &name->property->field;
|
||||
oname = env->curname;
|
||||
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) {
|
||||
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);
|
||||
tobj.num = obj->num;
|
||||
tobj.num.number = tobj.num.number << (field->bitoffset & 7);
|
||||
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;
|
||||
}
|
||||
}
|
39
usr.sbin/acpi/amldb/aml/aml_store.h
Normal file
39
usr.sbin/acpi/amldb/aml/aml_store.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Takanori Watanabe
|
||||
* Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: aml_store.h,v 1.8 2000/08/09 14:47:44 iwasaki Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _AML_STORE_H_
|
||||
#define _AML_STORE_H_
|
||||
|
||||
void aml_store_to_name(struct aml_environ *, union aml_object *,
|
||||
struct aml_name *);
|
||||
void aml_store_to_object(struct aml_environ *, union aml_object *,
|
||||
union aml_object *);
|
||||
|
||||
#endif /* _AML_STORE_H_ */
|
Loading…
Reference in New Issue
Block a user