diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 17:17:53 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 17:17:53 +0000 |
commit | b2ad5f821b1381492d792ca10b1eb7a107b48f14 (patch) | |
tree | 954a648692e7da983db1d2470953705f6a729264 /drivers/acpi | |
parent | c9c06167e7933d93a6e396174c68abf242294abb (diff) |
Merge with Linux 2.4.0-prerelease. Big Makefile rewrite, test your
Makefiles.
Diffstat (limited to 'drivers/acpi')
139 files changed, 9255 insertions, 5905 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index c5f3d5ed8..307cb08ad 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -2,32 +2,36 @@ # Makefile for the Linux ACPI interpreter # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := acpi.o -O_OBJS := -M_OBJS := + +export-objs := ksyms.o export ACPI_CFLAGS ACPI_CFLAGS := -D_LINUX +# +# CONFIG_ACPI_KERNEL_CONFIG is currently only IA64 +# +ifdef CONFIG_ACPI_KERNEL_CONFIG + ACPI_CFLAGS += -DCONFIG_ACPI_KERNEL_CONFIG_ONLY +endif + EXTRA_CFLAGS += -I./include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +acpi-subdirs := common dispatcher events hardware \ + interpreter namespace parser resources tables - SUB_DIRS += common dispatcher events hardware\ - interpreter namespace parser resources tables +subdir-$(CONFIG_ACPI) += $(acpi-subdirs) - ACPI_OBJS := $(patsubst %,%.o,$(SUB_DIRS)) - ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %,%.o,$(acpi-subdirs)) +obj-$(CONFIG_ACPI) += os.o ksyms.o - O_OBJS += $(ACPI_OBJS) +ifdef CONFIG_ACPI_KERNEL_CONFIG + obj-$(CONFIG_ACPI) += acpiconf.o osconf.o +else + obj-$(CONFIG_ACPI) += driver.o cmbatt.o cpu.o ec.o ksyms.o sys.o table.o power.o endif include $(TOPDIR)/Rules.make diff --git a/drivers/acpi/cmbatt.c b/drivers/acpi/cmbatt.c new file mode 100644 index 000000000..c45aa810c --- /dev/null +++ b/drivers/acpi/cmbatt.c @@ -0,0 +1,402 @@ +/* + * cmbatt.c - Control Method Battery driver + * + * Copyright (C) 2000 Andrew Grover + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * Changes: + * Brendan Burns <bburns@wso.williams.edu> 2000-11-15 + * - added proc battery interface + * - parse returned data from _BST and _BIF + * Andy Grover <andrew.grover@intel.com> 2000-12-8 + * - improved proc interface + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/proc_fs.h> +#include "acpi.h" +#include "driver.h" + +#define _COMPONENT OS_DEPENDENT + MODULE_NAME ("cmbatt") + +/* ACPI-specific defines */ +#define ACPI_CMBATT_HID "PNP0C0A" +#define ACPI_BATT_PRESENT 0x10 +#define ACPI_BATT_UNKNOWN 0xFFFFFFFF + +/* driver-specific defines */ +#define MAX_CM_BATTERIES 0x8 +#define MAX_BATT_STRLEN 0x20 + +struct cmbatt_info +{ + u32 power_unit; + u32 design_capacity; + u32 last_full_capacity; + u32 battery_technology; + u32 design_voltage; + u32 design_capacity_warning; + u32 design_capacity_low; + u32 battery_capacity_granularity_1; + u32 battery_capacity_granularity_2; + + char model_number[MAX_BATT_STRLEN]; + char serial_number[MAX_BATT_STRLEN]; + char battery_type[MAX_BATT_STRLEN]; + char oem_info[MAX_BATT_STRLEN]; +}; + +struct cmbatt_context +{ + u32 is_present; + ACPI_HANDLE handle; + char UID[9]; + char *power_unit; + struct cmbatt_info info; +}; + +struct cmbatt_status +{ + u32 state; + u32 present_rate; + u32 remaining_capacity; + u32 present_voltage; +}; + +static u32 batt_count = 0; + +static struct cmbatt_context batt_list[MAX_CM_BATTERIES]; + +static ACPI_STATUS +acpi_get_battery_status(ACPI_HANDLE handle, struct cmbatt_status *result) +{ + ACPI_OBJECT *obj; + ACPI_OBJECT *objs; + ACPI_BUFFER buf; + + buf.length = 0; + buf.pointer = NULL; + + /* determine buffer length needed */ + if (acpi_evaluate_object(handle, "_BST", NULL, &buf) != AE_BUFFER_OVERFLOW) { + printk(KERN_ERR "Cmbatt: Could not get battery status struct length\n"); + return AE_NOT_FOUND; + } + + buf.pointer = kmalloc(buf.length, GFP_KERNEL); + if (!buf.pointer) + return AE_NO_MEMORY; + + /* get the data */ + if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_BST", NULL, &buf))) { + printk(KERN_ERR "Cmbatt: Could not get battery status\n"); + kfree (buf.pointer); + return AE_NOT_FOUND; + } + + obj = (ACPI_OBJECT *) buf.pointer; + objs = obj->package.elements; + + result->state = objs[0].number.value; + result->present_rate = objs[1].number.value; + result->remaining_capacity = objs[2].number.value; + result->present_voltage = objs[3].number.value; + + kfree(buf.pointer); + + return AE_OK; +} + +static ACPI_STATUS +acpi_get_battery_info(ACPI_HANDLE handle, struct cmbatt_info *result) +{ + ACPI_OBJECT *obj; + ACPI_OBJECT *objs; + ACPI_BUFFER buf; + + buf.length = 0; + buf.pointer = NULL; + + /* determine the length of the data */ + if (acpi_evaluate_object(handle, "_BIF", NULL, &buf) != AE_BUFFER_OVERFLOW) { + printk(KERN_ERR "Cmbatt: Could not get battery info struct length\n"); + return AE_NOT_FOUND; + } + + buf.pointer = kmalloc(buf.length, GFP_KERNEL); + if (!buf.pointer) + return AE_NO_MEMORY; + + /* get the data */ + if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_BIF", NULL, &buf))) { + printk(KERN_ERR "Cmbatt: Could not get battery info\n"); + kfree (buf.pointer); + return AE_NOT_FOUND; + } + + obj = (ACPI_OBJECT *) buf.pointer; + objs = obj->package.elements; + + result->power_unit=objs[0].number.value; + result->design_capacity=objs[1].number.value; + result->last_full_capacity=objs[2].number.value; + result->battery_technology=objs[3].number.value; + result->design_voltage=objs[4].number.value; + result->design_capacity_warning=objs[5].number.value; + result->design_capacity_low=objs[6].number.value; + result->battery_capacity_granularity_1=objs[7].number.value; + result->battery_capacity_granularity_2=objs[8].number.value; + + /* BUG: trailing NULL issue */ + strncpy(result->model_number, objs[9].string.pointer, MAX_BATT_STRLEN-1); + strncpy(result->serial_number, objs[10].string.pointer, MAX_BATT_STRLEN-1); + strncpy(result->battery_type, objs[11].string.pointer, MAX_BATT_STRLEN-1); + strncpy(result->oem_info, objs[12].string.pointer, MAX_BATT_STRLEN-1); + + kfree(buf.pointer); + + return AE_OK; +} + +/* + * We found a device with the correct HID + */ +static ACPI_STATUS +acpi_found_cmbatt(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +{ + ACPI_DEVICE_INFO info; + + if (batt_count >= MAX_CM_BATTERIES) { + printk(KERN_ERR "Cmbatt: MAX_CM_BATTERIES exceeded\n"); + return AE_OK; + } + + if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { + printk(KERN_ERR "Cmbatt: Could not get battery object info\n"); + return (AE_OK); + } + + if (info.valid & ACPI_VALID_UID) { + strncpy(batt_list[batt_count].UID, info.unique_id, 9); + } + else if (batt_count > 1) { + printk(KERN_WARNING "Cmbatt: No UID but more than 1 battery\n"); + } + + if (!(info.valid & ACPI_VALID_STA)) { + printk(KERN_ERR "Cmbatt: Battery _STA invalid\n"); + return AE_OK; + } + + if (!(info.current_status & ACPI_BATT_PRESENT)) { + printk(KERN_INFO "Cmbatt: Battery socket %d empty\n", batt_count); + batt_list[batt_count].is_present = FALSE; + } + else { + printk(KERN_INFO "Cmbatt: Battery socket %d occupied\n", batt_count); + batt_list[batt_count].is_present = TRUE; + if (acpi_get_battery_info(handle, &batt_list[batt_count].info) != AE_OK) { + printk(KERN_ERR "acpi_get_battery_info failed\n"); + return AE_OK; + } + + batt_list[batt_count].power_unit = (batt_list[batt_count].info.power_unit) ? "mA" : "mW"; + } + + batt_list[batt_count].handle = handle; + + batt_count++; + + return AE_OK; +} + +static int +proc_read_batt_info(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct cmbatt_info *info; + u32 batt_num = (u32) data; + char *p = page; + int len; + + info = &batt_list[batt_num].info; + + /* don't get info more than once for a single proc read */ + if (off != 0) + goto end; + + if (!batt_list[batt_num].is_present) { + p += sprintf(p, "battery %d not present\n", batt_num); + goto end; + } + + if (info->last_full_capacity == ACPI_BATT_UNKNOWN) + p += sprintf(p, "Unknown last full capacity\n"); + else + p += sprintf(p, "Last Full Capacity %x %s /hr\n", + info->last_full_capacity, batt_list[batt_num].power_unit); + + if (info->design_capacity == ACPI_BATT_UNKNOWN) + p += sprintf(p, "Unknown Design Capacity\n"); + else + p += sprintf(p, "Design Capacity %x %s /hr\n", + info->design_capacity, batt_list[batt_num].power_unit); + + if (info->battery_technology) + p += sprintf(p, "Secondary Battery Technology\n"); + else + p += sprintf(p, "Primary Battery Technology\n"); + + if (info->design_voltage == ACPI_BATT_UNKNOWN) + p += sprintf(p, "Unknown Design Voltage\n"); + else + p += sprintf(p, "Design Voltage %x mV\n", + info->design_voltage); + + p += sprintf(p, "Design Capacity Warning %d\n", + info->design_capacity_warning); + p += sprintf(p, "Design Capacity Low %d\n", + info->design_capacity_low); + p += sprintf(p, "Battery Capacity Granularity 1 %d\n", + info->battery_capacity_granularity_1); + p += sprintf(p, "Battery Capacity Granularity 2 %d\n", + info->battery_capacity_granularity_2); + p += sprintf(p, "model number %s\nserial number %s\nbattery type %s\nOEM info %s\n", + info->model_number,info->serial_number, + info->battery_type,info->oem_info); +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static int +proc_read_batt_status(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct cmbatt_status status; + u32 batt_num = (u32) data; + char *p = page; + int len; + + /* don't get status more than once for a single proc read */ + if (off != 0) + goto end; + + if (!batt_list[batt_num].is_present) { + p += sprintf(p, "battery %d not present\n", batt_num); + goto end; + } + + printk("getting batt status\n"); + + if (acpi_get_battery_status(batt_list[batt_num].handle, &status) != AE_OK) { + printk(KERN_ERR "Cmbatt: acpi_get_battery_status failed\n"); + goto end; + } + + p += sprintf(p, "Remaining Capacity: %x\n", status.remaining_capacity); + + if (status.state & 0x1) + p += sprintf(p, "Battery discharging\n"); + if (status.state & 0x2) + p += sprintf(p, "Battery charging\n"); + if (status.state & 0x4) + p += sprintf(p, "Battery critically low\n"); + + if (status.present_rate == ACPI_BATT_UNKNOWN) + p += sprintf(p, "Battery rate unknown\n"); + else + p += sprintf(p, "Battery rate %x\n", + status.present_rate); + + if (status.remaining_capacity == ACPI_BATT_UNKNOWN) + p += sprintf(p, "Battery capacity unknown\n"); + else + p += sprintf(p, "Battery capacity %x %s\n", + status.remaining_capacity, batt_list[batt_num].power_unit); + + if (status.present_voltage == ACPI_BATT_UNKNOWN) + p += sprintf(p, "Battery voltage unknown\n"); + else + p += sprintf(p, "Battery voltage %x volts\n", + status.present_voltage); + +end: + + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + + + +int +acpi_cmbatt_init(void) +{ + int i; + + acpi_get_devices(ACPI_CMBATT_HID, + acpi_found_cmbatt, + NULL, + NULL); + + for (i = 0; i < batt_count; i++) { + + char batt_name[20]; + + sprintf(batt_name, "power/batt%d_info", i); + create_proc_read_entry(batt_name, 0, NULL, + proc_read_batt_info, (void *) i); + + sprintf(batt_name, "power/batt%d_status", i); + create_proc_read_entry(batt_name, 0, NULL, + proc_read_batt_status, (void *) i); + + } + + return 0; +} + +int +acpi_cmbatt_terminate(void) +{ + int i; + + for (i = 0; i < batt_count; i++) { + + char batt_name[20]; + + sprintf(batt_name, "power/batt%d_info", i); + remove_proc_entry(batt_name, NULL); + + sprintf(batt_name, "power/batt%d_status", i); + remove_proc_entry(batt_name, NULL); + } + + return 0; +} diff --git a/drivers/acpi/common/Makefile b/drivers/acpi/common/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/common/Makefile +++ b/drivers/acpi/common/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/common/cmalloc.c b/drivers/acpi/common/cmalloc.c index cd67322b4..b7a64e5b6 100644 --- a/drivers/acpi/common/cmalloc.c +++ b/drivers/acpi/common/cmalloc.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmalloc - local memory allocation routines - * $Revision: 73 $ + * $Revision: 79 $ * *****************************************************************************/ @@ -57,11 +57,15 @@ _cm_allocate ( u32 line) { void *address = NULL; + DEBUG_ONLY_MEMBERS (\ + ACPI_STATUS status) + /* Check for an inadvertent size of zero bytes */ if (!size) { - REPORT_ERROR ("Cm_allocate: Attempt to allocate zero bytes"); + _REPORT_ERROR (module, line, component, + ("Cm_allocate: Attempt to allocate zero bytes\n")); size = 1; } @@ -70,7 +74,7 @@ _cm_allocate ( /* Report allocation error */ _REPORT_ERROR (module, line, component, - "Cm_allocate: Memory allocation failure"); + ("Cm_allocate: Could not allocate size %X\n", size)); return (NULL); } @@ -103,11 +107,15 @@ _cm_callocate ( u32 line) { void *address = NULL; + DEBUG_ONLY_MEMBERS (\ + ACPI_STATUS status) + /* Check for an inadvertent size of zero bytes */ if (!size) { - REPORT_ERROR ("Cm_callocate: Attempt to allocate zero bytes"); + _REPORT_ERROR (module, line, component, + ("Cm_callocate: Attempt to allocate zero bytes\n")); return (NULL); } @@ -118,8 +126,7 @@ _cm_callocate ( /* Report allocation error */ _REPORT_ERROR (module, line, component, - "Cm_callocate: Memory allocation failure"); - + ("Cm_callocate: Could not allocate size %X\n", size)); return (NULL); } @@ -153,7 +160,7 @@ _cm_free ( if (NULL == address) { _REPORT_ERROR (module, line, component, - "_Cm_free: Trying to delete a NULL address."); + ("_Cm_free: Trying to delete a NULL address\n")); return; } diff --git a/drivers/acpi/common/cmclib.c b/drivers/acpi/common/cmclib.c index 4309ac465..5146b09c5 100644 --- a/drivers/acpi/common/cmclib.c +++ b/drivers/acpi/common/cmclib.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmclib - Local implementation of C library functions - * $Revision: 24 $ + * $Revision: 28 $ * *****************************************************************************/ @@ -41,10 +41,6 @@ MODULE_NAME ("cmclib") -#ifdef _MSC_VER /* disable some level-4 warnings for VC++ */ -#pragma warning(disable:4706) /* warning C4706: assignment within conditional expression */ -#endif - #ifndef ACPI_USE_SYSTEM_CLIBRARY /******************************************************************************* @@ -371,146 +367,146 @@ acpi_cm_memset ( #define POSITIVE 0 -#define _XA 0x00 /* extra alphabetic - not supported */ -#define _XS 0x40 /* extra space */ -#define _BB 0x00 /* BEL, BS, etc. - not supported */ -#define _CN 0x20 /* CR, FF, HT, NL, VT */ -#define _DI 0x04 /* '0'-'9' */ -#define _LO 0x02 /* 'a'-'z' */ -#define _PU 0x10 /* punctuation */ -#define _SP 0x08 /* space */ -#define _UP 0x01 /* 'A'-'Z' */ -#define _XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */ - -const u8 _ctype[257] = { - _CN, /* 0x0 0. */ - _CN, /* 0x1 1. */ - _CN, /* 0x2 2. */ - _CN, /* 0x3 3. */ - _CN, /* 0x4 4. */ - _CN, /* 0x5 5. */ - _CN, /* 0x6 6. */ - _CN, /* 0x7 7. */ - _CN, /* 0x8 8. */ - _CN|_SP, /* 0x9 9. */ - _CN|_SP, /* 0xA 10. */ - _CN|_SP, /* 0xB 11. */ - _CN|_SP, /* 0xC 12. */ - _CN|_SP, /* 0xD 13. */ - _CN, /* 0xE 14. */ - _CN, /* 0xF 15. */ - _CN, /* 0x10 16. */ - _CN, /* 0x11 17. */ - _CN, /* 0x12 18. */ - _CN, /* 0x13 19. */ - _CN, /* 0x14 20. */ - _CN, /* 0x15 21. */ - _CN, /* 0x16 22. */ - _CN, /* 0x17 23. */ - _CN, /* 0x18 24. */ - _CN, /* 0x19 25. */ - _CN, /* 0x1A 26. */ - _CN, /* 0x1B 27. */ - _CN, /* 0x1C 28. */ - _CN, /* 0x1D 29. */ - _CN, /* 0x1E 30. */ - _CN, /* 0x1F 31. */ - _XS|_SP, /* 0x20 32. ' ' */ - _PU, /* 0x21 33. '!' */ - _PU, /* 0x22 34. '"' */ - _PU, /* 0x23 35. '#' */ - _PU, /* 0x24 36. '$' */ - _PU, /* 0x25 37. '%' */ - _PU, /* 0x26 38. '&' */ - _PU, /* 0x27 39. ''' */ - _PU, /* 0x28 40. '(' */ - _PU, /* 0x29 41. ')' */ - _PU, /* 0x2A 42. '*' */ - _PU, /* 0x2B 43. '+' */ - _PU, /* 0x2C 44. ',' */ - _PU, /* 0x2D 45. '-' */ - _PU, /* 0x2E 46. '.' */ - _PU, /* 0x2F 47. '/' */ - _XD|_DI, /* 0x30 48. '0' */ - _XD|_DI, /* 0x31 49. '1' */ - _XD|_DI, /* 0x32 50. '2' */ - _XD|_DI, /* 0x33 51. '3' */ - _XD|_DI, /* 0x34 52. '4' */ - _XD|_DI, /* 0x35 53. '5' */ - _XD|_DI, /* 0x36 54. '6' */ - _XD|_DI, /* 0x37 55. '7' */ - _XD|_DI, /* 0x38 56. '8' */ - _XD|_DI, /* 0x39 57. '9' */ - _PU, /* 0x3A 58. ':' */ - _PU, /* 0x3B 59. ';' */ - _PU, /* 0x3C 60. '<' */ - _PU, /* 0x3D 61. '=' */ - _PU, /* 0x3E 62. '>' */ - _PU, /* 0x3F 63. '?' */ - _PU, /* 0x40 64. '@' */ - _XD|_UP, /* 0x41 65. 'A' */ - _XD|_UP, /* 0x42 66. 'B' */ - _XD|_UP, /* 0x43 67. 'C' */ - _XD|_UP, /* 0x44 68. 'D' */ - _XD|_UP, /* 0x45 69. 'E' */ - _XD|_UP, /* 0x46 70. 'F' */ - _UP, /* 0x47 71. 'G' */ - _UP, /* 0x48 72. 'H' */ - _UP, /* 0x49 73. 'I' */ - _UP, /* 0x4A 74. 'J' */ - _UP, /* 0x4B 75. 'K' */ - _UP, /* 0x4C 76. 'L' */ - _UP, /* 0x4D 77. 'M' */ - _UP, /* 0x4E 78. 'N' */ - _UP, /* 0x4F 79. 'O' */ - _UP, /* 0x50 80. 'P' */ - _UP, /* 0x51 81. 'Q' */ - _UP, /* 0x52 82. 'R' */ - _UP, /* 0x53 83. 'S' */ - _UP, /* 0x54 84. 'T' */ - _UP, /* 0x55 85. 'U' */ - _UP, /* 0x56 86. 'V' */ - _UP, /* 0x57 87. 'W' */ - _UP, /* 0x58 88. 'X' */ - _UP, /* 0x59 89. 'Y' */ - _UP, /* 0x5A 90. 'Z' */ - _PU, /* 0x5B 91. '[' */ - _PU, /* 0x5C 92. '\' */ - _PU, /* 0x5D 93. ']' */ - _PU, /* 0x5E 94. '^' */ - _PU, /* 0x5F 95. '_' */ - _PU, /* 0x60 96. '`' */ - _XD|_LO, /* 0x61 97. 'a' */ - _XD|_LO, /* 0x62 98. 'b' */ - _XD|_LO, /* 0x63 99. 'c' */ - _XD|_LO, /* 0x64 100. 'd' */ - _XD|_LO, /* 0x65 101. 'e' */ - _XD|_LO, /* 0x66 102. 'f' */ - _LO, /* 0x67 103. 'g' */ - _LO, /* 0x68 104. 'h' */ - _LO, /* 0x69 105. 'i' */ - _LO, /* 0x6A 106. 'j' */ - _LO, /* 0x6B 107. 'k' */ - _LO, /* 0x6C 108. 'l' */ - _LO, /* 0x6D 109. 'm' */ - _LO, /* 0x6E 110. 'n' */ - _LO, /* 0x6F 111. 'o' */ - _LO, /* 0x70 112. 'p' */ - _LO, /* 0x71 113. 'q' */ - _LO, /* 0x72 114. 'r' */ - _LO, /* 0x73 115. 's' */ - _LO, /* 0x74 116. 't' */ - _LO, /* 0x75 117. 'u' */ - _LO, /* 0x76 118. 'v' */ - _LO, /* 0x77 119. 'w' */ - _LO, /* 0x78 120. 'x' */ - _LO, /* 0x79 121. 'y' */ - _LO, /* 0x7A 122. 'z' */ - _PU, /* 0x7B 123. '{' */ - _PU, /* 0x7C 124. '|' */ - _PU, /* 0x7D 125. '}' */ - _PU, /* 0x7E 126. '~' */ - _CN, /* 0x7F 127. */ +#define _ACPI_XA 0x00 /* extra alphabetic - not supported */ +#define _ACPI_XS 0x40 /* extra space */ +#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */ +#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */ +#define _ACPI_DI 0x04 /* '0'-'9' */ +#define _ACPI_LO 0x02 /* 'a'-'z' */ +#define _ACPI_PU 0x10 /* punctuation */ +#define _ACPI_SP 0x08 /* space */ +#define _ACPI_UP 0x01 /* 'A'-'Z' */ +#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */ + +static const u8 _acpi_ctype[257] = { + _ACPI_CN, /* 0x0 0. */ + _ACPI_CN, /* 0x1 1. */ + _ACPI_CN, /* 0x2 2. */ + _ACPI_CN, /* 0x3 3. */ + _ACPI_CN, /* 0x4 4. */ + _ACPI_CN, /* 0x5 5. */ + _ACPI_CN, /* 0x6 6. */ + _ACPI_CN, /* 0x7 7. */ + _ACPI_CN, /* 0x8 8. */ + _ACPI_CN|_ACPI_SP, /* 0x9 9. */ + _ACPI_CN|_ACPI_SP, /* 0xA 10. */ + _ACPI_CN|_ACPI_SP, /* 0xB 11. */ + _ACPI_CN|_ACPI_SP, /* 0xC 12. */ + _ACPI_CN|_ACPI_SP, /* 0xD 13. */ + _ACPI_CN, /* 0xE 14. */ + _ACPI_CN, /* 0xF 15. */ + _ACPI_CN, /* 0x10 16. */ + _ACPI_CN, /* 0x11 17. */ + _ACPI_CN, /* 0x12 18. */ + _ACPI_CN, /* 0x13 19. */ + _ACPI_CN, /* 0x14 20. */ + _ACPI_CN, /* 0x15 21. */ + _ACPI_CN, /* 0x16 22. */ + _ACPI_CN, /* 0x17 23. */ + _ACPI_CN, /* 0x18 24. */ + _ACPI_CN, /* 0x19 25. */ + _ACPI_CN, /* 0x1A 26. */ + _ACPI_CN, /* 0x1B 27. */ + _ACPI_CN, /* 0x1C 28. */ + _ACPI_CN, /* 0x1D 29. */ + _ACPI_CN, /* 0x1E 30. */ + _ACPI_CN, /* 0x1F 31. */ + _ACPI_XS|_ACPI_SP, /* 0x20 32. ' ' */ + _ACPI_PU, /* 0x21 33. '!' */ + _ACPI_PU, /* 0x22 34. '"' */ + _ACPI_PU, /* 0x23 35. '#' */ + _ACPI_PU, /* 0x24 36. '$' */ + _ACPI_PU, /* 0x25 37. '%' */ + _ACPI_PU, /* 0x26 38. '&' */ + _ACPI_PU, /* 0x27 39. ''' */ + _ACPI_PU, /* 0x28 40. '(' */ + _ACPI_PU, /* 0x29 41. ')' */ + _ACPI_PU, /* 0x2A 42. '*' */ + _ACPI_PU, /* 0x2B 43. '+' */ + _ACPI_PU, /* 0x2C 44. ',' */ + _ACPI_PU, /* 0x2D 45. '-' */ + _ACPI_PU, /* 0x2E 46. '.' */ + _ACPI_PU, /* 0x2F 47. '/' */ + _ACPI_XD|_ACPI_DI, /* 0x30 48. '0' */ + _ACPI_XD|_ACPI_DI, /* 0x31 49. '1' */ + _ACPI_XD|_ACPI_DI, /* 0x32 50. '2' */ + _ACPI_XD|_ACPI_DI, /* 0x33 51. '3' */ + _ACPI_XD|_ACPI_DI, /* 0x34 52. '4' */ + _ACPI_XD|_ACPI_DI, /* 0x35 53. '5' */ + _ACPI_XD|_ACPI_DI, /* 0x36 54. '6' */ + _ACPI_XD|_ACPI_DI, /* 0x37 55. '7' */ + _ACPI_XD|_ACPI_DI, /* 0x38 56. '8' */ + _ACPI_XD|_ACPI_DI, /* 0x39 57. '9' */ + _ACPI_PU, /* 0x3A 58. ':' */ + _ACPI_PU, /* 0x3B 59. ';' */ + _ACPI_PU, /* 0x3C 60. '<' */ + _ACPI_PU, /* 0x3D 61. '=' */ + _ACPI_PU, /* 0x3E 62. '>' */ + _ACPI_PU, /* 0x3F 63. '?' */ + _ACPI_PU, /* 0x40 64. '@' */ + _ACPI_XD|_ACPI_UP, /* 0x41 65. 'A' */ + _ACPI_XD|_ACPI_UP, /* 0x42 66. 'B' */ + _ACPI_XD|_ACPI_UP, /* 0x43 67. 'C' */ + _ACPI_XD|_ACPI_UP, /* 0x44 68. 'D' */ + _ACPI_XD|_ACPI_UP, /* 0x45 69. 'E' */ + _ACPI_XD|_ACPI_UP, /* 0x46 70. 'F' */ + _ACPI_UP, /* 0x47 71. 'G' */ + _ACPI_UP, /* 0x48 72. 'H' */ + _ACPI_UP, /* 0x49 73. 'I' */ + _ACPI_UP, /* 0x4A 74. 'J' */ + _ACPI_UP, /* 0x4B 75. 'K' */ + _ACPI_UP, /* 0x4C 76. 'L' */ + _ACPI_UP, /* 0x4D 77. 'M' */ + _ACPI_UP, /* 0x4E 78. 'N' */ + _ACPI_UP, /* 0x4F 79. 'O' */ + _ACPI_UP, /* 0x50 80. 'P' */ + _ACPI_UP, /* 0x51 81. 'Q' */ + _ACPI_UP, /* 0x52 82. 'R' */ + _ACPI_UP, /* 0x53 83. 'S' */ + _ACPI_UP, /* 0x54 84. 'T' */ + _ACPI_UP, /* 0x55 85. 'U' */ + _ACPI_UP, /* 0x56 86. 'V' */ + _ACPI_UP, /* 0x57 87. 'W' */ + _ACPI_UP, /* 0x58 88. 'X' */ + _ACPI_UP, /* 0x59 89. 'Y' */ + _ACPI_UP, /* 0x5A 90. 'Z' */ + _ACPI_PU, /* 0x5B 91. '[' */ + _ACPI_PU, /* 0x5C 92. '\' */ + _ACPI_PU, /* 0x5D 93. ']' */ + _ACPI_PU, /* 0x5E 94. '^' */ + _ACPI_PU, /* 0x5F 95. '_' */ + _ACPI_PU, /* 0x60 96. '`' */ + _ACPI_XD|_ACPI_LO, /* 0x61 97. 'a' */ + _ACPI_XD|_ACPI_LO, /* 0x62 98. 'b' */ + _ACPI_XD|_ACPI_LO, /* 0x63 99. 'c' */ + _ACPI_XD|_ACPI_LO, /* 0x64 100. 'd' */ + _ACPI_XD|_ACPI_LO, /* 0x65 101. 'e' */ + _ACPI_XD|_ACPI_LO, /* 0x66 102. 'f' */ + _ACPI_LO, /* 0x67 103. 'g' */ + _ACPI_LO, /* 0x68 104. 'h' */ + _ACPI_LO, /* 0x69 105. 'i' */ + _ACPI_LO, /* 0x6A 106. 'j' */ + _ACPI_LO, /* 0x6B 107. 'k' */ + _ACPI_LO, /* 0x6C 108. 'l' */ + _ACPI_LO, /* 0x6D 109. 'm' */ + _ACPI_LO, /* 0x6E 110. 'n' */ + _ACPI_LO, /* 0x6F 111. 'o' */ + _ACPI_LO, /* 0x70 112. 'p' */ + _ACPI_LO, /* 0x71 113. 'q' */ + _ACPI_LO, /* 0x72 114. 'r' */ + _ACPI_LO, /* 0x73 115. 's' */ + _ACPI_LO, /* 0x74 116. 't' */ + _ACPI_LO, /* 0x75 117. 'u' */ + _ACPI_LO, /* 0x76 118. 'v' */ + _ACPI_LO, /* 0x77 119. 'w' */ + _ACPI_LO, /* 0x78 120. 'x' */ + _ACPI_LO, /* 0x79 121. 'y' */ + _ACPI_LO, /* 0x7A 122. 'z' */ + _ACPI_PU, /* 0x7B 123. '{' */ + _ACPI_PU, /* 0x7C 124. '|' */ + _ACPI_PU, /* 0x7D 125. '}' */ + _ACPI_PU, /* 0x7E 126. '~' */ + _ACPI_CN, /* 0x7F 127. */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80 to 0x8F */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90 to 0x9F */ @@ -522,10 +518,10 @@ const u8 _ctype[257] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xF0 to 0x100 */ }; -#define IS_UPPER(c) (_ctype[(unsigned char)(c)] & (_UP)) -#define IS_LOWER(c) (_ctype[(unsigned char)(c)] & (_LO)) -#define IS_DIGIT(c) (_ctype[(unsigned char)(c)] & (_DI)) -#define IS_SPACE(c) (_ctype[(unsigned char)(c)] & (_SP)) +#define IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) +#define IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) +#define IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI)) +#define IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP)) /******************************************************************************* @@ -628,7 +624,7 @@ acpi_cm_strstr ( return (NULL); } - /* Walk entire string, uppercasing the letters */ + /* Walk entire string, comparing the letters */ for (string = string1; *string2; ) { if (*string2 != *string) { diff --git a/drivers/acpi/common/cmcopy.c b/drivers/acpi/common/cmcopy.c index 08b498601..68b7bda01 100644 --- a/drivers/acpi/common/cmcopy.c +++ b/drivers/acpi/common/cmcopy.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmcopy - Internal to external object translation utilities - * $Revision: 56 $ + * $Revision: 61 $ * *****************************************************************************/ @@ -63,7 +63,7 @@ PKG_SEARCH_INFO level[MAX_PACKAGE_DEPTH]; * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_cm_build_external_simple_object ( ACPI_OPERAND_OBJECT *internal_obj, ACPI_OBJECT *external_obj, @@ -102,7 +102,7 @@ acpi_cm_build_external_simple_object ( case ACPI_TYPE_STRING: - length = internal_obj->string.length; + length = internal_obj->string.length + 1; external_obj->string.length = internal_obj->string.length; external_obj->string.pointer = (NATIVE_CHAR *) data_space; source_ptr = (u8 *) internal_obj->string.pointer; @@ -199,7 +199,7 @@ acpi_cm_build_external_simple_object ( * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_cm_build_external_package_object ( ACPI_OPERAND_OBJECT *internal_obj, u8 *buffer, @@ -487,6 +487,10 @@ acpi_cm_build_internal_simple_object ( } +#ifdef ACPI_FUTURE_IMPLEMENTATION + +/* Code to convert packages that are parameters to control methods */ + /****************************************************************************** * * FUNCTION: Acpi_cm_build_internal_package_object @@ -506,7 +510,7 @@ acpi_cm_build_internal_simple_object ( * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_cm_build_internal_package_object ( ACPI_OPERAND_OBJECT *internal_obj, u8 *buffer, @@ -641,6 +645,8 @@ acpi_cm_build_internal_package_object ( } /* while (1) */ } +#endif /* Future implementation */ + /****************************************************************************** * @@ -667,6 +673,10 @@ acpi_cm_build_internal_object ( /* * Package objects contain other objects (which can be objects) * buildpackage does it all + * + * TBD: Package conversion must be completed and tested + * NOTE: this code converts packages as input parameters to + * control methods only. This is a very, very rare case. */ /* Status = Acpi_cm_build_internal_package_object(Internal_obj, diff --git a/drivers/acpi/common/cmdebug.c b/drivers/acpi/common/cmdebug.c index 8e5fc0969..a55372d5c 100644 --- a/drivers/acpi/common/cmdebug.c +++ b/drivers/acpi/common/cmdebug.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmdebug - Debug print routines - * $Revision: 60 $ + * $Revision: 61 $ * *****************************************************************************/ @@ -118,7 +118,7 @@ function_trace_ptr ( acpi_gbl_nesting_level++; debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS, - " %2.2ld Entered Function: %s, 0x%p\n", + " %2.2ld Entered Function: %s, %p\n", acpi_gbl_nesting_level, function_name, pointer); } @@ -184,7 +184,7 @@ function_trace_u32 ( acpi_gbl_nesting_level++; debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS, - " %2.2ld Entered Function: %s, 0x%lX\n", + " %2.2ld Entered Function: %s, %lX\n", acpi_gbl_nesting_level, function_name, integer); } @@ -285,7 +285,7 @@ function_value_exit ( { debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS, - " %2.2ld Exiting Function: %s, 0x%X\n", + " %2.2ld Exiting Function: %s, %X\n", acpi_gbl_nesting_level, function_name, value); acpi_gbl_nesting_level--; @@ -319,7 +319,7 @@ function_ptr_exit ( { debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS, - " %2.2ld Exiting Function: %s, 0x%p\n", + " %2.2ld Exiting Function: %s, %p\n", acpi_gbl_nesting_level, function_name, ptr); acpi_gbl_nesting_level--; diff --git a/drivers/acpi/common/cmdelete.c b/drivers/acpi/common/cmdelete.c index 9eca0ca29..a6e74c12f 100644 --- a/drivers/acpi/common/cmdelete.c +++ b/drivers/acpi/common/cmdelete.c @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: cmdelete - object deletion and reference count utilities - * $Revision: 53 $ + * $Revision: 60 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -34,7 +34,7 @@ MODULE_NAME ("cmdelete") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_delete_internal_obj * @@ -52,6 +52,7 @@ acpi_cm_delete_internal_obj ( ACPI_OPERAND_OBJECT *object) { void *obj_pointer = NULL; + ACPI_OPERAND_OBJECT *handler_desc; if (!object) { @@ -120,6 +121,36 @@ acpi_cm_delete_internal_obj ( break; + case ACPI_TYPE_REGION: + + + if (object->region.extra) { + /* + * Free the Region_context if and only if the handler is one of the + * default handlers -- and therefore, we created the context object + * locally, it was not created by an external caller. + */ + handler_desc = object->region.addr_handler; + if ((handler_desc) && + (handler_desc->addr_handler.hflags == ADDR_HANDLER_DEFAULT_INSTALLED)) + { + obj_pointer = object->region.extra->extra.region_context; + } + + /* Now we can free the Extra object */ + + acpi_cm_delete_object_desc (object->region.extra); + } + break; + + + case ACPI_TYPE_FIELD_UNIT: + + if (object->field_unit.extra) { + acpi_cm_delete_object_desc (object->field_unit.extra); + } + break; + default: break; } @@ -148,7 +179,7 @@ acpi_cm_delete_internal_obj ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_delete_internal_object_list * @@ -197,12 +228,11 @@ acpi_cm_delete_internal_object_list ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_update_ref_count * * PARAMETERS: *Object - Object whose ref count is to be updated - * Count - Current ref count * Action - What to do * * RETURN: New ref count @@ -211,7 +241,7 @@ acpi_cm_delete_internal_object_list ( * ******************************************************************************/ -void +static void acpi_cm_update_ref_count ( ACPI_OPERAND_OBJECT *object, u32 action) @@ -287,7 +317,7 @@ acpi_cm_update_ref_count ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_update_object_reference * @@ -397,9 +427,8 @@ acpi_cm_update_object_reference ( * these are simply ignored */ - status = - acpi_cm_create_update_state_and_push (object->package.elements[i], - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->package.elements[i], action, &state_list); if (ACPI_FAILURE (status)) { return (status); } @@ -409,9 +438,9 @@ acpi_cm_update_object_reference ( case ACPI_TYPE_FIELD_UNIT: - status = - acpi_cm_create_update_state_and_push (object->field_unit.container, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->field_unit.container, action, &state_list); + if (ACPI_FAILURE (status)) { return (status); } @@ -420,9 +449,8 @@ acpi_cm_update_object_reference ( case INTERNAL_TYPE_DEF_FIELD: - status = - acpi_cm_create_update_state_and_push (object->field.container, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->field.container, action, &state_list); if (ACPI_FAILURE (status)) { return (status); } @@ -431,16 +459,14 @@ acpi_cm_update_object_reference ( case INTERNAL_TYPE_BANK_FIELD: - status = - acpi_cm_create_update_state_and_push (object->bank_field.bank_select, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->bank_field.bank_select, action, &state_list); if (ACPI_FAILURE (status)) { return (status); } - status = - acpi_cm_create_update_state_and_push (object->bank_field.container, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->bank_field.container, action, &state_list); if (ACPI_FAILURE (status)) { return (status); } @@ -449,8 +475,6 @@ acpi_cm_update_object_reference ( case ACPI_TYPE_REGION: - acpi_cm_update_ref_count (object->region.method, action); - /* TBD: [Investigate] Acpi_cm_update_ref_count (Object->Region.Addr_handler, Action); */ @@ -490,7 +514,7 @@ acpi_cm_update_object_reference ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_add_reference * @@ -517,7 +541,6 @@ acpi_cm_add_reference ( return; } - /* * We have a valid ACPI internal object, now increment the reference count */ @@ -528,7 +551,7 @@ acpi_cm_add_reference ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_remove_reference * @@ -562,15 +585,6 @@ acpi_cm_remove_reference ( acpi_cm_update_object_reference (object, REF_DECREMENT); - /* - * If the reference count has reached zero, - * delete the object and all sub-objects contained within it - */ -/* - if (Object->Common.Reference_count == 0) { - Acpi_cm_delete_internal_obj (Object); - } -*/ return; } diff --git a/drivers/acpi/common/cmeval.c b/drivers/acpi/common/cmeval.c index 21fd86b0c..29a5cefa6 100644 --- a/drivers/acpi/common/cmeval.c +++ b/drivers/acpi/common/cmeval.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmeval - Object evaluation - * $Revision: 14 $ + * $Revision: 19 $ * *****************************************************************************/ @@ -37,7 +37,8 @@ * * FUNCTION: Acpi_cm_evaluate_numeric_object * - * PARAMETERS: Device_node - Node for the device + * PARAMETERS: *Object_name - Object name to be evaluated + * Device_node - Node for the device * *Address - Where the value is returned * * RETURN: Status @@ -53,7 +54,7 @@ ACPI_STATUS acpi_cm_evaluate_numeric_object ( NATIVE_CHAR *object_name, ACPI_NAMESPACE_NODE *device_node, - u32 *address) + ACPI_INTEGER *address) { ACPI_OPERAND_OBJECT *obj_desc; ACPI_STATUS status; @@ -151,15 +152,13 @@ acpi_cm_execute_HID ( if (obj_desc->common.type == ACPI_TYPE_NUMBER) { /* Convert the Numeric HID to string */ - acpi_aml_eisa_id_to_string (obj_desc->number.value, hid->data.buffer); - hid->type = STRING_DEVICE_ID; + acpi_aml_eisa_id_to_string ((u32) obj_desc->number.value, hid->buffer); } else { /* Copy the String HID from the returned object */ - hid->data.string_ptr = obj_desc->string.pointer; - hid->type = STRING_PTR_DEVICE_ID; + STRNCPY(hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer)); } } @@ -226,16 +225,15 @@ acpi_cm_execute_UID ( else { if (obj_desc->common.type == ACPI_TYPE_NUMBER) { - /* Convert the Numeric HID to string */ + /* Convert the Numeric UID to string */ - uid->data.number = obj_desc->number.value; + acpi_aml_unsigned_integer_to_string (obj_desc->number.value, uid->buffer); } else { - /* Copy the String HID from the returned object */ + /* Copy the String UID from the returned object */ - uid->data.string_ptr = obj_desc->string.pointer; - uid->type = STRING_PTR_DEVICE_ID; + STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer)); } } @@ -276,35 +274,35 @@ acpi_cm_execute_STA ( status = acpi_ns_evaluate_relative (device_node, METHOD_NAME__STA, NULL, &obj_desc); - if (ACPI_FAILURE (status)) { - - - return (status); + if (AE_NOT_FOUND == status) { + *flags = 0x0F; + status = AE_OK; } - /* Did we get a return object? */ - - if (!obj_desc) { - return (AE_TYPE); - } + else /* success */ { + /* Did we get a return object? */ - /* Is the return object of the correct type? */ + if (!obj_desc) { + return (AE_TYPE); + } - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { - status = AE_TYPE; - } + /* Is the return object of the correct type? */ - else { - /* Extract the status flags */ + if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + status = AE_TYPE; + } - *flags = obj_desc->number.value; - } + else { + /* Extract the status flags */ + *flags = (u32) obj_desc->number.value; + } - /* On exit, we must delete the return object */ + /* On exit, we must delete the return object */ - acpi_cm_remove_reference (obj_desc); + acpi_cm_remove_reference (obj_desc); + } return (status); } diff --git a/drivers/acpi/common/cmglobal.c b/drivers/acpi/common/cmglobal.c index 82b810e4c..4b4460f46 100644 --- a/drivers/acpi/common/cmglobal.c +++ b/drivers/acpi/common/cmglobal.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmglobal - Global variables for the ACPI subsystem - * $Revision: 99 $ + * $Revision: 112 $ * *****************************************************************************/ @@ -29,6 +29,7 @@ #include "acevents.h" #include "acnamesp.h" #include "acinterp.h" +#include "amlcode.h" #define _COMPONENT MISCELLANEOUS @@ -52,7 +53,7 @@ u32 acpi_dbg_level = NORMAL_DEFAULT; /* Debug switch - layer (component) mask */ -u32 acpi_dbg_layer = ALL_COMPONENTS; +u32 acpi_dbg_layer = COMPONENT_DEFAULT; u32 acpi_gbl_nesting_level = 0; @@ -70,6 +71,9 @@ u32 acpi_gbl_startup_flags = 0; u8 acpi_gbl_shutdown = TRUE; +u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; + + /****************************************************************************** * * Namespace globals @@ -134,16 +138,16 @@ u8 acpi_gbl_ns_properties[] = NSP_NORMAL, /* 21 Alias */ NSP_NORMAL, /* 22 Notify */ NSP_NORMAL, /* 23 Address Handler */ - NSP_NORMAL, /* 24 Def_field_defn */ - NSP_NORMAL, /* 25 Bank_field_defn */ - NSP_NORMAL, /* 26 Index_field_defn */ - NSP_NORMAL, /* 27 If */ - NSP_NORMAL, /* 28 Else */ - NSP_NORMAL, /* 29 While */ - NSP_NEWSCOPE, /* 30 Scope */ - NSP_LOCAL, /* 31 Def_any */ - NSP_NORMAL, /* 32 Method Arg */ - NSP_NORMAL, /* 33 Method Local */ + NSP_NEWSCOPE | NSP_LOCAL, /* 24 Resource */ + NSP_NORMAL, /* 25 Def_field_defn */ + NSP_NORMAL, /* 26 Bank_field_defn */ + NSP_NORMAL, /* 27 Index_field_defn */ + NSP_NORMAL, /* 28 If */ + NSP_NORMAL, /* 29 Else */ + NSP_NORMAL, /* 30 While */ + NSP_NEWSCOPE, /* 31 Scope */ + NSP_LOCAL, /* 32 Def_any */ + NSP_NORMAL, /* 33 Extra */ NSP_NORMAL /* 34 Invalid */ }; @@ -152,6 +156,10 @@ u8 acpi_gbl_ns_properties[] = * * Table globals * + * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. + * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables + * that are not used by the subsystem are simply ignored. + * ******************************************************************************/ @@ -160,22 +168,17 @@ ACPI_TABLE_DESC acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] = { - /* Name, Signature, Signature size, How many allowed?, Supported? Global typed pointer */ - - /* RSDP 0 */ {"RSDP", RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, - /* APIC 1 */ {APIC_SIG, APIC_SIG, sizeof (APIC_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_APIC}, - /* DSDT 2 */ {DSDT_SIG, DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_DSDT}, - /* FACP 3 */ {FACP_SIG, FACP_SIG, sizeof (FACP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACP}, - /* FACS 4 */ {FACS_SIG, FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACS}, - /* PSDT 5 */ {PSDT_SIG, PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, - /* RSDT 6 */ {RSDT_SIG, RSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, - /* SSDT 7 */ {SSDT_SIG, SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, - /* SBST 8 */ {SBST_SIG, SBST_SIG, sizeof (SBST_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_SBST}, - /* BOOT 9 */ {BOOT_SIG, BOOT_SIG, sizeof (BOOT_SIG)-1, ACPI_TABLE_SINGLE, AE_SUPPORT, NULL} + /*********** Name, Signature, Signature size, How many allowed?, Supported? Global typed pointer */ + + /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, + /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_DSDT}, + /* FADT 2 */ {FADT_SIG, FADT_SIG, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FADT}, + /* FACS 3 */ {FACS_SIG, FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACS}, + /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, + /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, + /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, }; -ACPI_INIT_DATA acpi_gbl_acpi_init_data; - /***************************************************************************** * @@ -337,22 +340,15 @@ acpi_cm_allocate_owner_id ( ***************************************************************************/ void -acpi_cm_init_globals (ACPI_INIT_DATA *init_data) +acpi_cm_init_globals ( + void) { u32 i; - if (init_data) { - MEMCPY (&acpi_gbl_acpi_init_data, init_data, sizeof (ACPI_INIT_DATA)); - } - - else { - MEMSET (&acpi_gbl_acpi_init_data, 0, sizeof (ACPI_INIT_DATA)); - } - /* ACPI table structure */ - for (i = 0; i < ACPI_TABLE_MAX; i++) { + for (i = 0; i < NUM_ACPI_TABLES; i++) { acpi_gbl_acpi_tables[i].prev = &acpi_gbl_acpi_tables[i]; acpi_gbl_acpi_tables[i].next = &acpi_gbl_acpi_tables[i]; acpi_gbl_acpi_tables[i].pointer = NULL; @@ -364,7 +360,7 @@ acpi_cm_init_globals (ACPI_INIT_DATA *init_data) /* Address Space handler array */ - for (i = 0; i < ACPI_MAX_ADDRESS_SPACE; i++) { + for (i = 0; i < ACPI_NUM_ADDRESS_SPACES; i++) { acpi_gbl_address_spaces[i].handler = NULL; acpi_gbl_address_spaces[i].context = NULL; } @@ -385,12 +381,10 @@ acpi_cm_init_globals (ACPI_INIT_DATA *init_data) /* Global "typed" ACPI table pointers */ acpi_gbl_RSDP = NULL; - acpi_gbl_RSDT = NULL; + acpi_gbl_XSDT = NULL; acpi_gbl_FACS = NULL; - acpi_gbl_FACP = NULL; - acpi_gbl_APIC = NULL; + acpi_gbl_FADT = NULL; acpi_gbl_DSDT = NULL; - acpi_gbl_SBST = NULL; /* Global Lock support */ @@ -404,7 +398,6 @@ acpi_cm_init_globals (ACPI_INIT_DATA *init_data) acpi_gbl_startup_flags = 0; acpi_gbl_global_lock_set = FALSE; acpi_gbl_rsdp_original_location = 0; - acpi_gbl_when_to_parse_methods = METHOD_PARSE_CONFIGURATION; acpi_gbl_cm_single_step = FALSE; acpi_gbl_db_terminate_threads = FALSE; acpi_gbl_shutdown = FALSE; @@ -442,15 +435,6 @@ acpi_cm_init_globals (ACPI_INIT_DATA *init_data) acpi_gbl_walk_state_cache_requests = 0; acpi_gbl_walk_state_cache_hits = 0; - /* Interpreter */ - - acpi_gbl_buf_seq = 0; - acpi_gbl_node_err = FALSE; - - /* Parser */ - - acpi_gbl_parsed_namespace_root = NULL; - /* Hardware oriented */ acpi_gbl_gpe0enable_register_save = NULL; diff --git a/drivers/acpi/common/cminit.c b/drivers/acpi/common/cminit.c index 18b243a0f..e6cfb7655 100644 --- a/drivers/acpi/common/cminit.c +++ b/drivers/acpi/common/cminit.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cminit - Common ACPI subsystem initialization - * $Revision: 79 $ + * $Revision: 91 $ * *****************************************************************************/ @@ -37,232 +37,112 @@ /******************************************************************************* * - * FUNCTION: Acpi_cm_facp_register_error + * FUNCTION: Acpi_cm_fadt_register_error * * PARAMETERS: *Register_name - Pointer to string identifying register * Value - Actual register contents value * Acpi_test_spec_section - TDS section containing assertion * Acpi_assertion - Assertion number being tested * - * RETURN: none + * RETURN: AE_BAD_VALUE * * DESCRIPTION: Display failure message and link failure to TDS assertion * ******************************************************************************/ -void -acpi_cm_facp_register_error ( +static ACPI_STATUS +acpi_cm_fadt_register_error ( NATIVE_CHAR *register_name, u32 value) { - REPORT_ERROR ("Invalid FACP register value"); + REPORT_ERROR ( + ("Invalid FADT register value, %s=%X (FADT=%p)\n", + register_name, value, acpi_gbl_FADT)); + + return (AE_BAD_VALUE); } /****************************************************************************** * - * FUNCTION: Acpi_cm_hardware_initialize + * FUNCTION: Acpi_cm_validate_fadt * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Initialize and validate various ACPI registers + * DESCRIPTION: Validate various ACPI registers in the FADT * ******************************************************************************/ ACPI_STATUS -acpi_cm_hardware_initialize (void) +acpi_cm_validate_fadt ( + void) { - ACPI_STATUS status = AE_OK; - u32 index; + ACPI_STATUS status = AE_OK; - /* Are we running on the actual hardware */ + /* + * Verify Fixed ACPI Description Table fields, + * but don't abort on any problems, just display error + */ - if (!acpi_gbl_acpi_hardware_present) { - /* No, just return */ - - return (AE_OK); + if (acpi_gbl_FADT->pm1_evt_len < 4) { + status = acpi_cm_fadt_register_error ("PM1_EVT_LEN", + (u32) acpi_gbl_FADT->pm1_evt_len); } - /* We must have the ACPI tables by the time we get here */ - - if (!acpi_gbl_FACP) { - acpi_gbl_restore_acpi_chipset = FALSE; - - return (AE_NO_ACPI_TABLES); + if (!acpi_gbl_FADT->pm1_cnt_len) { + status = acpi_cm_fadt_register_error ("PM1_CNT_LEN", + 0); } - /* Must support *some* mode! */ -/* - if (!(System_flags & SYS_MODES_MASK)) { - Restore_acpi_chipset = FALSE; - - return (AE_ERROR); + if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address)) { + status = acpi_cm_fadt_register_error ("PM1a_EVT_BLK", + 0); } -*/ + if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_cnt_blk.address)) { + status = acpi_cm_fadt_register_error ("PM1a_CNT_BLK", + 0); + } + if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)) { + status = acpi_cm_fadt_register_error ("PM_TMR_BLK", + 0); + } - switch (acpi_gbl_system_flags & SYS_MODES_MASK) + if ((ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm2_cnt_blk.address) && + !acpi_gbl_FADT->pm2_cnt_len)) { - /* Identify current ACPI/legacy mode */ - - case (SYS_MODE_ACPI): - - acpi_gbl_original_mode = SYS_MODE_ACPI; - break; - - - case (SYS_MODE_LEGACY): - - acpi_gbl_original_mode = SYS_MODE_LEGACY; - break; + status = acpi_cm_fadt_register_error ("PM2_CNT_LEN", + (u32) acpi_gbl_FADT->pm2_cnt_len); + } + if (acpi_gbl_FADT->pm_tm_len < 4) { + status = acpi_cm_fadt_register_error ("PM_TM_LEN", + (u32) acpi_gbl_FADT->pm_tm_len); + } - case (SYS_MODE_ACPI | SYS_MODE_LEGACY): + /* length of GPE blocks must be a multiple of 2 */ - if (acpi_hw_get_mode () == SYS_MODE_ACPI) { - acpi_gbl_original_mode = SYS_MODE_ACPI; - } - else { - acpi_gbl_original_mode = SYS_MODE_LEGACY; - } - break; + if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) && + (acpi_gbl_FADT->gpe0blk_len & 1)) + { + status = acpi_cm_fadt_register_error ("GPE0_BLK_LEN", + (u32) acpi_gbl_FADT->gpe0blk_len); } - - if (acpi_gbl_system_flags & SYS_MODE_ACPI) { - /* Target system supports ACPI mode */ - - /* - * The purpose of this block of code is to save the initial state - * of the ACPI event enable registers. An exit function will be - * registered which will restore this state when the application - * exits. The exit function will also clear all of the ACPI event - * status bits prior to restoring the original mode. - * - * The location of the PM1a_evt_blk enable registers is defined as the - * base of PM1a_evt_blk + PM1a_evt_blk_length / 2. Since the spec further - * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset - * for the enable registers is always 2 from the base. It is hard - * coded here. If this changes in the spec, this code will need to - * be modified. The PM1b_evt_blk behaves as expected. - */ - - acpi_gbl_pm1_enable_register_save = - acpi_os_in16 ((acpi_gbl_FACP->pm1a_evt_blk + 2)); - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_gbl_pm1_enable_register_save |= - acpi_os_in16 ((acpi_gbl_FACP->pm1b_evt_blk + 2)); - } - - - /* - * The GPEs behave similarly, except that the length of the register - * block is not fixed, so the buffer must be allocated with malloc - */ - - if (acpi_gbl_FACP->gpe0blk && acpi_gbl_FACP->gpe0blk_len) { - /* GPE0 specified in FACP */ - - acpi_gbl_gpe0enable_register_save = - acpi_cm_allocate (DIV_2 (acpi_gbl_FACP->gpe0blk_len)); - if (!acpi_gbl_gpe0enable_register_save) { - return (AE_NO_MEMORY); - } - - /* Save state of GPE0 enable bits */ - - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe0blk_len); index++) { - acpi_gbl_gpe0enable_register_save[index] = - acpi_os_in8 (acpi_gbl_FACP->gpe0blk + - DIV_2 (acpi_gbl_FACP->gpe0blk_len)); - } - } - - else { - acpi_gbl_gpe0enable_register_save = NULL; - } - - if (acpi_gbl_FACP->gpe1_blk && acpi_gbl_FACP->gpe1_blk_len) { - /* GPE1 defined */ - - acpi_gbl_gpe1_enable_register_save = - acpi_cm_allocate (DIV_2 (acpi_gbl_FACP->gpe1_blk_len)); - if (!acpi_gbl_gpe1_enable_register_save) { - return (AE_NO_MEMORY); - } - - /* save state of GPE1 enable bits */ - - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe1_blk_len); index++) { - acpi_gbl_gpe1_enable_register_save[index] = - acpi_os_in8 (acpi_gbl_FACP->gpe1_blk + - DIV_2 (acpi_gbl_FACP->gpe1_blk_len)); - } - } - - else { - acpi_gbl_gpe1_enable_register_save = NULL; - } - - - /* - * Verify Fixed ACPI Description Table fields, - * but don't abort on any problems, just display error - */ - - if (acpi_gbl_FACP->pm1_evt_len < 4) { - acpi_cm_facp_register_error ("PM1_EVT_LEN", - (u32) acpi_gbl_FACP->pm1_evt_len); - } - - if (!acpi_gbl_FACP->pm1_cnt_len) { - acpi_cm_facp_register_error ("PM1_CNT_LEN", - (u32) acpi_gbl_FACP->pm1_cnt_len); - } - - if (!acpi_gbl_FACP->pm1a_evt_blk) { - acpi_cm_facp_register_error ("PM1a_EVT_BLK", acpi_gbl_FACP->pm1a_evt_blk); - } - - if (!acpi_gbl_FACP->pm1a_cnt_blk) { - acpi_cm_facp_register_error ("PM1a_CNT_BLK", acpi_gbl_FACP->pm1a_cnt_blk); - } - - if (!acpi_gbl_FACP->pm_tmr_blk) { - acpi_cm_facp_register_error ("PM_TMR_BLK", acpi_gbl_FACP->pm_tmr_blk); - } - - if (acpi_gbl_FACP->pm2_cnt_blk && !acpi_gbl_FACP->pm2_cnt_len) { - acpi_cm_facp_register_error ("PM2_CNT_LEN", - (u32) acpi_gbl_FACP->pm2_cnt_len); - } - - if (acpi_gbl_FACP->pm_tm_len < 4) { - acpi_cm_facp_register_error ("PM_TM_LEN", - (u32) acpi_gbl_FACP->pm_tm_len); - } - - /* length not multiple of 2 */ - if (acpi_gbl_FACP->gpe0blk && (acpi_gbl_FACP->gpe0blk_len & 1)) { - acpi_cm_facp_register_error ("GPE0_BLK_LEN", - (u32) acpi_gbl_FACP->gpe0blk_len); - } - - /* length not multiple of 2 */ - if (acpi_gbl_FACP->gpe1_blk && (acpi_gbl_FACP->gpe1_blk_len & 1)) { - acpi_cm_facp_register_error ("GPE1_BLK_LEN", - (u32) acpi_gbl_FACP->gpe1_blk_len); - } + if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) && + (acpi_gbl_FADT->gpe1_blk_len & 1)) + { + status = acpi_cm_fadt_register_error ("GPE1_BLK_LEN", + (u32) acpi_gbl_FADT->gpe1_blk_len); } - return (status); } @@ -355,8 +235,6 @@ acpi_cm_subsystem_shutdown (void) acpi_cm_dump_current_allocations (ACPI_UINT32_MAX, NULL); #endif - BREAKPOINT3; - return (AE_OK); } diff --git a/drivers/acpi/common/cmobject.c b/drivers/acpi/common/cmobject.c index a60e58f68..95e70fb14 100644 --- a/drivers/acpi/common/cmobject.c +++ b/drivers/acpi/common/cmobject.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmobject - ACPI object create/delete/size/cache routines - * $Revision: 27 $ + * $Revision: 34 $ * *****************************************************************************/ @@ -193,7 +193,7 @@ _cm_allocate_object_desc ( /* Allocation failed */ _REPORT_ERROR (module_name, line_number, component_id, - "Could not allocate Object Descriptor"); + ("Could not allocate an object descriptor\n")); return (NULL); } @@ -424,7 +424,7 @@ acpi_cm_get_simple_object_size ( case ACPI_TYPE_STRING: - length += internal_obj->string.length; + length += internal_obj->string.length + 1; break; @@ -499,10 +499,10 @@ acpi_cm_get_package_object_size ( { ACPI_OPERAND_OBJECT *this_internal_obj; - ACPI_OPERAND_OBJECT *parent_obj[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 }; + ACPI_OPERAND_OBJECT *parent_obj[MAX_PACKAGE_DEPTH]; ACPI_OPERAND_OBJECT *this_parent; u32 this_index; - u32 index[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 }; + u32 index[MAX_PACKAGE_DEPTH]; u32 length = 0; u32 object_space; u32 current_depth = 0; @@ -510,6 +510,11 @@ acpi_cm_get_package_object_size ( ACPI_STATUS status; + /* Init the package stack TBD: replace with linked list */ + + MEMSET(parent_obj, 0, MAX_PACKAGE_DEPTH); + MEMSET(index, 0, MAX_PACKAGE_DEPTH); + parent_obj[0] = internal_obj; while (1) { @@ -519,7 +524,7 @@ acpi_cm_get_package_object_size ( /* - * Check for 1) An unitialized package element. It is completely + * Check for 1) An uninitialized package element. It is completely * legal to declare a package and leave it uninitialized * 2) Any type other than a package. Packages are handled * below. diff --git a/drivers/acpi/common/cmutils.c b/drivers/acpi/common/cmutils.c index 6ebf3fb42..cb3d959c8 100644 --- a/drivers/acpi/common/cmutils.c +++ b/drivers/acpi/common/cmutils.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: cmutils - common utility procedures - * $Revision: 18 $ + * $Revision: 21 $ * ******************************************************************************/ @@ -618,6 +618,55 @@ acpi_cm_delete_generic_state_cache ( /******************************************************************************* * + * FUNCTION: Acpi_cm_resolve_package_references + * + * PARAMETERS: Obj_desc - The Package object on which to resolve refs + * + * RETURN: Status + * + * DESCRIPTION: Walk through a package and turn internal references into values + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_resolve_package_references ( + ACPI_OPERAND_OBJECT *obj_desc) +{ + u32 count; + ACPI_OPERAND_OBJECT *sub_object; + + if (obj_desc->common.type != ACPI_TYPE_PACKAGE) { + /* Must be a package */ + + REPORT_ERROR (("Must resolve Package Refs on a Package\n")); + return(AE_ERROR); + } + + for (count = 0; count < obj_desc->package.count; count++) { + sub_object = obj_desc->package.elements[count]; + + if (sub_object->common.type == INTERNAL_TYPE_REFERENCE) { + if (sub_object->reference.op_code == AML_ZERO_OP) { + sub_object->common.type = ACPI_TYPE_NUMBER; + sub_object->number.value = 0; + } + else if (sub_object->reference.op_code == AML_ONE_OP) { + sub_object->common.type = ACPI_TYPE_NUMBER; + sub_object->number.value = 1; + } + else if (sub_object->reference.op_code == AML_ONES_OP) { + sub_object->common.type = ACPI_TYPE_NUMBER; + sub_object->number.value = ACPI_INTEGER_MAX; + } + } + } + + return(AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: _Report_error * * PARAMETERS: Module_name - Caller's module name (for error output) @@ -635,13 +684,11 @@ void _report_error ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message) + u32 component_id) { - debug_print (module_name, line_number, component_id, ACPI_ERROR, - "*** Error: %s\n", message); + acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number); } @@ -664,13 +711,10 @@ void _report_warning ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message) + u32 component_id) { - debug_print (module_name, line_number, component_id, ACPI_WARN, - "*** Warning: %s\n", message); - + acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number); } @@ -693,13 +737,10 @@ void _report_info ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message) + u32 component_id) { - debug_print (module_name, line_number, component_id, ACPI_INFO, - "*** Info: %s\n", message); - + acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number); } diff --git a/drivers/acpi/common/cmxface.c b/drivers/acpi/common/cmxface.c index 4b4d2d06b..fc063850c 100644 --- a/drivers/acpi/common/cmxface.c +++ b/drivers/acpi/common/cmxface.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmxface - External interfaces for "global" ACPI functions - * $Revision: 43 $ + * $Revision: 55 $ * *****************************************************************************/ @@ -39,7 +39,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_initialize + * FUNCTION: Acpi_initialize_subsystem * * PARAMETERS: None * @@ -51,20 +51,22 @@ ******************************************************************************/ ACPI_STATUS -acpi_initialize (ACPI_INIT_DATA *init_data) +acpi_initialize_subsystem ( + void) { ACPI_STATUS status; /* Initialize all globals used by the subsystem */ - acpi_cm_init_globals (init_data); + acpi_cm_init_globals (); /* Initialize the OS-Dependent layer */ status = acpi_os_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR ("OSD Initialization Failure"); + REPORT_ERROR (("OSD failed to initialize, %s\n", + acpi_cm_format_exception (status))); return (status); } @@ -72,10 +74,24 @@ acpi_initialize (ACPI_INIT_DATA *init_data) status = acpi_cm_mutex_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR ("Global Mutex Initialization Failure"); + REPORT_ERROR (("Global mutex creation failure, %s\n", + acpi_cm_format_exception (status))); return (status); } + /* + * Initialize the namespace manager and + * the root of the namespace tree + */ + + status = acpi_ns_root_initialize (); + if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Namespace initialization failure, %s\n", + acpi_cm_format_exception (status))); + return (status); + } + + /* If configured, initialize the AML debugger */ DEBUGGER_EXEC (acpi_db_initialize ()); @@ -86,6 +102,116 @@ acpi_initialize (ACPI_INIT_DATA *init_data) /******************************************************************************* * + * FUNCTION: Acpi_enable_subsystem + * + * PARAMETERS: Flags - Init/enable Options + * + * RETURN: Status + * + * DESCRIPTION: Completes the subsystem initialization including hardware. + * Puts system into ACPI mode if it isn't already. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_enable_subsystem ( + u32 flags) +{ + ACPI_STATUS status = AE_OK; + + + /* Sanity check the FADT for valid values */ + + status = acpi_cm_validate_fadt (); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* + * Install the default Op_region handlers. These are + * installed unless other handlers have already been + * installed via the Install_address_space_handler interface + */ + + if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { + status = acpi_ev_install_default_address_space_handlers (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + /* + * We must initialize the hardware before we can enable ACPI. + */ + + if (!(flags & ACPI_NO_HARDWARE_INIT)) { + status = acpi_hw_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + /* + * Enable ACPI on this platform + */ + + if (!(flags & ACPI_NO_ACPI_ENABLE)) { + status = acpi_enable (); + if (ACPI_FAILURE (status)) { + /* TBD: workaround. Old Lions don't enable properly */ + /*return (Status);*/ + } + } + + /* + * Note: + * We must have the hardware AND events initialized before we can execute + * ANY control methods SAFELY. Any control method can require ACPI hardware + * support, so the hardware MUST be initialized before execution! + */ + + if (!(flags & ACPI_NO_EVENT_INIT)) { + status = acpi_ev_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + + /* + * Initialize all device objects in the namespace + * This runs the _STA, _INI, and _HID methods, and detects + * the PCI root bus(es) + */ + + if (!(flags & ACPI_NO_DEVICE_INIT)) { + status = acpi_ns_initialize_devices (flags & ACPI_NO_PCI_INIT); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + + /* + * Initialize the objects that remain unitialized. This + * runs the executable AML that is part of the declaration of Op_regions + * and Fields. + */ + + if (!(flags & ACPI_NO_OBJECT_INIT)) { + status = acpi_ns_initialize_objects (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + + return (status); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_terminate * * PARAMETERS: None @@ -102,7 +228,7 @@ acpi_terminate (void) /* Terminate the AML Debuger if present */ - acpi_gbl_db_terminate_threads = TRUE; + DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); /* TBD: [Investigate] This is no longer needed?*/ /* Acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */ @@ -202,7 +328,7 @@ acpi_get_system_info ( /* Current status of the ACPI tables, per table type */ info_ptr->num_table_types = NUM_ACPI_TABLES; - for (i = 0; i < NUM_ACPI_TABLES; i++); { + for (i = 0; i < NUM_ACPI_TABLES; i++) { info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count; } diff --git a/drivers/acpi/cpu.c b/drivers/acpi/cpu.c index 2736e86a9..00ec59da5 100644 --- a/drivers/acpi/cpu.c +++ b/drivers/acpi/cpu.c @@ -37,55 +37,65 @@ static unsigned long acpi_pblk = ACPI_INVALID; static int acpi_c2_tested = 0; static int acpi_c3_tested = 0; static int acpi_max_c_state = 1; +static int acpi_pm_tmr_len; /* * Clear busmaster activity flag */ static inline void -acpi_clear_bm_activity(struct acpi_facp *facp) +acpi_clear_bm_activity(void) { - acpi_write_pm1_status(facp, ACPI_BM); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 0); } /* * Returns 1 if there has been busmaster activity */ static inline int -acpi_bm_activity(struct acpi_facp *facp) +acpi_bm_activity(void) { - return acpi_read_pm1_status(facp) & ACPI_BM; + return acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, BM_STS); } /* * Set system to sleep through busmaster requests */ static void -acpi_sleep_on_busmaster(struct acpi_facp *facp) +acpi_sleep_on_busmaster(void) { - u32 pm1_cntr = acpi_read_pm1_control(facp); - if (pm1_cntr & ACPI_BM_RLD) { - pm1_cntr &= ~ACPI_BM_RLD; - acpi_write_pm1_control(facp, pm1_cntr); - } + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); } /* * Set system to wake on busmaster requests */ static void -acpi_wake_on_busmaster(struct acpi_facp *facp) +acpi_wake_on_busmaster(void) { - u32 pm1_cntr = acpi_read_pm1_control(facp); - if (!(pm1_cntr & ACPI_BM_RLD)) { - pm1_cntr |= ACPI_BM_RLD; - acpi_write_pm1_control(facp, pm1_cntr); - } - acpi_clear_bm_activity(facp); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); } -/* The ACPI timer is just the low 24 bits */ -#define TIME_BEGIN(tmr) inl(tmr) -#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff) +u32 +acpi_read_pm_timer(void) +{ + return acpi_hw_register_read(ACPI_MTX_LOCK, PM_TIMER); +} + +/* + * Do a compare, accounting for 24/32bit rollover + */ +static u32 +acpi_compare_pm_timers(u32 first, u32 second) +{ + if (first < second) { + return (second - first); + } else { + if (acpi_pm_tmr_len == 24) + return (second + (0xFFFFFF - first)); + else + return (second + (0xFFFFFFFF - first)); + } +} /* * Idle loop (uniprocessor only) @@ -94,11 +104,11 @@ static void acpi_idle(void) { static int sleep_level = 1; - struct acpi_facp *facp = &acpi_facp; + FADT_DESCRIPTOR *fadt = &acpi_fadt; - if (!facp - || facp->hdr.signature != ACPI_FACP_SIG - || !facp->pm_tmr + if (!fadt + || (STRNCMP(fadt->header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) + || !fadt->Xpm_tmr_blk.address || !acpi_pblk) goto not_initialized; @@ -116,110 +126,108 @@ acpi_idle(void) sleep3: sleep_level = 3; if (!acpi_c3_tested) { - printk(KERN_DEBUG "ACPI C3 works\n"); + DEBUG_PRINT(ACPI_INFO, ("C3 works\n")); acpi_c3_tested = 1; } - acpi_wake_on_busmaster(facp); - if (facp->pm2_cnt) + acpi_wake_on_busmaster(); + if (fadt->Xpm2_cnt_blk.address) goto sleep3_with_arbiter; for (;;) { unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; - + unsigned long diff; + __cli(); if (current->need_resched) goto out; - if (acpi_bm_activity(facp)) + if (acpi_bm_activity()) goto sleep2; - time = TIME_BEGIN(pm_tmr); + time = acpi_read_pm_timer(); inb(acpi_pblk + ACPI_P_LVL3); /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); + acpi_read_pm_timer(); + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); __sti(); - if (time < acpi_c3_exit_latency) + if (diff < acpi_c3_exit_latency) goto sleep2; } sleep3_with_arbiter: for (;;) { unsigned long time; - u8 arbiter; - unsigned int pm2_cntr = facp->pm2_cnt; - unsigned int pm_tmr = facp->pm_tmr; + unsigned long diff; __cli(); if (current->need_resched) goto out; - if (acpi_bm_activity(facp)) + if (acpi_bm_activity()) goto sleep2; - time = TIME_BEGIN(pm_tmr); - arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS; + time = acpi_read_pm_timer(); + /* Disable arbiter, park on CPU */ - outb(arbiter | ACPI_ARB_DIS, pm2_cntr); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1); inb(acpi_pblk + ACPI_P_LVL3); /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); + acpi_read_pm_timer(); + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); /* Enable arbiter again.. */ - outb(arbiter, pm2_cntr); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0); __sti(); - if (time < acpi_c3_exit_latency) + if (diff < acpi_c3_exit_latency) goto sleep2; } sleep2: sleep_level = 2; if (!acpi_c2_tested) { - printk(KERN_DEBUG "ACPI C2 works\n"); + DEBUG_PRINT(ACPI_INFO, ("C2 works\n")); acpi_c2_tested = 1; } - acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */ + acpi_wake_on_busmaster(); /* Required to track BM activity.. */ for (;;) { unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; + unsigned long diff; __cli(); if (current->need_resched) goto out; - time = TIME_BEGIN(pm_tmr); + time = acpi_read_pm_timer(); inb(acpi_pblk + ACPI_P_LVL2); /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); + acpi_read_pm_timer(); + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); __sti(); - if (time < acpi_c2_exit_latency) + if (diff < acpi_c2_exit_latency) goto sleep1; - if (acpi_bm_activity(facp)) { - acpi_clear_bm_activity(facp); + if (acpi_bm_activity()) { + acpi_clear_bm_activity(); continue; } - if (time > acpi_c3_enter_latency + if (diff > acpi_c3_enter_latency && acpi_max_c_state >= 3) goto sleep3; } sleep1: sleep_level = 1; - acpi_sleep_on_busmaster(facp); + acpi_sleep_on_busmaster(); for (;;) { unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; + unsigned long diff; __cli(); if (current->need_resched) goto out; - time = TIME_BEGIN(pm_tmr); + time = acpi_read_pm_timer(); safe_halt(); - time = TIME_END(pm_tmr, time); - if (time > acpi_c2_enter_latency + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); + if (diff > acpi_c2_enter_latency && acpi_max_c_state >= 2) goto sleep2; } @@ -240,7 +248,7 @@ acpi_idle(void) * Get processor information */ static ACPI_STATUS -acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) { ACPI_OBJECT obj; ACPI_CX_STATE lat[4]; @@ -253,10 +261,11 @@ acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf))) return AE_OK; - printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n", - obj.processor.proc_id, - obj.processor.pblk_address, - obj.processor.pblk_length); + DEBUG_PRINT(ACPI_INFO, ("PBLK %d @ 0x%04x:%d\n", + obj.processor.proc_id, + obj.processor.pblk_address, + obj.processor.pblk_length)); + if (acpi_pblk != ACPI_INVALID || !obj.processor.pblk_address || obj.processor.pblk_length != 6) @@ -270,19 +279,16 @@ acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) return AE_OK; if (lat[2].latency < MAX_CX_STATE_LATENCY) { - printk(KERN_INFO "ACPI: C2"); + printk(KERN_INFO "ACPI: System firmware supports: C2"); acpi_c2_exit_latency = lat[2].latency; acpi_max_c_state = 2; if (lat[3].latency < MAX_CX_STATE_LATENCY) { - printk(", C3 supported\n"); + printk(" C3"); acpi_c3_exit_latency = lat[3].latency; acpi_max_c_state = 3; } - else { - printk(" supported\n"); - } - + printk("\n"); } memset(throttle, 0, sizeof(throttle)); @@ -296,9 +302,29 @@ acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) if (throttle[i].percent_of_clock) count++; } + + /* 0% throttled really doesn't count */ count--; - if (count > 0) - printk(KERN_INFO "ACPI: %d throttling states\n", count); + + if (count > 0) { + DEBUG_PRINT(ACPI_INFO, ("%d throttling states\n", count)); + } + + return AE_OK; +} + +static int +acpi_pm_timer_init(void) +{ + FADT_DESCRIPTOR *fadt = &acpi_fadt; + + if (fadt->tmr_val_ext) { + acpi_pm_tmr_len = 32; + } else { + acpi_pm_tmr_len = 24; + } + + DEBUG_PRINT(ACPI_INFO, ("PM Timer width: %d bits\n", acpi_pm_tmr_len)); return AE_OK; } @@ -309,10 +335,13 @@ acpi_cpu_init(void) acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_find_cpu, + acpi_found_cpu, NULL, NULL); + acpi_pm_timer_init(); + + #ifdef CONFIG_SMP if (smp_num_cpus == 1) pm_idle = acpi_idle; diff --git a/drivers/acpi/dispatcher/Makefile b/drivers/acpi/dispatcher/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/dispatcher/Makefile +++ b/drivers/acpi/dispatcher/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index cea6a9883..d9d73ccea 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dsmethod - Parser/Interpreter interface - control method parsing - * $Revision: 52 $ + * $Revision: 53 $ * *****************************************************************************/ @@ -387,7 +387,7 @@ acpi_ds_restart_control_method ( * NULL if no return value */ - status = acpi_ds_result_stack_push (return_desc, walk_state); + status = acpi_ds_result_push (return_desc, walk_state); if (ACPI_FAILURE (status)) { acpi_cm_remove_reference (return_desc); return (status); diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index bc19feaca..e6913fabf 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dsmthdat - control method arguments and local variables - * $Revision: 34 $ + * $Revision: 36 $ * ******************************************************************************/ @@ -71,10 +71,10 @@ acpi_ds_method_data_init ( for (i = 0; i < MTH_NUM_ARGS; i++) { MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name, NAMEOF_ARG_NTE); - walk_state->arguments[i].name |= (i << 24); walk_state->arguments[i].data_type = ACPI_DESC_TYPE_NAMED; - walk_state->arguments[i].type = INTERNAL_TYPE_METHOD_ARGUMENT; + walk_state->arguments[i].type = ACPI_TYPE_ANY; + walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; } /* Init the method locals */ @@ -85,7 +85,8 @@ acpi_ds_method_data_init ( walk_state->local_variables[i].name |= (i << 24); walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED; - walk_state->local_variables[i].type = INTERNAL_TYPE_METHOD_LOCAL_VAR; + walk_state->local_variables[i].type = ACPI_TYPE_ANY; + walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; } return (AE_OK); diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index db0531ad6..042cc4a80 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 43 $ + * $Revision: 53 $ * *****************************************************************************/ @@ -64,9 +64,13 @@ acpi_ds_init_one_object ( { OBJECT_TYPE_INTERNAL type; ACPI_STATUS status; - INIT_WALK_INFO *info = (INIT_WALK_INFO *) context; + ACPI_INIT_WALK_INFO *info = (ACPI_INIT_WALK_INFO *) context; + u8 table_revision; + info->object_count++; + table_revision = info->table_desc->pointer->revision; + /* * We are only interested in objects owned by the table that * was just loaded @@ -98,6 +102,14 @@ acpi_ds_init_one_object ( info->method_count++; + /* + * Set the execution data width (32 or 64) based upon the + * revision number of the parent ACPI table. + */ + + if (table_revision == 1) { + ((ACPI_NAMESPACE_NODE *)obj_handle)->flags |= ANOBJ_DATA_WIDTH_32; + } /* * Always parse methods to detect errors, we may delete @@ -113,14 +125,10 @@ acpi_ds_init_one_object ( } /* - * Keep the parse tree only if we are parsing all methods - * at init time (versus just-in-time) + * Delete the parse tree. We simple re-parse the method + * for every execution since there isn't much overhead */ - - if (acpi_gbl_when_to_parse_methods != METHOD_PARSE_AT_INIT) { - acpi_ns_delete_namespace_subtree (obj_handle); - } - + acpi_ns_delete_namespace_subtree (obj_handle); break; default: @@ -154,12 +162,13 @@ acpi_ds_initialize_objects ( ACPI_NAMESPACE_NODE *start_node) { ACPI_STATUS status; - INIT_WALK_INFO info; + ACPI_INIT_WALK_INFO info; - info.method_count = 0; + info.method_count = 0; info.op_region_count = 0; - info.table_desc = table_desc; + info.object_count = 0; + info.table_desc = table_desc; /* Walk entire namespace from the supplied root */ @@ -218,7 +227,7 @@ acpi_ds_init_object_from_op ( /* First arg is a number */ - acpi_ds_create_operand (walk_state, op->value.arg); + acpi_ds_create_operand (walk_state, op->value.arg, 0); arg_desc = walk_state->operands [walk_state->num_operands - 1]; acpi_ds_obj_stack_pop (1, walk_state); @@ -239,16 +248,24 @@ acpi_ds_init_object_from_op ( /* Get the value, delete the internal object */ - (*obj_desc)->buffer.length = arg_desc->number.value; + (*obj_desc)->buffer.length = (u32) arg_desc->number.value; acpi_cm_remove_reference (arg_desc); /* Allocate the buffer */ - (*obj_desc)->buffer.pointer = - acpi_cm_callocate ((*obj_desc)->buffer.length); + if ((*obj_desc)->buffer.length == 0) { + (*obj_desc)->buffer.pointer = NULL; + REPORT_WARNING (("Buffer created with zero length in AML\n")); + break; + } + + else { + (*obj_desc)->buffer.pointer = + acpi_cm_callocate ((*obj_desc)->buffer.length); - if (!(*obj_desc)->buffer.pointer) { - return (AE_NO_MEMORY); + if (!(*obj_desc)->buffer.pointer) { + return (AE_NO_MEMORY); + } } /* @@ -360,7 +377,7 @@ acpi_ds_init_object_from_op ( * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ds_build_internal_simple_obj ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op, @@ -369,6 +386,8 @@ acpi_ds_build_internal_simple_obj ( ACPI_OPERAND_OBJECT *obj_desc; OBJECT_TYPE_INTERNAL type; ACPI_STATUS status; + u32 length; + char *name; if (op->opcode == AML_NAMEPATH_OP) { @@ -387,6 +406,22 @@ acpi_ds_build_internal_simple_obj ( (ACPI_NAMESPACE_NODE **)&(op->node)); if (ACPI_FAILURE (status)) { + if (status == AE_NOT_FOUND) { + name = NULL; + acpi_ns_externalize_name (ACPI_UINT32_MAX, op->value.string, &length, &name); + + if (name) { + REPORT_WARNING (("Reference %s AML %X not found\n", + name, op->aml_offset)); + acpi_cm_free (name); + } + else { + REPORT_WARNING (("Reference %s AML %X not found\n", + op->value.string, op->aml_offset)); + } + *obj_desc_ptr = NULL; + } + return (status); } } @@ -473,7 +508,7 @@ acpi_ds_build_internal_package_obj ( if (!obj_desc->package.elements) { /* Package vector allocation failure */ - REPORT_ERROR ("Ds_build_internal_package_obj: Package vector allocation failure"); + REPORT_ERROR (("Ds_build_internal_package_obj: Package vector allocation failure\n")); acpi_cm_delete_object_desc (obj_desc); return (AE_NO_MEMORY); @@ -578,7 +613,7 @@ acpi_ds_create_node ( status = acpi_ds_build_internal_object (walk_state, op->value.arg, &obj_desc); if (ACPI_FAILURE (status)) { - goto cleanup; + return (status); } diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 80fc3ebe2..21e15bc26 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -2,7 +2,7 @@ * * Module Name: dsopcode - Dispatcher Op Region support and handling of * "control" opcodes - * $Revision: 17 $ + * $Revision: 28 $ * *****************************************************************************/ @@ -40,9 +40,117 @@ /***************************************************************************** * + * FUNCTION: Acpi_ds_get_field_unit_arguments + * + * PARAMETERS: Obj_desc - A valid Field_unit object + * + * RETURN: Status. + * + * DESCRIPTION: Get Field_unit Buffer and Index. This implements the late + * evaluation of these field attributes. + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ds_get_field_unit_arguments ( + ACPI_OPERAND_OBJECT *obj_desc) +{ + ACPI_OPERAND_OBJECT *extra_desc; + ACPI_NAMESPACE_NODE *node; + ACPI_PARSE_OBJECT *op; + ACPI_PARSE_OBJECT *field_op; + ACPI_STATUS status; + ACPI_TABLE_DESC *table_desc; + + + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + return (AE_OK); + } + + + /* Get the AML pointer (method object) and Field_unit node */ + + extra_desc = obj_desc->field_unit.extra; + node = obj_desc->field_unit.node; + + + /* + * Allocate a new parser op to be the root of the parsed + * Op_region tree + */ + + op = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!op) { + return (AE_NO_MEMORY); + } + + /* Save the Node for use in Acpi_ps_parse_aml */ + + op->node = acpi_ns_get_parent_object (node); + + /* Get a handle to the parent ACPI table */ + + status = acpi_tb_handle_to_object (node->owner_id, &table_desc); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Pass1: Parse the entire Field_unit declaration */ + + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, 0, + NULL, NULL, NULL, acpi_ds_load1_begin_op, acpi_ds_load1_end_op); + if (ACPI_FAILURE (status)) { + acpi_ps_delete_parse_tree (op); + return (status); + } + + + /* Get and init the actual Fiel_unit_op created above */ + + field_op = op->value.arg; + op->node = node; + + + field_op = op->value.arg; + field_op->node = node; + acpi_ps_delete_parse_tree (op); + + /* Acpi_evaluate the address and length arguments for the Op_region */ + + op = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!op) { + return (AE_NO_MEMORY); + } + + op->node = acpi_ns_get_parent_object (node); + + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, + ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE, + NULL /*Method_desc*/, NULL, NULL, + acpi_ds_exec_begin_op, acpi_ds_exec_end_op); + /* All done with the parse tree, delete it */ + + acpi_ps_delete_parse_tree (op); + + + /* + * The pseudo-method object is no longer needed since the region is + * now initialized + */ + acpi_cm_remove_reference (obj_desc->field_unit.extra); + obj_desc->field_unit.extra = NULL; + + return (status); +} + + +/***************************************************************************** + * * FUNCTION: Acpi_ds_get_region_arguments * - * PARAMETERS: Rgn_desc - A valid region object + * PARAMETERS: Obj_desc - A valid region object * * RETURN: Status. * @@ -53,9 +161,9 @@ ACPI_STATUS acpi_ds_get_region_arguments ( - ACPI_OPERAND_OBJECT *rgn_desc) + ACPI_OPERAND_OBJECT *obj_desc) { - ACPI_OPERAND_OBJECT *method_desc; + ACPI_OPERAND_OBJECT *extra_desc = NULL; ACPI_NAMESPACE_NODE *node; ACPI_PARSE_OBJECT *op; ACPI_PARSE_OBJECT *region_op; @@ -63,14 +171,15 @@ acpi_ds_get_region_arguments ( ACPI_TABLE_DESC *table_desc; - if (rgn_desc->region.flags & AOPOBJ_DATA_VALID) { + if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { return (AE_OK); } - method_desc = rgn_desc->region.method; - node = rgn_desc->region.node; + /* Get the AML pointer (method object) and region node */ + extra_desc = obj_desc->region.extra; + node = obj_desc->region.node; /* * Allocate a new parser op to be the root of the parsed @@ -95,8 +204,8 @@ acpi_ds_get_region_arguments ( /* Parse the entire Op_region declaration, creating a parse tree */ - status = acpi_ps_parse_aml (op, method_desc->method.pcode, - method_desc->method.pcode_length, 0, + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, 0, NULL, NULL, NULL, acpi_ds_load1_begin_op, acpi_ds_load1_end_op); if (ACPI_FAILURE (status)) { @@ -107,8 +216,8 @@ acpi_ds_get_region_arguments ( /* Get and init the actual Region_op created above */ -/* Region_op = Op->Value.Arg; - Op->Node = Node;*/ + region_op = op->value.arg; + op->node = node; region_op = op->value.arg; @@ -124,16 +233,12 @@ acpi_ds_get_region_arguments ( op->node = acpi_ns_get_parent_object (node); - status = acpi_ps_parse_aml (op, method_desc->method.pcode, - method_desc->method.pcode_length, + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE, NULL /*Method_desc*/, NULL, NULL, acpi_ds_exec_begin_op, acpi_ds_exec_end_op); -/* - Acpi_ps_walk_parsed_aml (Region_op, Region_op, NULL, NULL, NULL, - NULL, Table_desc->Table_id, - Acpi_ds_exec_begin_op, Acpi_ds_exec_end_op); -*/ + /* All done with the parse tree, delete it */ acpi_ps_delete_parse_tree (op); @@ -174,6 +279,252 @@ acpi_ds_initialize_region ( /***************************************************************************** * + * FUNCTION: Acpi_ds_eval_field_unit_operands + * + * PARAMETERS: Op - A valid Field_unit Op object + * + * RETURN: Status + * + * DESCRIPTION: Get Field_unit Buffer and Index + * Called from Acpi_ds_exec_end_op during Field_unit parse tree walk + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ds_eval_field_unit_operands ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op) +{ + ACPI_STATUS status; + ACPI_OPERAND_OBJECT *field_desc; + ACPI_NAMESPACE_NODE *node; + ACPI_PARSE_OBJECT *next_op; + u32 offset; + u32 bit_offset; + u16 bit_count; + + + ACPI_OPERAND_OBJECT *res_desc = NULL; + ACPI_OPERAND_OBJECT *cnt_desc = NULL; + ACPI_OPERAND_OBJECT *off_desc = NULL; + ACPI_OPERAND_OBJECT *src_desc = NULL; + u32 num_operands = 3; + + + /* + * This is where we evaluate the address and length fields of the Op_field_unit declaration + */ + + node = op->node; + + /* Next_op points to the op that holds the Buffer */ + next_op = op->value.arg; + + /* Acpi_evaluate/create the address and length operands */ + + status = acpi_ds_create_operands (walk_state, next_op); + if (ACPI_FAILURE (status)) { + return (status); + } + + field_desc = acpi_ns_get_attached_object (node); + if (!field_desc) { + return (AE_NOT_EXIST); + } + + + /* Resolve the operands */ + + status = acpi_aml_resolve_operands (op->opcode, WALK_OPERANDS, walk_state); + + /* Get the operands */ + + status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state); + if (AML_CREATE_FIELD_OP == op->opcode) { + num_operands = 4; + status |= acpi_ds_obj_stack_pop_object (&cnt_desc, walk_state); + } + + status |= acpi_ds_obj_stack_pop_object (&off_desc, walk_state); + status |= acpi_ds_obj_stack_pop_object (&src_desc, walk_state); + + if (ACPI_FAILURE (status)) { + /* Invalid parameters on object stack */ + + goto cleanup; + } + + + offset = (u32) off_desc->number.value; + + + /* + * If Res_desc is a Name, it will be a direct name pointer after + * Acpi_aml_resolve_operands() + */ + + if (!VALID_DESCRIPTOR_TYPE (res_desc, ACPI_DESC_TYPE_NAMED)) { + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + + /* + * Setup the Bit offsets and counts, according to the opcode + */ + + switch (op->opcode) + { + + /* Def_create_bit_field */ + + case AML_BIT_FIELD_OP: + + /* Offset is in bits, Field is a bit */ + + bit_offset = offset; + bit_count = 1; + break; + + + /* Def_create_byte_field */ + + case AML_BYTE_FIELD_OP: + + /* Offset is in bytes, field is a byte */ + + bit_offset = 8 * offset; + bit_count = 8; + break; + + + /* Def_create_word_field */ + + case AML_WORD_FIELD_OP: + + /* Offset is in bytes, field is a word */ + + bit_offset = 8 * offset; + bit_count = 16; + break; + + + /* Def_create_dWord_field */ + + case AML_DWORD_FIELD_OP: + + /* Offset is in bytes, field is a dword */ + + bit_offset = 8 * offset; + bit_count = 32; + break; + + + /* Def_create_field */ + + case AML_CREATE_FIELD_OP: + + /* Offset is in bits, count is in bits */ + + bit_offset = offset; + bit_count = (u16) cnt_desc->number.value; + break; + + + default: + + status = AE_AML_BAD_OPCODE; + goto cleanup; + } + + + /* + * Setup field according to the object type + */ + + switch (src_desc->common.type) + { + + /* Source_buff := Term_arg=>Buffer */ + + case ACPI_TYPE_BUFFER: + + if (bit_offset + (u32) bit_count > + (8 * (u32) src_desc->buffer.length)) + { + status = AE_AML_BUFFER_LIMIT; + goto cleanup; + } + + + /* Construct the remainder of the field object */ + + field_desc->field_unit.access = (u8) ACCESS_ANY_ACC; + field_desc->field_unit.lock_rule = (u8) GLOCK_NEVER_LOCK; + field_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE; + field_desc->field_unit.length = bit_count; + field_desc->field_unit.bit_offset = (u8) (bit_offset % 8); + field_desc->field_unit.offset = DIV_8 (bit_offset); + field_desc->field_unit.container = src_desc; + + /* Reference count for Src_desc inherits Field_desc count */ + + src_desc->common.reference_count = (u16) (src_desc->common.reference_count + + field_desc->common.reference_count); + + break; + + + /* Improper object type */ + + default: + + if ((src_desc->common.type > (u8) INTERNAL_TYPE_REFERENCE) || + !acpi_cm_valid_object_type (src_desc->common.type)) + + + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + + if (AML_CREATE_FIELD_OP == op->opcode) { + /* Delete object descriptor unique to Create_field */ + + acpi_cm_remove_reference (cnt_desc); + cnt_desc = NULL; + } + + +cleanup: + + /* Always delete the operands */ + + acpi_cm_remove_reference (off_desc); + acpi_cm_remove_reference (src_desc); + + if (AML_CREATE_FIELD_OP == op->opcode) { + acpi_cm_remove_reference (cnt_desc); + } + + /* On failure, delete the result descriptor */ + + if (ACPI_FAILURE (status)) { + acpi_cm_remove_reference (res_desc); /* Result descriptor */ + } + + else { + /* Now the address and length are valid for this op_field_unit */ + + field_desc->field_unit.flags |= AOPOBJ_DATA_VALID; + } + + return (status); +} + + +/***************************************************************************** + * * FUNCTION: Acpi_ds_eval_region_operands * * PARAMETERS: Op - A valid region Op object @@ -192,7 +543,7 @@ acpi_ds_eval_region_operands ( { ACPI_STATUS status; ACPI_OPERAND_OBJECT *obj_desc; - ACPI_OPERAND_OBJECT *region_desc; + ACPI_OPERAND_OBJECT *operand_desc; ACPI_NAMESPACE_NODE *node; ACPI_PARSE_OBJECT *next_op; @@ -216,31 +567,41 @@ acpi_ds_eval_region_operands ( return (status); } - region_desc = acpi_ns_get_attached_object (node); - if (!region_desc) { - return (AE_NOT_EXIST); + /* Resolve the length and address operands to numbers */ + + status = acpi_aml_resolve_operands (op->opcode, WALK_OPERANDS, walk_state); + if (ACPI_FAILURE (status)) { + return (status); } - /* Get the length and save it */ - /* Top of stack */ - obj_desc = walk_state->operands[walk_state->num_operands - 1]; + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + return (AE_NOT_EXIST); + } - region_desc->region.length = obj_desc->number.value; - acpi_cm_remove_reference (obj_desc); + /* + * Get the length operand and save it + * (at Top of stack) + */ + operand_desc = walk_state->operands[walk_state->num_operands - 1]; - /* Get the address and save it */ + obj_desc->region.length = (u32) operand_desc->number.value; + acpi_cm_remove_reference (operand_desc); - /* Top of stack - 1 */ - obj_desc = walk_state->operands[walk_state->num_operands - 2]; + /* + * Get the address and save it + * (at top of stack - 1) + */ + operand_desc = walk_state->operands[walk_state->num_operands - 2]; - region_desc->region.address = obj_desc->number.value; - acpi_cm_remove_reference (obj_desc); + obj_desc->region.address = (ACPI_PHYSICAL_ADDRESS) operand_desc->number.value; + acpi_cm_remove_reference (operand_desc); /* Now the address and length are valid for this opregion */ - region_desc->region.flags |= AOPOBJ_DATA_VALID; + obj_desc->region.flags |= AOPOBJ_DATA_VALID; return (status); } @@ -294,6 +655,7 @@ acpi_ds_exec_begin_control_op ( */ walk_state->control_state->control.aml_predicate_start = walk_state->parser_state->aml - 1; + /* TBD: can this be removed? */ /*Acpi_ps_pkg_length_encoding_size (GET8 (Walk_state->Parser_state->Aml));*/ break; @@ -385,15 +747,14 @@ acpi_ds_exec_end_control_op ( status = AE_CTRL_PENDING; } -/* else {*/ - /* Pop this control state and free it */ - control_state = - acpi_cm_pop_generic_state (&walk_state->control_state); + /* Pop this control state and free it */ - walk_state->aml_last_while = control_state->control.aml_predicate_start; - acpi_cm_delete_generic_state (control_state); -/* }*/ + control_state = + acpi_cm_pop_generic_state (&walk_state->control_state); + + walk_state->aml_last_while = control_state->control.aml_predicate_start; + acpi_cm_delete_generic_state (control_state); break; @@ -434,7 +795,9 @@ acpi_ds_exec_end_control_op ( walk_state->return_desc = walk_state->operands[0]; } - else if (walk_state->num_results > 0) { + else if ((walk_state->results) && + (walk_state->results->results.num_results > 0)) + { /* * The return value has come from a previous calculation. * @@ -443,12 +806,12 @@ acpi_ds_exec_end_control_op ( * cease to exist at the end of the method. */ - status = acpi_aml_resolve_to_value (&walk_state->results [0], walk_state); + status = acpi_aml_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state); if (ACPI_FAILURE (status)) { return (status); } - walk_state->return_desc = walk_state->results [0]; + walk_state->return_desc = walk_state->results->results.obj_desc [0]; } else { diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 0b811bebd..2efa43e51 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dsutils - Dispatcher utilities - * $Revision: 44 $ + * $Revision: 50 $ * ******************************************************************************/ @@ -52,7 +52,8 @@ u8 acpi_ds_is_result_used ( - ACPI_PARSE_OBJECT *op) + ACPI_PARSE_OBJECT *op, + ACPI_WALK_STATE *walk_state) { ACPI_OPCODE_INFO *parent_info; @@ -85,13 +86,6 @@ acpi_ds_is_result_used ( } - /* Never delete the return value associated with a return opcode */ - - if (op->parent->opcode == AML_RETURN_OP) { - return (TRUE); - } - - /* * Decide what to do with the result based on the parent. If * the parent opcode will not use the result, delete the object. @@ -105,8 +99,54 @@ acpi_ds_is_result_used ( * In these cases, the parent will never use the return object */ case OPTYPE_CONTROL: /* IF, ELSE, WHILE only */ + + switch (op->parent->opcode) + { + case AML_RETURN_OP: + + /* Never delete the return value associated with a return opcode */ + + return (TRUE); + break; + + case AML_IF_OP: + case AML_WHILE_OP: + + /* + * If we are executing the predicate AND this is the predicate op, + * we will use the return value! + */ + + if ((walk_state->control_state->common.state == CONTROL_PREDICATE_EXECUTING) && + (walk_state->control_state->control.predicate_op == op)) + { + return (TRUE); + } + + break; + } + + + /* Fall through to not used case below */ + + case OPTYPE_NAMED_OBJECT: /* Scope, method, etc. */ + /* + * These opcodes allow Term_arg(s) as operands and therefore + * method calls. The result is used. + */ + if ((op->parent->opcode == AML_REGION_OP) || + (op->parent->opcode == AML_CREATE_FIELD_OP) || + (op->parent->opcode == AML_BIT_FIELD_OP) || + (op->parent->opcode == AML_BYTE_FIELD_OP) || + (op->parent->opcode == AML_WORD_FIELD_OP) || + (op->parent->opcode == AML_DWORD_FIELD_OP) || + (op->parent->opcode == AML_QWORD_FIELD_OP)) + { + return (TRUE); + } + return (FALSE); break; @@ -158,13 +198,13 @@ acpi_ds_delete_result_if_not_used ( } - if (!acpi_ds_is_result_used (op)) { + if (!acpi_ds_is_result_used (op, walk_state)) { /* * Must pop the result stack (Obj_desc should be equal * to Result_obj) */ - status = acpi_ds_result_stack_pop (&obj_desc, walk_state); + status = acpi_ds_result_pop (&obj_desc, walk_state); if (ACPI_SUCCESS (status)) { acpi_cm_remove_reference (result_obj); } @@ -193,7 +233,8 @@ acpi_ds_delete_result_if_not_used ( ACPI_STATUS acpi_ds_create_operand ( ACPI_WALK_STATE *walk_state, - ACPI_PARSE_OBJECT *arg) + ACPI_PARSE_OBJECT *arg, + u32 arg_index) { ACPI_STATUS status = AE_OK; NATIVE_CHAR *name_string; @@ -237,6 +278,7 @@ acpi_ds_create_operand ( parent_op = arg->parent; if ((acpi_ps_is_node_op (parent_op->opcode)) && (parent_op->opcode != AML_METHODCALL_OP) && + (parent_op->opcode != AML_REGION_OP) && (parent_op->opcode != AML_NAMEPATH_OP)) { /* Enter name into namespace if not found */ @@ -340,7 +382,7 @@ acpi_ds_create_operand ( * by the evaluation of this argument */ - status = acpi_ds_result_stack_pop (&obj_desc, walk_state); + status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state); if (ACPI_FAILURE (status)) { /* * Only error is underflow, and this indicates @@ -404,17 +446,14 @@ acpi_ds_create_operands ( { ACPI_STATUS status = AE_OK; ACPI_PARSE_OBJECT *arg; - u32 args_pushed = 0; - - - arg = first_arg; + u32 arg_count = 0; /* For all arguments in the list... */ + arg = first_arg; while (arg) { - - status = acpi_ds_create_operand (walk_state, arg); + status = acpi_ds_create_operand (walk_state, arg, arg_count); if (ACPI_FAILURE (status)) { goto cleanup; } @@ -422,7 +461,7 @@ acpi_ds_create_operands ( /* Move on to next argument, if any */ arg = arg->next; - args_pushed++; + arg_count++; } return (status); @@ -435,7 +474,7 @@ cleanup: * objects */ - acpi_ds_obj_stack_pop_and_delete (args_pushed, walk_state); + acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state); return (status); } @@ -539,8 +578,10 @@ acpi_ds_map_opcode_to_data_type ( case AML_NAMEPATH_OP: data_type = INTERNAL_TYPE_REFERENCE; break; - } + default: + break; + } break; @@ -557,8 +598,10 @@ acpi_ds_map_opcode_to_data_type ( data_type = ACPI_TYPE_PACKAGE; break; - } + default: + break; + } break; @@ -581,21 +624,18 @@ acpi_ds_map_opcode_to_data_type ( flags = OP_HAS_RETURN_VALUE; data_type = ACPI_TYPE_ANY; - break; case OPTYPE_METHOD_CALL: flags = OP_HAS_RETURN_VALUE; data_type = ACPI_TYPE_METHOD; - break; case OPTYPE_NAMED_OBJECT: data_type = acpi_ds_map_named_opcode_to_data_type (opcode); - break; diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 9cac0aac3..1f7e329ad 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -2,7 +2,7 @@ * * Module Name: dswexec - Dispatcher method execution callbacks; * dispatch to interpreter. - * $Revision: 42 $ + * $Revision: 50 $ * *****************************************************************************/ @@ -40,6 +40,110 @@ /***************************************************************************** * + * FUNCTION: Acpi_ds_get_predicate_value + * + * PARAMETERS: Walk_state - Current state of the parse tree walk + * + * RETURN: Status + * + * DESCRIPTION: + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ds_get_predicate_value ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op, + u32 has_result_obj) +{ + ACPI_STATUS status = AE_OK; + ACPI_OPERAND_OBJECT *obj_desc; + + + walk_state->control_state->common.state = 0; + + if (has_result_obj) { + status = acpi_ds_result_pop (&obj_desc, walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + else { + status = acpi_ds_create_operand (walk_state, op, 0); + if (ACPI_FAILURE (status)) { + return (status); + } + + status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } + + obj_desc = walk_state->operands [0]; + } + + if (!obj_desc) { + return (AE_AML_NO_OPERAND); + } + + + /* + * Result of predicate evaluation currently must + * be a number + */ + + if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + + /* TBD: 64/32-bit */ + + obj_desc->number.value &= (UINT64) 0x00000000FFFFFFFF; + + /* + * Save the result of the predicate evaluation on + * the control stack + */ + + if (obj_desc->number.value) { + walk_state->control_state->common.value = TRUE; + } + + else { + /* + * Predicate is FALSE, we will just toss the + * rest of the package + */ + + walk_state->control_state->common.value = FALSE; + status = AE_CTRL_FALSE; + } + + +cleanup: + + /* Break to debugger to display result */ + + DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state)); + + /* + * Delete the predicate result object (we know that + * we don't need it anymore) + */ + + acpi_cm_remove_reference (obj_desc); + + walk_state->control_state->common.state = CONTROL_NORMAL; + + return (status); +} + + +/***************************************************************************** + * * FUNCTION: Acpi_ds_exec_begin_op * * PARAMETERS: Walk_state - Current state of the parse tree walk @@ -117,6 +221,11 @@ acpi_ds_exec_begin_op ( { case OPTYPE_CONTROL: + status = acpi_ds_result_stack_push (walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } + status = acpi_ds_exec_begin_control_op (walk_state, op); break; @@ -134,6 +243,33 @@ acpi_ds_exec_begin_op ( status = acpi_ds_load2_begin_op (op->opcode, op, walk_state, NULL); } + + + if (op->opcode == AML_REGION_OP) { + status = acpi_ds_result_stack_push (walk_state); + } + + break; + + + /* most operators with arguments */ + + case OPTYPE_MONADIC1: + case OPTYPE_DYADIC1: + case OPTYPE_MONADIC2: + case OPTYPE_MONADIC2_r: + case OPTYPE_DYADIC2: + case OPTYPE_DYADIC2_r: + case OPTYPE_DYADIC2_s: + case OPTYPE_RECONFIGURATION: + case OPTYPE_INDEX: + case OPTYPE_MATCH: + case OPTYPE_FATAL: + case OPTYPE_CREATE_FIELD: + + /* Start a new result/operand state */ + + status = acpi_ds_result_stack_push (walk_state); break; @@ -171,7 +307,6 @@ acpi_ds_exec_end_op ( ACPI_STATUS status = AE_OK; u16 opcode; u8 optype; - ACPI_OPERAND_OBJECT *obj_desc; ACPI_PARSE_OBJECT *next_op; ACPI_NAMESPACE_NODE *node; ACPI_PARSE_OBJECT *first_arg; @@ -236,10 +371,11 @@ acpi_ds_exec_end_op ( case OPTYPE_RECONFIGURATION: case OPTYPE_INDEX: case OPTYPE_MATCH: - case OPTYPE_CREATE_FIELD: case OPTYPE_FATAL: + /* Build resolved operand stack */ + status = acpi_ds_create_operands (walk_state, first_arg); if (ACPI_FAILURE (status)) { goto cleanup; @@ -247,9 +383,16 @@ acpi_ds_exec_end_op ( operand_index = walk_state->num_operands - 1; + + /* Done with this result state (Now that operand stack is built) */ + + status = acpi_ds_result_stack_pop (walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + switch (optype) { - case OPTYPE_MONADIC1: /* 1 Operand, 0 External_result, 0 Internal_result */ @@ -263,10 +406,6 @@ acpi_ds_exec_end_op ( /* 1 Operand, 0 External_result, 1 Internal_result */ status = acpi_aml_exec_monadic2 (opcode, walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } - break; @@ -275,10 +414,6 @@ acpi_ds_exec_end_op ( /* 1 Operand, 1 External_result, 1 Internal_result */ status = acpi_aml_exec_monadic2_r (opcode, walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } - break; @@ -287,7 +422,6 @@ acpi_ds_exec_end_op ( /* 2 Operands, 0 External_result, 0 Internal_result */ status = acpi_aml_exec_dyadic1 (opcode, walk_state); - break; @@ -296,10 +430,6 @@ acpi_ds_exec_end_op ( /* 2 Operands, 0 External_result, 1 Internal_result */ status = acpi_aml_exec_dyadic2 (opcode, walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } - break; @@ -307,17 +437,7 @@ acpi_ds_exec_end_op ( /* 2 Operands, 1 or 2 External_results, 1 Internal_result */ - - /* NEW INTERFACE: - * Pass in Walk_state, keep result obj but let interpreter - * push the result - */ - status = acpi_aml_exec_dyadic2_r (opcode, walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } - break; @@ -326,59 +446,49 @@ acpi_ds_exec_end_op ( /* 2 Operands, 0 External_result, 1 Internal_result */ status = acpi_aml_exec_dyadic2_s (opcode, walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } - break; - case OPTYPE_RECONFIGURATION: + case OPTYPE_INDEX: /* Type 2 opcode with 3 operands */ - /* 1 or 2 operands, 0 Internal Result */ + /* 3 Operands, 1 External_result, 1 Internal_result */ - status = acpi_aml_exec_reconfiguration (opcode, walk_state); + status = acpi_aml_exec_index (walk_state, &result_obj); break; - case OPTYPE_CREATE_FIELD: + case OPTYPE_MATCH: /* Type 2 opcode with 6 operands */ - /* 3 or 4 Operands, 0 External_result, 0 Internal_result */ + /* 6 Operands, 0 External_result, 1 Internal_result */ - status = acpi_aml_exec_create_field (opcode, walk_state); + status = acpi_aml_exec_match (walk_state, &result_obj); break; - case OPTYPE_FATAL: + case OPTYPE_RECONFIGURATION: - /* 3 Operands, 0 External_result, 0 Internal_result */ + /* 1 or 2 operands, 0 Internal Result */ - status = acpi_aml_exec_fatal (walk_state); + status = acpi_aml_exec_reconfiguration (opcode, walk_state); break; - case OPTYPE_INDEX: /* Type 2 opcode with 3 operands */ - - /* 3 Operands, 1 External_result, 1 Internal_result */ + case OPTYPE_FATAL: - status = acpi_aml_exec_index (walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } + /* 3 Operands, 0 External_result, 0 Internal_result */ + status = acpi_aml_exec_fatal (walk_state); break; + } - - case OPTYPE_MATCH: /* Type 2 opcode with 6 operands */ - - /* 6 Operands, 0 External_result, 1 Internal_result */ - - status = acpi_aml_exec_match (walk_state, &result_obj); - if (ACPI_SUCCESS (status)) { - status = acpi_ds_result_stack_push (result_obj, walk_state); - } - - break; + /* + * If a result object was returned from above, push it on the + * current result stack + */ + if (ACPI_SUCCESS (status) && + result_obj) + { + status = acpi_ds_result_push (result_obj, walk_state); } break; @@ -390,6 +500,7 @@ acpi_ds_exec_end_op ( status = acpi_ds_exec_end_control_op (walk_state, op); + acpi_ds_result_stack_pop (walk_state); break; @@ -400,17 +511,17 @@ acpi_ds_exec_end_op ( * the method Node pointer */ /* Next_op points to the op that holds the method name */ + next_op = first_arg; node = next_op->node; /* Next_op points to first argument op */ - next_op = next_op->next; + next_op = next_op->next; /* * Get the method's arguments and put them on the operand stack */ - status = acpi_ds_create_operands (walk_state, next_op); if (ACPI_FAILURE (status)) { break; @@ -428,55 +539,52 @@ acpi_ds_exec_end_op ( break; } - /* Open new scope on the scope stack */ -/* - Status = Acpi_ns_scope_stack_push_entry (Node); - if (ACPI_FAILURE (Status)) { - break; - } -*/ + /* + * Tell the walk loop to preempt this running method and + * execute the new method + */ + status = AE_CTRL_TRANSFER; - /* Tell the walk loop to preempt this running method and - execute the new method */ + /* + * Return now; we don't want to disturb anything, + * especially the operand count! + */ + return (status); + break; - status = AE_CTRL_TRANSFER; - /* Return now; we don't want to disturb anything, - especially the operand count! */ + case OPTYPE_CREATE_FIELD: + + status = acpi_ds_load2_end_op (walk_state, op); + if (ACPI_FAILURE (status)) { + break; + } - return (status); + status = acpi_ds_eval_field_unit_operands (walk_state, op); break; case OPTYPE_NAMED_OBJECT: - status = acpi_ds_load2_end_op (walk_state, op); if (ACPI_FAILURE (status)) { break; } -/* - if ((Walk_state->Origin->Opcode == AML_METHOD_OP) && - (Walk_state->Origin != Op)) - { - Status = Acpi_ds_load2_end_op (Walk_state, Op); - if (ACPI_FAILURE (Status)) { - break; - } - } -*/ switch (op->opcode) { case AML_REGION_OP: status = acpi_ds_eval_region_operands (walk_state, op); + if (ACPI_FAILURE (status)) { + break; + } + status = acpi_ds_result_stack_pop (walk_state); break; case AML_METHOD_OP: - break; @@ -504,6 +612,12 @@ acpi_ds_exec_end_op ( /* + * ACPI 2.0 support for 64-bit integers: + * Truncate numeric result value if we are executing from a 32-bit ACPI table + */ + acpi_aml_truncate_for32bit_table (result_obj, walk_state); + + /* * Check if we just completed the evaluation of a * conditional predicate */ @@ -513,70 +627,12 @@ acpi_ds_exec_end_op ( CONTROL_PREDICATE_EXECUTING) && (walk_state->control_state->control.predicate_op == op)) { - /* Completed the predicate, the result must be a number */ - - walk_state->control_state->common.state = 0; - - if (result_obj) { - status = acpi_ds_result_stack_pop (&obj_desc, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - } - - else { - status = acpi_ds_create_operand (walk_state, op); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - obj_desc = walk_state->operands [0]; - } - - if (!obj_desc) { - status = AE_AML_NO_OPERAND; - goto cleanup; - } - - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - /* Save the result of the predicate evaluation on - the control stack */ - - if (obj_desc->number.value) { - walk_state->control_state->common.value = TRUE; - } - else { - /* Predicate is FALSE, we will just toss the - rest of the package */ - - walk_state->control_state->common.value = FALSE; - status = AE_CTRL_FALSE; - } - - /* Break to debugger to display result */ - - DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state)); - - /* Delete the predicate result object (we know that - we don't need it anymore) and cleanup the stack */ - - acpi_cm_remove_reference (obj_desc); + status = acpi_ds_get_predicate_value (walk_state, op, (u32) result_obj); result_obj = NULL; - - walk_state->control_state->common.state = CONTROL_NORMAL; } cleanup: - if (result_obj) { /* Break to debugger to display result */ diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index fd82d5a0e..b3f1dc062 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswload - Dispatcher namespace load callbacks - * $Revision: 19 $ + * $Revision: 24 $ * *****************************************************************************/ @@ -86,6 +86,7 @@ acpi_ds_load1_begin_op ( data_type = acpi_ds_map_named_opcode_to_data_type (opcode); + /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve @@ -438,6 +439,11 @@ acpi_ds_load2_end_op ( case AML_WORD_FIELD_OP: case AML_DWORD_FIELD_OP: + /* + * Create the field object, but the field buffer and index must + * be evaluated later during the execution phase + */ + /* Get the Name_string argument */ if (op->opcode == AML_CREATE_FIELD_OP) { @@ -468,15 +474,22 @@ acpi_ds_load2_end_op ( op->node = new_node; /* - * If this is NOT a control method, we need to evaluate this opcode now. + * If there is no object attached to the node, this node was just created and + * we need to create the field object. Otherwise, this was a lookup of an + * existing node and we don't want to create the field object again. */ - - /* THIS WON"T WORK. Must execute all operands like Add(). => Must do an execute pass - if (!Walk_state->Method_desc) { - Status = Acpi_ds_exec_end_op (Walk_state, Op); + if (!new_node->object) { + /* + * The Field definition is not fully parsed at this time. + * (We must save the address of the AML for the buffer and index operands) + */ + status = acpi_aml_exec_create_field (((ACPI_PARSE2_OBJECT *) op)->data, + ((ACPI_PARSE2_OBJECT *) op)->length, + new_node, walk_state); } - */ } + + break; @@ -619,7 +632,8 @@ acpi_ds_load2_end_op ( status = acpi_aml_exec_create_region (((ACPI_PARSE2_OBJECT *) op)->data, ((ACPI_PARSE2_OBJECT *) op)->length, - arg->value.integer, walk_state); + (ACPI_ADDRESS_SPACE_TYPE) arg->value.integer, + walk_state); break; @@ -639,7 +653,15 @@ acpi_ds_load2_end_op ( case AML_NAME_OP: - status = acpi_ds_create_node (walk_state, node, op); + /* + * Because of the execution pass through the non-control-method + * parts of the table, we can arrive here twice. Only init + * the named object node the first time through + */ + + if (!node->object) { + status = acpi_ds_create_node (walk_state, node, op); + } break; @@ -662,3 +684,4 @@ cleanup: return (status); } + diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index 89750b341..11b6a6cb9 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswscope - Scope stack manipulation - * $Revision: 38 $ + * $Revision: 40 $ * *****************************************************************************/ @@ -89,14 +89,14 @@ acpi_ds_scope_stack_push ( if (!node) { /* invalid scope */ - REPORT_ERROR ("Ds_scope_stack_push: null scope passed"); + REPORT_ERROR (("Ds_scope_stack_push: null scope passed\n")); return (AE_BAD_PARAMETER); } /* Make sure object type is valid */ if (!acpi_aml_validate_object_type (type)) { - REPORT_WARNING ("Ds_scope_stack_push: type code out of range"); + REPORT_WARNING (("Ds_scope_stack_push: type code out of range\n")); } diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index cc2088492..a15a6f5f7 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswstate - Dispatcher parse tree walk management routines - * $Revision: 31 $ + * $Revision: 36 $ * *****************************************************************************/ @@ -49,20 +49,20 @@ ******************************************************************************/ ACPI_STATUS -acpi_ds_result_stack_clear ( +xxx_acpi_ds_result_stack_clear ( ACPI_WALK_STATE *walk_state) { - - walk_state->num_results = 0; - walk_state->current_result = 0; - +/* + Walk_state->Num_results = 0; + Walk_state->Current_result = 0; +*/ return (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ds_result_stack_push + * FUNCTION: Acpi_ds_result_insert * * PARAMETERS: Object - Object to push * Walk_state - Current Walk state @@ -74,18 +74,29 @@ acpi_ds_result_stack_clear ( ******************************************************************************/ ACPI_STATUS -acpi_ds_result_stack_push ( +acpi_ds_result_insert ( void *object, + u32 index, ACPI_WALK_STATE *walk_state) { + ACPI_GENERIC_STATE *state; - if (walk_state->num_results >= OBJ_NUM_OPERANDS) { - return (AE_STACK_OVERFLOW); + state = walk_state->results; + if (!state) { + return (AE_NOT_EXIST); + } + + if (index >= OBJ_NUM_OPERANDS) { + return (AE_BAD_PARAMETER); + } + + if (!object) { + return (AE_BAD_PARAMETER); } - walk_state->results [walk_state->num_results] = object; - walk_state->num_results++; + state->results.obj_desc [index] = object; + state->results.num_results++; return (AE_OK); } @@ -93,7 +104,7 @@ acpi_ds_result_stack_push ( /******************************************************************************* * - * FUNCTION: Acpi_ds_result_stack_pop + * FUNCTION: Acpi_ds_result_remove * * PARAMETERS: Object - Where to return the popped object * Walk_state - Current Walk state @@ -106,31 +117,250 @@ acpi_ds_result_stack_push ( ******************************************************************************/ ACPI_STATUS -acpi_ds_result_stack_pop ( +acpi_ds_result_remove ( ACPI_OPERAND_OBJECT **object, + u32 index, ACPI_WALK_STATE *walk_state) { + ACPI_GENERIC_STATE *state; - /* Check for stack underflow */ + state = walk_state->results; + if (!state) { + return (AE_NOT_EXIST); + } - if (walk_state->num_results == 0) { + + + /* Check for a valid result object */ + + if (!state->results.obj_desc [index]) { return (AE_AML_NO_OPERAND); } + /* Remove the object */ + + state->results.num_results--; + + *object = state->results.obj_desc [index]; + state->results.obj_desc [index] = NULL; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ds_result_pop + * + * PARAMETERS: Object - Where to return the popped object + * Walk_state - Current Walk state + * + * RETURN: Status + * + * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In + * other words, this is a FIFO. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ds_result_pop ( + ACPI_OPERAND_OBJECT **object, + ACPI_WALK_STATE *walk_state) +{ + u32 index; + ACPI_GENERIC_STATE *state; - /* Pop the stack */ - walk_state->num_results--; + state = walk_state->results; + if (!state) { + return (AE_OK); + } + + + if (!state->results.num_results) { + return (AE_STACK_UNDERFLOW); + } + + /* Remove top element */ + + state->results.num_results--; + + for (index = OBJ_NUM_OPERANDS; index; index--) { + /* Check for a valid result object */ + + if (state->results.obj_desc [index -1]) { + *object = state->results.obj_desc [index -1]; + state->results.obj_desc [index -1] = NULL; + + return (AE_OK); + } + } + + + return (AE_STACK_UNDERFLOW); +} + +/******************************************************************************* + * + * FUNCTION: Acpi_ds_result_pop + * + * PARAMETERS: Object - Where to return the popped object + * Walk_state - Current Walk state + * + * RETURN: Status + * + * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In + * other words, this is a FIFO. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ds_result_pop_from_bottom ( + ACPI_OPERAND_OBJECT **object, + ACPI_WALK_STATE *walk_state) +{ + u32 index; + ACPI_GENERIC_STATE *state; + + + state = walk_state->results; + if (!state) { + return (AE_NOT_EXIST); + } + + + if (!state->results.num_results) { + return (AE_STACK_UNDERFLOW); + } + + /* Remove Bottom element */ + + *object = state->results.obj_desc [0]; + + + /* Push entire stack down one element */ + + for (index = 0; index < state->results.num_results; index++) { + state->results.obj_desc [index] = state->results.obj_desc [index + 1]; + } + + state->results.num_results--; /* Check for a valid result object */ - if (!walk_state->results [walk_state->num_results]) { + if (!*object) { return (AE_AML_NO_OPERAND); } - *object = walk_state->results [walk_state->num_results]; - walk_state->results [walk_state->num_results] = NULL; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ds_result_pop + * + * PARAMETERS: Object - Where to return the popped object + * Walk_state - Current Walk state + * + * RETURN: Status + * + * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In + * other words, this is a FIFO. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ds_result_push ( + ACPI_OPERAND_OBJECT *object, + ACPI_WALK_STATE *walk_state) +{ + ACPI_GENERIC_STATE *state; + + + state = walk_state->results; + if (!state) { + return (AE_OK); + } + + if (state->results.num_results == OBJ_NUM_OPERANDS) { + return (AE_STACK_OVERFLOW); + } + + if (!object) { + return (AE_BAD_PARAMETER); + } + + + state->results.obj_desc [state->results.num_results] = object; + state->results.num_results++; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ds_result_stack_push + * + * PARAMETERS: Object - Object to push + * Walk_state - Current Walk state + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ds_result_stack_push ( + ACPI_WALK_STATE *walk_state) +{ + ACPI_GENERIC_STATE *state; + + + state = acpi_cm_create_generic_state (); + if (!state) { + return (AE_NO_MEMORY); + } + + acpi_cm_push_generic_state (&walk_state->results, state); + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ds_result_stack_pop + * + * PARAMETERS: Walk_state - Current Walk state + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ds_result_stack_pop ( + ACPI_WALK_STATE *walk_state) +{ + ACPI_GENERIC_STATE *state; + + + /* Check for stack underflow */ + + if (walk_state->results == NULL) { + return (AE_AML_NO_OPERAND); + } + + + state = acpi_cm_pop_generic_state (&walk_state->results); + + acpi_cm_delete_generic_state (state); return (AE_OK); } @@ -414,7 +644,7 @@ acpi_ds_get_current_walk_state ( * ******************************************************************************/ -void +static void acpi_ds_push_walk_state ( ACPI_WALK_STATE *walk_state, ACPI_WALK_LIST *walk_list) @@ -528,7 +758,9 @@ acpi_ds_create_walk_state ( /* Init the method args/local */ +#ifndef _ACPI_ASL_COMPILER acpi_ds_method_data_init (walk_state); +#endif /* Put the new state at the head of the walk list */ @@ -565,6 +797,7 @@ acpi_ds_delete_walk_state ( return; } + /* Always must free any linked control states */ while (walk_state->control_state) { @@ -574,7 +807,6 @@ acpi_ds_delete_walk_state ( acpi_cm_delete_generic_state (state); } - /* Always must free any linked parse states */ while (walk_state->scope_info) { @@ -584,6 +816,16 @@ acpi_ds_delete_walk_state ( acpi_cm_delete_generic_state (state); } + /* Always must free any stacked result states */ + + while (walk_state->results) { + state = walk_state->results; + walk_state->results = state->common.next; + + acpi_cm_delete_generic_state (state); + } + + /* If walk cache is full, just free this wallkstate object */ if (acpi_gbl_walk_state_cache_depth >= MAX_WALK_CACHE_DEPTH) { diff --git a/drivers/acpi/driver.c b/drivers/acpi/driver.c index 5015551eb..222598120 100644 --- a/drivers/acpi/driver.c +++ b/drivers/acpi/driver.c @@ -17,6 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + * Changes + * David Woodhouse <dwmw2@redhat.com> 2000-12-6 + * - Fix interruptible_sleep_on() races + */ #include <linux/config.h> #include <linux/module.h> @@ -32,6 +37,12 @@ #include "acpi.h" #include "driver.h" +#ifdef CONFIG_ACPI_KERNEL_CONFIG +#include <asm/efi.h> +#define ACPI_CAN_USE_EFI_STRUCT +#endif + + #define _COMPONENT OS_DEPENDENT MODULE_NAME ("driver") @@ -48,7 +59,15 @@ static volatile acpi_sstate_t acpi_event_state = ACPI_S0; static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); static volatile int acpi_thread_pid = -1; + +/************************************************/ +/* DECLARE_TASK_QUEUE is defined in */ +/* /usr/src/linux/include/linux/tqueue.h */ +/* So, acpi_thread_run is a pointer to a */ +/* tq_struct structure,defined in the same file.*/ +/************************************************/ static DECLARE_TASK_QUEUE(acpi_thread_run); + static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait); static struct ctl_table_header *acpi_sysctl = NULL; @@ -98,6 +117,38 @@ acpi_do_ulong(ctl_table * ctl, return 0; } +static int +acpi_do_pm_timer(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + int size; + u32 val = 0; + + char str[12]; + + if (file->f_pos) { + *len = 0; + return 0; + } + + val = acpi_read_pm_timer(); + + size = sprintf(str, "0x%08x\n", val); + if (*len >= size) { + copy_to_user(buffer, str, size); + *len = size; + } + else + *len = 0; + + file->f_pos += *len; + + return 0; +} + /* * Handle ACPI event */ @@ -105,13 +156,18 @@ static u32 acpi_event(void *context) { unsigned long flags; - int event = (int) context; + int event = (int)(long)context; int mask = 0; switch (event) { - case ACPI_EVENT_POWER_BUTTON: mask = ACPI_PWRBTN; break; - case ACPI_EVENT_SLEEP_BUTTON: mask = ACPI_SLPBTN; break; - default: return AE_ERROR; + case ACPI_EVENT_POWER_BUTTON: + mask = ACPI_PWRBTN; + break; + case ACPI_EVENT_SLEEP_BUTTON: + mask = ACPI_SLPBTN; + break; + default: + return AE_ERROR; } if (mask) { @@ -148,8 +204,12 @@ acpi_do_event(ctl_table * ctl, return 0; } - for (;;) { + while (!event_status) { unsigned long flags; + DECLARE_WAITQUEUE(wait, current); + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&acpi_event_wait, &wait); // we need an atomic exchange here spin_lock_irqsave(&acpi_event_lock, flags); @@ -158,11 +218,12 @@ acpi_do_event(ctl_table * ctl, spin_unlock_irqrestore(&acpi_event_lock, flags); event_state = acpi_event_state; - if (event_status) - break; + if (!event_status) + schedule(); + + remove_wait_queue(&acpi_event_wait, &wait); + set_current_state(TASK_RUNNING); - // wait for an event to arrive - interruptible_sleep_on(&acpi_event_wait); if (signal_pending(current)) return -ERESTARTSYS; } @@ -196,19 +257,78 @@ acpi_do_sleep(ctl_table * ctl, } } else { -#ifdef CONFIG_ACPI_S1_SLEEP int status = acpi_enter_sx(ACPI_S1); if (status) return status; -#endif } file->f_pos += *len; return 0; } + /* - * Run queued callback + * Output important ACPI tables to proc */ +static int +acpi_do_table(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + u32 table_type; + size_t size; + ACPI_BUFFER buf; + u8* data; + + table_type = (u32) ctl->data; + size = 0; + buf.length = 0; + buf.pointer = NULL; + + /* determine what buffer size we will need */ + if (acpi_get_table(table_type, 1, &buf) != AE_BUFFER_OVERFLOW) { + *len = 0; + return 0; + } + + buf.pointer = kmalloc(buf.length, GFP_KERNEL); + if (!buf.pointer) { + return -ENOMEM; + } + + /* get the table for real */ + if (!ACPI_SUCCESS(acpi_get_table(table_type, 1, &buf))) { + kfree(buf.pointer); + *len = 0; + return 0; + } + + if (file->f_pos < buf.length) { + data = buf.pointer + file->f_pos; + size = buf.length - file->f_pos; + if (size > *len) + size = *len; + if (copy_to_user(buffer, data, size)) + return -EFAULT; + } + + kfree(buf.pointer); + + *len = size; + file->f_pos += size; + return 0; +} + +/********************************************************************/ +/* R U N Q U E U E D C A L L B A C K */ +/* */ +/* The "callback" function address that was tramped through via */ +/* "acpi_run" below is finally called and executed. If we trace all */ +/* this down, the function is acpi_ev_asynch_execute_gpe_method, in */ +/* evevent.c The only other function that is ever queued is */ +/* acpi_ev_global_lock_thread in evmisc.c. */ +/********************************************************************/ static void acpi_run_exec(void *context) { @@ -266,6 +386,20 @@ static struct ctl_table acpi_table[] = {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event}, + {ACPI_FADT, "fadt", (void *) ACPI_TABLE_FADT, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_DSDT, "dsdt", (void *) ACPI_TABLE_DSDT, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_FACS, "facs", (void *) ACPI_TABLE_FACS, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_XSDT, "xsdt", (void *) ACPI_TABLE_XSDT, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_PMTIMER, "pm_timer", NULL, 0, 0444, NULL, &acpi_do_pm_timer}, + {0} }; @@ -281,50 +415,75 @@ static struct ctl_table acpi_dir_table[] = static int acpi_thread(void *context) { + ACPI_PHYSICAL_ADDRESS rsdp_phys; + /* * initialize */ - daemonize(); - strcpy(current->comm, "acpi"); + strcpy(current->comm, "kacpid"); + + if (!ACPI_SUCCESS(acpi_initialize_subsystem())) { + printk(KERN_ERR "ACPI: Driver initialization failed\n"); + return -ENODEV; + } - if (!ACPI_SUCCESS(acpi_initialize(NULL))) { - printk(KERN_ERR "ACPI: initialize failed\n"); +#ifndef ACPI_CAN_USE_EFI_STRUCT + if (!ACPI_SUCCESS(acpi_find_root_pointer(&rsdp_phys))) { + printk(KERN_ERR "ACPI: System description tables not found\n"); return -ENODEV; } +#else + rsdp_phys = efi.acpi; +#endif + + printk(KERN_ERR "ACPI: System description tables found\n"); - if (acpi_load_tables()) + if (!ACPI_SUCCESS(acpi_find_and_load_tables(rsdp_phys))) return -ENODEV; if (PM_IS_ACTIVE()) { - printk(KERN_NOTICE "ACPI: APM is already active.\n"); + printk(KERN_NOTICE "ACPI: APM is already active, exiting\n"); acpi_terminate(); return -ENODEV; } - pm_active = 1; - - if (!ACPI_SUCCESS(acpi_enable())) { - printk(KERN_ERR "ACPI: enable failed\n"); + if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION))) { + printk(KERN_ERR "ACPI: Subsystem enable failed\n"); acpi_terminate(); return -ENODEV; } + printk(KERN_ERR "ACPI: Subsystem enabled\n"); + + pm_active = 1; + acpi_cpu_init(); acpi_sys_init(); acpi_ec_init(); + acpi_power_init(); - if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( - ACPI_EVENT_POWER_BUTTON, - acpi_event, - (void *) ACPI_EVENT_POWER_BUTTON))) { - printk(KERN_ERR "ACPI: power button enable failed\n"); + /* + * Non-intuitive: 0 means pwr and sleep are implemented using the fixed + * feature model, so we install handlers. 1 means a control method + * implementation, or none at all, so do nothing. See ACPI spec. + */ + if (acpi_fadt.pwr_button == 0) { + if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( + ACPI_EVENT_POWER_BUTTON, + acpi_event, + (void *) ACPI_EVENT_POWER_BUTTON))) { + printk(KERN_ERR "ACPI: power button enable failed\n"); + } } - if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( - ACPI_EVENT_SLEEP_BUTTON, - acpi_event, - (void *) ACPI_EVENT_SLEEP_BUTTON))) { - printk(KERN_ERR "ACPI: sleep button enable failed\n"); + + if (acpi_fadt.sleep_button == 0) { + if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( + ACPI_EVENT_SLEEP_BUTTON, + acpi_event, + (void *) ACPI_EVENT_SLEEP_BUTTON))) { + printk(KERN_ERR "ACPI: sleep button enable failed\n"); + } } acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); @@ -333,9 +492,20 @@ acpi_thread(void *context) * run */ for (;;) { - interruptible_sleep_on(&acpi_thread_wait); + DECLARE_WAITQUEUE(wait, current); + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&acpi_thread_wait, &wait); + + if (list_empty(&acpi_thread_run)) + schedule(); + + remove_wait_queue(&acpi_thread_wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) break; + run_task_queue(&acpi_thread_run); } @@ -343,7 +513,9 @@ acpi_thread(void *context) * terminate */ unregister_sysctl_table(acpi_sysctl); - acpi_terminate(); + + /* do not terminate, because we need acpi in order to shut down */ + /*acpi_terminate();*/ acpi_thread_pid = -1; diff --git a/drivers/acpi/driver.h b/drivers/acpi/driver.h index a26402b40..9abae5d56 100644 --- a/drivers/acpi/driver.h +++ b/drivers/acpi/driver.h @@ -35,6 +35,7 @@ * cpu.c */ int acpi_cpu_init(void); +u32 acpi_read_pm_timer(void); extern unsigned long acpi_c2_exit_latency; extern unsigned long acpi_c3_exit_latency; @@ -50,8 +51,11 @@ int acpi_run(void (*callback)(void*), void *context); * ec.c */ int acpi_ec_init(void); -int acpi_ec_read(int addr, int *value); -int acpi_ec_write(int addr, int value); + +/* + * power.c + */ +int acpi_power_init(void); /* * sys.c @@ -62,54 +66,10 @@ int acpi_enter_sx(acpi_sstate_t state); extern volatile acpi_sstate_t acpi_sleep_state; /* - * tables.c - */ -extern struct acpi_facp acpi_facp; - -int acpi_load_tables(void); - -/* - * access ACPI registers + * table.c */ +extern FADT_DESCRIPTOR acpi_fadt; -extern inline u32 -acpi_read_pm1_control(struct acpi_facp *facp) -{ - u32 value = 0; - if (facp->pm1a_cnt) - value = inw(facp->pm1a_cnt); - if (facp->pm1b_cnt) - value |= inw(facp->pm1b_cnt); - return value; -} - -extern inline void -acpi_write_pm1_control(struct acpi_facp *facp, u32 value) -{ - if (facp->pm1a_cnt) - outw(value, facp->pm1a_cnt); - if (facp->pm1b_cnt) - outw(value, facp->pm1b_cnt); -} - -extern inline u32 -acpi_read_pm1_status(struct acpi_facp *facp) -{ - u32 value = 0; - if (facp->pm1a_evt) - value = inw(facp->pm1a_evt); - if (facp->pm1b_evt) - value |= inw(facp->pm1b_evt); - return value; -} - -extern inline void -acpi_write_pm1_status(struct acpi_facp *facp, u32 value) -{ - if (facp->pm1a_evt) - outw(value, facp->pm1a_evt); - if (facp->pm1b_evt) - outw(value, facp->pm1b_evt); -} +int acpi_find_and_load_tables(u64 rsdp); #endif /* __DRIVER_H */ diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 16067d1e7..8f6f61e36 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1,37 +1,34 @@ /* - * ec.c - Embedded controller support + * ec.c - Embedded controller support * - * Copyright (C) 2000 Andrew Henroid + * Copyright (C) 2000 Andrew Henroid * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/kernel.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/pm.h> #include <linux/acpi.h> -#include <linux/delay.h> -#include <asm/io.h> +#include <linux/slab.h> #include "acpi.h" #include "driver.h" +#include "ec.h" #define _COMPONENT OS_DEPENDENT MODULE_NAME ("ec") -#define ACPI_EC_HID "PNP0A09" +#define ACPI_EC_HID "PNP0C09" enum { @@ -52,88 +49,478 @@ enum ACPI_EC_QUERY = 0x84, }; +typedef struct +{ + ACPI_HANDLE acpi_handle; + u32 gpe_bit; + ACPI_IO_ADDRESS status_port; + ACPI_IO_ADDRESS data_port; + u32 need_global_lock; +} ec_context_t; + + +typedef struct +{ + ec_context_t *ec; + u8 data; + +} EC_QUERY_DATA; + +static char object_name[] = {'_', 'Q', '0', '0', '\0'}; + +static char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + + +static ACPI_STATUS +ec_io_wait ( + ec_context_t *ec, + EC_EVENT wait_event) +{ + EC_STATUS ec_status = 0; + UINT32 i = 100; + + if (!ec || ((wait_event != EC_EVENT_OUTPUT_BUFFER_FULL) + && (wait_event != EC_EVENT_INPUT_BUFFER_EMPTY))) + return(AE_BAD_PARAMETER); + + /* + * Wait for Event: + * --------------- + * Poll the EC status register waiting for the event to occur. + * Note that we'll wait a maximum of 1ms in 10us chunks. + */ + switch (wait_event) { + case EC_EVENT_OUTPUT_BUFFER_FULL: + do { + ec_status = acpi_os_in8(ec->status_port); + if (ec_status & EC_FLAG_OUTPUT_BUFFER) + return(AE_OK); + acpi_os_sleep_usec(10); + } while (--i>0); + break; + case EC_EVENT_INPUT_BUFFER_EMPTY: + do { + ec_status = acpi_os_in8(ec->status_port); + if (!(ec_status & EC_FLAG_INPUT_BUFFER)) + return(AE_OK); + acpi_os_sleep_usec(10); + } while (--i>0); + break; + } + + return(AE_TIME); +} + +static ACPI_STATUS +ec_io_read ( + ec_context_t *ec, + ACPI_IO_ADDRESS io_port, + UINT8 *data, + EC_EVENT wait_event) +{ + ACPI_STATUS status = AE_OK; + + if (!ec || !data) + return(AE_BAD_PARAMETER); + + *data = acpi_os_in8(io_port); + + if (wait_event) + status = ec_io_wait(ec, wait_event); + + return(status); +} + +static ACPI_STATUS +ec_io_write ( + ec_context_t *ec, + ACPI_IO_ADDRESS io_port, + UINT8 data, + EC_EVENT wait_event) +{ + ACPI_STATUS status = AE_OK; + + if (!ec) + return(AE_BAD_PARAMETER); + + acpi_os_out8(io_port, data); + + if (wait_event) + status = ec_io_wait(ec, wait_event); + + return(status); +} + +static ACPI_STATUS +ec_read ( + ec_context_t *ec, + UINT8 address, + UINT8 *data) +{ + ACPI_STATUS status = AE_OK; + + FUNCTION_TRACE("ec_read"); + + if (!ec || !data) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + status = ec_io_write(ec, ec->status_port, EC_COMMAND_READ, EC_EVENT_INPUT_BUFFER_EMPTY); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Unable to send 'read command' to EC.\n")); + return_ACPI_STATUS(status); + } + + status = ec_io_write(ec, ec->data_port, address, EC_EVENT_OUTPUT_BUFFER_FULL); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Unable to send 'read address' to EC.\n")); + return_ACPI_STATUS(status); + } + + status = ec_io_read(ec, ec->data_port, data, EC_EVENT_NONE); + + DEBUG_PRINT(ACPI_INFO, ("Read data[0x%02x] from address[0x%02x] on ec.\n", (*data), address)); + + return_ACPI_STATUS(status); +} + +static ACPI_STATUS +ec_write ( + ec_context_t *ec, + UINT8 address, + UINT8 data) +{ + ACPI_STATUS status = AE_OK; + + FUNCTION_TRACE("ec_write"); + + if (!ec) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + status = ec_io_write(ec, ec->status_port, EC_COMMAND_WRITE, EC_EVENT_INPUT_BUFFER_EMPTY); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write command' to EC.\n")); + return_ACPI_STATUS(status); + } + + status = ec_io_write(ec, ec->data_port, address, EC_EVENT_INPUT_BUFFER_EMPTY); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write address' to EC.\n")); + return_ACPI_STATUS(status); + } + + status = ec_io_write(ec, ec->data_port, data, EC_EVENT_INPUT_BUFFER_EMPTY); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write data' to EC.\n")); + return_ACPI_STATUS(status); + } + + DEBUG_PRINT(ACPI_INFO, ("Wrote data[0x%02x] to address[0x%02x] on ec.\n", data, address)); + + return_ACPI_STATUS(status); +} + +static ACPI_STATUS +ec_transaction ( + ec_context_t *ec, + EC_REQUEST *request) +{ + ACPI_STATUS status = AE_OK; + + FUNCTION_TRACE("ec_transaction"); + + if (!ec || !request) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + /* + * Obtaining semaphore (mutex) to serialize all EC transactions. + */ + /* + DEBUG_PRINT(ACPI_INFO, ("Calling acpi_os_wait_semaphore(%p, 1, %d)\n", ec->mutex, EC_DEFAULT_TIMEOUT)); + status = acpi_os_wait_semaphore(ec->mutex, 1, EC_DEFAULT_TIMEOUT); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + */ + + /* + * Perform the transaction. + */ + switch (request->command) { + + case EC_COMMAND_READ: + status = ec_read(ec, request->address, &(request->data)); + break; + + case EC_COMMAND_WRITE: + status = ec_write(ec, request->address, request->data); + break; + + default: + status = AE_SUPPORT; + break; + } + + /* + * Signal the semaphore (mutex) to indicate transaction completion. + */ + /* + DEBUG_PRINT(ACPI_INFO, ("Calling acpi_os_signal_semaphore(%p, 1)\n", ec->mutex)); + acpi_os_signal_semaphore(ec->mutex, 1); + */ + + return_ACPI_STATUS(status); +} + +static ACPI_STATUS +ec_space_setup ( + ACPI_HANDLE region_handle, + UINT32 function, + void *handler_context, + void **return_context) +{ + // TODO: What is this function for? + /* + * The ec object is in the handler context and is needed + * when calling the ec_space_handler. + */ + *return_context = handler_context; + + return AE_OK; +} + + -static int acpi_ec_data = 0; -static int acpi_ec_status = 0; -static DECLARE_WAIT_QUEUE_HEAD(acpi_ec_wait); -/* - * handle GPE - */ static void -acpi_ec_gpe(void *context) +ec_query_handler ( + void *context) { - printk(KERN_INFO "ACPI: EC GPE\n"); - if (waitqueue_active(&acpi_ec_wait)) - wake_up_interruptible(&acpi_ec_wait); + ACPI_STATUS status = AE_OK; + EC_QUERY_DATA *ec_q = (EC_QUERY_DATA*)context; + + FUNCTION_TRACE("ec_query_handler"); + + if (!ec_q || !ec_q->ec) { + DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) context.\n")); + return_VOID; + } + + /* + * Evaluate _Qxx: + * -------------- + * Evaluate corresponding _Qxx method. Note that a zero query + * value indicates a spurious EC_SCI (no such thing as _Q00). + */ + object_name[2] = hex[((ec_q->data >> 4) & 0x0F)]; + object_name[3] = hex[(ec_q->data & 0x0F)]; + + DEBUG_PRINT(ACPI_INFO, ("Read query data[0x%02x] from ec - evaluating [%s].\n", ec_q->data, object_name)); + + status = acpi_evaluate_object(ec_q->ec->acpi_handle, object_name, NULL, NULL); + + kfree(ec_q); + + return_VOID; } /* - * wait for read/write status to clear + * handle GPE */ static void -acpi_ec_wait_control(void) +ec_gpe_handler(void *context) { - udelay(1); - while(inb(acpi_ec_status) & ACPI_EC_IBF) - udelay(10); + ACPI_STATUS status = AE_OK; + ec_context_t *ec = (ec_context_t *) context; + EC_QUERY_DATA *ec_q = NULL; + EC_STATUS ec_status = 0; + + FUNCTION_TRACE("ec_gpe_handler"); + + if (!ec) { + DEBUG_PRINT(ACPI_INFO, ("Invalid (NULL) context.\n")); + return_VOID; + } + + // GET SPINLOCK! + + /* + * EC_SCI? + * ------- + * Check the EC_SCI bit to see if this is an EC_SCI event. If not (e.g. + * OBF/IBE) just return, as we already poll to detect these events. + */ + ec_status = acpi_os_in8(ec->status_port); + DEBUG_PRINT(ACPI_INFO, ("EC Status Register: [0x%02x]\n", ec_status)); + if (!(ec_status & EC_FLAG_SCI)) + return_VOID; + + DEBUG_PRINT(ACPI_INFO, ("EC_SCI detected - running QUERY.\n")); + + // TODO: Need GFP_ATOMIC 'switch' for OSL interface... + ec_q = kmalloc(sizeof(EC_QUERY_DATA), GFP_ATOMIC); + if (!ec_q) { + DEBUG_PRINT(ACPI_INFO, ("Memory allocation failure.\n")); + return_VOID; + } + + ec_q->ec = ec; + ec_q->data = 0; + + /* + * Run Query: + * ---------- + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ + status = ec_io_write(ec, ec->status_port, EC_COMMAND_QUERY, EC_EVENT_OUTPUT_BUFFER_FULL); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Unable to send 'query command' to EC.\n")); + goto End; + } + + status = ec_io_read(ec, ec->data_port, &(ec_q->data), EC_EVENT_NONE); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_WARN, ("Error reading query data.\n")); + goto End; + } + + // RELEASE SPINLOCK! + + if (!ec_q->data) { + DEBUG_PRINT(ACPI_WARN, ("Spurious EC SCI detected.\n")); + status = AE_ERROR; + goto End; + } + + /* + * Defer _Qxx Execution: + * --------------------- + * Can't evaluate this method now 'cause we're at interrupt-level. + */ + status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, ec_query_handler, ec_q); + if (ACPI_FAILURE(status)) { + DEBUG_PRINT(ACPI_ERROR, ("Unable to defer _Qxx method evaluation.\n")); + goto End; + } + +End: + if (ACPI_FAILURE(status)) + kfree(ec_q); + + return_VOID; } -/* - * read a byte from the EC - */ -int -acpi_ec_read(int addr, int *value) +static ACPI_STATUS +ec_region_setup ( + ACPI_HANDLE handle, + u32 function, + void *handler_context, + void **region_context) { - if (!acpi_ec_data || !acpi_ec_status) - return -1; + FUNCTION_TRACE("acpi_ec_region_setup"); - outb(ACPI_EC_READ, acpi_ec_status); - acpi_ec_wait_control(); - outb(addr, acpi_ec_data); - acpi_ec_wait_control(); - interruptible_sleep_on(&acpi_ec_wait); - *value = inb(acpi_ec_data); + printk("acpi_ec_region_setup\n"); - return 0; + if (function == ACPI_REGION_DEACTIVATE) + { + if (*region_context) + { + acpi_cm_free (*region_context); + *region_context = NULL; + } + + return_ACPI_STATUS (AE_OK); + } + + *region_context = NULL; + + return_ACPI_STATUS (AE_OK); } -/* - * write a byte to the EC - */ -int -acpi_ec_write(int addr, int value) +/***************************************************************************** + * + * FUNCTION: ec_region_handler + * + * PARAMETERS: function - Read or Write operation + * address - Where in the space to read or write + * bit_width - Field width in bits (8, 16, or 32) + * value - Pointer to in or out value + * context - context pointer + * + * RETURN: <TBD> + * + * DESCRIPTION: Handler for the Embedded Controller (EC) address space + * (Op Region) + * + ****************************************************************************/ + +static ACPI_STATUS +ec_region_handler ( + UINT32 function, + ACPI_PHYSICAL_ADDRESS address, + UINT32 bit_width, + UINT32 *value, + void *handler_context, + void *region_context) { - if (!acpi_ec_data || !acpi_ec_status) - return -1; + ACPI_STATUS status = AE_OK; + ec_context_t *ec = NULL; + EC_REQUEST ec_request; - outb(ACPI_EC_WRITE, acpi_ec_status); - acpi_ec_wait_control(); - outb(addr, acpi_ec_data); - acpi_ec_wait_control(); - outb(value, acpi_ec_data); - acpi_ec_wait_control(); - interruptible_sleep_on(&acpi_ec_wait); + FUNCTION_TRACE("ec_space_handler"); - return 0; + if (address > 0xFF || bit_width != 8 || !value || !handler_context) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + ec = (ec_context_t*)handler_context; + + switch (function) { + + case ADDRESS_SPACE_READ: + ec_request.command = EC_COMMAND_READ; + ec_request.address = address; + ec_request.data = 0; + break; + + case ADDRESS_SPACE_WRITE: + ec_request.command = EC_COMMAND_WRITE; + ec_request.address = address; + ec_request.data = (UINT8)(*value); + break; + + default: + DEBUG_PRINT(ACPI_WARN, ("Received request with invalid function [0x%08X].\n", function)); + return_ACPI_STATUS(AE_BAD_PARAMETER); + break; + } + + DEBUG_PRINT(ACPI_INFO, ("device[ec] command[0x%02X] address[0x%02X] data[0x%02X]\n", ec_request.command, ec_request.address, ec_request.data)); + + /* + * Perform the Transaction. + */ + status = ec_transaction(ec, &ec_request); + if (ACPI_SUCCESS(status)) + (*value) = (UINT32)ec_request.data; + + return_ACPI_STATUS(status); } /* * Get Embedded Controller information */ static ACPI_STATUS -acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +found_ec( + ACPI_HANDLE handle, + u32 level, + void *ctx, + void **value) { - ACPI_DEVICE_INFO dev_info; + ACPI_STATUS status; ACPI_OBJECT obj; ACPI_BUFFER buf; RESOURCE *res; - int gpe; - - if (!ACPI_SUCCESS(acpi_get_object_info(handle, &dev_info)) - || !(dev_info.valid & ACPI_VALID_HID) - || 0 != STRCMP(dev_info.hardware_id, ACPI_EC_HID)) - return AE_OK; + ec_context_t *ec_cxt; buf.length = 0; buf.pointer = NULL; @@ -142,40 +529,73 @@ acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value) buf.pointer = kmalloc(buf.length, GFP_KERNEL); if (!buf.pointer) - return AE_OK; + return AE_NO_MEMORY; if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) { kfree(buf.pointer); return AE_OK; } + ec_cxt = kmalloc(sizeof(ec_context_t), GFP_KERNEL); + if (!ec_cxt) { + kfree(buf.pointer); + return AE_NO_MEMORY; + } + + ec_cxt->acpi_handle = handle; + res = (RESOURCE*) buf.pointer; - acpi_ec_data = (int) res->data.io.min_base_address; - res = (RESOURCE*)((u8*) buf.pointer + res->length); - acpi_ec_status = (int) res->data.io.min_base_address; + ec_cxt->data_port = res->data.io.min_base_address; + res = NEXT_RESOURCE(res); + ec_cxt->status_port = (int) res->data.io.min_base_address; kfree(buf.pointer); + /* determine GPE bit */ + /* BUG: in acpi 2.0 this could return a package */ buf.length = sizeof(obj); buf.pointer = &obj; if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf)) || obj.type != ACPI_TYPE_NUMBER) return AE_OK; - gpe = (int) obj.number.value; - printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,%d)\n", - acpi_ec_data, acpi_ec_status, gpe); + ec_cxt->gpe_bit = obj.number.value; + + /* determine if we need the Global Lock when accessing */ + buf.length = sizeof(obj); + buf.pointer = &obj; + + status = acpi_evaluate_object(handle, "_GLK", NULL, &buf); + if (status == AE_NOT_FOUND) + ec_cxt->need_global_lock = 0; + else if (!ACPI_SUCCESS(status) || obj.type != ACPI_TYPE_NUMBER) { + DEBUG_PRINT(ACPI_ERROR, ("_GLK failed\n")); + return AE_OK; + } + + ec_cxt->need_global_lock = obj.number.value; + + printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,gpe %d GL %d)\n", + ec_cxt->data_port, ec_cxt->status_port, ec_cxt->gpe_bit, + ec_cxt->need_global_lock); if (!ACPI_SUCCESS(acpi_install_gpe_handler( - gpe, - (ACPI_EVENT_LEVEL_TRIGGERED - | ACPI_EVENT_EDGE_TRIGGERED), - acpi_ec_gpe, - NULL))) { + ec_cxt->gpe_bit, + ACPI_EVENT_EDGE_TRIGGERED, + ec_gpe_handler, + ec_cxt))) { - DEBUG_PRINT(ACPI_ERROR, ("Could not install GPE handler for EC.\n")); + REPORT_ERROR(("Could not install GPE handler for EC.\n")); return AE_OK; } + + status = acpi_install_address_space_handler (handle, ADDRESS_SPACE_EC, + ec_region_handler, ec_region_setup, ec_cxt); + + if (!ACPI_SUCCESS(status)) { + REPORT_ERROR(("Could not install EC address " + "space handler, error %s\n", acpi_cm_format_exception (status))); + } return AE_OK; } @@ -183,11 +603,19 @@ acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value) int acpi_ec_init(void) { - acpi_walk_namespace(ACPI_TYPE_DEVICE, - ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - acpi_find_ec, - NULL, - NULL); + acpi_get_devices(ACPI_EC_HID, + found_ec, + NULL, + NULL); + + return 0; +} + +int +acpi_ec_terminate(void) +{ + /* TODO */ + /* walk list of EC's */ + /* free their context and release resources */ return 0; } diff --git a/drivers/acpi/ec.h b/drivers/acpi/ec.h new file mode 100644 index 000000000..e81356362 --- /dev/null +++ b/drivers/acpi/ec.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2000 Andrew Grover + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef __EC_H__ +#define __EC_H__ + +// TODO: Linux-specific +#include <linux/spinlock.h> +#include <asm/semaphore.h> + +#include <actypes.h> +#include <acexcep.h> + +/***************************************************************************** + * Types & Other Defines + *****************************************************************************/ + +#define EC_DEFAULT_TIMEOUT 1000 /* 1 second */ +#define EC_GPE_UNKNOWN 0xFFFFFFFF +#define EC_PORT_UNKNOWN 0x00000000 +#define EC_BURST_ENABLE_ACKNOWLEDGE 0x90 + +/* + * EC_COMMAND: + * ----------- + */ +typedef UINT8 EC_COMMAND; + +#define EC_COMMAND_UNKNOWN ((EC_COMMAND) 0x00) +#define EC_COMMAND_READ ((EC_COMMAND) 0x80) +#define EC_COMMAND_WRITE ((EC_COMMAND) 0x81) +#define EC_COMMAND_QUERY ((EC_COMMAND) 0x84) + +/* + * EC_STATUS: + * ---------- + * The encoding of the EC status register is illustrated below. + * Note that a set bit (1) indicates the property is TRUE + * (e.g. if bit 0 is set then the output buffer is full). + * +-+-+-+-+-+-+-+-+ + * |7|6|5|4|3|2|1|0| + * +-+-+-+-+-+-+-+-+ + * | | | | | | | | + * | | | | | | | +- Output Buffer Full (OBF)? + * | | | | | | +--- Input Buffer Full (IBF)? + * | | | | | +----- <reserved> + * | | | | +------- data Register is command Byte? + * | | | +--------- Burst Mode Enabled? + * | | +----------- SCI event? + * | +------------- SMI event? + * +--------------- <Reserved> + * + */ +typedef UINT8 EC_STATUS; + +#define EC_FLAG_OUTPUT_BUFFER ((EC_STATUS) 0x01) +#define EC_FLAG_INPUT_BUFFER ((EC_STATUS) 0x02) +#define EC_FLAG_BURST_MODE ((EC_STATUS) 0x10) +#define EC_FLAG_SCI ((EC_STATUS) 0x20) + +/* + * EC_EVENT: + * --------- + */ +typedef UINT8 EC_EVENT; + +#define EC_EVENT_UNKNOWN ((EC_EVENT) 0x00) +#define EC_EVENT_NONE ((EC_EVENT) 0x00) +#define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01) +#define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02) +#define EC_EVENT_SCI ((EC_EVENT) 0x03) + +/* + * EC_REQUEST: + * ----------- + */ +typedef struct +{ + EC_COMMAND command; + UINT8 address; + UINT8 data; +} EC_REQUEST; + +#endif /* __EC_H__ */ diff --git a/drivers/acpi/events/Makefile b/drivers/acpi/events/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/events/Makefile +++ b/drivers/acpi/events/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index b3e57cd79..d5ce143a8 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -2,7 +2,7 @@ * * Module Name: evevent - Fixed and General Purpose Acpi_event * handling and dispatch - * $Revision: 13 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -34,6 +34,86 @@ MODULE_NAME ("evevent") +/************************************************************************** + * + * FUNCTION: Acpi_ev_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly + * configured, disables SCI event sources, installs the SCI + * handler + * + *************************************************************************/ + +ACPI_STATUS +acpi_ev_initialize ( + void) +{ + ACPI_STATUS status; + + + /* Make sure we've got ACPI tables */ + + if (!acpi_gbl_DSDT) { + return (AE_NO_ACPI_TABLES); + } + + + /* Make sure the BIOS supports ACPI mode */ + + if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { + return (AE_ERROR); + } + + + acpi_gbl_original_mode = acpi_hw_get_mode(); + + /* + * Initialize the Fixed and General Purpose Acpi_events prior. This is + * done prior to enabling SCIs to prevent interrupts from occuring + * before handers are installed. + */ + + status = acpi_ev_fixed_event_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + + status = acpi_ev_gpe_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Install the SCI handler */ + + status = acpi_ev_install_sci_handler (); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* Install handlers for control method GPE handlers (_Lxx, _Exx) */ + + status = acpi_ev_init_gpe_control_methods (); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Install the handler for the Global Lock */ + + status = acpi_ev_init_global_lock_handler (); + if (ACPI_FAILURE (status)) { + return (status); + } + + + return (status); +} + + /****************************************************************************** * * FUNCTION: Acpi_ev_fixed_event_initialize @@ -58,16 +138,11 @@ acpi_ev_fixed_event_initialize(void) acpi_gbl_fixed_event_handlers[i].context = NULL; } - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_PMTIMER + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_GLOBAL + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_POWER_BUTTON + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_SLEEP_BUTTON + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_RTC + - TMR_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, TMR_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, GBL_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, PWRBTN_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, SLPBTN_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, RTC_EN, 0); return (AE_OK); } @@ -89,25 +164,17 @@ u32 acpi_ev_fixed_event_detect(void) { u32 int_status = INTERRUPT_NOT_HANDLED; - u32 status_register = 0; - u32 enable_register = 0; + u32 status_register; + u32 enable_register; /* * Read the fixed feature status and enable registers, as all the cases * depend on their values. */ - status_register = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk); - if (acpi_gbl_FACP->pm1b_evt_blk) { - status_register |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk); - } + status_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); + enable_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); - enable_register = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); - if (acpi_gbl_FACP->pm1b_evt_blk) { - enable_register |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); - } /* power management timer roll over */ @@ -162,20 +229,53 @@ u32 acpi_ev_fixed_event_dispatch ( u32 event) { + u32 register_id; + /* Clear the status bit */ - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, TMR_STS + - event, 1); + switch (event) + { + case ACPI_EVENT_PMTIMER: + register_id = TMR_STS; + break; + + case ACPI_EVENT_GLOBAL: + register_id = GBL_STS; + break; + + case ACPI_EVENT_POWER_BUTTON: + register_id = PWRBTN_STS; + break; + + case ACPI_EVENT_SLEEP_BUTTON: + register_id = SLPBTN_STS; + break; + + case ACPI_EVENT_RTC: + register_id = RTC_STS; + break; + + default: + return 0; + break; + } + + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, register_id, 1); /* * Make sure we've got a handler. If not, report an error. * The event is disabled to prevent further interrupts. */ if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - TMR_EN + event, 0); + register_id = (PM1_EN | REGISTER_BIT_ID(register_id)); + + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, + register_id, 0); + + REPORT_ERROR ( + ("Ev_gpe_dispatch: No installed handler for fixed event [%08X]\n", + event)); - REPORT_ERROR("No installed handler for fixed event."); return (INTERRUPT_NOT_HANDLED); } @@ -210,15 +310,28 @@ acpi_ev_gpe_initialize (void) /* - * Setup various GPE counts + * Set up various GPE counts + * + * You may ask,why are the GPE register block lengths divided by 2? + * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event + * Registers, we have, + * + * "Each register block contains two registers of equal length + * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the + * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN + * The length of the GPE1_STS and GPE1_EN registers is equal to + * half the GPE1_LEN. If a generic register block is not supported + * then its respective block pointer and block length values in the + * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need + * to be the same size." */ - gpe0register_count = (u16) DIV_2 (acpi_gbl_FACP->gpe0blk_len); - gpe1_register_count = (u16) DIV_2 (acpi_gbl_FACP->gpe1_blk_len); + gpe0register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); + gpe1_register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count; if (!acpi_gbl_gpe_register_count) { - REPORT_WARNING ("No GPEs defined in the FACP"); + REPORT_WARNING (("Zero GPEs are defined in the FADT\n")); return (AE_OK); } @@ -262,10 +375,10 @@ acpi_ev_gpe_initialize (void) for (i = 0; i < gpe0register_count; i++) { acpi_gbl_gpe_registers[register_index].status_addr = - (u16) (acpi_gbl_FACP->gpe0blk + i); + (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i); acpi_gbl_gpe_registers[register_index].enable_addr = - (u16) (acpi_gbl_FACP->gpe0blk + i + gpe0register_count); + (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i + gpe0register_count); acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i); @@ -289,13 +402,13 @@ acpi_ev_gpe_initialize (void) for (i = 0; i < gpe1_register_count; i++) { acpi_gbl_gpe_registers[register_index].status_addr = - (u16) (acpi_gbl_FACP->gpe1_blk + i); + (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i); acpi_gbl_gpe_registers[register_index].enable_addr = - (u16) (acpi_gbl_FACP->gpe1_blk + i + gpe1_register_count); + (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i + gpe1_register_count); acpi_gbl_gpe_registers[register_index].gpe_base = - (u8) (acpi_gbl_FACP->gpe1_base + MUL_8 (i)); + (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i)); for (j = 0; j < 8; j++) { gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j; @@ -339,7 +452,7 @@ acpi_ev_gpe_initialize (void) * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ev_save_method_info ( ACPI_HANDLE obj_handle, u32 level, @@ -446,29 +559,6 @@ acpi_ev_init_gpe_control_methods (void) /****************************************************************************** * - * FUNCTION: Acpi_ev_gpe_cleanup - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Cleanup in preparation for unload. - * - ******************************************************************************/ - -void -acpi_ev_gpe_cleanup (void) -{ - - acpi_cm_free (acpi_gbl_gpe_registers); - acpi_cm_free (acpi_gbl_gpe_info); - - return; -} - - -/****************************************************************************** - * * FUNCTION: Acpi_ev_gpe_detect * * PARAMETERS: None @@ -549,7 +639,7 @@ acpi_ev_gpe_detect (void) * ******************************************************************************/ -void +static void acpi_ev_asynch_execute_gpe_method ( void *context) { @@ -557,38 +647,28 @@ acpi_ev_asynch_execute_gpe_method ( ACPI_GPE_LEVEL_INFO gpe_info; - /* Take a snapshot of the GPE info for this level */ - + /* + * Take a snapshot of the GPE info for this level + */ acpi_cm_acquire_mutex (ACPI_MTX_EVENTS); gpe_info = acpi_gbl_gpe_info [gpe_number]; acpi_cm_release_mutex (ACPI_MTX_EVENTS); /* - * Function Handler (e.g. EC): - * --------------------------- - * Execute the installed function handler to handle this event. - */ - if (gpe_info.handler) { - gpe_info.handler (gpe_info.context); - } - - /* * Method Handler (_Lxx, _Exx): * ---------------------------- - * Acpi_evaluate the _Lxx/_Exx control method that corresponds to this GPE. + * Evaluate the _Lxx/_Exx control method that corresponds to this GPE. */ - else if (gpe_info.method_handle) { + if (gpe_info.method_handle) { acpi_ns_evaluate_by_handle (gpe_info.method_handle, NULL, NULL); } /* * Level-Triggered? * ---------------- - * If level-triggered, clear the GPE status bit after execution. Note - * that edge-triggered events are cleared prior to calling (via DPC) - * this function. + * If level-triggered we clear the GPE status bit after handling the event. */ - if (gpe_info.type | ACPI_EVENT_LEVEL_TRIGGERED) { + if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { acpi_hw_clear_gpe (gpe_number); } @@ -624,11 +704,13 @@ u32 acpi_ev_gpe_dispatch ( u32 gpe_number) { + ACPI_GPE_LEVEL_INFO gpe_info; /*DEBUG_INCREMENT_EVENT_COUNT (EVENT_GENERAL);*/ - /* Ensure that we have a valid GPE number */ - + /* + * Valid GPE number? + */ if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) { return (INTERRUPT_NOT_HANDLED); } @@ -638,48 +720,59 @@ acpi_ev_gpe_dispatch ( */ acpi_hw_disable_gpe (gpe_number); - /* - * Edge-Triggered? - * --------------- - * If edge-triggered, clear the GPE status bit now. Note that - * level-triggered events are cleared after the GPE is serviced - * (see Acpi_ev_asynch_execute_gpe_method). - */ - if (acpi_gbl_gpe_info [gpe_number].type | ACPI_EVENT_EDGE_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } + gpe_info = acpi_gbl_gpe_info [gpe_number]; - /* - * Queue-up the Handler: - * --------------------- - * Queue the handler, which is either an installable function handler - * (e.g. EC) or a control method (e.g. _Lxx/_Exx) for later execution. - */ - if (acpi_gbl_gpe_info [gpe_number].handler || - acpi_gbl_gpe_info [gpe_number].method_handle) - { - if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE, - acpi_ev_asynch_execute_gpe_method, - (void*)(NATIVE_UINT)gpe_number))) - { - /* - * Shoudn't occur, but if it does report an error. Note that - * the GPE will remain disabled until the ACPI Core Subsystem - * is restarted, or the handler is removed/reinstalled. - */ - REPORT_ERROR ("Unable to queue-up handler for GPE."); + /* + * Edge-Triggered? + * --------------- + * If edge-triggered, clear the GPE status bit now. Note that + * level-triggered events are cleared after the GPE is serviced. + */ + if (gpe_info.type & ACPI_EVENT_EDGE_TRIGGERED) { + acpi_hw_clear_gpe (gpe_number); } - } - /* - * Non Handled GPEs: - * ----------------- - * GPEs without handlers are disabled and kept that way until a handler - * is registered for them. - */ - else { - REPORT_ERROR ("No installed handler for GPE."); - } + /* + * Function Handler (e.g. EC)? + */ + if (gpe_info.handler) { + /* Invoke function handler (at interrupt level). */ + gpe_info.handler (gpe_info.context); + + /* Level-Triggered? */ + if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { + acpi_hw_clear_gpe (gpe_number); + } + + /* Enable GPE */ + acpi_hw_enable_gpe (gpe_number); + } + /* + * Method Handler (e.g. _Exx/_Lxx)? + */ + else if (gpe_info.method_handle) { + if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE, + acpi_ev_asynch_execute_gpe_method, (void*)(NATIVE_UINT)gpe_number))) + { + /* + * Shoudn't occur, but if it does report an error. Note that + * the GPE will remain disabled until the ACPI Core Subsystem + * is restarted, or the handler is removed/reinstalled. + */ + REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE bit [%X]\n", gpe_number)); + } + } + /* + * No Handler? Report an error and leave the GPE disabled. + */ + else { + REPORT_ERROR (("Acpi_ev_gpe_dispatch: No installed handler for GPE [%X]\n", gpe_number)); + + /* Level-Triggered? */ + if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { + acpi_hw_clear_gpe (gpe_number); + } + } return (INTERRUPT_HANDLED); } diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 5ca325c46..a52f2dc3d 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -2,7 +2,7 @@ * * Module Name: evmisc - ACPI device notification handler dispatch * and ACPI Global Lock support - * $Revision: 13 $ + * $Revision: 20 $ * *****************************************************************************/ @@ -157,7 +157,7 @@ acpi_ev_notify_dispatch ( * **************************************************************************/ -void +static void acpi_ev_global_lock_thread ( void *context) { @@ -185,7 +185,7 @@ acpi_ev_global_lock_thread ( * **************************************************************************/ -u32 +static u32 acpi_ev_global_lock_handler ( void *context) { @@ -199,7 +199,7 @@ acpi_ev_global_lock_handler ( * take another interrupt when it becomes free. */ - global_lock = &acpi_gbl_FACS->global_lock; + global_lock = acpi_gbl_FACS->global_lock; ACPI_ACQUIRE_GLOBAL_LOCK (global_lock, acquired); if (acquired) { /* Got the lock, now wake all threads waiting for it */ @@ -275,9 +275,9 @@ acpi_ev_acquire_global_lock(void) } - /* We must acquire the actualy hardware lock */ + /* We must acquire the actual hardware lock */ - global_lock = &acpi_gbl_FACS->global_lock; + global_lock = acpi_gbl_FACS->global_lock; ACPI_ACQUIRE_GLOBAL_LOCK (global_lock, acquired); if (acquired) { /* We got the lock */ @@ -298,11 +298,8 @@ acpi_ev_acquire_global_lock(void) * Since this wait will block, we must release the interpreter */ - acpi_aml_exit_interpreter (); status = acpi_aml_system_wait_semaphore (acpi_gbl_global_lock_semaphore, ACPI_UINT32_MAX); - acpi_aml_enter_interpreter (); - return (status); } @@ -323,7 +320,8 @@ acpi_ev_release_global_lock (void) void *global_lock; - if (!acpi_gbl_FACS) { + if (!acpi_gbl_global_lock_thread_count) { + REPORT_WARNING(("Releasing a non-acquired Global Lock\n")); return; } @@ -331,7 +329,6 @@ acpi_ev_release_global_lock (void) acpi_gbl_global_lock_thread_count--; - /* Have all threads released the lock? */ if (!acpi_gbl_global_lock_thread_count) { @@ -340,7 +337,7 @@ acpi_ev_release_global_lock (void) * release */ - global_lock = &acpi_gbl_FACS->global_lock; + global_lock = acpi_gbl_FACS->global_lock; ACPI_RELEASE_GLOBAL_LOCK (global_lock, pending); acpi_gbl_global_lock_acquired = FALSE; @@ -349,8 +346,8 @@ acpi_ev_release_global_lock (void) * register */ if (pending) { - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, - PM1_CONTROL | GBL_RLS, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, + GBL_RLS, 1); } } diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index d544b1bbc..53cae6392 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -1,7 +1,7 @@ /****************************************************************************** * - * Module Name: evregion - ACPI Address_space / Op_region handler dispatch - * $Revision: 76 $ + * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch + * $Revision: 93 $ * *****************************************************************************/ @@ -34,202 +34,6 @@ MODULE_NAME ("evregion") -#define PCI_ROOT_HID_STRING "PNP0A03" -#define PCI_ROOT_HID_VALUE 0x030AD041 /* EISAID("PNP0A03") */ - - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_find_one_pci_root_bus - * - * PARAMETERS: - * - * RETURN: None - * - * DESCRIPTION: - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_find_one_pci_root_bus ( - ACPI_HANDLE obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - ACPI_NAMESPACE_NODE *node; - ACPI_OPERAND_OBJECT *obj_desc; - ACPI_STATUS status; - - - node = (ACPI_NAMESPACE_NODE *) obj_handle; - obj_desc = ((ACPI_NAMESPACE_NODE *) obj_handle)->object; - - - /* - * We are looking for all valid _HID objects. - */ - - if (STRNCMP ((NATIVE_CHAR *) &node->name, METHOD_NAME__HID, ACPI_NAME_SIZE) || - (!obj_desc)) - { - return (AE_OK); - } - - - /* - * Found an _HID object. - * Now we need a HID with the value EISAID("PNP0A03") - * HID can be either a number or a string. - */ - - switch (obj_desc->common.type) - { - case ACPI_TYPE_NUMBER: - - if (obj_desc->number.value != PCI_ROOT_HID_VALUE) { - return (AE_OK); - } - - break; - - case ACPI_TYPE_STRING: - - if (STRNCMP (obj_desc->string.pointer, PCI_ROOT_HID_STRING, - sizeof (PCI_ROOT_HID_STRING))) - { - return (AE_OK); - } - - break; - - default: - - return (AE_OK); - } - - - /* - * We found a valid PCI_ROOT_HID. - * The parent of the HID entry is the PCI device; Install the default PCI - * handler for this PCI device. - */ - - status = acpi_install_address_space_handler (acpi_ns_get_parent_object (node), - ADDRESS_SPACE_PCI_CONFIG, - ACPI_DEFAULT_HANDLER, NULL, NULL); - - return (AE_OK); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_find_pci_root_buses - * - * PARAMETERS: - * - * RETURN: None - * - * DESCRIPTION: - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_find_pci_root_buses ( - void) -{ - - acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - FALSE, acpi_ev_find_one_pci_root_bus, NULL, NULL); - - return (AE_OK); -} - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_init_one_device - * - * PARAMETERS: The usual "I'm a namespace callback" stuff - * - * RETURN: ACPI_STATUS - * - * DESCRIPTION: This is called once per device soon after ACPI is enabled - * to initialize each device. It determines if the device is - * present, and if so, calls _INI. - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_init_one_device ( - ACPI_HANDLE obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - ACPI_STATUS status; - ACPI_OPERAND_OBJECT *ret_obj; - - - /* - * Run _STA to determine if we can run _INI on the device. - */ - status = acpi_ns_evaluate_relative(obj_handle, "_STA", NULL, &ret_obj); - if (AE_NOT_FOUND == status) { - /* No _STA means device is present */ - } - else if (ACPI_FAILURE (status)) { - return (status); - } - else if (ret_obj) { - if (ACPI_TYPE_NUMBER != ret_obj->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - /* - * if _STA "present" bit not set, we're done. - */ - if (!(ret_obj->number.value & 1)) { - goto cleanup; - } - } - - /* - * The device is present. Run _INI. - */ - - status = acpi_ns_evaluate_relative(obj_handle, "_INI", NULL, NULL); - -cleanup: - - acpi_cm_remove_reference (ret_obj); - return (status); -} - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_init_devices - * - * PARAMETERS: None - * - * RETURN: ACPI_STATUS - * - * DESCRIPTION: This initializes all ACPI devices. - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_init_devices ( - void) -{ - acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - FALSE, acpi_ev_init_one_device, NULL, NULL); - - return (AE_OK); -} - - /************************************************************************** * * FUNCTION: Acpi_ev_install_default_address_space_handlers @@ -250,23 +54,45 @@ acpi_ev_install_default_address_space_handlers ( /* - * NOTE: All address spaces (PCI Config, EC, SMBus) are scope dependent - * and registration must occur for a specific device. In the case - * system memory and IO address spaces there is currently no device - * associated with the address space. For these we use the root. + * All address spaces (PCI Config, EC, SMBus) are scope dependent + * and registration must occur for a specific device. In the case + * system memory and IO address spaces there is currently no device + * associated with the address space. For these we use the root. + * We install the default PCI config space handler at the root so + * that this space is immediately available even though the we have + * not enumerated all the PCI Root Buses yet. This is to conform + * to the ACPI specification which states that the PCI config + * space must be always available -- even though we are nowhere + * near ready to find the PCI root buses at this point. + * + * NOTE: We ignore AE_EXIST because this means that a handler has + * already been installed (via Acpi_install_address_space_handler) */ status = acpi_install_address_space_handler (acpi_gbl_root_node, ADDRESS_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL); - if (ACPI_FAILURE (status)) { + if ((ACPI_FAILURE (status)) && + (status != AE_EXIST)) + { return (status); } status = acpi_install_address_space_handler (acpi_gbl_root_node, ADDRESS_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL); - if (ACPI_FAILURE (status)) { + if ((ACPI_FAILURE (status)) && + (status != AE_EXIST)) + { + return (status); + } + + status = acpi_install_address_space_handler (acpi_gbl_root_node, + ADDRESS_SPACE_PCI_CONFIG, + ACPI_DEFAULT_HANDLER, NULL, NULL); + if ((ACPI_FAILURE (status)) && + (status != AE_EXIST)) + { return (status); } @@ -275,7 +101,7 @@ acpi_ev_install_default_address_space_handlers ( } -/* TBD: [Restructure] Move to the methods directory */ +/* TBD: [Restructure] Move elsewhere */ /************************************************************************** * @@ -290,7 +116,7 @@ acpi_ev_install_default_address_space_handlers ( * *************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ev_execute_reg_method ( ACPI_OPERAND_OBJECT *region_obj, u32 function) @@ -301,7 +127,7 @@ acpi_ev_execute_reg_method ( ACPI_STATUS status; - if (region_obj->region.REGmethod == NULL) { + if (region_obj->region.extra->extra.method_REG == NULL) { return (AE_OK); } @@ -337,7 +163,7 @@ acpi_ev_execute_reg_method ( /* * Execute the method, no return value */ - status = acpi_ns_evaluate_by_handle (region_obj->region.REGmethod, params, NULL); + status = acpi_ns_evaluate_by_handle (region_obj->region.extra->extra.method_REG, params, NULL); return (status); } @@ -364,7 +190,7 @@ ACPI_STATUS acpi_ev_address_space_dispatch ( ACPI_OPERAND_OBJECT *region_obj, u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value) { @@ -381,7 +207,7 @@ acpi_ev_address_space_dispatch ( handler_desc = region_obj->region.addr_handler; if (!handler_desc) { - return(AE_EXIST); + return(AE_NOT_EXIST); } /* @@ -421,11 +247,13 @@ acpi_ev_address_space_dispatch ( return(status); } + region_obj->region.flags |= AOPOBJ_INITIALIZED; + /* * Save the returned context for use in all accesses to * this particular region. */ - region_obj->region.region_context = region_context; + region_obj->region.extra->extra.region_context = region_context; } /* @@ -447,7 +275,7 @@ acpi_ev_address_space_dispatch ( */ status = handler (function, address, bit_width, value, handler_desc->addr_handler.context, - region_obj->region.region_context); + region_obj->region.extra->extra.region_context); if (!(handler_desc->addr_handler.flags & ADDR_HANDLER_DEFAULT_INSTALLED)) { @@ -462,10 +290,10 @@ acpi_ev_address_space_dispatch ( /****************************************************************************** * - * FUNCTION: Acpi_ev_disassociate_region_and_handler + * FUNCTION: Acpi_ev_disassociate_region_from_handler * - * PARAMETERS: Handler_obj - Handler Object - * Region_obj - Region Object + * PARAMETERS: Region_obj - Region Object + * Acpi_ns_is_locked - Namespace Region Already Locked? * * RETURN: None * @@ -476,16 +304,19 @@ acpi_ev_address_space_dispatch ( void acpi_ev_disassociate_region_from_handler( - ACPI_OPERAND_OBJECT *region_obj) + ACPI_OPERAND_OBJECT *region_obj, + u8 acpi_ns_is_locked) { ACPI_OPERAND_OBJECT *handler_obj; ACPI_OPERAND_OBJECT *obj_desc; ACPI_OPERAND_OBJECT **last_obj_ptr; ADDRESS_SPACE_SETUP region_setup; - void *region_context = region_obj->region.region_context; + void *region_context; ACPI_STATUS status; + region_context = region_obj->region.extra->extra.region_context; + /* * Get the address handler from the region object */ @@ -517,11 +348,19 @@ acpi_ev_disassociate_region_from_handler( *last_obj_ptr = obj_desc->region.next; obj_desc->region.next = NULL; /* Must clear field */ + if (acpi_ns_is_locked) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + } + /* * Now stop region accesses by executing the _REG method */ acpi_ev_execute_reg_method (region_obj, 0); + if (acpi_ns_is_locked) { + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + } + /* * Call the setup handler with the deactivate notification */ @@ -534,6 +373,8 @@ acpi_ev_disassociate_region_from_handler( * Init routine may fail, Just ignore errors */ + region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); + /* * Remove handler reference in the region * @@ -572,6 +413,7 @@ acpi_ev_disassociate_region_from_handler( * * PARAMETERS: Handler_obj - Handler Object * Region_obj - Region Object + * Acpi_ns_is_locked - Namespace Region Already Locked? * * RETURN: None * @@ -757,7 +599,7 @@ acpi_ev_addr_handler_helper ( * * First disconnect region for any previous handler (if any) */ - acpi_ev_disassociate_region_from_handler (obj_desc); + acpi_ev_disassociate_region_from_handler (obj_desc, FALSE); /* * Then connect the region to the new handler diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index cb1b2de5b..92e5f198f 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -1,7 +1,7 @@ /****************************************************************************** * - * Module Name: evrgnini- ACPI Address_space / Op_region init - * $Revision: 22 $ + * Module Name: evrgnini- ACPI Address_space (Op_region) init + * $Revision: 31 $ * *****************************************************************************/ @@ -56,12 +56,8 @@ acpi_ev_system_memory_region_setup ( void *handler_context, void **region_context) { - ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - if (function == ACPI_REGION_DEACTIVATE) { - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); - if (*region_context) { acpi_cm_free (*region_context); *region_context = NULL; @@ -77,10 +73,6 @@ acpi_ev_system_memory_region_setup ( return (AE_NO_MEMORY); } - /* Init. (Mapping fields are all set to zeros above) */ - - region_obj->region.flags |= AOPOBJ_INITIALIZED; - return (AE_OK); } @@ -107,15 +99,11 @@ acpi_ev_io_space_region_setup ( void *handler_context, void **region_context) { - ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - if (function == ACPI_REGION_DEACTIVATE) { *region_context = NULL; - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); } else { *region_context = handler_context; - region_obj->region.flags |= AOPOBJ_INITIALIZED; } return (AE_OK); @@ -135,7 +123,7 @@ acpi_ev_io_space_region_setup ( * * DESCRIPTION: Do any prep work for region handling * - * MUTEX: Assumes namespace is locked + * MUTEX: Assumes namespace is not locked * ****************************************************************************/ @@ -147,12 +135,12 @@ acpi_ev_pci_config_region_setup ( void **region_context) { ACPI_STATUS status = AE_OK; - u32 temp; + ACPI_INTEGER temp; PCI_HANDLER_CONTEXT *pci_context = *region_context; ACPI_OPERAND_OBJECT *handler_obj; ACPI_NAMESPACE_NODE *node; ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - + DEVICE_ID object_hID; handler_obj = region_obj->region.addr_handler; @@ -161,12 +149,10 @@ acpi_ev_pci_config_region_setup ( * No installed handler. This shouldn't happen because the dispatch * routine checks before we get here, but we check again just in case. */ - return(AE_EXIST); + return(AE_NOT_EXIST); } if (function == ACPI_REGION_DEACTIVATE) { - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); - if (pci_context) { acpi_cm_free (pci_context); *region_context = NULL; @@ -197,8 +183,6 @@ acpi_ev_pci_config_region_setup ( node = acpi_ns_get_parent_object (region_obj->region.node); - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); - /* Acpi_evaluate the _ADR object */ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp); @@ -210,7 +194,7 @@ acpi_ev_pci_config_region_setup ( /* * Got it.. */ - pci_context->dev_func = temp; + pci_context->dev_func = (u32) temp; } /* @@ -221,14 +205,43 @@ acpi_ev_pci_config_region_setup ( * This is the device the handler has been registered to handle. */ - node = handler_obj->addr_handler.node; + /* + * If the Addr_handler.Node is still pointing to the root, we need + * to scan upward for a PCI Root bridge and re-associate the Op_region + * handlers with that device. + */ + if (handler_obj->addr_handler.node == acpi_gbl_root_node) { + /* + * Node is currently the parent object + */ + while (node != acpi_gbl_root_node) { + status = acpi_cm_execute_HID(node, &object_hID); + + if (ACPI_SUCCESS (status)) { + if (!(STRNCMP(object_hID.buffer, PCI_ROOT_HID_STRING, + sizeof (PCI_ROOT_HID_STRING)))) + { + acpi_install_address_space_handler(node, + ADDRESS_SPACE_PCI_CONFIG, + ACPI_DEFAULT_HANDLER, NULL, NULL); + + break; + } + } + + node = acpi_ns_get_parent_object(node); + } + } + else { + node = handler_obj->addr_handler.node; + } status = acpi_cm_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp); if (ACPI_SUCCESS (status)) { /* * Got it.. */ - pci_context->seg = temp; + pci_context->seg = (u32) temp; } status = acpi_cm_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp); @@ -236,15 +249,11 @@ acpi_ev_pci_config_region_setup ( /* * Got it.. */ - pci_context->bus = temp; + pci_context->bus = (u32) temp; } *region_context = pci_context; - acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - - region_obj->region.flags |= AOPOBJ_INITIALIZED; - return (AE_OK); } @@ -271,16 +280,11 @@ acpi_ev_default_region_setup ( void *handler_context, void **region_context) { - ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - - if (function == ACPI_REGION_DEACTIVATE) { *region_context = NULL; - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); } else { *region_context = handler_context; - region_obj->region.flags |= AOPOBJ_INITIALIZED; } return (AE_OK); @@ -315,7 +319,7 @@ acpi_ev_initialize_region ( { ACPI_OPERAND_OBJECT *handler_obj; ACPI_OPERAND_OBJECT *obj_desc; - u32 space_id; + ACPI_ADDRESS_SPACE_TYPE space_id; ACPI_NAMESPACE_NODE *node; ACPI_STATUS status; ACPI_NAMESPACE_NODE *method_node; @@ -332,7 +336,7 @@ acpi_ev_initialize_region ( space_id = region_obj->region.space_id; region_obj->region.addr_handler = NULL; - region_obj->region.REGmethod = NULL; + region_obj->region.extra->extra.method_REG = NULL; region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); /* @@ -346,7 +350,7 @@ acpi_ev_initialize_region ( * definition. This will be executed when the handler is attached * or removed */ - region_obj->region.REGmethod = method_node; + region_obj->region.extra->extra.method_REG = method_node; } /* diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index ef307998a..02320e93c 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c @@ -2,7 +2,7 @@ * * Module Name: evsci - System Control Interrupt configuration and * legacy to ACPI mode state transition functions - * $Revision: 59 $ + * $Revision: 67 $ * ******************************************************************************/ @@ -48,7 +48,7 @@ * * FUNCTION: Acpi_ev_sci_handler * - * PARAMETERS: none + * PARAMETERS: Context - Calling Context * * RETURN: Status code indicates whether interrupt was handled. * @@ -58,7 +58,7 @@ * ******************************************************************************/ -u32 +static u32 acpi_ev_sci_handler (void *context) { u32 interrupt_handled = INTERRUPT_NOT_HANDLED; @@ -68,7 +68,7 @@ acpi_ev_sci_handler (void *context) * Make sure that ACPI is enabled by checking SCI_EN. Note that we are * required to treat the SCI interrupt as sharable, level, active low. */ - if (!acpi_hw_register_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) { + if (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) { /* ACPI is not enabled; this interrupt cannot be for us */ return (INTERRUPT_NOT_HANDLED); @@ -110,7 +110,7 @@ acpi_ev_install_sci_handler (void) u32 except = AE_OK; - except = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FACP->sci_int, + except = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_handler, NULL); @@ -163,7 +163,7 @@ acpi_ev_remove_sci_handler (void) #endif - acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FACP->sci_int, + acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_handler); return (AE_OK); @@ -208,20 +208,11 @@ acpi_ev_restore_acpi_state (void) if (acpi_gbl_restore_acpi_chipset == TRUE) { /* Restore the fixed events */ - if (acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk + 2) != - acpi_gbl_pm1_enable_register_save) - { - acpi_os_out16 ((acpi_gbl_FACP->pm1a_evt_blk + 2), - acpi_gbl_pm1_enable_register_save); - } - - if (acpi_gbl_FACP->pm1b_evt_blk) { - if (acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk + 2) != + if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) != acpi_gbl_pm1_enable_register_save) - { - acpi_os_out16 ((acpi_gbl_FACP->pm1b_evt_blk + 2), - acpi_gbl_pm1_enable_register_save); - } + { + acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN, + acpi_gbl_pm1_enable_register_save); } @@ -232,26 +223,24 @@ acpi_ev_restore_acpi_state (void) /* Now restore the GPEs */ - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe0blk_len); index++) { - if (acpi_os_in8 (acpi_gbl_FACP->gpe0blk + - DIV_2 (acpi_gbl_FACP->gpe0blk_len)) != - acpi_gbl_gpe0enable_register_save[index]) + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { + if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) != + acpi_gbl_gpe0enable_register_save[index]) { - acpi_os_out8 ((acpi_gbl_FACP->gpe0blk + - DIV_2 (acpi_gbl_FACP->gpe0blk_len)), - acpi_gbl_gpe0enable_register_save[index]); + acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index, + acpi_gbl_gpe0enable_register_save[index]); } } - if (acpi_gbl_FACP->gpe1_blk && acpi_gbl_FACP->gpe1_blk_len) { - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe1_blk_len); index++) { - if (acpi_os_in8 (acpi_gbl_FACP->gpe1_blk + - DIV_2 (acpi_gbl_FACP->gpe1_blk_len)) != + /* GPE 1 present? */ + + if (acpi_gbl_FADT->gpe1_blk_len) { + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { + if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) != acpi_gbl_gpe1_enable_register_save[index]) { - acpi_os_out8 ((acpi_gbl_FACP->gpe1_blk + - DIV_2 (acpi_gbl_FACP->gpe1_blk_len)), - acpi_gbl_gpe1_enable_register_save[index]); + acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index, + acpi_gbl_gpe1_enable_register_save[index]); } } } diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 761b66151..c3bbad0ff 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evxface - External interfaces for ACPI events - * $Revision: 88 $ + * $Revision: 97 $ * *****************************************************************************/ @@ -81,9 +81,9 @@ acpi_install_fixed_event_handler ( acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; - if (1 != acpi_hw_register_access (ACPI_WRITE, - ACPI_MTX_LOCK, event + TMR_EN, 1)) - { + status = acpi_enable_event(event, ACPI_EVENT_FIXED); + + if (!ACPI_SUCCESS(status)) { /* Remove the handler */ acpi_gbl_fixed_event_handlers[event].handler = NULL; @@ -131,11 +131,12 @@ acpi_remove_fixed_event_handler ( /* Disable the event before removing the handler - just in case... */ - if (0 != acpi_hw_register_access (ACPI_WRITE, - ACPI_MTX_LOCK, event + TMR_EN, 0)) - { + status = acpi_disable_event(event, ACPI_EVENT_FIXED); + + if (!ACPI_SUCCESS(status)) { status = AE_ERROR; - goto cleanup; + acpi_cm_release_mutex (ACPI_MTX_EVENTS); + return (status); } /* Remove the handler */ @@ -143,7 +144,6 @@ acpi_remove_fixed_event_handler ( acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; -cleanup: acpi_cm_release_mutex (ACPI_MTX_EVENTS); return (status); } @@ -426,14 +426,14 @@ unlock_and_exit: * * PARAMETERS: Gpe_number - The GPE number. The numbering scheme is * bank 0 first, then bank 1. - * Trigger - Whether this GPE should be treated as an + * Type - Whether this GPE should be treated as an * edge- or level-triggered interrupt. * Handler - Address of the handler * Context - Value passed to the handler on each GPE * * RETURN: Status * - * DESCRIPTION: Install a handler for a General Purpose Acpi_event. + * DESCRIPTION: Install a handler for a General Purpose Event. * ******************************************************************************/ @@ -554,11 +554,9 @@ cleanup: * DESCRIPTION: Acquire the ACPI Global Lock * ******************************************************************************/ - ACPI_STATUS acpi_acquire_global_lock ( - u32 timeout, - u32 *out_handle) + void) { ACPI_STATUS status; @@ -573,7 +571,6 @@ acpi_acquire_global_lock ( status = acpi_ev_acquire_global_lock (); acpi_aml_exit_interpreter (); - *out_handle = 0; return (status); } @@ -592,12 +589,8 @@ acpi_acquire_global_lock ( ACPI_STATUS acpi_release_global_lock ( - u32 handle) + void) { - - - /* TBD: [Restructure] Validate handle */ - acpi_ev_release_global_lock (); return (AE_OK); } diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index aee0ba1ba..5b7652e52 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable - * $Revision: 19 $ + * $Revision: 26 $ * *****************************************************************************/ @@ -35,14 +35,6 @@ MODULE_NAME ("evxfevnt") -ACPI_STATUS -acpi_ev_find_pci_root_buses ( - void); - -ACPI_STATUS -acpi_ev_init_devices ( - void); - /************************************************************************** * * FUNCTION: Acpi_enable @@ -51,9 +43,7 @@ acpi_ev_init_devices ( * * RETURN: Status * - * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly - * configured, disables SCI event sources, installs the SCI - * handler, and transfers the system into ACPI mode. + * DESCRIPTION: Transfers the system into ACPI mode. * *************************************************************************/ @@ -69,52 +59,12 @@ acpi_enable (void) return (AE_NO_ACPI_TABLES); } - /* Init the hardware */ - - /* - * With the advent of a 3-pass parser, we need to be - * prepared to execute on initialized HW before the - * namespace has completed its load. - */ - - status = acpi_cm_hardware_initialize (); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Make sure the BIOS supports ACPI mode */ if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { return (AE_ERROR); } - - acpi_gbl_original_mode = acpi_hw_get_mode(); - - /* - * Initialize the Fixed and General Purpose Acpi_events prior. This is - * done prior to enabling SCIs to prevent interrupts from occuring - * before handers are installed. - */ - - status = acpi_ev_fixed_event_initialize (); - if (ACPI_FAILURE (status)) { - return (status); - } - - status = acpi_ev_gpe_initialize (); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Install the SCI handler */ - - status = acpi_ev_install_sci_handler (); - if (ACPI_FAILURE (status)) { - return (status); - } - /* Transition to ACPI mode */ status = acpi_hw_set_mode (SYS_MODE_ACPI); @@ -122,32 +72,6 @@ acpi_enable (void) return (status); } - /* Install handlers for control method GPE handlers (_Lxx, _Exx) */ - - acpi_ev_init_gpe_control_methods (); - - status = acpi_ev_init_global_lock_handler (); - - /* - * Perform additional initialization that may cause control methods - * to be executed - * - * It may be wise to move this code to a new interface - */ - - - /* - * Install PCI config space handler for all PCI root bridges. A PCI root - * bridge is found by searching for devices containing a HID with the value - * EISAID("PNP0A03") - */ - - acpi_ev_find_pci_root_buses (); - - /* Call _INI on all devices */ - - acpi_ev_init_devices (); - return (status); } @@ -250,7 +174,12 @@ acpi_enable_event ( * enable register bit) */ - acpi_hw_register_access (ACPI_WRITE, TRUE, register_id, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); + + if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { + return (AE_ERROR); + } + break; @@ -344,7 +273,12 @@ acpi_disable_event ( * enable register bit) */ - acpi_hw_register_access (ACPI_WRITE, TRUE, register_id, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0); + + if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { + return (AE_ERROR); + } + break; @@ -435,7 +369,7 @@ acpi_clear_event ( * status register bit) */ - acpi_hw_register_access (ACPI_WRITE, TRUE, register_id, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); break; @@ -532,7 +466,7 @@ acpi_get_event_status ( /* Get the status of the requested fixed event */ - *event_status = acpi_hw_register_access (ACPI_READ, TRUE, register_id); + *event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id); break; diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c index 61a04be9e..71116cfc8 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/events/evxfregn.c @@ -2,7 +2,7 @@ * * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and * Address Spaces. - * $Revision: 20 $ + * $Revision: 26 $ * *****************************************************************************/ @@ -43,12 +43,12 @@ * PARAMETERS: Device - Handle for the device * Space_id - The address space ID * Handler - Address of the handler + * Setup - Address of the setup function * Context - Value passed to the handler on each access * * RETURN: Status * - * DESCRIPTION: Install a handler for accesses on an address space controlled - * a specific device. + * DESCRIPTION: Install a handler for all Op_regions of a given Space_id. * ******************************************************************************/ @@ -190,7 +190,7 @@ acpi_install_address_space_handler ( /* Attach the new object to the Node */ - status = acpi_ns_attach_object (device, obj_desc, (u8) type); + status = acpi_ns_attach_object (node, obj_desc, (u8) type); if (ACPI_FAILURE (status)) { acpi_cm_remove_reference (obj_desc); goto unlock_and_exit; @@ -337,7 +337,7 @@ acpi_remove_address_space_handler ( * The region is just inaccessible as indicated to * the _REG method */ - acpi_ev_disassociate_region_from_handler(region_obj); + acpi_ev_disassociate_region_from_handler(region_obj, FALSE); /* * Walk the list, since we took the first region and it diff --git a/drivers/acpi/hardware/Makefile b/drivers/acpi/hardware/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/hardware/Makefile +++ b/drivers/acpi/hardware/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index 5ccfc1924..d2154a1a2 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: hwacpi - ACPI hardware functions - mode and timer - * $Revision: 22 $ + * $Revision: 34 $ * *****************************************************************************/ @@ -34,6 +34,151 @@ /****************************************************************************** * + * FUNCTION: Acpi_hw_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize and validate various ACPI registers + * + ******************************************************************************/ + +ACPI_STATUS +acpi_hw_initialize ( + void) +{ + ACPI_STATUS status = AE_OK; + u32 index; + + + /* We must have the ACPI tables by the time we get here */ + + if (!acpi_gbl_FADT) { + acpi_gbl_restore_acpi_chipset = FALSE; + + return (AE_NO_ACPI_TABLES); + } + + /* Must support *some* mode! */ +/* + if (!(System_flags & SYS_MODES_MASK)) { + Restore_acpi_chipset = FALSE; + + return (AE_ERROR); + } + +*/ + + + switch (acpi_gbl_system_flags & SYS_MODES_MASK) + { + /* Identify current ACPI/legacy mode */ + + case (SYS_MODE_ACPI): + + acpi_gbl_original_mode = SYS_MODE_ACPI; + break; + + + case (SYS_MODE_LEGACY): + + acpi_gbl_original_mode = SYS_MODE_LEGACY; + break; + + + case (SYS_MODE_ACPI | SYS_MODE_LEGACY): + + if (acpi_hw_get_mode () == SYS_MODE_ACPI) { + acpi_gbl_original_mode = SYS_MODE_ACPI; + } + else { + acpi_gbl_original_mode = SYS_MODE_LEGACY; + } + + break; + } + + + if (acpi_gbl_system_flags & SYS_MODE_ACPI) { + /* Target system supports ACPI mode */ + + /* + * The purpose of this code is to save the initial state + * of the ACPI event enable registers. An exit function will be + * registered which will restore this state when the application + * exits. The exit function will also clear all of the ACPI event + * status bits prior to restoring the original mode. + * + * The location of the PM1a_evt_blk enable registers is defined as the + * base of PM1a_evt_blk + DIV_2(PM1a_evt_blk_length). Since the spec further + * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset + * for the enable registers is always 2 from the base. It is hard + * coded here. If this changes in the spec, this code will need to + * be modified. The PM1b_evt_blk behaves as expected. + */ + + acpi_gbl_pm1_enable_register_save = (u16) acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN); + + + /* + * The GPEs behave similarly, except that the length of the register + * block is not fixed, so the buffer must be allocated with malloc + */ + + if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) && + acpi_gbl_FADT->gpe0blk_len) + { + /* GPE0 specified in FADT */ + + acpi_gbl_gpe0enable_register_save = + acpi_cm_allocate (DIV_2 (acpi_gbl_FADT->gpe0blk_len)); + if (!acpi_gbl_gpe0enable_register_save) { + return (AE_NO_MEMORY); + } + + /* Save state of GPE0 enable bits */ + + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { + acpi_gbl_gpe0enable_register_save[index] = + (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index); + } + } + + else { + acpi_gbl_gpe0enable_register_save = NULL; + } + + if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) && + acpi_gbl_FADT->gpe1_blk_len) + { + /* GPE1 defined */ + + acpi_gbl_gpe1_enable_register_save = + acpi_cm_allocate (DIV_2 (acpi_gbl_FADT->gpe1_blk_len)); + if (!acpi_gbl_gpe1_enable_register_save) { + return (AE_NO_MEMORY); + } + + /* save state of GPE1 enable bits */ + + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { + acpi_gbl_gpe1_enable_register_save[index] = + (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index); + } + } + + else { + acpi_gbl_gpe1_enable_register_save = NULL; + } + } + + return (status); +} + + +/****************************************************************************** + * * FUNCTION: Acpi_hw_set_mode * * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY @@ -56,7 +201,7 @@ acpi_hw_set_mode ( if (mode == SYS_MODE_ACPI) { /* BIOS should have disabled ALL fixed and GP events */ - acpi_os_out8 (acpi_gbl_FACP->smi_cmd, acpi_gbl_FACP->acpi_enable); + acpi_os_out8 (acpi_gbl_FADT->smi_cmd, acpi_gbl_FADT->acpi_enable); } else if (mode == SYS_MODE_LEGACY) { @@ -65,7 +210,7 @@ acpi_hw_set_mode ( * enable bits to default */ - acpi_os_out8 (acpi_gbl_FACP->smi_cmd, acpi_gbl_FACP->acpi_disable); + acpi_os_out8 (acpi_gbl_FADT->smi_cmd, acpi_gbl_FADT->acpi_disable); } if (acpi_hw_get_mode () == mode) { @@ -78,8 +223,7 @@ acpi_hw_set_mode ( /****************************************************************************** * - * FUNCTION: Acpi_hw - + * FUNCTION: Acpi_hw_get_mode * * PARAMETERS: none * @@ -95,7 +239,7 @@ acpi_hw_get_mode (void) { - if (acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, SCI_EN)) { + if (acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, SCI_EN)) { return (SYS_MODE_ACPI); } else { @@ -177,7 +321,7 @@ acpi_hw_pmt_ticks (void) { u32 ticks; - ticks = acpi_os_in32 (acpi_gbl_FACP->pm_tmr_blk); + ticks = acpi_os_in32 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)); return (ticks); } @@ -198,7 +342,7 @@ acpi_hw_pmt_ticks (void) u32 acpi_hw_pmt_resolution (void) { - if (0 == acpi_gbl_FACP->tmr_val_ext) { + if (0 == acpi_gbl_FADT->tmr_val_ext) { return (24); } diff --git a/drivers/acpi/hardware/hwcpu32.c b/drivers/acpi/hardware/hwcpu32.c index bf1027ec5..fba28acc7 100644 --- a/drivers/acpi/hardware/hwcpu32.c +++ b/drivers/acpi/hardware/hwcpu32.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: hwcpu32.c - CPU support for IA32 (Throttling, Cx_states) - * $Revision: 33 $ + * $Revision: 39 $ * *****************************************************************************/ @@ -132,7 +132,7 @@ acpi_hw_enter_c2( * We have to do something useless after reading LVL2 because chipsets * cannot guarantee that STPCLK# gets asserted in time to freeze execution. */ - acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); + acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); /* * Compute Time in C2: @@ -171,7 +171,6 @@ acpi_hw_enter_c3( u32 *pm_timer_ticks) { u32 timer = 0; - u8 pm2_cnt_blk = 0; u32 bus_master_status = 0; @@ -187,12 +186,12 @@ acpi_hw_enter_c3( * eventually cause a demotion to C2 */ if (1 == (bus_master_status = - acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS))) + acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS))) { /* * Clear the BM_STS bit by setting it. */ - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1); *pm_timer_ticks = 0; return (AE_OK); } @@ -207,9 +206,7 @@ acpi_hw_enter_c3( * ---------------------- * Set the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits. */ - pm2_cnt_blk = acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); - pm2_cnt_blk |= 0x01; - acpi_os_out8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk, pm2_cnt_blk); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1); /* * Get the timer base before entering C state @@ -229,8 +226,7 @@ acpi_hw_enter_c3( * We have to do something useless after reading LVL3 because chipsets * cannot guarantee that STPCLK# gets asserted in time to freeze execution. */ - acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); - + acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); /* * Immediately compute the time in the C state */ @@ -241,9 +237,7 @@ acpi_hw_enter_c3( * ------------------------ * Clear the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits. */ - pm2_cnt_blk = acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); - pm2_cnt_blk &= 0xFE; - acpi_os_out8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk, pm2_cnt_blk); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0); /* TBD: [Unhandled]: Support 24-bit timers (this algorithm assumes 32-bit) */ @@ -332,7 +326,7 @@ acpi_hw_set_cx ( switch (cx_state) { case 3: - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); break; } @@ -346,7 +340,7 @@ acpi_hw_set_cx ( switch (acpi_hw_active_cx_state) { case 3: - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); break; } @@ -408,15 +402,15 @@ acpi_hw_get_cx_info ( * and on SMP systems when P_LVL2_UP (which indicates C2 only on UP) * is not set. */ - if (acpi_gbl_FACP->plvl2_lat <= 100) { + if (acpi_gbl_FADT->plvl2_lat <= 100) { if (!SMP_system) { acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; - cx_states[2] = acpi_gbl_FACP->plvl2_lat; + cx_states[2] = acpi_gbl_FADT->plvl2_lat; } - else if (!acpi_gbl_FACP->plvl2_up) { + else if (!acpi_gbl_FADT->plvl2_up) { acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; - cx_states[2] = acpi_gbl_FACP->plvl2_lat; + cx_states[2] = acpi_gbl_FADT->plvl2_lat; } } @@ -431,12 +425,12 @@ acpi_hw_get_cx_info ( * cannot be used on SMP systems, and flushing caches (e.g. WBINVD) * is simply too costly (at this time). */ - if (acpi_gbl_FACP->plvl3_lat <= 1000) { - if (!SMP_system && (acpi_gbl_FACP->pm2_cnt_blk && - acpi_gbl_FACP->pm2_cnt_len)) + if (acpi_gbl_FADT->plvl3_lat <= 1000) { + if (!SMP_system && (acpi_gbl_FADT->Xpm2_cnt_blk.address && + acpi_gbl_FADT->pm2_cnt_len)) { acpi_hw_cx_handlers[3] = acpi_hw_enter_c3; - cx_states[3] = acpi_gbl_FACP->plvl3_lat; + cx_states[3] = acpi_gbl_FADT->plvl3_lat; } } diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index e4fa7ad98..2b413fac8 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions - * $Revision: 22 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -32,9 +32,6 @@ MODULE_NAME ("hwgpe") -u8 decode_to8bit [8] = {1,2,4,8,16,32,64,128}; - - /****************************************************************************** * * FUNCTION: Acpi_hw_enable_gpe @@ -63,7 +60,7 @@ acpi_hw_enable_gpe ( /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Read the current value of the register, set the appropriate bit @@ -103,7 +100,7 @@ acpi_hw_disable_gpe ( /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Read the current value of the register, clear the appropriate bit, @@ -142,7 +139,7 @@ acpi_hw_clear_gpe ( /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Write a one to the appropriate bit in the status register to @@ -187,7 +184,7 @@ acpi_hw_get_gpe_status ( /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Enabled?: diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index 2ab4b1d95..77b6a1c8c 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c @@ -3,7 +3,7 @@ * * Module Name: hwregs - Read/write access functions for the various ACPI * control and status registers. - * $Revision: 67 $ + * $Revision: 86 $ * ******************************************************************************/ @@ -36,8 +36,8 @@ /* This matches the #defines in actypes.h. */ -NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", - "\\_S4_","\\_S4_b","\\_S5_"}; +NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", + "\\_S4_","\\_S4_b","\\_S5_"}; /******************************************************************************* @@ -53,7 +53,7 @@ NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", * ******************************************************************************/ -u32 +static u32 acpi_hw_get_bit_shift ( u32 mask) { @@ -87,28 +87,31 @@ acpi_hw_clear_acpi_status (void) acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - acpi_os_out16 (acpi_gbl_FACP->pm1a_evt_blk, (u16) ALL_FIXED_STS_BITS); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); + - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_os_out16 ((u16) acpi_gbl_FACP->pm1b_evt_blk, + if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address)) { + acpi_os_out16 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address), (u16) ALL_FIXED_STS_BITS); } /* now clear the GPE Bits */ - if (acpi_gbl_FACP->gpe0blk_len) { - gpe_length = (u16) DIV_2 (acpi_gbl_FACP->gpe0blk_len); + if (acpi_gbl_FADT->gpe0blk_len) { + gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); for (index = 0; index < gpe_length; index++) { - acpi_os_out8 ((acpi_gbl_FACP->gpe0blk + index), (u8) 0xff); + acpi_os_out8 ((ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + index), + (u8) 0xff); } } - if (acpi_gbl_FACP->gpe1_blk_len) { - gpe_length = (u16) DIV_2 (acpi_gbl_FACP->gpe1_blk_len); + if (acpi_gbl_FADT->gpe1_blk_len) { + gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); for (index = 0; index < gpe_length; index++) { - acpi_os_out8 ((acpi_gbl_FACP->gpe1_blk + index), (u8) 0xff); + acpi_os_out8 ((ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + index), + (u8) 0xff); } } @@ -162,7 +165,7 @@ acpi_hw_obtain_sleep_type_register_data ( } if (!obj_desc) { - REPORT_ERROR ("Missing Sleep State object"); + REPORT_ERROR (("Missing Sleep State object\n")); return (AE_NOT_EXIST); } @@ -172,17 +175,12 @@ acpi_hw_obtain_sleep_type_register_data ( * two elements */ - if (obj_desc->common.type != ACPI_TYPE_PACKAGE) { - /* Must be a package */ - - REPORT_ERROR ("Sleep State object is not of type Package"); - status = AE_ERROR; - } + status = acpi_cm_resolve_package_references(obj_desc); - else if (obj_desc->package.count < 2) { + if (obj_desc->package.count < 2) { /* Must have at least two elements */ - REPORT_ERROR ("Sleep State package does not have at least two elements"); + REPORT_ERROR (("Sleep State package does not have at least two elements\n")); status = AE_ERROR; } @@ -193,7 +191,7 @@ acpi_hw_obtain_sleep_type_register_data ( { /* Must have two */ - REPORT_ERROR ("Sleep State package elements are not both of type Number"); + REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); status = AE_ERROR; } @@ -216,23 +214,23 @@ acpi_hw_obtain_sleep_type_register_data ( /******************************************************************************* * - * FUNCTION: Acpi_hw_register_access + * FUNCTION: Acpi_hw_register_bit_access * * PARAMETERS: Read_write - Either ACPI_READ or ACPI_WRITE. * Use_lock - Lock the hardware - * Register_id - index of ACPI register to access + * Register_id - index of ACPI Register to access * Value - (only used on write) value to write to the - * register. Shifted all the way right. + * Register. Shifted all the way right. * - * RETURN: Value written to or read from specified register. This value + * RETURN: Value written to or read from specified Register. This value * is shifted all the way right. * - * DESCRIPTION: Generic ACPI register read/write function. + * DESCRIPTION: Generic ACPI Register read/write function. * ******************************************************************************/ u32 -acpi_hw_register_access ( +acpi_hw_register_bit_access ( NATIVE_UINT read_write, u8 use_lock, u32 register_id, @@ -241,7 +239,6 @@ acpi_hw_register_access ( u32 register_value = 0; u32 mask = 0; u32 value = 0; - ACPI_IO_ADDRESS gpe_reg = 0; if (read_write == ACPI_WRITE) { @@ -252,183 +249,125 @@ acpi_hw_register_access ( va_end (marker); } - /* - * TBD: [Restructure] May want to split the Acpi_event code and the - * Control code - */ + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + } /* * Decode the Register ID + * Register id = Register block id | bit id + * + * Check bit id to fine locate Register offset. + * check Mask to determine Register offset, and then read-write. */ - switch (register_id & REGISTER_BLOCK_MASK) + switch (REGISTER_BLOCK_ID(register_id)) { - case PM1_EVT: - - if (register_id < TMR_EN) { - /* status register */ - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - + case PM1_STS: - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk); - if (acpi_gbl_FACP->pm1b_evt_blk) { - register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk); - } - - switch (register_id) - { - case TMR_STS: - mask = TMR_STS_MASK; - break; - - case BM_STS: - mask = BM_STS_MASK; - break; + switch (register_id) + { + case TMR_STS: + mask = TMR_STS_MASK; + break; - case GBL_STS: - mask = GBL_STS_MASK; - break; + case BM_STS: + mask = BM_STS_MASK; + break; - case PWRBTN_STS: - mask = PWRBTN_STS_MASK; - break; + case GBL_STS: + mask = GBL_STS_MASK; + break; - case SLPBTN_STS: - mask = SLPBTN_STS_MASK; - break; + case PWRBTN_STS: + mask = PWRBTN_STS_MASK; + break; - case RTC_STS: - mask = RTC_STS_MASK; - break; + case SLPBTN_STS: + mask = SLPBTN_STS_MASK; + break; - case WAK_STS: - mask = WAK_STS_MASK; - break; + case RTC_STS: + mask = RTC_STS_MASK; + break; - default: - mask = 0; - break; - } + case WAK_STS: + mask = WAK_STS_MASK; + break; - if (read_write == ACPI_WRITE) { - /* - * Status registers are different from the rest. Clear by - * writing 1, writing 0 has no effect. So, the only relevent - * information is the single bit we're interested in, all - * others should be written as 0 so they will be left - * unchanged - */ + default: + mask = 0; + break; + } - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); - if (value) { - acpi_os_out16 (acpi_gbl_FACP->pm1a_evt_blk, (u16) value); + if (read_write == ACPI_WRITE) { + /* + * Status Registers are different from the rest. Clear by + * writing 1, writing 0 has no effect. So, the only relevent + * information is the single bit we're interested in, all + * others should be written as 0 so they will be left + * unchanged + */ - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_os_out16 (acpi_gbl_FACP->pm1b_evt_blk, (u16) value); - } + value <<= acpi_hw_get_bit_shift (mask); + value &= mask; - register_value = 0; - } - } + if (value) { + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, (u16) value); - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + register_value = 0; } } - else { - /* enable register */ - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); - - if (acpi_gbl_FACP->pm1b_evt_blk) { - register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); + break; - } - switch (register_id) - { - case TMR_EN: - mask = TMR_EN_MASK; - break; + case PM1_EN: - case GBL_EN: - mask = GBL_EN_MASK; - break; + switch (register_id) + { + case TMR_EN: + mask = TMR_EN_MASK; + break; - case PWRBTN_EN: - mask = PWRBTN_EN_MASK; - break; + case GBL_EN: + mask = GBL_EN_MASK; + break; - case SLPBTN_EN: - mask = SLPBTN_EN_MASK; - break; + case PWRBTN_EN: + mask = PWRBTN_EN_MASK; + break; - case RTC_EN: - mask = RTC_EN_MASK; - break; + case SLPBTN_EN: + mask = SLPBTN_EN_MASK; + break; - default: - mask = 0; - break; - } + case RTC_EN: + mask = RTC_EN_MASK; + break; - if (read_write == ACPI_WRITE) { - register_value &= ~mask; - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - register_value |= value; - - acpi_os_out16 ((acpi_gbl_FACP->pm1a_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)), - (u16) register_value); - - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_os_out16 ((acpi_gbl_FACP->pm1b_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)), - (u16) register_value); - } - } - if(ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); - } + default: + mask = 0; + break; } - break; - - case PM1_CONTROL: + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); - register_value = 0; + if (read_write == ACPI_WRITE) { + register_value &= ~mask; + value <<= acpi_hw_get_bit_shift (mask); + value &= mask; + register_value |= value; - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (u16) register_value); } - if (register_id != SLP_TYPE_B) { - /* - * SLP_TYPx registers are written differently - * than any other control registers with - * respect to A and B registers. The value - * for A may be different than the value for B - */ + break; - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_cnt_blk); - } - if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (u32) SLP_TYPE_A) { - register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_cnt_blk); - } + case PM1_CONTROL: switch (register_id) { @@ -458,6 +397,14 @@ acpi_hw_register_access ( break; } + + /* + * Read the PM1 Control register. + * Note that at this level, the fact that there are actually TWO + * registers (A and B) and that B may not exist, are abstracted. + */ + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); + if (read_write == ACPI_WRITE) { register_value &= ~mask; value <<= acpi_hw_get_bit_shift (mask); @@ -465,47 +412,23 @@ acpi_hw_register_access ( register_value |= value; /* - * SLP_TYPE_x registers are written differently - * than any other control registers with - * respect to A and B registers. The value + * SLP_TYPE_x Registers are written differently + * than any other control Registers with + * respect to A and B Registers. The value * for A may be different than the value for B + * + * Therefore, pass the Register_id, not just generic PM1_CONTROL, + * because we need to do different things. Yuck. */ - if (register_id != SLP_TYPE_B) { - if (mask == SLP_EN_MASK) { - disable(); /* disable interrupts */ - } - - acpi_os_out16 (acpi_gbl_FACP->pm1a_cnt_blk, (u16) register_value); - - if (mask == SLP_EN_MASK) { - /* - * Enable interrupts, the SCI handler is likely going to - * be invoked as soon as interrupts are enabled, since gpe's - * and most fixed resume events also generate SCI's. - */ - enable(); - } - } - - if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (u32) SLP_TYPE_A) { - acpi_os_out16 (acpi_gbl_FACP->pm1b_cnt_blk, (u16) register_value); - } - } - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + register_id, (u16) register_value); } break; case PM2_CONTROL: - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm2_cnt_blk); switch (register_id) { case ARB_DIS: @@ -517,85 +440,64 @@ acpi_hw_register_access ( break; } + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); + if (read_write == ACPI_WRITE) { register_value &= ~mask; value <<= acpi_hw_get_bit_shift (mask); value &= mask; register_value |= value; - acpi_os_out16 (acpi_gbl_FACP->pm2_cnt_blk, (u16) register_value); - } - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + PM2_CONTROL, (u8) (register_value)); } break; case PM_TIMER: - register_value = acpi_os_in32 (acpi_gbl_FACP->pm_tmr_blk); - mask = 0xFFFFFFFF; + mask = TMR_VAL_MASK; + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + PM_TIMER); break; case GPE1_EN_BLOCK: - - gpe_reg = (acpi_gbl_FACP->gpe1_blk + acpi_gbl_FACP->gpe1_base) + - (gpe_reg + (DIV_2 (acpi_gbl_FACP->gpe1_blk_len))); - - case GPE1_STS_BLOCK: - - if (!gpe_reg) { - gpe_reg = (acpi_gbl_FACP->gpe1_blk + acpi_gbl_FACP->gpe1_base); - } - - case GPE0_EN_BLOCK: - - if (!gpe_reg) { - gpe_reg = acpi_gbl_FACP->gpe0blk + DIV_2 (acpi_gbl_FACP->gpe0blk_len); - } - - case GPE0_STS_BLOCK: - if (!gpe_reg) { - gpe_reg = acpi_gbl_FACP->gpe0blk; - } - - /* Determine the bit to be accessed */ + /* Determine the bit to be accessed + * + * (u32) Register_id: + * 31 24 16 8 0 + * +--------+--------+--------+--------+ + * | gpe_block_id | gpe_bit_number | + * +--------+--------+--------+--------+ + * + * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK + * gpe_bit_number is relative from the gpe_block (0x00~0xFF) + */ - mask = (((u32) register_id) & BIT_IN_REGISTER_MASK); - mask = 1 << (mask-1); + mask = REGISTER_BIT_ID(register_id); /* gpe_bit_number */ + register_id = REGISTER_BLOCK_ID(register_id) | (mask >> 3); + mask = acpi_gbl_decode_to8bit [mask % 8]; /* * The base address of the GPE 0 Register Block * Plus 1/2 the length of the GPE 0 Register Block - * The enable register is the register following the Status Register - * and each register is defined as 1/2 of the total Register Block + * The enable Register is the Register following the Status Register + * and each Register is defined as 1/2 of the total Register Block */ /* * This sets the bit within Enable_bit that needs to be written to - * the register indicated in Mask to a 1, all others are 0 + * the Register indicated in Mask to a 1, all others are 0 */ - if (mask > LOW_BYTE) { - /* Shift the value 1 byte to the right and add 1 to the register */ - - mask >>= ONE_BYTE; - gpe_reg++; - } - /* Now get the current Enable Bits in the selected Reg */ - if(ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - - register_value = (u32) acpi_os_in8 (gpe_reg); + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id); if (read_write == ACPI_WRITE) { register_value &= ~mask; value <<= acpi_hw_get_bit_shift (mask); @@ -603,29 +505,494 @@ acpi_hw_register_access ( register_value |= value; /* This write will put the Action state into the General Purpose */ - /* Enable Register indexed by the value in Mask */ - acpi_os_out8 (gpe_reg, (u8) register_value); - register_value = (u32) acpi_os_in8 (gpe_reg); - } - - if(ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + register_id, (u8) register_value); + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id); } break; + case SMI_CMD_BLOCK: case PROCESSOR_BLOCK: + /* not used */ default: mask = 0; break; } + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + } + register_value &= mask; register_value >>= acpi_hw_get_bit_shift (mask); return (register_value); } + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_register_read + * + * PARAMETERS: Use_lock - Mutex hw access. + * Register_id - Register_iD + Offset. + * + * RETURN: Value read or written. + * + * DESCRIPTION: Acpi register read function. Registers are read at the + * given offset. + * + ******************************************************************************/ + +u32 +acpi_hw_register_read ( + u8 use_lock, + u32 register_id) +{ + u32 value = 0; + u32 bank_offset; + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + } + + + switch (REGISTER_BLOCK_ID(register_id)) + { + case PM1_STS: /* 16-bit access */ + + value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, 0); + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, 0); + break; + + + case PM1_EN: /* 16-bit access*/ + + bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); + value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset); + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset); + break; + + + case PM1_CONTROL: /* 16-bit access */ + + if (register_id != SLP_TYPE_B) { + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); + } + + if (register_id != SLP_TYPE_A) { + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); + } + break; + + + case PM2_CONTROL: /* 8-bit access */ + + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xpm2_cnt_blk, 0); + break; + + + case PM_TIMER: /* 32-bit access */ + + value = acpi_hw_low_level_read (32, &acpi_gbl_FADT->Xpm_tmr_blk, 0); + break; + + + case GPE0_STS_BLOCK: /* 8-bit access */ + + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, 0); + break; + + + case GPE0_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len); + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset); + break; + + + case GPE1_STS_BLOCK: /* 8-bit access */ + + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, 0); + break; + + + case GPE1_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len); + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); + break; + + + case SMI_CMD_BLOCK: /* 8bit */ + + value = (u32) acpi_os_in8 (acpi_gbl_FADT->smi_cmd); + break; + + + default: + value = 0; + break; + } + + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + } + + return (value); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_register_write + * + * PARAMETERS: Use_lock - Mutex hw access. + * Register_id - Register_iD + Offset. + * + * RETURN: Value read or written. + * + * DESCRIPTION: Acpi register Write function. Registers are written at the + * given offset. + * + ******************************************************************************/ + +void +acpi_hw_register_write ( + u8 use_lock, + u32 register_id, + u32 value) +{ + u32 bank_offset; + + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + } + + + switch (REGISTER_BLOCK_ID (register_id)) + { + case PM1_STS: /* 16-bit access */ + + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, 0); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, 0); + break; + + + case PM1_EN: /* 16-bit access*/ + + bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset); + break; + + + case PM1_CONTROL: /* 16-bit access */ + + /* + * If SLP_TYP_A or SLP_TYP_B, only write to one reg block. + * Otherwise, write to both. + */ + if (register_id == SLP_TYPE_A) { + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); + } + else if (register_id == SLP_TYPE_B) { + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); + } + else { + /* disable/re-enable interrupts if sleeping */ + if (register_id == SLP_EN) { + disable(); + } + + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); + + if (register_id == SLP_EN) { + enable(); + } + } + + break; + + + case PM2_CONTROL: /* 8-bit access */ + + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xpm2_cnt_blk, 0); + break; + + + case PM_TIMER: /* 32-bit access */ + + acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->Xpm_tmr_blk, 0); + break; + + + case GPE0_STS_BLOCK: /* 8-bit access */ + + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, 0); + break; + + + case GPE0_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len); + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset); + break; + + + case GPE1_STS_BLOCK: /* 8-bit access */ + + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, 0); + break; + + + case GPE1_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len); + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); + break; + + + case SMI_CMD_BLOCK: /* 8bit */ + + /* For 2.0, SMI_CMD is always in IO space */ + /* TBD: what about 1.0? 0.71? */ + + acpi_os_out8 (acpi_gbl_FADT->smi_cmd, (u8) value); + break; + + + default: + value = 0; + break; + } + + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + } + + return; +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_low_level_read + * + * PARAMETERS: Register - GAS register structure + * Offset - Offset from the base address in the GAS + * Width - 8, 16, or 32 + * + * RETURN: Value read + * + * DESCRIPTION: Read from either memory, IO, or PCI config space. + * + ******************************************************************************/ + +u32 +acpi_hw_low_level_read ( + u32 width, + ACPI_GAS *reg, + u32 offset) +{ + u32 value = 0; + ACPI_PHYSICAL_ADDRESS mem_address; + ACPI_IO_ADDRESS io_address; + u32 pci_register; + u32 pci_dev_func; + + + /* + * Must have a valid pointer to a GAS structure, and + * a non-zero address within + */ + if ((!reg) || + (!ACPI_VALID_ADDRESS (reg->address))) + { + return 0; + } + + + /* + * Three address spaces supported: + * Memory, Io, or PCI config. + */ + + switch (reg->address_space_id) + { + case ADDRESS_SPACE_SYSTEM_MEMORY: + + mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); + + switch (width) + { + case 8: + value = acpi_os_mem_in8 (mem_address); + break; + case 16: + value = acpi_os_mem_in16 (mem_address); + break; + case 32: + value = acpi_os_mem_in32 (mem_address); + break; + } + break; + + + case ADDRESS_SPACE_SYSTEM_IO: + + io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); + + switch (width) + { + case 8: + value = acpi_os_in8 (io_address); + break; + case 16: + value = acpi_os_in16 (io_address); + break; + case 32: + value = acpi_os_in32 (io_address); + break; + } + break; + + + case ADDRESS_SPACE_PCI_CONFIG: + + pci_dev_func = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg->address)); + pci_register = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset; + + switch (width) + { + case 8: + acpi_os_read_pci_cfg_byte (0, pci_dev_func, pci_register, (u8 *) &value); + break; + case 16: + acpi_os_read_pci_cfg_word (0, pci_dev_func, pci_register, (u16 *) &value); + break; + case 32: + acpi_os_read_pci_cfg_dword (0, pci_dev_func, pci_register, (u32 *) &value); + break; + } + break; + } + + return value; +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_low_level_write + * + * PARAMETERS: Width - 8, 16, or 32 + * Value - To be written + * Register - GAS register structure + * Offset - Offset from the base address in the GAS + * + * + * RETURN: Value read + * + * DESCRIPTION: Read from either memory, IO, or PCI config space. + * + ******************************************************************************/ + +void +acpi_hw_low_level_write ( + u32 width, + u32 value, + ACPI_GAS *reg, + u32 offset) +{ + ACPI_PHYSICAL_ADDRESS mem_address; + ACPI_IO_ADDRESS io_address; + u32 pci_register; + u32 pci_dev_func; + + + /* + * Must have a valid pointer to a GAS structure, and + * a non-zero address within + */ + if ((!reg) || + (!ACPI_VALID_ADDRESS (reg->address))) + { + return; + } + + + /* + * Three address spaces supported: + * Memory, Io, or PCI config. + */ + + switch (reg->address_space_id) + { + case ADDRESS_SPACE_SYSTEM_MEMORY: + + mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); + + switch (width) + { + case 8: + acpi_os_mem_out8 (mem_address, (u8) value); + break; + case 16: + acpi_os_mem_out16 (mem_address, (u16) value); + break; + case 32: + acpi_os_mem_out32 (mem_address, (u32) value); + break; + } + break; + + + case ADDRESS_SPACE_SYSTEM_IO: + + io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); + + switch (width) + { + case 8: + acpi_os_out8 (io_address, (u8) value); + break; + case 16: + acpi_os_out16 (io_address, (u16) value); + break; + case 32: + acpi_os_out32 (io_address, (u32) value); + break; + } + break; + + + case ADDRESS_SPACE_PCI_CONFIG: + + pci_dev_func = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg->address)); + pci_register = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset; + + switch (width) + { + case 8: + acpi_os_write_pci_cfg_byte (0, pci_dev_func, pci_register, (u8) value); + break; + case 16: + acpi_os_write_pci_cfg_word (0, pci_dev_func, pci_register, (u16) value); + break; + case 32: + acpi_os_write_pci_cfg_dword (0, pci_dev_func, pci_register, (u32) value); + break; + } + break; + } +} diff --git a/drivers/acpi/hardware/hwxface.c b/drivers/acpi/hardware/hwxface.c index fbe564b46..156c946e7 100644 --- a/drivers/acpi/hardware/hwxface.c +++ b/drivers/acpi/hardware/hwxface.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: hwxface.c - Hardware access external interfaces - * $Revision: 31 $ + * $Revision: 36 $ * *****************************************************************************/ @@ -69,7 +69,7 @@ acpi_get_processor_throttling_info ( NATIVE_UINT num_throttle_states; NATIVE_UINT buffer_space_needed; NATIVE_UINT i; - u8 duty_width = 0; + u8 duty_width; ACPI_NAMESPACE_NODE *cpu_node; ACPI_OPERAND_OBJECT *cpu_obj; ACPI_CPU_THROTTLING_STATE *state_ptr; @@ -100,12 +100,10 @@ acpi_get_processor_throttling_info ( return (AE_NOT_FOUND); } -#ifndef _IA64 /* - * No Duty fields in IA64 tables + * (Duty Width on IA-64 is zero) */ - duty_width = acpi_gbl_FACP->duty_width; -#endif + duty_width = acpi_gbl_FADT->duty_width; /* * P0 must always have a P_BLK all others may be null @@ -115,7 +113,7 @@ acpi_get_processor_throttling_info ( * */ if (!cpu_obj->processor.length || !duty_width || - (0xFFFF < cpu_obj->processor.address)) + (ACPI_UINT16_MAX < cpu_obj->processor.address)) { /* * Acpi_even though we can't throttle, we still have one state (100%) @@ -177,8 +175,8 @@ acpi_get_processor_throttling_state ( ACPI_OPERAND_OBJECT *cpu_obj; u32 num_throttle_states; u32 duty_cycle; - u8 duty_offset = 0; - u8 duty_width = 0; + u8 duty_offset; + u8 duty_width; /* Convert and validate the device handle */ @@ -195,13 +193,11 @@ acpi_get_processor_throttling_state ( return (AE_NOT_FOUND); } -#ifndef _IA64 /* * No Duty fields in IA64 tables */ - duty_offset = acpi_gbl_FACP->duty_offset; - duty_width = acpi_gbl_FACP->duty_width; -#endif + duty_offset = acpi_gbl_FADT->duty_offset; + duty_width = acpi_gbl_FADT->duty_width; /* * Must have a valid P_BLK P0 must have a P_BLK all others may be null @@ -211,7 +207,7 @@ acpi_get_processor_throttling_state ( * also, if Duty_width is zero there are no additional states */ if (!cpu_obj->processor.length || !duty_width || - (0xFFFF < cpu_obj->processor.address)) + (ACPI_UINT16_MAX < cpu_obj->processor.address)) { *throttle_state = 0; return(AE_OK); @@ -263,8 +259,8 @@ acpi_set_processor_throttling_state ( ACPI_NAMESPACE_NODE *cpu_node; ACPI_OPERAND_OBJECT *cpu_obj; u32 num_throttle_states = 0; - u8 duty_offset = 0; - u8 duty_width = 0; + u8 duty_offset; + u8 duty_width; u32 duty_cycle = 0; @@ -282,13 +278,11 @@ acpi_set_processor_throttling_state ( return (AE_NOT_FOUND); } -#ifndef _IA64 /* * No Duty fields in IA64 tables */ - duty_offset = acpi_gbl_FACP->duty_offset; - duty_width = acpi_gbl_FACP->duty_width; -#endif + duty_offset = acpi_gbl_FADT->duty_offset; + duty_width = acpi_gbl_FADT->duty_width; /* * Must have a valid P_BLK P0 must have a P_BLK all others may be null @@ -298,7 +292,7 @@ acpi_set_processor_throttling_state ( * also, if Duty_width is zero there are no additional states */ if (!cpu_obj->processor.length || !duty_width || - (0xFFFF < cpu_obj->processor.address)) + (ACPI_UINT16_MAX < cpu_obj->processor.address)) { /* * If caller wants to set the state to the only state we handle @@ -314,7 +308,7 @@ acpi_set_processor_throttling_state ( return (AE_SUPPORT); } - num_throttle_states = (int) acpi_hw_local_pow (2,duty_width); + num_throttle_states = (u32) acpi_hw_local_pow (2,duty_width); /* * Convert throttling state to duty cycle (invert). @@ -533,9 +527,10 @@ acpi_get_timer ( ACPI_STATUS acpi_set_firmware_waking_vector ( - void *physical_address) + ACPI_PHYSICAL_ADDRESS physical_address) { + /* Make sure that we have an FACS */ if (!acpi_gbl_FACS) { @@ -544,7 +539,12 @@ acpi_set_firmware_waking_vector ( /* Set the vector */ - * ((void **) acpi_gbl_FACS->firmware_waking_vector) = physical_address; + if (acpi_gbl_FACS->vector_width == 32) { + * (u32 *) acpi_gbl_FACS->firmware_waking_vector = (u32) physical_address; + } + else { + *acpi_gbl_FACS->firmware_waking_vector = physical_address; + } return (AE_OK); } @@ -555,7 +555,7 @@ acpi_set_firmware_waking_vector ( * FUNCTION: Acpi_get_firmware_waking_vector * * PARAMETERS: *Physical_address - Output buffer where contents of - * the d_firmware_waking_vector field of + * the Firmware_waking_vector field of * the FACS will be stored. * * RETURN: Status @@ -566,9 +566,10 @@ acpi_set_firmware_waking_vector ( ACPI_STATUS acpi_get_firmware_waking_vector ( - void **physical_address) + ACPI_PHYSICAL_ADDRESS *physical_address) { + if (!physical_address) { return (AE_BAD_PARAMETER); } @@ -581,8 +582,12 @@ acpi_get_firmware_waking_vector ( /* Get the vector */ - *physical_address = * ((void **) acpi_gbl_FACS->firmware_waking_vector); - + if (acpi_gbl_FACS->vector_width == 32) { + *physical_address = * (u32 *) acpi_gbl_FACS->firmware_waking_vector; + } + else { + *physical_address = *acpi_gbl_FACS->firmware_waking_vector; + } return (AE_OK); } diff --git a/drivers/acpi/include/accommon.h b/drivers/acpi/include/accommon.h index e914ffeb2..37e13b228 100644 --- a/drivers/acpi/include/accommon.h +++ b/drivers/acpi/include/accommon.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: accommon.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 74 $ + * $Revision: 82 $ * *****************************************************************************/ @@ -43,7 +43,7 @@ void acpi_cm_init_globals ( - ACPI_INIT_DATA *init_data); + void); void acpi_cm_terminate ( @@ -51,7 +51,7 @@ acpi_cm_terminate ( /* - * Acpi_cm_init - miscellaneous initialization and shutdown + * Cm_init - miscellaneous initialization and shutdown */ ACPI_STATUS @@ -62,10 +62,16 @@ ACPI_STATUS acpi_cm_subsystem_shutdown ( void); +ACPI_STATUS +acpi_cm_validate_fadt ( + void); + /* - * Acpi_cm_global - Global data structures and procedures + * Cm_global - Global data structures and procedures */ +#ifdef ACPI_DEBUG + NATIVE_CHAR * acpi_cm_get_mutex_name ( u32 mutex_id); @@ -74,6 +80,13 @@ NATIVE_CHAR * acpi_cm_get_type_name ( u32 type); +NATIVE_CHAR * +acpi_cm_get_region_name ( + u8 space_id); + +#endif + + u8 acpi_cm_valid_object_type ( u32 type); @@ -84,7 +97,7 @@ acpi_cm_allocate_owner_id ( /* - * Acpi_cm_clib - Local implementations of C library functions + * Cm_clib - Local implementations of C library functions */ NATIVE_UINT @@ -161,7 +174,7 @@ acpi_cm_to_lower ( /* - * Acpi_cm_copy - Object construction and conversion interfaces + * Cm_copy - Object construction and conversion interfaces */ ACPI_STATUS @@ -204,7 +217,7 @@ acpi_cm_build_copy_internal_package_object ( /* - * Acpi_cm_create - Object creation + * Cm_create - Object creation */ ACPI_STATUS @@ -221,7 +234,7 @@ _cm_create_internal_object ( /* - * Acpi_cm_debug - Debug interfaces + * Cm_debug - Debug interfaces */ u32 @@ -315,22 +328,19 @@ void _report_info ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message); + u32 component_id); void _report_error ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message); + u32 component_id); void _report_warning ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message); + u32 component_id); void acpi_cm_dump_buffer ( @@ -341,7 +351,7 @@ acpi_cm_dump_buffer ( /* - * Acpi_cm_delete - Object deletion + * Cm_delete - Object deletion */ void @@ -362,7 +372,7 @@ acpi_cm_delete_internal_object_list ( /* - * Acpi_cm_eval - object evaluation + * Cm_eval - object evaluation */ /* Method name strings */ @@ -378,9 +388,9 @@ acpi_cm_delete_internal_object_list ( ACPI_STATUS acpi_cm_evaluate_numeric_object ( - NATIVE_CHAR *method_name, + NATIVE_CHAR *object_name, ACPI_NAMESPACE_NODE *device_node, - u32 *address); + ACPI_INTEGER *address); ACPI_STATUS acpi_cm_execute_HID ( @@ -399,7 +409,7 @@ acpi_cm_execute_UID ( /* - * Acpi_cm_error - exception interfaces + * Cm_error - exception interfaces */ NATIVE_CHAR * @@ -408,7 +418,7 @@ acpi_cm_format_exception ( /* - * Acpi_cm_mutex - mutual exclusion interfaces + * Cm_mutex - mutual exclusion interfaces */ ACPI_STATUS @@ -437,7 +447,7 @@ acpi_cm_release_mutex ( /* - * Acpi_cm_object - internal object create/delete/cache routines + * Cm_object - internal object create/delete/cache routines */ void * @@ -459,7 +469,7 @@ acpi_cm_valid_internal_object ( /* - * Acpi_cm_ref_cnt - Object reference count management + * Cm_ref_cnt - Object reference count management */ void @@ -471,7 +481,7 @@ acpi_cm_remove_reference ( ACPI_OPERAND_OBJECT *object); /* - * Acpi_cm_size - Object size routines + * Cm_size - Object size routines */ ACPI_STATUS @@ -491,7 +501,7 @@ acpi_cm_get_object_size( /* - * Acpi_cm_state - Generic state creation/cache routines + * Cm_state - Generic state creation/cache routines */ void @@ -536,7 +546,7 @@ acpi_cm_delete_object_cache ( void); /* - * Acpi_cmutils + * Cmutils */ u8 @@ -547,6 +557,10 @@ u8 acpi_cm_valid_acpi_character ( NATIVE_CHAR character); +ACPI_STATUS +acpi_cm_resolve_package_references ( + ACPI_OPERAND_OBJECT *obj_desc); + /* * Memory allocation functions and related macros. diff --git a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h index 5e1427950..2b210339b 100644 --- a/drivers/acpi/include/acconfig.h +++ b/drivers/acpi/include/acconfig.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acconfig.h - Global configuration constants - * $Revision: 42 $ + * $Revision: 48 $ * *****************************************************************************/ @@ -55,29 +55,6 @@ #define ACPI_CA_VERSION __DATE__ -/* Name of host operating system (returned by the _OS_ namespace object) */ - -#ifdef _LINUX -#define ACPI_OS_NAME "Linux" -#else -#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" -#endif - - -/* - * How and when control methods will be parsed - * The default action is to parse all methods at table load time to verify them, but delete the parse trees - * to conserve memory. Methods are parsed just in time before execution and the parse tree is deleted - * when execution completes. - */ -#define METHOD_PARSE_AT_INIT 0x0 /* Parse at table init, never delete the method parse tree */ -#define METHOD_PARSE_JUST_IN_TIME 0x1 /* Parse only when a method is invoked */ -#define METHOD_DELETE_AT_COMPLETION 0x2 /* Delete parse tree on method completion */ - -/* Default parsing configuration */ - -#define METHOD_PARSE_CONFIGURATION (METHOD_PARSE_JUST_IN_TIME | METHOD_DELETE_AT_COMPLETION) - /* Maximum objects in the various object caches */ @@ -87,15 +64,6 @@ #define MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */ #define MAX_WALK_CACHE_DEPTH 2 /* Objects for parse tree walks (method execution) */ -/* - * Name_space Table size - * - * All tables are the same size to simplify the implementation. - * Tables may be extended by allocating additional tables that - * are in turn linked together to form a chain of tables. - */ - -#define NS_TABLE_SIZE 4 /* String size constants */ @@ -164,14 +132,14 @@ /* Names within the namespace are 4 bytes long */ #define ACPI_NAME_SIZE 4 -#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 s8 for separator */ +#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 s8 for separator */ #define PATH_SEPARATOR '.' /* Constants used in searching for the RSDP in low memory */ -#define LO_RSDP_WINDOW_BASE (void *) 0 -#define HI_RSDP_WINDOW_BASE (void *) 0xE0000 +#define LO_RSDP_WINDOW_BASE 0 /* Physical Address */ +#define HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ #define LO_RSDP_WINDOW_SIZE 0x400 #define HI_RSDP_WINDOW_SIZE 0x20000 #define RSDP_SCAN_STEP 16 diff --git a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h index 02efd62e8..2bc9e7165 100644 --- a/drivers/acpi/include/acdebug.h +++ b/drivers/acpi/include/acdebug.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdebug.h - ACPI/AML debugger - * $Revision: 35 $ + * $Revision: 37 $ * *****************************************************************************/ @@ -205,6 +205,7 @@ acpi_db_find_references ( void acpi_db_display_op ( + ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *origin, u32 num_opcodes); @@ -218,8 +219,13 @@ acpi_db_display_path ( void acpi_db_display_opcode ( + ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op); +void +acpi_db_decode_internal_object ( + ACPI_OPERAND_OBJECT *obj_desc); + /* * dbdisply - debug display commands diff --git a/drivers/acpi/include/acdispat.h b/drivers/acpi/include/acdispat.h index d87bb47fd..599e46c36 100644 --- a/drivers/acpi/include/acdispat.h +++ b/drivers/acpi/include/acdispat.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdispat.h - dispatcher (parser to interpreter interface) - * $Revision: 29 $ + * $Revision: 33 $ * *****************************************************************************/ @@ -61,7 +61,11 @@ acpi_ds_obj_stack_pop_object ( ACPI_WALK_STATE *walk_state); -/* dsregion - Op region support */ +/* dsopcode - support for late evaluation */ + +ACPI_STATUS +acpi_ds_get_field_unit_arguments ( + ACPI_OPERAND_OBJECT *obj_desc); ACPI_STATUS acpi_ds_get_region_arguments ( @@ -84,6 +88,13 @@ acpi_ds_exec_end_control_op ( /* dsexec - Parser/Interpreter interface, method execution callbacks */ + +ACPI_STATUS +acpi_ds_get_predicate_value ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op, + u32 has_result_obj); + ACPI_STATUS acpi_ds_exec_begin_op ( u16 opcode, @@ -145,6 +156,18 @@ acpi_ds_load2_end_op ( ACPI_WALK_STATE *state, ACPI_PARSE_OBJECT *op); +ACPI_STATUS +acpi_ds_load3_begin_op ( + u16 opcode, + ACPI_PARSE_OBJECT *op, + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT **out_op); + +ACPI_STATUS +acpi_ds_load3_end_op ( + ACPI_WALK_STATE *state, + ACPI_PARSE_OBJECT *op); + /* dsmthdat - method data (locals/args) */ @@ -284,6 +307,11 @@ acpi_ds_create_node ( /* dsregn - Parser/Interpreter interface - Op Region parsing */ ACPI_STATUS +acpi_ds_eval_field_unit_operands ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op); + +ACPI_STATUS acpi_ds_eval_region_operands ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op); @@ -297,7 +325,8 @@ acpi_ds_initialize_region ( u8 acpi_ds_is_result_used ( - ACPI_PARSE_OBJECT *op); + ACPI_PARSE_OBJECT *op, + ACPI_WALK_STATE *walk_state); void acpi_ds_delete_result_if_not_used ( @@ -308,7 +337,8 @@ acpi_ds_delete_result_if_not_used ( ACPI_STATUS acpi_ds_create_operand ( ACPI_WALK_STATE *walk_state, - ACPI_PARSE_OBJECT *arg); + ACPI_PARSE_OBJECT *arg, + u32 args_remaining); ACPI_STATUS acpi_ds_create_operands ( @@ -377,12 +407,10 @@ acpi_ds_pop_walk_state ( ACPI_STATUS acpi_ds_result_stack_pop ( - ACPI_OPERAND_OBJECT **object, ACPI_WALK_STATE *walk_state); ACPI_STATUS acpi_ds_result_stack_push ( - void *object, ACPI_WALK_STATE *walk_state); ACPI_STATUS @@ -397,5 +425,31 @@ void acpi_ds_delete_walk_state_cache ( void); +ACPI_STATUS +acpi_ds_result_insert ( + void *object, + u32 index, + ACPI_WALK_STATE *walk_state); + +ACPI_STATUS +acpi_ds_result_remove ( + ACPI_OPERAND_OBJECT **object, + u32 index, + ACPI_WALK_STATE *walk_state); + +ACPI_STATUS +acpi_ds_result_pop ( + ACPI_OPERAND_OBJECT **object, + ACPI_WALK_STATE *walk_state); + +ACPI_STATUS +acpi_ds_result_push ( + ACPI_OPERAND_OBJECT *object, + ACPI_WALK_STATE *walk_state); + +ACPI_STATUS +acpi_ds_result_pop_from_bottom ( + ACPI_OPERAND_OBJECT **object, + ACPI_WALK_STATE *walk_state); #endif /* _ACDISPAT_H_ */ diff --git a/drivers/acpi/include/acenv.h b/drivers/acpi/include/acenv.h index 30c347b5f..f867a348f 100644 --- a/drivers/acpi/include/acenv.h +++ b/drivers/acpi/include/acenv.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acenv.h - Generation environment specific items - * $Revision: 53 $ + * $Revision: 65 $ * *****************************************************************************/ @@ -28,6 +28,35 @@ /* + * Configuration for ACPI Utilities + */ + +#ifdef _ACPI_DUMP_APP +#define ACPI_DEBUG +#define ACPI_APPLICATION +#define ENABLE_DEBUGGER +#define ACPI_USE_SYSTEM_CLIBRARY +#define PARSER_ONLY +#endif + +#ifdef _ACPI_EXEC_APP +#undef DEBUGGER_THREADING +#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED +#define ACPI_DEBUG +#define ACPI_APPLICATION +#define ENABLE_DEBUGGER +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + +#ifdef _ACPI_ASL_COMPILER +#define ACPI_DEBUG +#define ACPI_APPLICATION +#define ENABLE_DEBUGGER +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + + +/* * Environment configuration. The purpose of this file is to interface to the * local generation environment. * @@ -64,50 +93,35 @@ * */ - -/* - * Environment-specific configuration - */ +/*! [Begin] no source code translation */ #ifdef _LINUX +#include "aclinux.h" -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/ctype.h> -#include <asm/system.h> -#include <asm/atomic.h> - -/* Use native Linux string library */ - -#define ACPI_USE_SYSTEM_CLIBRARY - -/* Special functions */ - -#define strtoul simple_strtoul +#elif _AED_EFI +#include "acefi.h" -/* Linux clib doesn't to strupr, but we do. */ -char * -strupr(char *str); +#elif WIN32 +#include "acwin.h" -#else - -#ifdef _AED_EFI - -#include <efi.h> -#include <efistdarg.h> -#include <efilib.h> +#elif __FreeBSD__ +#include "acfreebsd.h" #else - /* All other environments */ #define ACPI_USE_STANDARD_HEADERS -#endif +/* Name of host operating system (returned by the _OS_ namespace object) */ + +#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" + #endif +/*! [End] no source code translation !*/ + /****************************************************************************** * * C library configuration @@ -218,132 +232,13 @@ typedef char *va_list; /* * Handle platform- and compiler-specific assembly language differences. + * These should already have been defined by the platform includes above. * * Notes: * 1) Interrupt 3 is used to break into a debugger * 2) Interrupts are turned off during ACPI register setup */ - -#ifdef __GNUC__ - - -#ifdef __ia64__ - -/* Single threaded */ -#define ACPI_APPLICATION - -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() -#define wbinvd() - -/*! [Begin] no source code translation */ -#include <asm/pal.h> - -/* PAL_HALT[_LIGHT] */ -#define halt() ia64_pal_halt_light() - -/* PAL_HALT */ -#define safe_halt() ia64_pal_halt(1) - -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - __asm__ volatile ("1: ld4 r29=%1\n" \ - ";;\n" \ - "mov ar.ccv=r29\n" \ - "mov r2=r29\n" \ - "shr.u r30=r29,1\n" \ - "and r29=-4,r29\n" \ - ";;\n" \ - "add r29=2,r29\n" \ - "and r30=1,r30\n" \ - ";;\n" \ - "add r29=r29,r30\n" \ - ";;\n" \ - "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ - ";;\n" \ - "cmp.eq p6,p7=r2,r30\n" \ - "(p7) br.dpnt.few 1b\n" \ - "cmp.gt p8,p9=3,r29\n" \ - ";;\n" \ - "(p8) mov %0=-1\n" \ - "(p9) mov %0=r0\n" \ - :"=r"(Acq):"m" __atomic_fool_gcc((GLptr)):"r2","r29","r30","memory"); \ - } while (0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - __asm__ volatile ("1: ld4 r29=%1\n" \ - ";;\n" \ - "mov ar.ccv=r29\n" \ - "mov r2=r29\n" \ - "and r29=-4,r29\n" \ - ";;\n" \ - "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ - ";;\n" \ - "cmp.eq p6,p7=r2,r30\n" \ - "(p7) br.dpnt.few 1b\n" \ - "and %0=1,r2\n" \ - ";;\n" \ - :"=r"(Acq):"m" __atomic_fool_gcc((GLptr)):"r2","r29","r30","memory"); \ - } while (0) -/*! [End] no source code translation !*/ - -#else /* DO IA32 */ - -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() -#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") -#define wbinvd() - -/*! [Begin] no source code translation - * - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in EAX ("=a") - * %1 and %2 are the input parameters in ECX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "btsl $0x1,%%edx;" \ - "adcl $0x0,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "cmpb $0x3,%%dl;" \ - "sbbl %%eax,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ - } while(0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ - } while(0) -/*! [End] no source code translation !*/ - -#endif /* IA 32 */ -#endif /* __GNUC__ */ - - /* Unrecognized compiler, use defaults */ #ifndef ACPI_ASM_MACROS @@ -370,4 +265,14 @@ typedef char *va_list; #endif +/****************************************************************************** + * + * Compiler-specific + * + *****************************************************************************/ + +/* this has been moved to compiler-specific headers, which are included from the + platform header. */ + + #endif /* __ACENV_H__ */ diff --git a/drivers/acpi/include/acevents.h b/drivers/acpi/include/acevents.h index 890297825..3e76370bf 100644 --- a/drivers/acpi/include/acevents.h +++ b/drivers/acpi/include/acevents.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acevents.h - Event subcomponent prototypes and defines - * $Revision: 56 $ + * $Revision: 62 $ * *****************************************************************************/ @@ -27,6 +27,11 @@ #define __ACEVENTS_H__ +ACPI_STATUS +acpi_ev_initialize ( + void); + + /* * Acpi_evfixed - Fixed event handling */ @@ -104,7 +109,7 @@ ACPI_STATUS acpi_ev_address_space_dispatch ( ACPI_OPERAND_OBJECT *region_obj, u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value); @@ -118,7 +123,8 @@ acpi_ev_addr_handler_helper ( void acpi_ev_disassociate_region_from_handler( - ACPI_OPERAND_OBJECT *region_obj); + ACPI_OPERAND_OBJECT *region_obj, + u8 acpi_ns_is_locked); ACPI_STATUS diff --git a/drivers/acpi/include/acexcep.h b/drivers/acpi/include/acexcep.h index 1b02ba16a..1629a0934 100644 --- a/drivers/acpi/include/acexcep.h +++ b/drivers/acpi/include/acexcep.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acexcep.h - Exception codes returned by the ACPI subsystem - * $Revision: 35 $ + * $Revision: 37 $ * *****************************************************************************/ @@ -89,6 +89,7 @@ #define AE_BAD_SIGNATURE (ACPI_STATUS) (0x0001 | AE_CODE_ACPI_TABLES) #define AE_BAD_HEADER (ACPI_STATUS) (0x0002 | AE_CODE_ACPI_TABLES) #define AE_BAD_CHECKSUM (ACPI_STATUS) (0x0003 | AE_CODE_ACPI_TABLES) +#define AE_BAD_VALUE (ACPI_STATUS) (0x0004 | AE_CODE_ACPI_TABLES) #define AE_CODE_TBL_MAX 0x0003 @@ -114,8 +115,9 @@ #define AE_AML_BAD_NAME (ACPI_STATUS) (0x000F | AE_CODE_AML) #define AE_AML_NAME_NOT_FOUND (ACPI_STATUS) (0x0010 | AE_CODE_AML) #define AE_AML_INTERNAL (ACPI_STATUS) (0x0011 | AE_CODE_AML) +#define AE_AML_INVALID_SPACE_ID (ACPI_STATUS) (0x0012 | AE_CODE_AML) -#define AE_CODE_AML_MAX 0x0011 +#define AE_CODE_AML_MAX 0x0012 /* * Internal exceptions used for control @@ -177,6 +179,7 @@ static NATIVE_CHAR *acpi_gbl_exception_names_tbl[] = "AE_BAD_SIGNATURE", "AE_BAD_HEADER", "AE_BAD_CHECKSUM", + "AE_BAD_VALUE", }; static NATIVE_CHAR *acpi_gbl_exception_names_aml[] = @@ -198,6 +201,7 @@ static NATIVE_CHAR *acpi_gbl_exception_names_aml[] = "AE_AML_BAD_NAME", "AE_AML_NAME_NOT_FOUND", "AE_AML_INTERNAL", + "AE_AML_INVALID_SPACE_ID", }; static NATIVE_CHAR *acpi_gbl_exception_names_ctrl[] = diff --git a/drivers/acpi/include/acgcc.h b/drivers/acpi/include/acgcc.h new file mode 100644 index 000000000..5992f493d --- /dev/null +++ b/drivers/acpi/include/acgcc.h @@ -0,0 +1,149 @@ +/****************************************************************************** + * + * Name: acgcc.h - GCC specific defines, etc. + * $Revision: 2 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACGCC_H__ +#define __ACGCC_H__ + +#define COMPILER_DEPENDENT_UINT64 unsigned long long + + +#ifdef __ia64__ +#define _IA64 + +/* Single threaded */ +#define ACPI_APPLICATION + +#define ACPI_ASM_MACROS +#define causeinterrupt(level) +#define BREAKPOINT3 +#define disable() __cli() +#define enable() __sti() +#define wbinvd() + +/*! [Begin] no source code translation */ + +#include <asm/pal.h> + +#define halt() ia64_pal_halt_light() /* PAL_HALT[_LIGHT] */ +#define safe_halt() ia64_pal_halt(1) /* PAL_HALT */ + + +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + __asm__ volatile ("1: ld4 r29=%1\n" \ + ";;\n" \ + "mov ar.ccv=r29\n" \ + "mov r2=r29\n" \ + "shr.u r30=r29,1\n" \ + "and r29=-4,r29\n" \ + ";;\n" \ + "add r29=2,r29\n" \ + "and r30=1,r30\n" \ + ";;\n" \ + "add r29=r29,r30\n" \ + ";;\n" \ + "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ + ";;\n" \ + "cmp.eq p6,p7=r2,r30\n" \ + "(p7) br.dpnt.few 1b\n" \ + "cmp.gt p8,p9=3,r29\n" \ + ";;\n" \ + "(p8) mov %0=-1\n" \ + "(p9) mov %0=r0\n" \ + :"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \ + } while (0) + +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + __asm__ volatile ("1: ld4 r29=%1\n" \ + ";;\n" \ + "mov ar.ccv=r29\n" \ + "mov r2=r29\n" \ + "and r29=-4,r29\n" \ + ";;\n" \ + "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ + ";;\n" \ + "cmp.eq p6,p7=r2,r30\n" \ + "(p7) br.dpnt.few 1b\n" \ + "and %0=1,r2\n" \ + ";;\n" \ + :"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \ + } while (0) +/*! [End] no source code translation !*/ + + +#else /* DO IA32 */ + + +#define ACPI_ASM_MACROS +#define causeinterrupt(level) +#define BREAKPOINT3 +#define disable() __cli() +#define enable() __sti() +#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") +#define wbinvd() + +/*! [Begin] no source code translation + * + * A brief explanation as GNU inline assembly is a bit hairy + * %0 is the output parameter in EAX ("=a") + * %1 and %2 are the input parameters in ECX ("c") + * and an immediate value ("i") respectively + * All actual register references are preceded with "%%" as in "%%edx" + * Immediate values in the assembly are preceded by "$" as in "$0x1" + * The final asm parameter are the operation altered non-output registers. + */ +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + int dummy; \ + asm("1: movl (%1),%%eax;" \ + "movl %%eax,%%edx;" \ + "andl %2,%%edx;" \ + "btsl $0x1,%%edx;" \ + "adcl $0x0,%%edx;" \ + "lock; cmpxchgl %%edx,(%1);" \ + "jnz 1b;" \ + "cmpb $0x3,%%dl;" \ + "sbbl %%eax,%%eax" \ + :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ + } while(0) + +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + int dummy; \ + asm("1: movl (%1),%%eax;" \ + "movl %%eax,%%edx;" \ + "andl %2,%%edx;" \ + "lock; cmpxchgl %%edx,(%1);" \ + "jnz 1b;" \ + "andl $0x1,%%eax" \ + :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ + } while(0) + +/*! [End] no source code translation !*/ + +#endif /* IA 32 */ + +#endif /* __ACGCC_H__ */ diff --git a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h index 15e617e32..248f72c9d 100644 --- a/drivers/acpi/include/acglobal.h +++ b/drivers/acpi/include/acglobal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acglobal.h - Declarations for global variables - * $Revision: 84 $ + * $Revision: 92 $ * *****************************************************************************/ @@ -74,13 +74,12 @@ extern u32 acpi_gbl_nesting_level; * of each in the system. Each global points to the actual table. * */ -ACPI_EXTERN ROOT_SYSTEM_DESCRIPTOR_POINTER *acpi_gbl_RSDP; -ACPI_EXTERN ROOT_SYSTEM_DESCRIPTION_TABLE *acpi_gbl_RSDT; -ACPI_EXTERN FIRMWARE_ACPI_CONTROL_STRUCTURE *acpi_gbl_FACS; -ACPI_EXTERN FIXED_ACPI_DESCRIPTION_TABLE *acpi_gbl_FACP; -ACPI_EXTERN APIC_TABLE *acpi_gbl_APIC; -ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_DSDT; -ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_SBST; +ACPI_EXTERN RSDP_DESCRIPTOR *acpi_gbl_RSDP; +ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT; +ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; +ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_DSDT; +ACPI_EXTERN ACPI_COMMON_FACS *acpi_gbl_FACS; + /* * Since there may be multiple SSDTs and PSDTS, a single pointer is not * sufficient; Therefore, there isn't one! @@ -99,7 +98,6 @@ extern ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES * (The table maps local handles to the real OS handles) */ ACPI_EXTERN ACPI_MUTEX_INFO acpi_gbl_acpi_mutex_info [NUM_MTX]; -extern ACPI_INIT_DATA acpi_gbl_acpi_init_data; /***************************************************************************** @@ -164,6 +162,7 @@ ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_sys_notify; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_system_flags; extern u32 acpi_gbl_startup_flags; +extern u8 acpi_gbl_decode_to8bit[]; /***************************************************************************** @@ -198,23 +197,8 @@ ACPI_EXTERN ALLOCATION_INFO *acpi_gbl_tail_alloc_ptr; ****************************************************************************/ -ACPI_EXTERN u32 acpi_gbl_when_to_parse_methods; ACPI_EXTERN ACPI_WALK_LIST *acpi_gbl_current_walk_list; -/* Base of AML block, and pointer to current location in it */ - -ACPI_EXTERN u8 *acpi_gbl_Pcode_base; -ACPI_EXTERN u8 *acpi_gbl_Pcode; - -/* - * Length of AML block, and remaining length of current package. - */ -ACPI_EXTERN u32 acpi_gbl_Pcode_block_len; -ACPI_EXTERN u32 acpi_gbl_Pcode_len; - -ACPI_EXTERN u32 acpi_gbl_buf_seq; /* Counts allocated Buffer descriptors */ -ACPI_EXTERN u32 acpi_gbl_node_err; /* Indicate if inc_error should be called */ - /* * Handle to the last method found - used during pass1 of load */ @@ -240,10 +224,6 @@ ACPI_EXTERN u8 acpi_gbl_cm_single_step; ACPI_EXTERN ACPI_PARSE_OBJECT *acpi_gbl_parsed_namespace_root; -extern ACPI_OPCODE_INFO acpi_gbl_aml_op_info[]; -extern u8 acpi_gbl_aml_op_info_index[256]; - - /***************************************************************************** * * Hardware globals @@ -290,9 +270,10 @@ ACPI_EXTERN u32 acpi_gbl_event_count[NUM_FIXED_EVENTS]; * ****************************************************************************/ +#ifdef ENABLE_DEBUGGER ACPI_EXTERN u8 acpi_gbl_method_executing; ACPI_EXTERN u8 acpi_gbl_db_terminate_threads; - +#endif /* Memory allocation metrics - Debug Only! */ diff --git a/drivers/acpi/include/achware.h b/drivers/acpi/include/achware.h index e537d6549..1a206e8d2 100644 --- a/drivers/acpi/include/achware.h +++ b/drivers/acpi/include/achware.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: achware.h -- hardware specific interfaces - * $Revision: 41 $ + * $Revision: 48 $ * *****************************************************************************/ @@ -31,15 +31,15 @@ ACPI_STATUS -acpi_hw_initialize( +acpi_hw_initialize ( void); ACPI_STATUS -acpi_hw_shutdown( +acpi_hw_shutdown ( void); ACPI_STATUS -acpi_hw_initialize_system_info( +acpi_hw_initialize_system_info ( void); ACPI_STATUS @@ -56,11 +56,37 @@ acpi_hw_get_mode_capabilities ( /* Register I/O Prototypes */ + u32 -acpi_hw_register_access ( +acpi_hw_register_bit_access ( NATIVE_UINT read_write, u8 use_lock, - u32 register_id, ... /* DWORD Value */); + u32 register_id, + ... /* DWORD Write Value */); + +u32 +acpi_hw_register_read ( + u8 use_lock, + u32 register_id); + +void +acpi_hw_register_write ( + u8 use_lock, + u32 register_id, + u32 value); + +u32 +acpi_hw_low_level_read ( + u32 width, + ACPI_GAS *reg, + u32 offset); + +void +acpi_hw_low_level_write ( + u32 width, + u32 value, + ACPI_GAS *reg, + u32 offset); void acpi_hw_clear_acpi_status ( @@ -125,6 +151,16 @@ ACPI_STATUS acpi_hw_get_cx_info ( u32 cx_states[]); +ACPI_STATUS +acpi_hw_get_cx_handler ( + u32 cx_state, + ACPI_C_STATE_HANDLER *handler); + +ACPI_STATUS +acpi_hw_set_cx_handler ( + u32 cx_state, + ACPI_C_STATE_HANDLER handler); + /* Throttling Prototypes */ @@ -165,5 +201,9 @@ u32 acpi_hw_pmt_resolution ( void); +ACPI_STATUS +acpi_get_timer ( + u32 *out_ticks); + #endif /* __ACHWARE_H__ */ diff --git a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h index 70bfc5682..c8c967492 100644 --- a/drivers/acpi/include/acinterp.h +++ b/drivers/acpi/include/acinterp.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * $Revision: 79 $ + * $Revision: 86 $ * *****************************************************************************/ @@ -120,7 +120,9 @@ acpi_aml_access_named_field ( ACPI_STATUS acpi_aml_exec_create_field ( - u16 opcode, + u8 *aml_ptr, + u32 aml_length, + ACPI_NAMESPACE_NODE *node, ACPI_WALK_STATE *walk_state); ACPI_STATUS @@ -160,7 +162,7 @@ ACPI_STATUS acpi_aml_exec_create_region ( u8 *aml_ptr, u32 acpi_aml_length, - u32 region_space, + u8 region_space, ACPI_WALK_STATE *walk_state); ACPI_STATUS @@ -324,7 +326,8 @@ acpi_aml_resolve_to_value ( ACPI_STATUS acpi_aml_resolve_node_to_value ( - ACPI_NAMESPACE_NODE **stack_ptr); + ACPI_NAMESPACE_NODE **stack_ptr, + ACPI_WALK_STATE *walk_state); ACPI_STATUS acpi_aml_resolve_object_to_value ( @@ -440,6 +443,11 @@ void acpi_aml_exit_interpreter ( void); +void +acpi_aml_truncate_for32bit_table ( + ACPI_OPERAND_OBJECT *obj_desc, + ACPI_WALK_STATE *walk_state); + u8 acpi_aml_validate_object_type ( ACPI_OBJECT_TYPE type); @@ -453,12 +461,8 @@ acpi_aml_release_global_lock ( u8 locked); u32 -acpi_aml_buf_seq ( - void); - -u32 acpi_aml_digits_needed ( - u32 value, + ACPI_INTEGER value, u32 base); ACPI_STATUS @@ -467,6 +471,11 @@ acpi_aml_eisa_id_to_string ( NATIVE_CHAR *out_string); ACPI_STATUS +acpi_aml_unsigned_integer_to_string ( + ACPI_INTEGER value, + NATIVE_CHAR *out_string); + +ACPI_STATUS acpi_aml_build_copy_internal_package_object ( ACPI_OPERAND_OBJECT *source_obj, ACPI_OPERAND_OBJECT *dest_obj, @@ -480,7 +489,7 @@ acpi_aml_build_copy_internal_package_object ( ACPI_STATUS acpi_aml_system_memory_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -489,7 +498,7 @@ acpi_aml_system_memory_space_handler ( ACPI_STATUS acpi_aml_system_io_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -498,7 +507,7 @@ acpi_aml_system_io_space_handler ( ACPI_STATUS acpi_aml_pci_config_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -507,7 +516,7 @@ acpi_aml_pci_config_space_handler ( ACPI_STATUS acpi_aml_embedded_controller_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -516,7 +525,7 @@ acpi_aml_embedded_controller_space_handler ( ACPI_STATUS acpi_aml_sm_bus_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, diff --git a/drivers/acpi/interpreter/amdump.c b/drivers/acpi/include/aclinux.h index 1499beaa2..673d5f96b 100644 --- a/drivers/acpi/interpreter/amdump.c +++ b/drivers/acpi/include/aclinux.h @@ -1,7 +1,7 @@ /****************************************************************************** * - * Module Name: amdump - Interpreter debug output routines - * $Revision: 90 $ + * Name: aclinux.h - OS specific defines, etc. + * $Revision: 6 $ * *****************************************************************************/ @@ -23,19 +23,28 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __ACLINUX_H__ +#define __ACLINUX_H__ -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "actables.h" -#define _COMPONENT INTERPRETER - MODULE_NAME ("amdump") +#define ACPI_OS_NAME "Linux" +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/ctype.h> +#include <asm/system.h> +#include <asm/atomic.h> -/* - * The following routines are used for debug output only - */ +/* Linux uses GCC */ + +#include "acgcc.h" + +#undef DEBUGGER_THREADING +#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED +/* Linux ia32 can't do int64 well */ +#ifndef _IA64 +#define ACPI_NO_INTEGER64_SUPPORT +#endif +#endif /* __ACLINUX_H__ */ diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h index c2f052f60..a647026f1 100644 --- a/drivers/acpi/include/aclocal.h +++ b/drivers/acpi/include/aclocal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 77 $ + * $Revision: 95 $ * *****************************************************************************/ @@ -125,7 +125,7 @@ typedef u16 ACPI_OWNER_ID; /* TBD: [Restructure] get rid of the need for this! */ -#define TABLE_ID_DSDT (ACPI_OWNER_ID) 0xD1D1 +#define TABLE_ID_DSDT (ACPI_OWNER_ID) 0x8000 /***************************************************************************** * @@ -157,8 +157,8 @@ typedef struct acpi_node { u8 data_type; u8 type; /* Type associated with this name */ - u32 name; /* ACPI Name, always 4 chars per ACPI spec */ u16 owner_id; + u32 name; /* ACPI Name, always 4 chars per ACPI spec */ void *object; /* Pointer to attached ACPI object (optional) */ @@ -175,8 +175,13 @@ typedef struct acpi_node /* Node flags */ -#define ANOBJ_AML_ATTACHMENT 0x1 -#define ANOBJ_END_OF_PEER_LIST 0x2 +#define ANOBJ_AML_ATTACHMENT 0x01 +#define ANOBJ_END_OF_PEER_LIST 0x02 +#define ANOBJ_DATA_WIDTH_32 0x04 /* Parent table is 64-bits */ +#define ANOBJ_METHOD_ARG 0x08 +#define ANOBJ_METHOD_LOCAL 0x10 +#define ANOBJ_METHOD_NO_RETVAL 0x20 +#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40 /* @@ -190,6 +195,7 @@ typedef struct acpi_table_desc ACPI_TABLE_HEADER *pointer; void *base_pointer; u8 *aml_pointer; + UINT64 physical_address; u32 aml_length; u32 length; u32 count; @@ -399,6 +405,22 @@ typedef struct acpi_pscope_state } ACPI_PSCOPE_STATE; +/* + * Result values - used to accumulate the results of nested + * AML arguments + */ +typedef struct acpi_result_values +{ + ACPI_STATE_COMMON + union acpi_operand_obj *obj_desc [OBJ_NUM_OPERANDS]; + u8 num_results; + u8 last_insert; + +} ACPI_RESULT_VALUES; + + +/* Generic state is union of structs above */ + typedef union acpi_gen_state { ACPI_COMMON_STATE common; @@ -406,6 +428,7 @@ typedef union acpi_gen_state ACPI_UPDATE_STATE update; ACPI_SCOPE_STATE scope; ACPI_PSCOPE_STATE parse_scope; + ACPI_RESULT_VALUES results; } ACPI_GENERIC_STATE; @@ -453,8 +476,7 @@ typedef struct acpi_opcode_info u32 parse_args; /* Grammar/Parse time arguments */ u32 runtime_args; /* Interpret time arguments */ - DEBUG_ONLY_MEMBERS ( - NATIVE_CHAR *name) /* op name (debug only) */ + DEBUG_ONLY_MEMBERS (NATIVE_CHAR *name) /* op name (debug only) */ } ACPI_OPCODE_INFO; @@ -481,7 +503,7 @@ typedef union acpi_parse_val DEBUG_ONLY_MEMBERS (\ NATIVE_CHAR op_name[16]) /* op name (debug only) */\ /* NON-DEBUG members below: */\ - ACPI_NAMESPACE_NODE *node;/* for use by interpreter */\ + ACPI_NAMESPACE_NODE *node; /* for use by interpreter */\ ACPI_PARSE_VALUE value; /* Value or args associated with the opcode */\ @@ -543,8 +565,9 @@ typedef struct acpi_parse_state #define NEXT_OP_DOWNWARD 1 #define NEXT_OP_UPWARD 2 -#define WALK_METHOD 1 #define WALK_NON_METHOD 0 +#define WALK_METHOD 1 +#define WALK_METHOD_RESTART 2 typedef struct acpi_walk_state { @@ -553,17 +576,17 @@ typedef struct acpi_walk_state u8 last_predicate; /* Result of last predicate */ u8 next_op_info; /* Info about Next_op */ u8 num_operands; /* Stack pointer for Operands[] array */ - u8 num_results; /* Stack pointer for Results[] array */ u8 current_result; /* */ struct acpi_walk_state *next; /* Next Walk_state in list */ - ACPI_PARSE_OBJECT *origin; /* Start of walk */ + ACPI_PARSE_OBJECT *origin; /* Start of walk [Obsolete] */ /* TBD: Obsolete with removal of WALK procedure ? */ ACPI_PARSE_OBJECT *prev_op; /* Last op that was processed */ ACPI_PARSE_OBJECT *next_op; /* next op to be processed */ + ACPI_GENERIC_STATE *results; /* Stack of accumulated results */ ACPI_GENERIC_STATE *control_state; /* List of control states (nested IFs) */ ACPI_GENERIC_STATE *scope_info; /* Stack of nested scopes */ ACPI_PARSE_STATE *parser_state; /* Current state of parser */ @@ -577,7 +600,6 @@ typedef struct acpi_walk_state ACPI_PARSE_OBJECT *method_call_op; /* Method_call Op if running a method */ struct acpi_node *method_call_node; /* Called method Node*/ union acpi_operand_obj *operands[OBJ_NUM_OPERANDS]; /* Operands passed to the interpreter */ - union acpi_operand_obj *results[OBJ_NUM_OPERANDS]; /* Accumulated results */ struct acpi_node arguments[MTH_NUM_ARGS]; /* Control method arguments */ struct acpi_node local_variables[MTH_NUM_LOCALS]; /* Control method locals */ u32 parse_flags; @@ -607,13 +629,30 @@ typedef struct acpi_walk_list /* Info used by Acpi_ps_init_objects */ -typedef struct init_walk_info +typedef struct acpi_init_walk_info { - u32 method_count; - u32 op_region_count; + u16 method_count; + u16 op_region_count; + u16 field_count; + u16 op_region_init; + u16 field_init; + u16 object_count; ACPI_TABLE_DESC *table_desc; -} INIT_WALK_INFO; +} ACPI_INIT_WALK_INFO; + + +/* Info used by TBD */ + +typedef struct acpi_device_walk_info +{ + u32 flags; + u16 device_count; + u16 num_STA; + u16 num_INI; + ACPI_TABLE_DESC *table_desc; + +} ACPI_DEVICE_WALK_INFO; /* TBD: [Restructure] Merge with struct above */ @@ -625,6 +664,14 @@ typedef struct acpi_walk_info } ACPI_WALK_INFO; +typedef struct acpi_get_devices_info +{ + WALK_CALLBACK user_function; + void *context; + NATIVE_CHAR *hid; + +} ACPI_GET_DEVICES_INFO; + /***************************************************************************** * @@ -633,16 +680,23 @@ typedef struct acpi_walk_info ****************************************************************************/ +/* PCI */ + +#define PCI_ROOT_HID_STRING "PNP0A03" +#define PCI_ROOT_HID_VALUE 0x030AD041 /* EISAID("PNP0A03") */ + + /* Sleep states */ -#define SLWA_DEBUG_LEVEL 4 -#define GTS_CALL 0 -#define GTS_WAKE 1 +#define SLWA_DEBUG_LEVEL 4 +#define GTS_CALL 0 +#define GTS_WAKE 1 /* Cx States */ -#define MAX_CX_STATE_LATENCY 0xFFFFFFFF -#define MAX_CX_STATES 4 +#define MAX_CX_STATE_LATENCY 0xFFFFFFFF +#define MAX_CX_STATES 4 + /* * The #define's and enum below establish an abstract way of identifying what @@ -650,66 +704,85 @@ typedef struct acpi_walk_info * values as they are used in switch statements and offset calculations. */ -#define REGISTER_BLOCK_MASK 0xFF00 -#define BIT_IN_REGISTER_MASK 0x00FF -#define PM1_EVT 0x0100 -#define PM1_CONTROL 0x0200 -#define PM2_CONTROL 0x0300 -#define PM_TIMER 0x0400 -#define PROCESSOR_BLOCK 0x0500 -#define GPE0_STS_BLOCK 0x0600 -#define GPE0_EN_BLOCK 0x0700 -#define GPE1_STS_BLOCK 0x0800 -#define GPE1_EN_BLOCK 0x0900 +#define REGISTER_BLOCK_MASK 0xFF00 /* Register Block Id */ +#define BIT_IN_REGISTER_MASK 0x00FF /* Bit Id in the Register Block Id */ +#define BYTE_IN_REGISTER_MASK 0x00FF /* Register Offset in the Register Block */ -enum -{ - /* PM1 status register ids */ - - TMR_STS = (PM1_EVT | 0x01), - BM_STS, - GBL_STS, - PWRBTN_STS, - SLPBTN_STS, - RTC_STS, - WAK_STS, +#define REGISTER_BLOCK_ID(reg_id) (reg_id & REGISTER_BLOCK_MASK) +#define REGISTER_BIT_ID(reg_id) (reg_id & BIT_IN_REGISTER_MASK) +#define REGISTER_OFFSET(reg_id) (reg_id & BYTE_IN_REGISTER_MASK) - /* PM1 enable register ids */ +/* + * Access Rule + * To access a Register Bit: + * -> Use Bit Name (= Register Block Id | Bit Id) defined in the enum. + * + * To access a Register: + * -> Use Register Id (= Register Block Id | Register Offset) + */ - TMR_EN, - /* need to skip 1 enable number since there's no bus master enable register */ - GBL_EN = (PM1_EVT | 0x0A), - PWRBTN_EN, - SLPBTN_EN, - RTC_EN, - /* PM1 control register ids */ +/* + * Register Block Id + */ +#define PM1_STS 0x0100 +#define PM1_EN 0x0200 +#define PM1_CONTROL 0x0300 +#define PM2_CONTROL 0x0400 +#define PM_TIMER 0x0500 +#define PROCESSOR_BLOCK 0x0600 +#define GPE0_STS_BLOCK 0x0700 +#define GPE0_EN_BLOCK 0x0800 +#define GPE1_STS_BLOCK 0x0900 +#define GPE1_EN_BLOCK 0x0A00 +#define SMI_CMD_BLOCK 0x0B00 - SCI_EN = (PM1_CONTROL | 0x01), - BM_RLD, - GBL_RLS, - SLP_TYPE_A, - SLP_TYPE_B, - SLP_EN, +/* + * Address space bitmasks for mmio or io spaces + */ - /* PM2 control register ids */ +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 - ARB_DIS = (PM2_CONTROL | 0x01), +/* + * Control bit definitions + */ +#define TMR_STS (PM1_STS | 0x01) +#define BM_STS (PM1_STS | 0x02) +#define GBL_STS (PM1_STS | 0x03) +#define PWRBTN_STS (PM1_STS | 0x04) +#define SLPBTN_STS (PM1_STS | 0x05) +#define RTC_STS (PM1_STS | 0x06) +#define WAK_STS (PM1_STS | 0x07) - /* PM Timer register ids */ +#define TMR_EN (PM1_EN | 0x01) + /* no BM_EN */ +#define GBL_EN (PM1_EN | 0x03) +#define PWRBTN_EN (PM1_EN | 0x04) +#define SLPBTN_EN (PM1_EN | 0x05) +#define RTC_EN (PM1_EN | 0x06) +#define WAK_EN (PM1_EN | 0x07) - TMR_VAL = (PM_TIMER | 0x01), +#define SCI_EN (PM1_CONTROL | 0x01) +#define BM_RLD (PM1_CONTROL | 0x02) +#define GBL_RLS (PM1_CONTROL | 0x03) +#define SLP_TYPE_A (PM1_CONTROL | 0x04) +#define SLP_TYPE_B (PM1_CONTROL | 0x05) +#define SLP_EN (PM1_CONTROL | 0x06) - GPE0_STS = (GPE0_STS_BLOCK | 0x01), - GPE0_EN = (GPE0_EN_BLOCK | 0x01), +#define ARB_DIS (PM2_CONTROL | 0x01) - GPE1_STS = (GPE1_STS_BLOCK | 0x01), - GPE1_EN = (GPE0_EN_BLOCK | 0x01), +#define TMR_VAL (PM_TIMER | 0x01) - /* Last register value is one less than LAST_REG */ +#define GPE0_STS (GPE0_STS_BLOCK | 0x01) +#define GPE0_EN (GPE0_EN_BLOCK | 0x01) - LAST_REG -}; +#define GPE1_STS (GPE1_STS_BLOCK | 0x01) +#define GPE1_EN (GPE1_EN_BLOCK | 0x01) #define TMR_STS_MASK 0x0001 @@ -720,8 +793,9 @@ enum #define RTC_STS_MASK 0x0400 #define WAK_STS_MASK 0x8000 -#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK | PWRBTN_STS_MASK | \ - SLPBTN_STS_MASK | RTC_STS_MASK | WAK_STS_MASK) +#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK \ + | PWRBTN_STS_MASK | SLPBTN_STS_MASK \ + | RTC_STS_MASK | WAK_STS_MASK) #define TMR_EN_MASK 0x0001 #define GBL_EN_MASK 0x0020 @@ -736,6 +810,7 @@ enum #define SLP_EN_MASK 0x2000 #define ARB_DIS_MASK 0x0001 +#define TMR_VAL_MASK 0xFFFFFFFF #define GPE0_STS_MASK #define GPE0_EN_MASK @@ -747,16 +822,6 @@ enum #define ACPI_READ 1 #define ACPI_WRITE 2 -#define LOW_BYTE 0x00FF -#define ONE_BYTE 0x08 - -#ifndef SET - #define SET 1 -#endif -#ifndef CLEAR - #define CLEAR 0 -#endif - /* Plug and play */ @@ -796,24 +861,11 @@ enum /* MUST HAVES */ - -typedef enum -{ - DWORD_DEVICE_ID, - STRING_PTR_DEVICE_ID, - STRING_DEVICE_ID - -} DEVICE_ID_TYPE; +#define DEVICE_ID_LENGTH 0x09 typedef struct { - DEVICE_ID_TYPE type; - union - { - u32 number; - NATIVE_CHAR *string_ptr; - NATIVE_CHAR buffer[9]; - } data; + NATIVE_CHAR buffer[DEVICE_ID_LENGTH]; } DEVICE_ID; diff --git a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h index a1e58d1d3..19cfa0591 100644 --- a/drivers/acpi/include/acmacros.h +++ b/drivers/acpi/include/acmacros.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 48 $ + * $Revision: 59 $ * *****************************************************************************/ @@ -63,6 +63,15 @@ #define HI_LIMIT(b) ((u8) (((b) & 0x00FF0000) >> 16)) +#ifdef _IA16 +#define ACPI_GET_ADDRESS(a) ((a).lo) +#define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(b);} +#define ACPI_VALID_ADDRESS(a) ((a).hi && (a).lo) +#else +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) +#define ACPI_VALID_ADDRESS(a) (a) +#endif /* * Extract a byte of data using a pointer. Any more than a byte and we * get into potential aligment issues -- see the STORE macros below @@ -128,6 +137,11 @@ #define MUL_16(a) _MUL(a,4) #define MOD_16(a) _MOD(a,16) +/* + * Divide and Modulo + */ +#define ACPI_DIVIDE(n,d) ((n) / (d)) +#define ACPI_MODULO(n,d) ((n) % (d)) /* * Rounding macros (Power of two boundaries only) @@ -137,17 +151,42 @@ #define ROUND_UP(value,boundary) (((value) + ((boundary)-1)) & (~((boundary)-1))) #define ROUND_DOWN_TO_32_BITS(a) ROUND_DOWN(a,4) +#define ROUND_DOWN_TO_64_BITS(a) ROUND_DOWN(a,8) #define ROUND_DOWN_TO_NATIVE_WORD(a) ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY) #define ROUND_UP_TO_32_bITS(a) ROUND_UP(a,4) +#define ROUND_UP_TO_64_bITS(a) ROUND_UP(a,8) #define ROUND_UP_TO_NATIVE_WORD(a) ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY) +#define ROUND_PTR_UP_TO_4(a,b) ((b *)(((NATIVE_UINT)(a) + 3) & ~3)) +#define ROUND_PTR_UP_TO_8(a,b) ((b *)(((NATIVE_UINT)(a) + 7) & ~7)) + +#define ROUND_UP_TO_1_k(a) (((a) + 1023) >> 10) #ifdef DEBUG_ASSERT #undef DEBUG_ASSERT #endif +/* Macros for GAS addressing */ + +#define ACPI_PCI_DEVICE_MASK (UINT64) 0x0000FFFF00000000 +#define ACPI_PCI_FUNCTION_MASK (UINT64) 0x00000000FFFF0000 +#define ACPI_PCI_REGISTER_MASK (UINT64) 0x000000000000FFFF + +#define ACPI_PCI_FUNCTION(a) (u32) ((((a) & ACPI_PCI_FUNCTION_MASK) >> 16)) +#define ACPI_PCI_DEVICE(a) (u32) ((((a) & ACPI_PCI_DEVICE_MASK) >> 32)) + +#ifndef _IA16 +#define ACPI_PCI_REGISTER(a) (u32) (((a) & ACPI_PCI_REGISTER_MASK)) +#define ACPI_PCI_DEVFUN(a) (u32) ((ACPI_PCI_DEVICE(a) << 16) | ACPI_PCI_FUNCTION(a)) + +#else +#define ACPI_PCI_REGISTER(a) (u32) (((a) & 0x0000FFFF)) +#define ACPI_PCI_DEVFUN(a) (u32) ((((a) & 0xFFFF0000) >> 16)) + +#endif + /* * An ACPI_HANDLE (which is actually an ACPI_NAMESPACE_NODE *) can appear in some contexts, * such as on ap_obj_stack, where a pointer to an ACPI_OPERAND_OBJECT can also @@ -216,14 +255,16 @@ #define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) #define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f)) -#define GET_CURRENT_ARG_TYPE(list) (list & 0x1F) -#define INCREMENT_ARG_LIST(list) (list >>= ARG_TYPE_WIDTH) +#define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) +#define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) /* * Reporting macros that are never compiled out */ +#define PARAM_LIST(pl) pl + /* * Error reporting. These versions add callers module and line#. Since * _THIS_MODULE gets compiled out when ACPI_DEBUG isn't defined, only @@ -232,23 +273,32 @@ #ifdef ACPI_DEBUG -#define REPORT_INFO(a) _report_info(_THIS_MODULE,__LINE__,_COMPONENT,a) -#define REPORT_ERROR(a) _report_error(_THIS_MODULE,__LINE__,_COMPONENT,a) -#define REPORT_WARNING(a) _report_warning(_THIS_MODULE,__LINE__,_COMPONENT,a) +#define REPORT_INFO(fp) {_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_ERROR(fp) {_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_WARNING(fp) {_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} #else -#define REPORT_INFO(a) _report_info("",__LINE__,_COMPONENT,a) -#define REPORT_ERROR(a) _report_error("",__LINE__,_COMPONENT,a) -#define REPORT_WARNING(a) _report_warning("",__LINE__,_COMPONENT,a) +#define REPORT_INFO(fp) {_report_info("ACPI",__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_ERROR(fp) {_report_error("ACPI",__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_WARNING(fp) {_report_warning("ACPI",__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} #endif /* Error reporting. These versions pass thru the module and line# */ -#define _REPORT_INFO(a,b,c,d) _report_info(a,b,c,d) -#define _REPORT_ERROR(a,b,c,d) _report_error(a,b,c,d) -#define _REPORT_WARNING(a,b,c,d) _report_warning(a,b,c,d) +#define _REPORT_INFO(a,b,c,fp) {_report_info(a,b,c); \ + debug_print_raw PARAM_LIST(fp);} +#define _REPORT_ERROR(a,b,c,fp) {_report_error(a,b,c); \ + debug_print_raw PARAM_LIST(fp);} +#define _REPORT_WARNING(a,b,c,fp) {_report_warning(a,b,c); \ + debug_print_raw PARAM_LIST(fp);} /* Buffer dump macros */ @@ -269,7 +319,7 @@ */ #define FUNCTION_TRACE(a) char * _proc_name = a;\ - function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a) + function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a) #define FUNCTION_TRACE_PTR(a,b) char * _proc_name = a;\ function_trace_ptr(_THIS_MODULE,__LINE__,_COMPONENT,a,(void *)b) #define FUNCTION_TRACE_U32(a,b) char * _proc_name = a;\ @@ -291,7 +341,7 @@ /* Conditional execution */ -#define DEBUG_EXEC(a) a; +#define DEBUG_EXEC(a) a #define NORMAL_EXEC(a) #define DEBUG_DEFINE(a) a; @@ -329,8 +379,6 @@ * */ -#define PARAM_LIST(pl) pl - #define TEST_DEBUG_SWITCH(lvl) if (((lvl) & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer)) #define DEBUG_PRINT(lvl,fp) TEST_DEBUG_SWITCH(lvl) {\ @@ -398,7 +446,7 @@ * DEBUG_PRINT stuff (set by ACPI_DEBUG) is on, or not. */ #ifdef ENABLE_DEBUGGER -#define DEBUGGER_EXEC(a) a; +#define DEBUGGER_EXEC(a) a #else #define DEBUGGER_EXEC(a) #endif @@ -412,7 +460,7 @@ #undef DEBUG_ONLY_MEMBERS #define DEBUG_ONLY_MEMBERS(a) #undef OP_INFO_ENTRY -#define OP_INFO_ENTRY(opcode,flags,name,Pargs,Iargs) {opcode,flags,Pargs,Iargs} +#define OP_INFO_ENTRY(flags,name,Pargs,Iargs) {flags,Pargs,Iargs} #endif @@ -432,4 +480,5 @@ #endif + #endif /* ACMACROS_H */ diff --git a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h index 696a554ce..e010a8118 100644 --- a/drivers/acpi/include/acnamesp.h +++ b/drivers/acpi/include/acnamesp.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 94 $ + * $Revision: 100 $ * *****************************************************************************/ @@ -56,12 +56,43 @@ #define NS_SEARCH_PARENT 0x01 #define NS_DONT_OPEN_SCOPE 0x02 #define NS_NO_PEER_SEARCH 0x04 +#define NS_ERROR_IF_FOUND 0x08 #define NS_WALK_UNLOCK TRUE #define NS_WALK_NO_UNLOCK FALSE ACPI_STATUS +acpi_ns_load_namespace ( + void); + +ACPI_STATUS +acpi_ns_initialize_objects ( + void); + +ACPI_STATUS +acpi_ns_initialize_devices ( + u32 flags); + + +/* Namespace init - nsxfinit */ + +ACPI_STATUS +acpi_ns_init_one_device ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +ACPI_STATUS +acpi_ns_init_one_object ( + ACPI_HANDLE obj_handle, + u32 level, + void *context, + void **return_value); + + +ACPI_STATUS acpi_ns_walk_namespace ( OBJECT_TYPE_INTERNAL type, ACPI_HANDLE start_object, @@ -87,6 +118,11 @@ acpi_ns_delete_namespace_by_owner ( /* Namespace loading - nsload */ ACPI_STATUS +acpi_ns_one_complete_parse ( + u32 pass_number, + ACPI_TABLE_DESC *table_desc); + +ACPI_STATUS acpi_ns_parse_table ( ACPI_TABLE_DESC *table_desc, ACPI_NAMESPACE_NODE *scope); @@ -320,10 +356,6 @@ acpi_ns_search_node ( OBJECT_TYPE_INTERNAL type, ACPI_NAMESPACE_NODE **ret_node); -ACPI_NAMESPACE_NODE * -acpi_ns_create_node ( - u32 acpi_name); - void acpi_ns_install_node ( ACPI_WALK_STATE *walk_state, diff --git a/drivers/acpi/include/acobject.h b/drivers/acpi/include/acobject.h index aeb8f201a..c801ff117 100644 --- a/drivers/acpi/include/acobject.h +++ b/drivers/acpi/include/acobject.h @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only) - * $Revision: 71 $ + * $Revision: 75 $ * *****************************************************************************/ @@ -58,7 +58,7 @@ */ -#define ACPI_OBJECT_COMMON_HEADER /* Two 32-bit fields, one pointer, 8-bit flag */\ +#define ACPI_OBJECT_COMMON_HEADER /* 32-bits plus 8-bit flag */\ u8 data_type; /* To differentiate various internal objs */\ u8 type; /* ACPI_OBJECT_TYPE */\ u16 reference_count; /* For object deletion management */\ @@ -74,7 +74,7 @@ /* * Common bitfield for the field objects */ -#define ACPI_COMMON_FIELD_INFO /* Three 32-bit values */\ +#define ACPI_COMMON_FIELD_INFO /* Three 32-bit values plus 8*/\ u8 granularity;\ u16 length; \ u32 offset; /* Byte offset within containing object */\ @@ -111,7 +111,7 @@ typedef struct /* NUMBER - has value */ { ACPI_OBJECT_COMMON_HEADER - u32 value; + ACPI_INTEGER value; } ACPI_OBJECT_NUMBER; @@ -155,8 +155,9 @@ typedef struct /* FIELD UNIT */ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO - u32 sequence; /* Container's sequence number */ + union acpi_operand_obj *extra; /* Pointer to executable AML (in field definition) */ + ACPI_NAMESPACE_NODE *node; /* containing object */ union acpi_operand_obj *container; /* Containing object (Buffer) */ } ACPI_OBJECT_FIELD_UNIT; @@ -218,16 +219,10 @@ typedef struct /* REGION */ u8 space_id; u32 length; - u32 address; - void *region_context; /* Region Specific data (Handler->Context - optional things like PCI _ADR) */ - - /* TBD: [Restructure] This field can go away when Pass3 is implemented */ - union acpi_operand_obj *method; /* Associated control method */ - + ACPI_PHYSICAL_ADDRESS address; + union acpi_operand_obj *extra; /* Pointer to executable AML (in region definition) */ union acpi_operand_obj *addr_handler; /* Handler for system notifies */ - ACPI_NAMESPACE_NODE *REGmethod; /* _REG method for this region (if any) */ ACPI_NAMESPACE_NODE *node; /* containing object */ union acpi_operand_obj *next; @@ -372,6 +367,27 @@ typedef struct /* Reference - Local object type */ } ACPI_OBJECT_REFERENCE; +/* + * Extra object is used as additional storage for types that + * have AML code in their declarations (Term_args) that must be + * evaluated at run time. + * + * Currently: Region and Field_unit types + */ + +typedef struct /* EXTRA */ +{ + ACPI_OBJECT_COMMON_HEADER + u8 byte_fill1; + u16 word_fill1; + u32 pcode_length; + u8 *pcode; + ACPI_NAMESPACE_NODE *method_REG; /* _REG method for this region (if any) */ + void *region_context; /* Region-specific data */ + +} ACPI_OBJECT_EXTRA; + + /****************************************************************************** * * ACPI_OPERAND_OBJECT Descriptor - a giant union of all of the above @@ -401,6 +417,7 @@ typedef union acpi_operand_obj ACPI_OBJECT_REFERENCE reference; ACPI_OBJECT_NOTIFY_HANDLER notify_handler; ACPI_OBJECT_ADDR_HANDLER addr_handler; + ACPI_OBJECT_EXTRA extra; } ACPI_OPERAND_OBJECT; diff --git a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h index c9983c8f7..664a5f8a8 100644 --- a/drivers/acpi/include/acoutput.h +++ b/drivers/acpi/include/acoutput.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acoutput.h -- debug output - * $Revision: 63 $ + * $Revision: 66 $ * *****************************************************************************/ @@ -60,6 +60,8 @@ #define DEBUGGER 0x00100000 #define ALL_COMPONENTS 0x001FFFFF +#define COMPONENT_DEFAULT (ALL_COMPONENTS) + /* Exception level -- used in the global "Debug_level" */ @@ -104,12 +106,12 @@ #define VERBOSE_TABLES 0x40000000 #define VERBOSE_EVENTS 0x80000000 -#define VERBOSE_ALL 0x70000000 +#define VERBOSE_ALL 0xF0000000 /* Defaults for Debug_level, debug and normal */ -#define DEBUG_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT | TRACE_TABLES | TRACE_IO) +#define DEBUG_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT) #define NORMAL_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT) #define DEBUG_ALL (VERBOSE_AML_DISASSEMBLE | TRACE_ALL | ACPI_ALL) diff --git a/drivers/acpi/include/acparser.h b/drivers/acpi/include/acparser.h index 0f3271d6f..d657749da 100644 --- a/drivers/acpi/include/acparser.h +++ b/drivers/acpi/include/acparser.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: acparser.h - AML Parser subcomponent prototypes and defines - * $Revision: 46 $ + * $Revision: 47 $ * *****************************************************************************/ @@ -188,7 +188,8 @@ void acpi_ps_pop_scope ( ACPI_PARSE_STATE *parser_state, ACPI_PARSE_OBJECT **op, - u32 *arg_list); + u32 *arg_list, + u32 *arg_count); ACPI_STATUS acpi_ps_push_scope ( diff --git a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h index d589ae93d..2f9eb4c13 100644 --- a/drivers/acpi/include/acpiosxf.h +++ b/drivers/acpi/include/acpiosxf.h @@ -1,9 +1,9 @@ /****************************************************************************** * - * Name: acpiosd.h - All interfaces to the OS-dependent layer. These - * interfaces must be implemented by the OS-dependent - * front-end to the ACPI subsystem. + * Name: acpiosxf.h - All interfaces to the OS-dependent layer. These + * interfaces must be implemented by the OS-dependent + * front-end to the ACPI subsystem. * *****************************************************************************/ @@ -35,10 +35,10 @@ /* Priorities for Acpi_os_queue_for_execution */ -#define OSD_PRIORITY_HIGH 1 -#define OSD_PRIORITY_MED 2 -#define OSD_PRIORITY_LO 3 -#define OSD_PRIORITY_GPE OSD_PRIORITY_HIGH +#define OSD_PRIORITY_GPE 1 +#define OSD_PRIORITY_HIGH 2 +#define OSD_PRIORITY_MED 3 +#define OSD_PRIORITY_LO 4 #define ACPI_NO_UNIT_LIMIT ((u32) -1) #define ACPI_MUTEX_SEM 1 @@ -112,7 +112,7 @@ acpi_os_free ( ACPI_STATUS acpi_os_map_memory ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, u32 length, void **logical_address); @@ -189,6 +189,37 @@ acpi_os_out32 ( ACPI_IO_ADDRESS out_port, u32 value); +/* + * Platform/Hardware independent physical memory interfaces + */ + +u8 +acpi_os_mem_in8 ( + ACPI_PHYSICAL_ADDRESS in_addr); + +u16 +acpi_os_mem_in16 ( + ACPI_PHYSICAL_ADDRESS in_addr); + +u32 +acpi_os_mem_in32 ( + ACPI_PHYSICAL_ADDRESS in_addr); + +void +acpi_os_mem_out8 ( + ACPI_PHYSICAL_ADDRESS out_addr, + u8 value); + +void +acpi_os_mem_out16 ( + ACPI_PHYSICAL_ADDRESS out_addr, + u16 value); + +void +acpi_os_mem_out32 ( + ACPI_PHYSICAL_ADDRESS out_addr, + u32 value); + /* * Standard access to PCI configuration space diff --git a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h index ca2afbae5..d70fa75a7 100644 --- a/drivers/acpi/include/acpixf.h +++ b/drivers/acpi/include/acpixf.h @@ -1,7 +1,7 @@ /****************************************************************************** * - * Name: acxface.h - External interfaces to the ACPI subsystem + * Name: acpixf.h - External interfaces to the ACPI subsystem * *****************************************************************************/ @@ -35,8 +35,12 @@ */ ACPI_STATUS -acpi_initialize ( - ACPI_INIT_DATA *init_data); +acpi_initialize_subsystem ( + void); + +ACPI_STATUS +acpi_enable_subsystem ( + u32 flags); ACPI_STATUS acpi_terminate ( @@ -65,8 +69,12 @@ acpi_format_exception ( */ ACPI_STATUS -acpi_load_firmware_tables ( - void); +acpi_find_root_pointer ( + ACPI_PHYSICAL_ADDRESS *rsdp_physical_address); + +ACPI_STATUS +acpi_load_tables ( + ACPI_PHYSICAL_ADDRESS rsdp_physical_address); ACPI_STATUS acpi_load_table ( @@ -94,10 +102,6 @@ acpi_get_table ( */ ACPI_STATUS -acpi_load_namespace ( - void); - -ACPI_STATUS acpi_walk_namespace ( ACPI_OBJECT_TYPE type, ACPI_HANDLE start_object, @@ -107,6 +111,13 @@ acpi_walk_namespace ( void * *return_value); ACPI_STATUS +acpi_get_devices ( + NATIVE_CHAR *HID, + WALK_CALLBACK user_function, + void *context, + void **return_value); + +ACPI_STATUS acpi_get_name ( ACPI_HANDLE handle, u32 name_type, @@ -203,6 +214,14 @@ acpi_install_gpe_handler ( void *context); ACPI_STATUS +acpi_acquire_global_lock ( + void); + +ACPI_STATUS +acpi_release_global_lock ( + void); + +ACPI_STATUS acpi_remove_gpe_handler ( u32 gpe_number, GPE_HANDLER handler); @@ -259,11 +278,11 @@ acpi_get_irq_routing_table ( ACPI_STATUS acpi_set_firmware_waking_vector ( - void *physical_address); + ACPI_PHYSICAL_ADDRESS physical_address); ACPI_STATUS acpi_get_firmware_waking_vector ( - void **physical_address); + ACPI_PHYSICAL_ADDRESS *physical_address); ACPI_STATUS acpi_get_processor_throttling_info ( diff --git a/drivers/acpi/include/actables.h b/drivers/acpi/include/actables.h index abc83c778..4dd724517 100644 --- a/drivers/acpi/include/actables.h +++ b/drivers/acpi/include/actables.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actables.h - ACPI table management - * $Revision: 20 $ + * $Revision: 27 $ * *****************************************************************************/ @@ -37,19 +37,26 @@ acpi_tb_handle_to_object ( u16 table_id, ACPI_TABLE_DESC **table_desc); - /* - * Acpi_tbfac - FACP, FACS utilities + * tbconvrt - Table conversion routines */ ACPI_STATUS -acpi_tb_get_table_facs ( - ACPI_TABLE_HEADER *buffer_ptr, +acpi_tb_convert_to_xsdt ( + ACPI_TABLE_DESC *table_info, + u32 *number_of_tables); + +ACPI_STATUS +acpi_tb_convert_table_fadt ( + void); + +ACPI_STATUS +acpi_tb_build_common_facs ( ACPI_TABLE_DESC *table_info); /* - * Acpi_tbget - Table "get" routines + * tbget - Table "get" routines */ ACPI_STATUS @@ -60,13 +67,22 @@ acpi_tb_get_table_ptr ( ACPI_STATUS acpi_tb_get_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, + ACPI_TABLE_HEADER *buffer_ptr, + ACPI_TABLE_DESC *table_info); + +ACPI_STATUS +acpi_tb_verify_rsdp ( + ACPI_PHYSICAL_ADDRESS RSDP_physical_address); + +ACPI_STATUS +acpi_tb_get_table_facs ( ACPI_TABLE_HEADER *buffer_ptr, ACPI_TABLE_DESC *table_info); /* - * Acpi_tbgetall - Get all firmware ACPI tables + * tbgetall - Get all firmware ACPI tables */ ACPI_STATUS @@ -76,7 +92,7 @@ acpi_tb_get_all_tables ( /* - * Acpi_tbinstall - Table installation + * tbinstall - Table installation */ ACPI_STATUS @@ -96,7 +112,7 @@ acpi_tb_init_table_descriptor ( /* - * Acpi_tbremove - Table removal and deletion + * tbremove - Table removal and deletion */ void @@ -107,17 +123,21 @@ void acpi_tb_delete_acpi_table ( ACPI_TABLE_TYPE type); -ACPI_TABLE_DESC * +void acpi_tb_delete_single_table ( ACPI_TABLE_DESC *table_desc); +ACPI_TABLE_DESC * +acpi_tb_uninstall_table ( + ACPI_TABLE_DESC *table_desc); + void acpi_tb_free_acpi_tables_of_type ( ACPI_TABLE_DESC *table_info); /* - * Acpi_tbrsd - RSDP, RSDT utilities + * tbrsd - RSDP, RSDT utilities */ ACPI_STATUS @@ -135,7 +155,7 @@ acpi_tb_find_rsdp ( /* - * Acpi_tbutils - common table utilities + * tbutils - common table utilities */ u8 @@ -144,7 +164,7 @@ acpi_tb_system_table_pointer ( ACPI_STATUS acpi_tb_map_acpi_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, u32 *size, void **logical_address); diff --git a/drivers/acpi/include/actbl.h b/drivers/acpi/include/actbl.h index fd1f6615a..34631e820 100644 --- a/drivers/acpi/include/actbl.h +++ b/drivers/acpi/include/actbl.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actbl.h - Table data structures defined in ACPI specification - * $Revision: 34 $ + * $Revision: 43 $ * *****************************************************************************/ @@ -31,32 +31,47 @@ * Values for description table header signatures */ -#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ -#define APIC_SIG "APIC" /* Multiple APIC Description Table */ -#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ -#define FACP_SIG "FACP" /* Fixed ACPI Description Table */ -#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ -#define PSDT_SIG "PSDT" /* Persistent System Description Table */ -#define RSDT_SIG "RSDT" /* Root System Description Table */ -#define SSDT_SIG "SSDT" /* Secondary System Description Table */ -#define SBST_SIG "SBST" /* Smart Battery Specification Table */ -#define BOOT_SIG "BOOT" /* Boot table */ +#define RSDP_NAME "RSDP" +#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ +#define APIC_SIG "APIC" /* Multiple APIC Description Table */ +#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ +#define FADT_SIG "FACP" /* Fixed ACPI Description Table */ +#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ +#define PSDT_SIG "PSDT" /* Persistent System Description Table */ +#define RSDT_SIG "RSDT" /* Root System Description Table */ +#define XSDT_SIG "XSDT" /* Extended System Description Table */ +#define SSDT_SIG "SSDT" /* Secondary System Description Table */ +#define SBST_SIG "SBST" /* Smart Battery Specification Table */ +#define SPIC_SIG "SPIC" /* iosapic table */ +#define BOOT_SIG "BOOT" /* Boot table */ -#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ +#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ /* values of Mapic.Model */ -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 /* values of Type in APIC_HEADER */ -#define APIC_PROC 0 -#define APIC_IO 1 +#define APIC_PROC 0 +#define APIC_IO 1 /* + * Common table types. The base code can remain + * constant if the underlying tables are changed + */ +#define RSDT_DESCRIPTOR RSDT_DESCRIPTOR_REV2 +#define XSDT_DESCRIPTOR XSDT_DESCRIPTOR_REV2 +#define FACS_DESCRIPTOR FACS_DESCRIPTOR_REV2 +#define FADT_DESCRIPTOR FADT_DESCRIPTOR_REV2 + + +#pragma pack(1) + +/* * Architecture-independent tables * The architecture dependent tables are in separate files */ @@ -66,10 +81,14 @@ typedef struct /* Root System Descriptor Pointer */ NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ u8 checksum; /* to make sum of struct == 0 */ NATIVE_CHAR oem_id [6]; /* OEM identification */ - u8 reserved; /* reserved - must be zero */ - u32 rsdt_physical_address; /* physical address of RSDT */ + u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */ + u32 rsdt_physical_address; /* 32-bit physical address of RSDT */ + u32 length; /* XSDT Length in bytes including hdr */ + UINT64 xsdt_physical_address; /* 64-bit physical address of XSDT */ + u8 extended_checksum; /* Checksum of entire table */ + NATIVE_CHAR reserved [3]; /* reserved field must be 0 */ -} ROOT_SYSTEM_DESCRIPTOR_POINTER; +} RSDP_DESCRIPTOR; typedef struct /* ACPI common table header */ @@ -88,6 +107,15 @@ typedef struct /* ACPI common table header */ } ACPI_TABLE_HEADER; +typedef struct /* Common FACS for internal use */ +{ + u32 *global_lock; + UINT64 *firmware_waking_vector; + u8 vector_width; + +} ACPI_COMMON_FACS; + + typedef struct /* APIC Table */ { ACPI_TABLE_HEADER header; /* table header */ @@ -146,6 +174,9 @@ typedef struct /* Smart Battery Description Table */ } SMART_BATTERY_DESCRIPTION_TABLE; +#pragma pack() + + /* * ACPI Table information. We save the table address, length, * and type of memory allocation (mapped or allocated) for each @@ -175,16 +206,12 @@ typedef struct _acpi_table_support } ACPI_TABLE_SUPPORT; - /* * Get the architecture-specific tables */ -#ifdef IA64 -#include "actbl64.h" -#else -#include "actbl32.h" -#endif - +#include "actbl1.h" /* Acpi 1.0 table defintions */ +#include "actbl71.h" /* Acpi 0.71 IA-64 Extension table defintions */ +#include "actbl2.h" /* Acpi 2.0 table definitions */ #endif /* __ACTBL_H__ */ diff --git a/drivers/acpi/include/actbl32.h b/drivers/acpi/include/actbl1.h index 3c602293f..019ba1680 100644 --- a/drivers/acpi/include/actbl32.h +++ b/drivers/acpi/include/actbl1.h @@ -1,7 +1,7 @@ /****************************************************************************** * - * Name: actbl32.h - ACPI tables specific to IA32 - * $Revision: 11 $ + * Name: actbl1.h - ACPI 1.0 tables + * $Revision: 15 $ * *****************************************************************************/ @@ -23,22 +23,27 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __ACTBL32_H__ -#define __ACTBL32_H__ +#ifndef __ACTBL1_H__ +#define __ACTBL1_H__ +#pragma pack(1) -/* IA32 Root System Description Table */ - +/*************************************/ +/* ACPI Specification Rev 1.0 for */ +/* the Root System Description Table */ +/*************************************/ typedef struct { ACPI_TABLE_HEADER header; /* Table header */ - void *table_offset_entry [1]; /* Array of pointers to other */ - /* tables' headers */ -} ROOT_SYSTEM_DESCRIPTION_TABLE; - + u32 table_offset_entry [1]; /* Array of pointers to other */ + /* ACPI tables */ +} RSDT_DESCRIPTOR_REV1; -/* IA32 Firmware ACPI Control Structure */ +/***************************************/ +/* ACPI Specification Rev 1.0 for */ +/* the Firmware ACPI Control Structure */ +/***************************************/ typedef struct { NATIVE_CHAR signature[4]; /* signature "FACS" */ @@ -50,32 +55,34 @@ typedef struct u32 reserved1 : 31; /* must be 0 */ u8 resverved3 [40]; /* reserved - must be zero */ -} FIRMWARE_ACPI_CONTROL_STRUCTURE; - +} FACS_DESCRIPTOR_REV1; -/* IA32 Fixed ACPI Description Table */ +/************************************/ +/* ACPI Specification Rev 1.0 for */ +/* the Fixed ACPI Description Table */ +/************************************/ typedef struct { ACPI_TABLE_HEADER header; /* table header */ - ACPI_TBLPTR firmware_ctrl; /* Physical address of FACS */ - ACPI_TBLPTR dsdt; /* Physical address of DSDT */ + u32 firmware_ctrl; /* Physical address of FACS */ + u32 dsdt; /* Physical address of DSDT */ u8 model; /* System Interrupt Model */ u8 reserved1; /* reserved */ u16 sci_int; /* System vector of SCI interrupt */ - ACPI_IO_ADDRESS smi_cmd; /* Port address of SMI command port */ + u32 smi_cmd; /* Port address of SMI command port */ u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ u8 reserved2; /* reserved - must be zero */ - ACPI_IO_ADDRESS pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - ACPI_IO_ADDRESS pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - ACPI_IO_ADDRESS pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - ACPI_IO_ADDRESS pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - ACPI_IO_ADDRESS pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - ACPI_IO_ADDRESS pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - ACPI_IO_ADDRESS gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - ACPI_IO_ADDRESS gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ + u32 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ + u32 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ + u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u32 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ + u32 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ @@ -107,9 +114,10 @@ typedef struct u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ u32 reserved5 : 23; /* reserved - must be zero */ -} FIXED_ACPI_DESCRIPTION_TABLE; +} FADT_DESCRIPTOR_REV1; +#pragma pack() -#endif /* __ACTBL32_H__ */ +#endif /* __ACTBL1_H__ */ diff --git a/drivers/acpi/include/actbl2.h b/drivers/acpi/include/actbl2.h new file mode 100644 index 000000000..e3ccf2188 --- /dev/null +++ b/drivers/acpi/include/actbl2.h @@ -0,0 +1,189 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * $Revision: 19 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + +/**************************************/ +/* Prefered Power Management Profiles */ +/**************************************/ +#define PM_UNSPECIFIED 0 +#define PM_DESKTOP 1 +#define PM_MOBILE 2 +#define PM_WORKSTATION 3 +#define PM_ENTERPRISE_SERVER 4 +#define PM_SOHO_SERVER 5 +#define PM_APPLIANCE_PC 6 + +/*********************************************/ +/* ACPI Boot Arch Flags, See spec Table 5-10 */ +/*********************************************/ +#define BAF_LEGACY_DEVICES 0x0001 +#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 + +#define FADT2_REVISION_ID 3 + +#pragma pack(1) + +/*************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Root System Description Table */ +/*************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + u32 table_offset_entry [1]; /* Array of pointers to */ + /* other tables' headers */ +} RSDT_DESCRIPTOR_REV2; + + +/********************************************/ +/* ACPI Specification Rev 2.0 for the */ +/* Extended System Description Table (XSDT) */ +/********************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + UINT64 table_offset_entry [1]; /* Array of pointers to */ + /* other tables' headers */ +} XSDT_DESCRIPTOR_REV2; + +/***************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Firmware ACPI Control Structure */ +/***************************************/ +typedef struct +{ + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */ + u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */ + u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ + u32 reserved1 : 31; /* must be 0 */ + UINT64 Xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */ + u8 version; /* Version of this table */ + u8 reserved3 [31]; /* reserved - must be zero */ + +} FACS_DESCRIPTOR_REV2; + + +/***************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Generic Address Structure (GAS) */ +/***************************************/ +typedef struct +{ + u8 address_space_id; /* Address space where struct or register exists. */ + u8 register_bit_width; /* Size in bits of given register */ + u8 register_bit_offset; /* Bit offset within the register */ + u8 reserved; /* Must be 0 */ + UINT64 address; /* 64-bit address of struct or register */ + +} ACPI_GAS; + + +/************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Fixed ACPI Description Table */ +/************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* table header */ + u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ + u32 V1_dsdt; /* 32-bit physical address of DSDT */ + u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ + u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ + u16 sci_int; /* System vector of SCI interrupt */ + u32 smi_cmd; /* Port address of SMI command port */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ + u8 pstate_cnt; /* processor performance state control*/ + u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ + u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ + u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u32 V1_gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ + u32 V1_gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u16 flush_size; /* number of flush strides that need to be read */ + u16 flush_stride; /* Processor's memory cache line width, in bytes */ + u8 duty_offset; /* Processor’s duty cycle index in processor's P_CNT reg*/ + u8 duty_width; /* Processor’s duty cycle value bit width in P_CNT register.*/ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ + u8 reserved2; /* reserved */ + u32 wb_invd : 1; /* wbinvd instruction works properly */ + u32 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */ + u32 proc_c1 : 1; /* all processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ + u32 dock_cap : 1; /* Supports Docking */ + u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/ + u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed. */ + u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices.*/ + u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */ + /* must be executed after writing the SLP_TYPx register. */ + u32 reserved6 : 18; /* reserved - must be zero */ + + ACPI_GAS reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the Reset_register port to reset the system. */ + u8 reserved7[3]; /* These three bytes must be zero */ + UINT64 Xfirmware_ctrl; /* 64-bit physical address of FACS */ + UINT64 Xdsdt; /* 64-bit physical address of DSDT */ + ACPI_GAS Xpm1a_evt_blk; /* Extended Power Mgt 1a Acpi_event Reg Blk address */ + ACPI_GAS Xpm1b_evt_blk; /* Extended Power Mgt 1b Acpi_event Reg Blk address */ + ACPI_GAS Xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ + ACPI_GAS Xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ + ACPI_GAS Xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ + ACPI_GAS Xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ + ACPI_GAS Xgpe0blk; /* Extended General Purpose Acpi_event 0 Reg Blk address */ + ACPI_GAS Xgpe1_blk; /* Extended General Purpose Acpi_event 1 Reg Blk address */ + +} FADT_DESCRIPTOR_REV2; + + +#pragma pack() + +#endif /* __ACTBL2_H__ */ + diff --git a/drivers/acpi/include/actbl64.h b/drivers/acpi/include/actbl64.h deleted file mode 100644 index fea6d134d..000000000 --- a/drivers/acpi/include/actbl64.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * - * Name: actbl64.h - ACPI tables specific to IA64 - * $Revision: 12 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __ACTBL64_H__ -#define __ACTBL64_H__ - - -typedef UINT64 IO_ADDRESS; /* Only for clarity in declarations */ - - -/* IA64 Root System Description Table */ - -typedef struct -{ - ACPI_TABLE_HEADER header; /* Table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - void *table_offset_entry [1]; /* Array of pointers to other */ - /* tables' headers */ -} ROOT_SYSTEM_DESCRIPTION_TABLE; - - -/* IA64 Firmware ACPI Control Structure */ - -typedef struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 reserved4; /* must be 0 */ - UINT64 firmware_waking_vector; /* ACPI OS waking vector */ - UINT64 global_lock; /* Global Lock */ - u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u8 resverved3 [28]; /* reserved - must be zero */ - -} FIRMWARE_ACPI_CONTROL_STRUCTURE; - - -/* IA64 Fixed ACPI Description Table */ - -typedef struct -{ - ACPI_TABLE_HEADER header; /* table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - ACPI_TBLPTR firmware_ctrl; /* Physical address of FACS */ - ACPI_TBLPTR dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 address_space; /* Address Space Bitmask */ - u16 sci_int; /* System vector of SCI interrupt */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ - u8 reserved2; /* reserved - must be zero */ - UINT64 smi_cmd; /* Port address of SMI command port */ - UINT64 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - UINT64 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - UINT64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - UINT64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - UINT64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - UINT64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - UINT64 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - UINT64 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 reserved3; /* reserved */ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u8 reserved4; /* reserved */ - u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ - u32 reserved5 : 1; /* reserved - must be zero */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 dock_cap : 1; /* Supports Docking */ - u32 reserved6 : 22; /* reserved - must be zero */ - -} FIXED_ACPI_DESCRIPTION_TABLE; - - -#endif /* __ACTBL64_H__ */ - diff --git a/drivers/acpi/include/actbl71.h b/drivers/acpi/include/actbl71.h new file mode 100644 index 000000000..408ec402e --- /dev/null +++ b/drivers/acpi/include/actbl71.h @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 + * This file includes tables specific to this + * specification revision. + * $Revision: 7 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL71_H__ +#define __ACTBL71_H__ + +/* 0.71 FADT Address_space data item bitmasks defines */ +/* If the associated bit is zero then it is in memory space else in io space */ +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 + +/* Only for clarity in declarations */ +typedef UINT64 IO_ADDRESS; + +#pragma pack(1) + +typedef struct /* Root System Descriptor Pointer */ +{ + NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + NATIVE_CHAR oem_id [6]; /* OEM identification */ + u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ + UINT64 rsdt_physical_address; /* 64-bit physical address of RSDT */ +} RSDP_DESCRIPTOR_REV071; + + +/*****************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Root System Description Table */ +/*****************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + UINT64 table_offset_entry [1]; /* Array of pointers to other */ + /* tables' headers */ +} RSDT_DESCRIPTOR_REV071; + + +/*******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Firmware ACPI Control Structure */ +/*******************************************/ +typedef struct +{ + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 reserved4; /* must be 0 */ + UINT64 firmware_waking_vector; /* ACPI OS waking vector */ + UINT64 global_lock; /* Global Lock */ + u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ + u32 reserved1 : 31; /* must be 0 */ + u8 reserved3 [28]; /* reserved - must be zero */ + +} FACS_DESCRIPTOR_REV071; + + +/******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Fixed ACPI Description Table */ +/******************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + UINT64 firmware_ctrl; /* 64-bit Physical address of FACS */ + UINT64 dsdt; /* 64-bit Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 address_space; /* Address Space Bitmask */ + u16 sci_int; /* System vector of SCI interrupt */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ + u8 reserved2; /* reserved - must be zero */ + UINT64 smi_cmd; /* Port address of SMI command port */ + UINT64 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ + UINT64 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ + UINT64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + UINT64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + UINT64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + UINT64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + UINT64 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ + UINT64 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 reserved3; /* reserved */ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u8 reserved4; /* reserved */ + u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ + u32 reserved5 : 1; /* reserved - must be zero */ + u32 proc_c1 : 1; /* all processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ + u32 dock_cap : 1; /* Supports Docking */ + u32 reserved6 : 22; /* reserved - must be zero */ + +} FADT_DESCRIPTOR_REV071; + +#pragma pack() + +#endif /* __ACTBL71_H__ */ + diff --git a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h index e3ac5f299..dfa28a9d9 100644 --- a/drivers/acpi/include/actypes.h +++ b/drivers/acpi/include/actypes.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 131 $ + * $Revision: 159 $ * *****************************************************************************/ @@ -48,9 +48,6 @@ * UCHAR Character. 1 byte unsigned value. */ -#ifdef __ia64__ -#define _IA64 -#endif #ifdef _IA64 /* @@ -62,14 +59,14 @@ typedef unsigned char UCHAR; typedef unsigned short UINT16; typedef int INT32; typedef unsigned int UINT32; -typedef long INT64; -typedef unsigned long UINT64; +typedef COMPILER_DEPENDENT_UINT64 UINT64; typedef UINT64 NATIVE_UINT; typedef INT64 NATIVE_INT; typedef NATIVE_UINT ACPI_TBLPTR; typedef UINT64 ACPI_IO_ADDRESS; +typedef UINT64 ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000008 @@ -85,17 +82,32 @@ typedef unsigned char BOOLEAN; typedef unsigned char UCHAR; typedef unsigned int UINT16; typedef long INT32; +typedef int INT16; typedef unsigned long UINT32; +typedef struct +{ + UINT32 Lo; + UINT32 Hi; + +} UINT64; + typedef UINT16 NATIVE_UINT; typedef INT16 NATIVE_INT; typedef UINT32 ACPI_TBLPTR; typedef UINT32 ACPI_IO_ADDRESS; +typedef void *ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000002 #define _HW_ALIGNMENT_SUPPORT +/* + * (16-bit only) internal integers must be 32-bits, so + * 64-bit integers cannot be supported + */ +#define ACPI_NO_INTEGER64_SUPPORT + #else /* @@ -107,18 +119,21 @@ typedef unsigned char UCHAR; typedef unsigned short UINT16; typedef int INT32; typedef unsigned int UINT32; +typedef COMPILER_DEPENDENT_UINT64 UINT64; typedef UINT32 NATIVE_UINT; typedef INT32 NATIVE_INT; typedef NATIVE_UINT ACPI_TBLPTR; typedef UINT32 ACPI_IO_ADDRESS; +typedef UINT64 ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000004 #define _HW_ALIGNMENT_SUPPORT - #endif + + /* * Miscellaneous common types */ @@ -132,8 +147,10 @@ typedef char NATIVE_CHAR; * Data type ranges */ -#define ACPI_UCHAR_MAX (UCHAR) 0xFF +#define ACPI_UINT8_MAX (UINT8) 0xFF +#define ACPI_UINT16_MAX (UINT16) 0xFFFF #define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF +#define ACPI_UINT64_MAX (UINT64) 0xFFFFFFFFFFFFFFFF #ifdef DEFINE_ALTERNATE_TYPES @@ -144,6 +161,7 @@ typedef INT32 s32; typedef UINT8 u8; typedef UINT16 u16; typedef UINT32 u32; +typedef UINT64 u64; #endif /*! [End] no source code translation !*/ @@ -178,11 +196,50 @@ typedef void* ACPI_HANDLE; /* Actually a ptr to an /* + * Acpi integer width. In ACPI version 1, integers are + * 32 bits. In ACPI version 2, integers are 64 bits. + * Note that this pertains to the ACPI integer type only, not + * other integers used in the implementation of the ACPI CA + * subsystem. + */ +#ifdef ACPI_NO_INTEGER64_SUPPORT + +/* 32-bit integers only, no 64-bit support */ + +typedef u32 ACPI_INTEGER; +#define ACPI_INTEGER_MAX ACPI_UINT32_MAX +#define ACPI_INTEGER_BIT_SIZE 32 +#define ACPI_MAX_BCD_VALUE 99999999 +#define ACPI_MAX_BCD_DIGITS 8 + +#else + +/* 64-bit integers */ + +typedef UINT64 ACPI_INTEGER; +#define ACPI_INTEGER_MAX ACPI_UINT64_MAX +#define ACPI_INTEGER_BIT_SIZE 64 +#define ACPI_MAX_BCD_VALUE 9999999999999999 +#define ACPI_MAX_BCD_DIGITS 16 + +#endif + + +/* * Constants with special meanings */ #define ACPI_ROOT_OBJECT (ACPI_HANDLE)(-1) +#define ACPI_FULL_INITIALIZATION 0x00 +#define ACPI_NO_ADDRESS_SPACE_INIT 0x01 +#define ACPI_NO_HARDWARE_INIT 0x02 +#define ACPI_NO_EVENT_INIT 0x04 +#define ACPI_NO_ACPI_ENABLE 0x08 +#define ACPI_NO_DEVICE_INIT 0x10 +#define ACPI_NO_PCI_INIT 0x20 +#define ACPI_NO_OBJECT_INIT 0x40 + /* * Sleep state constants @@ -204,17 +261,14 @@ typedef void* ACPI_HANDLE; /* Actually a ptr to an typedef u32 ACPI_TABLE_TYPE; #define ACPI_TABLE_RSDP (ACPI_TABLE_TYPE) 0 -#define ACPI_TABLE_APIC (ACPI_TABLE_TYPE) 1 -#define ACPI_TABLE_DSDT (ACPI_TABLE_TYPE) 2 -#define ACPI_TABLE_FACP (ACPI_TABLE_TYPE) 3 -#define ACPI_TABLE_FACS (ACPI_TABLE_TYPE) 4 -#define ACPI_TABLE_PSDT (ACPI_TABLE_TYPE) 5 -#define ACPI_TABLE_RSDT (ACPI_TABLE_TYPE) 6 -#define ACPI_TABLE_SSDT (ACPI_TABLE_TYPE) 7 -#define ACPI_TABLE_SBST (ACPI_TABLE_TYPE) 8 -#define ACPI_TABLE_BOOT (ACPI_TABLE_TYPE) 9 -#define ACPI_TABLE_MAX 9 -#define NUM_ACPI_TABLES 10 +#define ACPI_TABLE_DSDT (ACPI_TABLE_TYPE) 1 +#define ACPI_TABLE_FADT (ACPI_TABLE_TYPE) 2 +#define ACPI_TABLE_FACS (ACPI_TABLE_TYPE) 3 +#define ACPI_TABLE_PSDT (ACPI_TABLE_TYPE) 4 +#define ACPI_TABLE_SSDT (ACPI_TABLE_TYPE) 5 +#define ACPI_TABLE_XSDT (ACPI_TABLE_TYPE) 6 +#define ACPI_TABLE_MAX 6 +#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1) /* @@ -266,21 +320,22 @@ typedef u8 OBJECT_TYPE_INTERNAL; #define INTERNAL_TYPE_ALIAS 21 /* 0x15 */ #define INTERNAL_TYPE_NOTIFY 22 /* 0x16 */ #define INTERNAL_TYPE_ADDRESS_HANDLER 23 /* 0x17 */ +#define INTERNAL_TYPE_RESOURCE 24 /* 0x18 */ -#define INTERNAL_TYPE_NODE_MAX 23 + +#define INTERNAL_TYPE_NODE_MAX 24 /* These are pseudo-types because there are never any namespace nodes with these types */ -#define INTERNAL_TYPE_DEF_FIELD_DEFN 24 /* 0x18 Name, Byte_const, multiple Field_element */ -#define INTERNAL_TYPE_BANK_FIELD_DEFN 25 /* 0x19 2 Name,DWord_const,Byte_const,multi Field_element */ -#define INTERNAL_TYPE_INDEX_FIELD_DEFN 26 /* 0x1A 2 Name, Byte_const, multiple Field_element */ -#define INTERNAL_TYPE_IF 27 /* 0x1B Op_code, multiple Code */ -#define INTERNAL_TYPE_ELSE 28 /* 0x1C multiple Code */ -#define INTERNAL_TYPE_WHILE 29 /* 0x1D Op_code, multiple Code */ -#define INTERNAL_TYPE_SCOPE 30 /* 0x1E Name, multiple Node */ -#define INTERNAL_TYPE_DEF_ANY 31 /* 0x1F type is Any, suppress search of enclosing scopes */ -#define INTERNAL_TYPE_METHOD_ARGUMENT 32 /* 0x20 */ -#define INTERNAL_TYPE_METHOD_LOCAL_VAR 33 /* 0x21 */ +#define INTERNAL_TYPE_DEF_FIELD_DEFN 25 /* 0x19 Name, Byte_const, multiple Field_element */ +#define INTERNAL_TYPE_BANK_FIELD_DEFN 26 /* 0x1A 2 Name,DWord_const,Byte_const,multi Field_element */ +#define INTERNAL_TYPE_INDEX_FIELD_DEFN 27 /* 0x1B 2 Name, Byte_const, multiple Field_element */ +#define INTERNAL_TYPE_IF 28 /* 0x1C Op_code, multiple Code */ +#define INTERNAL_TYPE_ELSE 29 /* 0x1D multiple Code */ +#define INTERNAL_TYPE_WHILE 30 /* 0x1E Op_code, multiple Code */ +#define INTERNAL_TYPE_SCOPE 31 /* 0x1F Name, multiple Node */ +#define INTERNAL_TYPE_DEF_ANY 32 /* 0x20 type is Any, suppress search of enclosing scopes */ +#define INTERNAL_TYPE_EXTRA 33 /* 0x21 */ #define INTERNAL_TYPE_MAX 33 @@ -339,6 +394,7 @@ typedef u32 ACPI_EVENT_TYPE; */ typedef u32 ACPI_EVENT_STATUS; +#define ACPI_EVENT_FLAG_DISABLED (ACPI_EVENT_STATUS) 0x00 #define ACPI_EVENT_FLAG_ENABLED (ACPI_EVENT_STATUS) 0x01 #define ACPI_EVENT_FLAG_SET (ACPI_EVENT_STATUS) 0x02 @@ -354,13 +410,15 @@ typedef u32 ACPI_EVENT_STATUS; /* Address Space (Operation Region) Types */ -typedef u32 ACPI_ADDRESS_SPACE_TYPE; +typedef u8 ACPI_ADDRESS_SPACE_TYPE; #define ADDRESS_SPACE_SYSTEM_MEMORY (ACPI_ADDRESS_SPACE_TYPE) 0 #define ADDRESS_SPACE_SYSTEM_IO (ACPI_ADDRESS_SPACE_TYPE) 1 #define ADDRESS_SPACE_PCI_CONFIG (ACPI_ADDRESS_SPACE_TYPE) 2 #define ADDRESS_SPACE_EC (ACPI_ADDRESS_SPACE_TYPE) 3 #define ADDRESS_SPACE_SMBUS (ACPI_ADDRESS_SPACE_TYPE) 4 +#define ADDRESS_SPACE_CMOS (ACPI_ADDRESS_SPACE_TYPE) 5 +#define ADDRESS_SPACE_PCI_BAR_TARGET (ACPI_ADDRESS_SPACE_TYPE) 6 /* @@ -373,7 +431,7 @@ typedef union acpi_obj struct { ACPI_OBJECT_TYPE type; - u32 value; /* The actual number */ + ACPI_INTEGER value; /* The actual number */ } number; struct @@ -553,7 +611,7 @@ void (*NOTIFY_HANDLER) ( typedef ACPI_STATUS (*ADDRESS_SPACE_HANDLER) ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -596,11 +654,8 @@ ACPI_STATUS (*WALK_CALLBACK) ( #define ACPI_COMMON_OBJ_INFO \ ACPI_OBJECT_TYPE type; /* ACPI object type */ \ - ACPI_NAME name; /* ACPI object Name */ \ - /* TBD: [Restructure] Do we want or need these next two??*/ \ - ACPI_HANDLE parent; /* Parent object */ \ - ACPI_HANDLE children; /* Linked list of children */ \ - u32 valid /* ????? */ + ACPI_NAME name /* ACPI object Name */ + typedef struct { @@ -612,12 +667,10 @@ typedef struct { ACPI_COMMON_OBJ_INFO; - /* - * TBD: [Restructure]: a HID or a _UID can return either a number or a string - */ + u32 valid; /* Are the next bits legit? */ NATIVE_CHAR hardware_id [9]; /* _HID value if any */ NATIVE_CHAR unique_id[9]; /* _UID value if any */ - u32 address; /* _ADR value if any */ + ACPI_INTEGER address; /* _ADR value if any */ u32 current_status; /* _STA value */ } ACPI_DEVICE_INFO; @@ -634,7 +687,7 @@ typedef struct typedef struct { - u8 *mapped_physical_address; + ACPI_PHYSICAL_ADDRESS mapped_physical_address; u8 *mapped_logical_address; u32 mapped_length; } MEM_HANDLER_CONTEXT; @@ -940,6 +993,8 @@ typedef struct _resource_tag #define RESOURCE_LENGTH 12 #define RESOURCE_LENGTH_NO_DATA 8 +#define NEXT_RESOURCE(res) (RESOURCE*)((u8*) res + res->length) + /* * END: Definitions for Resource Attributes */ @@ -949,7 +1004,7 @@ typedef struct _resource_tag */ typedef struct { - u32 address; + ACPI_INTEGER address; u32 pin; u32 source_index; NATIVE_CHAR source[1]; diff --git a/drivers/acpi/include/amlcode.h b/drivers/acpi/include/amlcode.h index 4c0b1a4b0..9a5cb2c52 100644 --- a/drivers/acpi/include/amlcode.h +++ b/drivers/acpi/include/amlcode.h @@ -3,7 +3,7 @@ * Name: amlcode.h - Definitions for AML, as included in "definition blocks" * Declarations and definitions contained herein are derived * directly from the ACPI specification. - * $Revision: 39 $ + * $Revision: 42 $ * *****************************************************************************/ @@ -42,9 +42,11 @@ #define AML_WORD_OP (u16) 0x0b #define AML_DWORD_OP (u16) 0x0c #define AML_STRING_OP (u16) 0x0d +#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */ #define AML_SCOPE_OP (u16) 0x10 #define AML_BUFFER_OP (u16) 0x11 #define AML_PACKAGE_OP (u16) 0x12 +#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */ #define AML_METHOD_OP (u16) 0x14 #define AML_DUAL_NAME_PREFIX (u16) 0x2e #define AML_MULTI_NAME_PREFIX_OP (u16) 0x2f @@ -90,6 +92,8 @@ #define AML_FIND_SET_LEFT_BIT_OP (u16) 0x81 #define AML_FIND_SET_RIGHT_BIT_OP (u16) 0x82 #define AML_DEREF_OF_OP (u16) 0x83 +#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */ +#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */ #define AML_NOTIFY_OP (u16) 0x86 #define AML_SIZE_OF_OP (u16) 0x87 #define AML_INDEX_OP (u16) 0x88 @@ -99,12 +103,21 @@ #define AML_BYTE_FIELD_OP (u16) 0x8c #define AML_BIT_FIELD_OP (u16) 0x8d #define AML_TYPE_OP (u16) 0x8e +#define AML_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */ #define AML_LAND_OP (u16) 0x90 #define AML_LOR_OP (u16) 0x91 #define AML_LNOT_OP (u16) 0x92 #define AML_LEQUAL_OP (u16) 0x93 #define AML_LGREATER_OP (u16) 0x94 #define AML_LLESS_OP (u16) 0x95 +#define AML_TO_BUFFER_OP (u16) 0x96 /* ACPI 2.0 */ +#define AML_TO_DECSTRING_OP (u16) 0x97 /* ACPI 2.0 */ +#define AML_TO_HEXSTRING_OP (u16) 0x98 /* ACPI 2.0 */ +#define AML_TO_INTEGER_OP (u16) 0x99 /* ACPI 2.0 */ +#define AML_TO_STRING_OP (u16) 0x9c /* ACPI 2.0 */ +#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */ +#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */ +#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */ #define AML_IF_OP (u16) 0xa0 #define AML_ELSE_OP (u16) 0xa1 #define AML_WHILE_OP (u16) 0xa2 @@ -125,6 +138,7 @@ #define AML_SHIFT_LEFT_BIT_OP (u16) 0x5b11 #define AML_COND_REF_OF_OP (u16) 0x5b12 #define AML_CREATE_FIELD_OP (u16) 0x5b13 +#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */ #define AML_LOAD_OP (u16) 0x5b20 #define AML_STALL_OP (u16) 0x5b21 #define AML_SLEEP_OP (u16) 0x5b22 @@ -147,6 +161,7 @@ #define AML_THERMAL_ZONE_OP (u16) 0x5b85 #define AML_INDEX_FIELD_OP (u16) 0x5b86 #define AML_BANK_FIELD_OP (u16) 0x5b87 +#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */ /* Bogus opcodes (they are actually two separate opcodes) */ @@ -278,6 +293,21 @@ #define OPTYPE_BOGUS 22 +/* Predefined Operation Region Space_iDs */ + +typedef enum +{ + REGION_MEMORY = 0, + REGION_IO, + REGION_PCI_CONFIG, + REGION_EC, + REGION_SMBUS, + REGION_CMOS, + REGION_PCI_BAR + +} AML_REGION_TYPES; + + /* Comparison operation codes for Match_op operator */ typedef enum @@ -347,23 +377,15 @@ typedef enum /* Array sizes. Used for range checking also */ -#define NUM_REGION_TYPES 5 +#define NUM_REGION_TYPES 7 #define NUM_ACCESS_TYPES 7 #define NUM_UPDATE_RULES 3 #define NUM_MATCH_OPS 7 #define NUM_OPCODES 256 #define NUM_FIELD_NAMES 2 -/* External declarations of the AML tables */ - -extern u8 acpi_gbl_aml [NUM_OPCODES]; -extern u16 acpi_gbl_pfx [NUM_OPCODES]; -extern NATIVE_CHAR *acpi_gbl_region_types [NUM_REGION_TYPES]; -extern NATIVE_CHAR *acpi_gbl_match_ops [NUM_MATCH_OPS]; -extern NATIVE_CHAR *acpi_gbl_access_types [NUM_ACCESS_TYPES]; -extern NATIVE_CHAR *acpi_gbl_update_rules [NUM_UPDATE_RULES]; -extern NATIVE_CHAR *acpi_gbl_FEnames [NUM_FIELD_NAMES]; +#define USER_REGION_BEGIN 0x80 /* * AML tables @@ -371,61 +393,10 @@ extern NATIVE_CHAR *acpi_gbl_FEnames [NUM_FIELD_NAMES]; #ifdef DEFINE_AML_GLOBALS -/* Data used in keeping track of fields */ - -NATIVE_CHAR *acpi_gbl_FEnames[NUM_FIELD_NAMES] = -{ - "skip", - "?access?" -}; /* FE = Field Element */ - - -/* Region type decoding */ - -NATIVE_CHAR *acpi_gbl_region_types[NUM_REGION_TYPES] = -{ - "System_memory", - "System_iO", - "PCIConfig", - "Embedded_control", - "SMBus" -}; - - -NATIVE_CHAR *acpi_gbl_match_ops[NUM_MATCH_OPS] = -{ - "Error", - "MTR", - "MEQ", - "MLE", - "MLT", - "MGE", - "MGT" -}; - - -/* Access type decoding */ - -NATIVE_CHAR *acpi_gbl_access_types[NUM_ACCESS_TYPES] = -{ - "Any_acc", - "Byte_acc", - "Word_acc", - "DWord_acc", - "Block_acc", - "SMBSend_recv_acc", - "SMBQuick_acc" -}; - - -/* Update rule decoding */ +/* External declarations of the AML tables */ -NATIVE_CHAR *acpi_gbl_update_rules[NUM_UPDATE_RULES] = -{ - "Preserve", - "Write_as_ones", - "Write_as_zeros" -}; +extern u8 acpi_gbl_aml [NUM_OPCODES]; +extern u16 acpi_gbl_pfx [NUM_OPCODES]; #endif /* DEFINE_AML_GLOBALS */ diff --git a/drivers/acpi/interpreter/Makefile b/drivers/acpi/interpreter/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/interpreter/Makefile +++ b/drivers/acpi/interpreter/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/interpreter/amconfig.c b/drivers/acpi/interpreter/amconfig.c index ccd6d2f7a..55e5b0510 100644 --- a/drivers/acpi/interpreter/amconfig.c +++ b/drivers/acpi/interpreter/amconfig.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 23 $ + * $Revision: 26 $ * *****************************************************************************/ @@ -51,7 +51,7 @@ * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_exec_load_table ( ACPI_OPERAND_OBJECT *rgn_desc, ACPI_HANDLE *ddb_handle) @@ -139,12 +139,17 @@ acpi_aml_exec_load_table ( /* Add the table to the namespace */ - status = acpi_load_namespace (); - if (ACPI_FAILURE (status)) { + /* TBD: [Restructure] - change to whatever new interface is appropriate */ +/* + Status = Acpi_load_namespace (); + if (ACPI_FAILURE (Status)) { +*/ /* TBD: [Errors] Unload the table on failure ? */ - - goto cleanup; +/* + goto Cleanup; } +*/ + /* TBD: [Investigate] we need a pointer to the table desc */ @@ -179,7 +184,7 @@ cleanup: * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_exec_unload_table ( ACPI_HANDLE ddb_handle) { @@ -219,7 +224,7 @@ acpi_aml_exec_unload_table ( /* Delete the table itself */ - acpi_tb_delete_single_table (table_info->installed_desc); + acpi_tb_uninstall_table (table_info->installed_desc); /* Delete the table descriptor (Ddb_handle) */ diff --git a/drivers/acpi/interpreter/amcreate.c b/drivers/acpi/interpreter/amcreate.c index acba79946..02d7933e1 100644 --- a/drivers/acpi/interpreter/amcreate.c +++ b/drivers/acpi/interpreter/amcreate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amcreate - Named object creation - * $Revision: 44 $ + * $Revision: 51 $ * *****************************************************************************/ @@ -66,197 +66,54 @@ * ******************************************************************************/ + ACPI_STATUS acpi_aml_exec_create_field ( - u16 opcode, + u8 *aml_ptr, + u32 aml_length, + ACPI_NAMESPACE_NODE *node, ACPI_WALK_STATE *walk_state) { - ACPI_OPERAND_OBJECT *res_desc = NULL; - ACPI_OPERAND_OBJECT *cnt_desc = NULL; - ACPI_OPERAND_OBJECT *off_desc = NULL; - ACPI_OPERAND_OBJECT *src_desc = NULL; - ACPI_OPERAND_OBJECT *field_desc; - ACPI_OPERAND_OBJECT *obj_desc; - OBJECT_TYPE_INTERNAL res_type; ACPI_STATUS status; - u32 num_operands = 3; - u32 offset; - u32 bit_offset; - u16 bit_count; - u8 type_found; - - - /* Resolve the operands */ - - status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state); - - /* Get the operands */ - - status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state); - if (AML_CREATE_FIELD_OP == opcode) { - num_operands = 4; - status |= acpi_ds_obj_stack_pop_object (&cnt_desc, walk_state); - } + ACPI_OPERAND_OBJECT *obj_desc; + ACPI_OPERAND_OBJECT *tmp_desc; - status |= acpi_ds_obj_stack_pop_object (&off_desc, walk_state); - status |= acpi_ds_obj_stack_pop_object (&src_desc, walk_state); - if (ACPI_FAILURE (status)) { - /* Invalid parameters on object stack */ + /* Create the region descriptor */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_FIELD_UNIT); + if (!obj_desc) { + status = AE_NO_MEMORY; goto cleanup; } + /* Construct the field object */ - offset = off_desc->number.value; - - - /* - * If Res_desc is a Name, it will be a direct name pointer after - * Acpi_aml_resolve_operands() - */ - - if (!VALID_DESCRIPTOR_TYPE (res_desc, ACPI_DESC_TYPE_NAMED)) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - + obj_desc->field_unit.access = (u8) ACCESS_ANY_ACC; + obj_desc->field_unit.lock_rule = (u8) GLOCK_NEVER_LOCK; + obj_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE; /* - * Setup the Bit offsets and counts, according to the opcode + * Allocate a method object for this field unit */ - switch (opcode) - { - - /* Def_create_bit_field */ - - case AML_BIT_FIELD_OP: - - /* Offset is in bits, Field is a bit */ - - bit_offset = offset; - bit_count = 1; - break; - - - /* Def_create_byte_field */ - - case AML_BYTE_FIELD_OP: - - /* Offset is in bytes, field is a byte */ - - bit_offset = 8 * offset; - bit_count = 8; - break; - - - /* Def_create_word_field */ - - case AML_WORD_FIELD_OP: - - /* Offset is in bytes, field is a word */ - - bit_offset = 8 * offset; - bit_count = 16; - break; - - - /* Def_create_dWord_field */ - - case AML_DWORD_FIELD_OP: - - /* Offset is in bytes, field is a dword */ - - bit_offset = 8 * offset; - bit_count = 32; - break; - - - /* Def_create_field */ - - case AML_CREATE_FIELD_OP: - - /* Offset is in bits, count is in bits */ - - bit_offset = offset; - bit_count = (u16) cnt_desc->number.value; - break; - - - default: - - status = AE_AML_BAD_OPCODE; + obj_desc->field_unit.extra = acpi_cm_create_internal_object ( + INTERNAL_TYPE_EXTRA); + if (!obj_desc->field_unit.extra) { + status = AE_NO_MEMORY; goto cleanup; } - /* - * Setup field according to the object type + * Remember location in AML stream of the field unit + * opcode and operands -- since the buffer and index + * operands must be evaluated. */ - switch (src_desc->common.type) - { - - /* Source_buff := Term_arg=>Buffer */ - - case ACPI_TYPE_BUFFER: - - if (bit_offset + (u32) bit_count > - (8 * (u32) src_desc->buffer.length)) - { - status = AE_AML_BUFFER_LIMIT; - goto cleanup; - } - + obj_desc->field_unit.extra->extra.pcode = aml_ptr; + obj_desc->field_unit.extra->extra.pcode_length = aml_length; + obj_desc->field_unit.node = node; - /* Allocate an object for the field */ - - field_desc = acpi_cm_create_internal_object (ACPI_TYPE_FIELD_UNIT); - if (!field_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Construct the field object */ - - field_desc->field_unit.access = (u8) ACCESS_ANY_ACC; - field_desc->field_unit.lock_rule = (u8) GLOCK_NEVER_LOCK; - field_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE; - field_desc->field_unit.length = bit_count; - field_desc->field_unit.bit_offset = (u8) (bit_offset % 8); - field_desc->field_unit.offset = DIV_8 (bit_offset); - field_desc->field_unit.container = src_desc; - field_desc->field_unit.sequence = src_desc->buffer.sequence; - - /* An additional reference for Src_desc */ - - acpi_cm_add_reference (src_desc); - - break; - - - /* Improper object type */ - - default: - - type_found = src_desc->common.type; - - if ((type_found > (u8) INTERNAL_TYPE_REFERENCE) || - !acpi_cm_valid_object_type (type_found)) - - - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - - if (AML_CREATE_FIELD_OP == opcode) { - /* Delete object descriptor unique to Create_field */ - - acpi_cm_remove_reference (cnt_desc); - cnt_desc = NULL; - } /* * This operation is supposed to cause the destination Name to refer @@ -268,11 +125,9 @@ acpi_aml_exec_create_field ( * reference before calling Acpi_aml_exec_store(). */ - res_type = acpi_ns_get_type (res_desc); - /* Type of Name's existing value */ - switch (res_type) + switch (acpi_ns_get_type (node)) { case ACPI_TYPE_FIELD_UNIT: @@ -282,21 +137,21 @@ acpi_aml_exec_create_field ( case INTERNAL_TYPE_DEF_FIELD: case INTERNAL_TYPE_INDEX_FIELD: - obj_desc = acpi_ns_get_attached_object (res_desc); - if (obj_desc) { + tmp_desc = acpi_ns_get_attached_object (node); + if (tmp_desc) { /* * There is an existing object here; delete it and zero out the * object field within the Node */ - acpi_cm_remove_reference (obj_desc); - acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) res_desc, NULL, + acpi_cm_remove_reference (tmp_desc); + acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) node, NULL, ACPI_TYPE_ANY); } /* Set the type to ANY (or the store below will fail) */ - ((ACPI_NAMESPACE_NODE *) res_desc)->type = ACPI_TYPE_ANY; + ((ACPI_NAMESPACE_NODE *) node)->type = ACPI_TYPE_ANY; break; @@ -309,32 +164,29 @@ acpi_aml_exec_create_field ( /* Store constructed field descriptor in result location */ - status = acpi_aml_exec_store (field_desc, res_desc, walk_state); + status = acpi_aml_exec_store (obj_desc, (ACPI_OPERAND_OBJECT *) node, walk_state); /* * If the field descriptor was not physically stored (or if a failure * above), we must delete it */ - if (field_desc->common.reference_count <= 1) { - acpi_cm_remove_reference (field_desc); + if (obj_desc->common.reference_count <= 1) { + acpi_cm_remove_reference (obj_desc); } -cleanup: + return (AE_OK); - /* Always delete the operands */ - acpi_cm_remove_reference (off_desc); - acpi_cm_remove_reference (src_desc); +cleanup: - if (AML_CREATE_FIELD_OP == opcode) { - acpi_cm_remove_reference (cnt_desc); - } + /* Delete region object and method subobject */ - /* On failure, delete the result descriptor */ + if (obj_desc) { + /* Remove deletes both objects! */ - if (ACPI_FAILURE (status)) { - acpi_cm_remove_reference (res_desc); /* Result descriptor */ + acpi_cm_remove_reference (obj_desc); + obj_desc = NULL; } return (status); @@ -543,25 +395,23 @@ ACPI_STATUS acpi_aml_exec_create_region ( u8 *aml_ptr, u32 aml_length, - u32 region_space, + u8 region_space, ACPI_WALK_STATE *walk_state) { ACPI_STATUS status; - ACPI_OPERAND_OBJECT *obj_desc_region; + ACPI_OPERAND_OBJECT *obj_desc; ACPI_NAMESPACE_NODE *node; - if (region_space >= NUM_REGION_TYPES) { - /* TBD: [Future] In ACPI 2.0, valid region space - * includes types 0-6 (Adding CMOS and PCIBARTarget). - * Also, types 0x80-0xff are defined as "OEM Region - * Space handler" - * - * Should this return an error, or should we just keep - * going? How do we handle the OEM region handlers? - */ - - REPORT_WARNING ("Unable to decode the Region_space"); + /* + * Space ID must be one of the predefined IDs, or in the user-defined + * range + */ + if ((region_space >= NUM_REGION_TYPES) && + (region_space < USER_REGION_BEGIN)) + { + REPORT_ERROR (("Invalid Address_space type %X\n", region_space)); + return (AE_AML_INVALID_SPACE_ID); } @@ -571,8 +421,8 @@ acpi_aml_exec_create_region ( /* Create the region descriptor */ - obj_desc_region = acpi_cm_create_internal_object (ACPI_TYPE_REGION); - if (!obj_desc_region) { + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_REGION); + if (!obj_desc) { status = AE_NO_MEMORY; goto cleanup; } @@ -580,32 +430,34 @@ acpi_aml_exec_create_region ( /* * Allocate a method object for this region. */ - obj_desc_region->region.method = acpi_cm_create_internal_object ( - ACPI_TYPE_METHOD); - if (!obj_desc_region->region.method) { + + obj_desc->region.extra = acpi_cm_create_internal_object ( + INTERNAL_TYPE_EXTRA); + if (!obj_desc->region.extra) { status = AE_NO_MEMORY; goto cleanup; } - /* Init the region from the operands */ - - obj_desc_region->region.space_id = (u8) region_space; - obj_desc_region->region.address = 0; - obj_desc_region->region.length = 0; - /* * Remember location in AML stream of address & length * operands since they need to be evaluated at run time. */ - obj_desc_region->region.method->method.pcode = aml_ptr; - obj_desc_region->region.method->method.pcode_length = aml_length; + + obj_desc->region.extra->extra.pcode = aml_ptr; + obj_desc->region.extra->extra.pcode_length = aml_length; + + /* Init the region from the operands */ + + obj_desc->region.space_id = region_space; + obj_desc->region.address = 0; + obj_desc->region.length = 0; /* Install the new region object in the parent Node */ - obj_desc_region->region.node = node; + obj_desc->region.node = node; - status = acpi_ns_attach_object (node, obj_desc_region, + status = acpi_ns_attach_object (node, obj_desc, (u8) ACPI_TYPE_REGION); if (ACPI_FAILURE (status)) { @@ -617,7 +469,7 @@ acpi_aml_exec_create_region ( * Namespace is NOT locked at this point. */ - status = acpi_ev_initialize_region (obj_desc_region, FALSE); + status = acpi_ev_initialize_region (obj_desc, FALSE); if (ACPI_FAILURE (status)) { /* @@ -635,11 +487,11 @@ cleanup: if (ACPI_FAILURE (status)) { /* Delete region object and method subobject */ - if (obj_desc_region) { + if (obj_desc) { /* Remove deletes both objects! */ - acpi_cm_remove_reference (obj_desc_region); - obj_desc_region = NULL; + acpi_cm_remove_reference (obj_desc); + obj_desc = NULL; } } diff --git a/drivers/acpi/interpreter/amdyadic.c b/drivers/acpi/interpreter/amdyadic.c index 69980c293..ba67b062a 100644 --- a/drivers/acpi/interpreter/amdyadic.c +++ b/drivers/acpi/interpreter/amdyadic.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators - * $Revision: 63 $ + * $Revision: 68 $ * *****************************************************************************/ @@ -106,7 +106,7 @@ acpi_aml_exec_dyadic1 ( /* Dispatch the notify to the appropriate handler */ - acpi_ev_notify_dispatch (node, val_desc->number.value); + acpi_ev_notify_dispatch (node, (u32) val_desc->number.value); break; default: @@ -117,7 +117,8 @@ acpi_aml_exec_dyadic1 ( default: - REPORT_ERROR ("Acpi_aml_exec_dyadic1: Unknown dyadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic1: Unknown dyadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; } @@ -162,7 +163,6 @@ acpi_aml_exec_dyadic2_r ( ACPI_OPERAND_OBJECT *ret_desc = NULL; ACPI_OPERAND_OBJECT *ret_desc2 = NULL; ACPI_STATUS status = AE_OK; - u32 remainder; u32 num_operands = 3; NATIVE_CHAR *new_buf; @@ -276,8 +276,9 @@ acpi_aml_exec_dyadic2_r ( case AML_DIVIDE_OP: - if ((u32) 0 == obj_desc2->number.value) { - REPORT_ERROR ("Aml_exec_dyadic2_r/Divide_op: Divide by zero"); + if (!obj_desc2->number.value) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Divide_op: Divide by zero\n")); status = AE_AML_DIVIDE_BY_ZERO; goto cleanup; @@ -289,14 +290,15 @@ acpi_aml_exec_dyadic2_r ( goto cleanup; } - remainder = obj_desc->number.value % - obj_desc2->number.value; - ret_desc->number.value = remainder; + /* Remainder (modulo) */ + + ret_desc->number.value = ACPI_MODULO (obj_desc->number.value, + obj_desc2->number.value); /* Result (what we used to call the quotient) */ - ret_desc2->number.value = obj_desc->number.value / - obj_desc2->number.value; + ret_desc2->number.value = ACPI_DIVIDE (obj_desc->number.value, + obj_desc2->number.value); break; @@ -360,7 +362,7 @@ acpi_aml_exec_dyadic2_r ( obj_desc2->string.length + 1); if (!new_buf) { REPORT_ERROR - ("Aml_exec_dyadic2_r/Concat_op: String allocation failure"); + (("Aml_exec_dyadic2_r/Concat_op: String allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; } @@ -389,7 +391,7 @@ acpi_aml_exec_dyadic2_r ( obj_desc2->buffer.length); if (!new_buf) { REPORT_ERROR - ("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure"); + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; } @@ -412,7 +414,7 @@ acpi_aml_exec_dyadic2_r ( default: - REPORT_ERROR ("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode %X\n", opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -548,7 +550,7 @@ acpi_aml_exec_dyadic2_s ( default: - REPORT_ERROR ("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -560,7 +562,7 @@ acpi_aml_exec_dyadic2_s ( */ if (status == AE_TIME) { - ret_desc->number.value = (u32)(-1); /* TRUE, op timed out */ + ret_desc->number.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */ status = AE_OK; } @@ -695,7 +697,7 @@ acpi_aml_exec_dyadic2 ( default: - REPORT_ERROR ("Acpi_aml_exec_dyadic2: Unknown dyadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic2: Unknown dyadic opcode %X\n", opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; break; @@ -705,7 +707,7 @@ acpi_aml_exec_dyadic2 ( /* Set return value to logical TRUE (all ones) or FALSE (zero) */ if (lboolean) { - ret_desc->number.value = 0xffffffff; + ret_desc->number.value = ACPI_INTEGER_MAX; } else { ret_desc->number.value = 0; diff --git a/drivers/acpi/interpreter/amfield.c b/drivers/acpi/interpreter/amfield.c index d12770854..356be14c2 100644 --- a/drivers/acpi/interpreter/amfield.c +++ b/drivers/acpi/interpreter/amfield.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amfield - ACPI AML (p-code) execution - field manipulation - * $Revision: 70 $ + * $Revision: 74 $ * *****************************************************************************/ @@ -105,7 +105,7 @@ acpi_aml_setup_field ( /* - * If the address and length have not been previously evaluated, + * If the Region Address and Length have not been previously evaluated, * evaluate them and save the results. */ if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) { @@ -116,6 +116,16 @@ acpi_aml_setup_field ( } } + + if ((obj_desc->common.type == ACPI_TYPE_FIELD_UNIT) && + (!(obj_desc->common.flags & AOPOBJ_DATA_VALID))) + { + /* + * Field Buffer and Index have not been previously evaluated, + */ + return (AE_AML_INTERNAL); + } + if (rgn_desc->region.length < (obj_desc->field.offset & ~((u32) field_byte_width - 1)) + field_byte_width) @@ -213,7 +223,16 @@ acpi_aml_access_named_field ( actual_byte_length = buffer_length; if (buffer_length > byte_field_length) { actual_byte_length = byte_field_length; + } + + /* TBD: should these round down to a power of 2? */ + + if (DIV_8(bit_granularity) > byte_field_length) { + bit_granularity = MUL_8(byte_field_length); + } + if (byte_granularity > byte_field_length) { + byte_granularity = byte_field_length; } diff --git a/drivers/acpi/interpreter/amfldio.c b/drivers/acpi/interpreter/amfldio.c index bdedfda3b..ce877c982 100644 --- a/drivers/acpi/interpreter/amfldio.c +++ b/drivers/acpi/interpreter/amfldio.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amfldio - Aml Field I/O - * $Revision: 26 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -59,7 +59,7 @@ acpi_aml_read_field_data ( { ACPI_STATUS status; ACPI_OPERAND_OBJECT *rgn_desc = NULL; - u32 address; + ACPI_PHYSICAL_ADDRESS address; u32 local_value = 0; u32 field_byte_width; @@ -93,9 +93,6 @@ acpi_aml_read_field_data ( field_byte_offset; - - - /* Invoke the appropriate Address_space/Op_region handler */ status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ, @@ -318,7 +315,7 @@ cleanup: * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_write_field_data ( ACPI_OPERAND_OBJECT *obj_desc, u32 field_byte_offset, @@ -327,7 +324,7 @@ acpi_aml_write_field_data ( { ACPI_STATUS status = AE_OK; ACPI_OPERAND_OBJECT *rgn_desc = NULL; - u32 address; + ACPI_PHYSICAL_ADDRESS address; u32 field_byte_width; @@ -352,8 +349,6 @@ acpi_aml_write_field_data ( (obj_desc->field.offset * field_byte_width) + field_byte_offset; - - /* Invoke the appropriate Address_space/Op_region handler */ status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_WRITE, @@ -379,7 +374,7 @@ acpi_aml_write_field_data ( * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_write_field_data_with_update_rule ( ACPI_OPERAND_OBJECT *obj_desc, u32 mask, diff --git a/drivers/acpi/interpreter/ammisc.c b/drivers/acpi/interpreter/ammisc.c index fb2c4874a..907169dfc 100644 --- a/drivers/acpi/interpreter/ammisc.c +++ b/drivers/acpi/interpreter/ammisc.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: ammisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 67 $ + * $Revision: 71 $ * *****************************************************************************/ @@ -100,6 +100,7 @@ cleanup: /* If we get back from the OS call, we might as well keep going. */ + REPORT_WARNING (("An AML \"fatal\" Opcode (Fatal_op) was executed\n")); return (AE_OK); } @@ -223,7 +224,7 @@ acpi_aml_exec_index ( ret_desc->reference.op_code = AML_INDEX_OP; ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD; ret_desc->reference.object = obj_desc; - ret_desc->reference.offset = idx_desc->number.value; + ret_desc->reference.offset = (u32) idx_desc->number.value; status = acpi_aml_exec_store (ret_desc, res_desc, walk_state); } @@ -320,7 +321,7 @@ acpi_aml_exec_match ( goto cleanup; } - index = start_desc->number.value; + index = (u32) start_desc->number.value; if (index >= (u32) pkg_desc->package.count) { status = AE_AML_PACKAGE_LIMIT; goto cleanup; diff --git a/drivers/acpi/interpreter/ammonad.c b/drivers/acpi/interpreter/ammonad.c index 7c3ba69c4..df9671c06 100644 --- a/drivers/acpi/interpreter/ammonad.c +++ b/drivers/acpi/interpreter/ammonad.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: ammonad - ACPI AML (p-code) execution for monadic operators - * $Revision: 79 $ + * $Revision: 88 $ * *****************************************************************************/ @@ -51,7 +51,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_get_object_reference ( ACPI_OPERAND_OBJECT *obj_desc, ACPI_OPERAND_OBJECT **ret_desc, @@ -180,7 +180,7 @@ acpi_aml_exec_monadic1 ( case AML_SLEEP_OP: - acpi_aml_system_do_suspend (obj_desc->number.value); + acpi_aml_system_do_suspend ((u32) obj_desc->number.value); break; @@ -188,7 +188,7 @@ acpi_aml_exec_monadic1 ( case AML_STALL_OP: - acpi_aml_system_do_stall (obj_desc->number.value); + acpi_aml_system_do_stall ((u32) obj_desc->number.value); break; @@ -196,7 +196,8 @@ acpi_aml_exec_monadic1 ( default: - REPORT_ERROR ("Acpi_aml_exec_monadic1: Unknown monadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_monadic1: Unknown monadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; break; @@ -238,10 +239,9 @@ acpi_aml_exec_monadic2_r ( ACPI_OPERAND_OBJECT *ret_desc2 = NULL; u32 res_val; ACPI_STATUS status; - u32 d0; - u32 d1; - u32 d2; - u32 d3; + u32 i; + u32 j; + ACPI_INTEGER digit; /* Resolve all operands */ @@ -294,11 +294,10 @@ acpi_aml_exec_monadic2_r ( ret_desc->number.value = obj_desc->number.value; /* - * Acpi x1.94 spec, Chapter 16 describes Integer as a 32-bit - * little endian unsigned value, so this boundry condition - * is valid. + * Acpi specification describes Integer type as a little + * endian unsigned value, so this boundry condition is valid. */ - for (res_val = 0; ret_desc->number.value && res_val < 32; ++res_val) { + for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { ret_desc->number.value >>= 1; } @@ -313,16 +312,16 @@ acpi_aml_exec_monadic2_r ( ret_desc->number.value = obj_desc->number.value; /* - * Acpi x1.94 spec, Chapter 16 describes Integer as a 32-bit - * little endian unsigned value, so this boundry condition - * is valid. + * Acpi specification describes Integer type as a little + * endian unsigned value, so this boundry condition is valid. */ - for (res_val = 0; ret_desc->number.value && res_val < 32; ++res_val) { + for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { ret_desc->number.value <<= 1; } - /* Since returns must be 1-based, subtract from 33 */ - ret_desc->number.value = res_val == 0 ? 0 : 33 - res_val; + /* Since returns must be 1-based, subtract from 33 (65) */ + + ret_desc->number.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val; break; @@ -330,17 +329,32 @@ acpi_aml_exec_monadic2_r ( case AML_FROM_BCD_OP: - d0 = (u32) (obj_desc->number.value & 15); - d1 = (u32) (obj_desc->number.value >> 4 & 15); - d2 = (u32) (obj_desc->number.value >> 8 & 15); - d3 = (u32) (obj_desc->number.value >> 12 & 15); + /* + * The 64-bit ACPI integer can hold 16 4-bit BCD integers + */ + ret_desc->number.value = 0; + for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { + /* Get one BCD digit */ - if (d0 > 9 || d1 > 9 || d2 > 9 || d3 > 9) { - status = AE_AML_NUMERIC_OVERFLOW; - goto cleanup; - } + digit = (ACPI_INTEGER) ((obj_desc->number.value >> (i * 4)) & 0xF); + + /* Check the range of the digit */ + + if (digit > 9) { + status = AE_AML_NUMERIC_OVERFLOW; + goto cleanup; + } - ret_desc->number.value = d0 + d1 * 10 + d2 * 100 + d3 * 1000; + if (digit > 0) { + /* Sum into the result with the appropriate power of 10 */ + + for (j = 0; j < i; j++) { + digit *= 10; + } + + ret_desc->number.value += digit; + } + } break; @@ -349,17 +363,26 @@ acpi_aml_exec_monadic2_r ( case AML_TO_BCD_OP: - if (obj_desc->number.value > 9999) { + if (obj_desc->number.value > ACPI_MAX_BCD_VALUE) { status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; } - ret_desc->number.value - = obj_desc->number.value % 10 - + (obj_desc->number.value / 10 % 10 << 4) - + (obj_desc->number.value / 100 % 10 << 8) - + (obj_desc->number.value / 1000 % 10 << 12); + ret_desc->number.value = 0; + for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { + /* Divide by nth factor of 10 */ + digit = obj_desc->number.value; + for (j = 0; j < i; j++) { + digit /= 10; + } + + /* Create the BCD digit */ + + if (digit > 0) { + ret_desc->number.value += (ACPI_MODULO (digit, 10) << (i * 4)); + } + } break; @@ -401,7 +424,7 @@ acpi_aml_exec_monadic2_r ( /* The object exists in the namespace, return TRUE */ - ret_desc->number.value = (u32) -1; + ret_desc->number.value = ACPI_INTEGER_MAX; goto cleanup; break; @@ -466,7 +489,8 @@ acpi_aml_exec_monadic2_r ( default: - REPORT_ERROR ("Acpi_aml_exec_monadic2_r: Unknown monadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_monadic2_r: Unknown monadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -523,7 +547,7 @@ acpi_aml_exec_monadic2 ( ACPI_STATUS resolve_status; ACPI_STATUS status; u32 type; - u32 value; + ACPI_INTEGER value; /* Attempt to resolve the operands */ @@ -693,7 +717,8 @@ acpi_aml_exec_monadic2 ( default: - REPORT_ERROR ("Acpi_aml_exec_monadic2/Type_op:internal error: Unknown Reference subtype"); + REPORT_ERROR (("Acpi_aml_exec_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n", + obj_desc->reference.op_code)); status = AE_AML_INTERNAL; goto cleanup; } @@ -946,7 +971,8 @@ acpi_aml_exec_monadic2 ( default: - REPORT_ERROR ("Acpi_aml_exec_monadic2: Internal error, unknown monadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_monadic2: Unknown monadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff --git a/drivers/acpi/interpreter/amnames.c b/drivers/acpi/interpreter/amnames.c index 00661a43c..ea4c26e08 100644 --- a/drivers/acpi/interpreter/amnames.c +++ b/drivers/acpi/interpreter/amnames.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amnames - interpreter/scanner name load/execute - * $Revision: 70 $ + * $Revision: 71 $ * *****************************************************************************/ @@ -90,7 +90,7 @@ acpi_aml_allocate_name_string ( name_string = acpi_cm_allocate (size_needed); if (!name_string) { - REPORT_ERROR ("Aml_allocate_name_string: name allocation failure"); + REPORT_ERROR (("Aml_allocate_name_string: name allocation failure\n")); return (NULL); } @@ -380,8 +380,8 @@ acpi_aml_get_name_string ( if (AE_CTRL_PENDING == status && has_prefix) { /* Ran out of segments after processing a prefix */ - REPORT_ERROR ("Ran out of segments after processing a prefix"); - + REPORT_ERROR ( + ("Aml_do_name: Malformed Name at %p\n", name_string)); status = AE_AML_BAD_NAME; } diff --git a/drivers/acpi/interpreter/amprep.c b/drivers/acpi/interpreter/amprep.c index 4bdc4f853..266cb0105 100644 --- a/drivers/acpi/interpreter/amprep.c +++ b/drivers/acpi/interpreter/amprep.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 67 $ + * $Revision: 72 $ * *****************************************************************************/ @@ -48,15 +48,27 @@ * ******************************************************************************/ -u32 +static u32 acpi_aml_decode_field_access_type ( - u32 access) + u32 access, + u16 length) { switch (access) { case ACCESS_ANY_ACC: - return (8); + if (length <= 8) { + return (8); + } + else if (length <= 16) { + return (16); + } + else if (length <= 32) { + return (32); + } + else { + return (8); + } break; case ACCESS_BYTE_ACC: @@ -97,7 +109,7 @@ acpi_aml_decode_field_access_type ( * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_prep_common_field_object ( ACPI_OPERAND_OBJECT *obj_desc, u8 field_flags, @@ -131,7 +143,7 @@ acpi_aml_prep_common_field_object ( /* Decode the access type so we can compute offsets */ - granularity = acpi_aml_decode_field_access_type (obj_desc->field.access); + granularity = acpi_aml_decode_field_access_type (obj_desc->field.access, obj_desc->field.length); if (!granularity) { return (AE_AML_OPERAND_VALUE); } diff --git a/drivers/acpi/interpreter/amregion.c b/drivers/acpi/interpreter/amregion.c index 6b89a0aa7..dfe4fab85 100644 --- a/drivers/acpi/interpreter/amregion.c +++ b/drivers/acpi/interpreter/amregion.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amregion - ACPI default Op_region (address space) handlers - * $Revision: 35 $ + * $Revision: 41 $ * *****************************************************************************/ @@ -58,7 +58,7 @@ ACPI_STATUS acpi_aml_system_memory_space_handler ( u32 function, - u32 address, /* TBD: [Future] Should this be A POINTER for 64-bit support? */ + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -98,8 +98,8 @@ acpi_aml_system_memory_space_handler ( * 2) Address beyond the current mapping? */ - if (((u8 *) address < mem_info->mapped_physical_address) || - (((u8 *) address + length) > + if ((address < mem_info->mapped_physical_address) || + ((address + length) > (mem_info->mapped_physical_address + mem_info->mapped_length))) { /* @@ -118,13 +118,15 @@ acpi_aml_system_memory_space_handler ( /* Create a new mapping starting at the address given */ - status = acpi_os_map_memory ((void *) address, SYSMEM_REGION_WINDOW_SIZE, + status = acpi_os_map_memory (address, SYSMEM_REGION_WINDOW_SIZE, (void **) &mem_info->mapped_logical_address); if (ACPI_FAILURE (status)) { return (status); } - mem_info->mapped_physical_address = (u8 *) address; + /* TBD: should these pointers go to 64-bit in all cases ? */ + + mem_info->mapped_physical_address = address; mem_info->mapped_length = SYSMEM_REGION_WINDOW_SIZE; } @@ -134,8 +136,10 @@ acpi_aml_system_memory_space_handler ( * access */ + /* TBD: should these pointers go to 64-bit in all cases ? */ + logical_addr_ptr = mem_info->mapped_logical_address + - ((u8 *) address - mem_info->mapped_physical_address); + (address - mem_info->mapped_physical_address); /* Perform the memory read or write */ @@ -212,7 +216,7 @@ acpi_aml_system_memory_space_handler ( ACPI_STATUS acpi_aml_system_io_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -304,7 +308,7 @@ acpi_aml_system_io_space_handler ( ACPI_STATUS acpi_aml_pci_config_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, diff --git a/drivers/acpi/interpreter/amresnte.c b/drivers/acpi/interpreter/amresnte.c index e2db2bfde..20c6a0b11 100644 --- a/drivers/acpi/interpreter/amresnte.c +++ b/drivers/acpi/interpreter/amresnte.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amresnte - AML Interpreter object resolution - * $Revision: 21 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -65,7 +65,9 @@ ACPI_STATUS acpi_aml_resolve_node_to_value ( - ACPI_NAMESPACE_NODE **stack_ptr) + ACPI_NAMESPACE_NODE **stack_ptr, + ACPI_WALK_STATE *walk_state) + { ACPI_STATUS status = AE_OK; ACPI_OPERAND_OBJECT *val_desc = NULL; @@ -76,7 +78,7 @@ acpi_aml_resolve_node_to_value ( u8 locked; u8 attached_aml_pointer = FALSE; u8 aml_opcode = 0; - u32 temp_val; + ACPI_INTEGER temp_val; OBJECT_TYPE_INTERNAL object_type; @@ -114,8 +116,7 @@ acpi_aml_resolve_node_to_value ( * and Method locals and arguments have a pseudo-Node */ if (entry_type == ACPI_TYPE_DEVICE || - entry_type == INTERNAL_TYPE_METHOD_ARGUMENT || - entry_type == INTERNAL_TYPE_METHOD_LOCAL_VAR) + (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { return (AE_OK); } @@ -174,7 +175,6 @@ acpi_aml_resolve_node_to_value ( obj_desc = val_desc; acpi_cm_add_reference (obj_desc); - break; @@ -211,90 +211,18 @@ acpi_aml_resolve_node_to_value ( case ACPI_TYPE_NUMBER: /* - * An ACPI_TYPE_NUMBER can be either an object or an AML pointer + * The Node has an attached internal object, make sure that it's a + * number */ - if (attached_aml_pointer) { - /* - * The attachment points into the AML stream, get the number from - * there. The actual number is based upon the AML opcode - * - * Note: Word_op and DWord_op will not work properly if the - * processor's endianness does not match the AML's. - */ - - switch (aml_opcode) - { - - case AML_ZERO_OP: - - temp_val = 0; - break; - - - case AML_ONE_OP: - - temp_val = 1; - break; - - - case AML_ONES_OP: - - temp_val = 0xFFFFFFFF; - break; - - - case AML_BYTE_OP: - - temp_val = (u32) ((u8 *) val_desc)[1]; - break; - - - case AML_WORD_OP: - - MOVE_UNALIGNED16_TO_32 (&temp_val, &((u8 *) val_desc)[1]); - break; - - - case AML_DWORD_OP: - - MOVE_UNALIGNED32_TO_32 (&temp_val, &((u8 *) val_desc)[1]); - break; - - - default: - - return (AE_AML_BAD_OPCODE); - - } /* switch */ - - - /* Create and initialize a new object */ - - obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); - if (!obj_desc) { - return (AE_NO_MEMORY); - } - - obj_desc->number.value = temp_val; + if (ACPI_TYPE_NUMBER != val_desc->common.type) { + return (AE_AML_OPERAND_TYPE); } - else { - /* - * The Node has an attached internal object, make sure that it's a - * number - */ - - if (ACPI_TYPE_NUMBER != val_desc->common.type) { - return (AE_AML_OPERAND_TYPE); - } - - /* Return an additional reference to the object */ - - obj_desc = val_desc; - acpi_cm_add_reference (obj_desc); - } + /* Return an additional reference to the object */ + obj_desc = val_desc; + acpi_cm_add_reference (obj_desc); break; @@ -331,7 +259,7 @@ acpi_aml_resolve_node_to_value ( * Fill in the object specific details */ if (ACPI_TYPE_BUFFER == object_type) { - obj_desc->buffer.pointer = acpi_cm_callocate(val_desc->field.length); + obj_desc->buffer.pointer = acpi_cm_callocate (val_desc->field.length); if (!obj_desc->buffer.pointer) { acpi_cm_remove_reference(obj_desc); return (AE_NO_MEMORY); @@ -339,18 +267,15 @@ acpi_aml_resolve_node_to_value ( obj_desc->buffer.length = val_desc->field.length; - status = acpi_aml_access_named_field (ACPI_READ, - (ACPI_HANDLE) node, - obj_desc->buffer.pointer, - obj_desc->buffer.length); + status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node, + obj_desc->buffer.pointer, obj_desc->buffer.length); if (ACPI_FAILURE (status)) { return (status); } } else { - status = acpi_aml_access_named_field (ACPI_READ, - (ACPI_HANDLE) node, + status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node, &temp_val, sizeof (temp_val)); if (ACPI_FAILURE (status)) { @@ -384,8 +309,7 @@ acpi_aml_resolve_node_to_value ( /* perform the update */ status = acpi_aml_access_named_field (ACPI_WRITE, - val_desc->bank_field.bank_select, - &val_desc->bank_field.value, + val_desc->bank_field.bank_select, &val_desc->bank_field.value, sizeof (val_desc->bank_field.value)); acpi_aml_release_global_lock (locked); @@ -404,6 +328,8 @@ acpi_aml_resolve_node_to_value ( return (status); } + /* Create an object for the result */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); if (!obj_desc) { return (AE_NO_MEMORY); @@ -431,10 +357,10 @@ acpi_aml_resolve_node_to_value ( locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule); /* Perform the update */ + status = acpi_aml_access_named_field (ACPI_WRITE, - val_desc->index_field.index, - &val_desc->index_field.value, - sizeof (val_desc->index_field.value)); + val_desc->index_field.index, &val_desc->index_field.value, + sizeof (val_desc->index_field.value)); acpi_aml_release_global_lock (locked); @@ -444,13 +370,14 @@ acpi_aml_resolve_node_to_value ( /* Read Data value */ - status = acpi_aml_access_named_field (ACPI_READ, - val_desc->index_field.data, - &temp_val, sizeof (temp_val)); + status = acpi_aml_access_named_field (ACPI_READ, val_desc->index_field.data, + &temp_val, sizeof (temp_val)); if (ACPI_FAILURE (status)) { return (status); } + /* Create an object for the result */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); if (!obj_desc) { return (AE_NO_MEMORY); @@ -471,6 +398,8 @@ acpi_aml_resolve_node_to_value ( break; } + /* Create object for result */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_ANY); if (!obj_desc) { return (AE_NO_MEMORY); @@ -504,11 +433,61 @@ acpi_aml_resolve_node_to_value ( acpi_cm_add_reference (obj_desc); break; + /* TYPE_Any is untyped, and thus there is no object associated with it */ case ACPI_TYPE_ANY: return (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ + break; + + + /* + * The only named references allowed are named constants + * + * e.g. Name (\OSFL, Ones) + */ + case INTERNAL_TYPE_REFERENCE: + + switch (val_desc->reference.op_code) + { + + case AML_ZERO_OP: + + temp_val = 0; + break; + + + case AML_ONE_OP: + + temp_val = 1; + break; + + + case AML_ONES_OP: + + temp_val = ACPI_INTEGER_MAX; + break; + + + default: + + return (AE_AML_BAD_OPCODE); + } + + /* Create object for result */ + + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + if (!obj_desc) { + return (AE_NO_MEMORY); + } + + obj_desc->number.value = temp_val; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (obj_desc, walk_state); + break; /* Default case is for unknown types */ diff --git a/drivers/acpi/interpreter/amresolv.c b/drivers/acpi/interpreter/amresolv.c index 508b140ab..2fa59e9bb 100644 --- a/drivers/acpi/interpreter/amresolv.c +++ b/drivers/acpi/interpreter/amresolv.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amresolv - AML Interpreter object resolution - * $Revision: 74 $ + * $Revision: 78 $ * *****************************************************************************/ @@ -69,7 +69,14 @@ acpi_aml_get_field_unit_value ( status = AE_AML_NO_OPERAND; } - else if (!field_desc->field_unit.container) { + if (!(field_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_field_unit_arguments (field_desc); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + if (!field_desc->field_unit.container) { status = AE_AML_INTERNAL; } @@ -77,12 +84,6 @@ acpi_aml_get_field_unit_value ( status = AE_AML_OPERAND_TYPE; } - else if (field_desc->field_unit.sequence - != field_desc->field_unit.container->buffer.sequence) - { - status = AE_AML_INTERNAL; - } - else if (!result_desc) { status = AE_AML_INTERNAL; } @@ -114,7 +115,7 @@ acpi_aml_get_field_unit_value ( mask = ((u32) 1 << field_desc->field_unit.length) - (u32) 1; } else { - mask = 0xFFFFFFFF; + mask = ACPI_UINT32_MAX; } result_desc->number.type = (u8) ACPI_TYPE_NUMBER; @@ -186,7 +187,7 @@ acpi_aml_resolve_to_value ( */ if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) { - status = acpi_aml_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr); + status = acpi_aml_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr, walk_state); } @@ -340,7 +341,11 @@ acpi_aml_resolve_object_to_value ( case AML_ONES_OP: stack_desc->common.type = (u8) ACPI_TYPE_NUMBER; - stack_desc->number.value = 0xFFFFFFFF; + stack_desc->number.value = ACPI_INTEGER_MAX; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (stack_desc, walk_state); break; diff --git a/drivers/acpi/interpreter/amresop.c b/drivers/acpi/interpreter/amresop.c index 4c67e5215..83fda4455 100644 --- a/drivers/acpi/interpreter/amresop.c +++ b/drivers/acpi/interpreter/amresop.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amresop - AML Interpreter operand/object resolution - * $Revision: 15 $ + * $Revision: 18 $ * *****************************************************************************/ @@ -41,6 +41,44 @@ /******************************************************************************* * + * FUNCTION: Acpi_aml_check_object_type + * + * PARAMETERS: Type_needed Object type needed + * This_type Actual object type + * Object Object pointer + * + * RETURN: Status + * + * DESCRIPTION: Check required type against actual type + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_check_object_type ( + ACPI_OBJECT_TYPE type_needed, + ACPI_OBJECT_TYPE this_type, + void *object) +{ + + + if (type_needed == ACPI_TYPE_ANY) { + /* All types OK, so we don't perform any typechecks */ + + return (AE_OK); + } + + + if (type_needed != this_type) { + return (AE_AML_OPERAND_TYPE); + } + + + return (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_aml_resolve_operands * * PARAMETERS: Opcode Opcode being interpreted @@ -71,6 +109,7 @@ acpi_aml_resolve_operands ( u32 arg_types; ACPI_OPCODE_INFO *op_info; u32 this_arg_type; + ACPI_OBJECT_TYPE type_needed; op_info = acpi_ps_get_opcode_info (opcode); @@ -81,8 +120,7 @@ acpi_aml_resolve_operands ( arg_types = op_info->runtime_args; if (arg_types == ARGI_INVALID_OPCODE) { - status = AE_AML_INTERNAL; - goto cleanup; + return (AE_AML_INTERNAL); } @@ -96,8 +134,7 @@ acpi_aml_resolve_operands ( while (GET_CURRENT_ARG_TYPE (arg_types)) { if (!stack_ptr || !*stack_ptr) { - status = AE_AML_INTERNAL; - goto cleanup; + return (AE_AML_INTERNAL); } /* Extract useful items */ @@ -120,8 +157,7 @@ acpi_aml_resolve_operands ( /* Check for bad ACPI_OBJECT_TYPE */ if (!acpi_aml_validate_object_type (object_type)) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; + return (AE_AML_OPERAND_TYPE); } if (object_type == (u8) INTERNAL_TYPE_REFERENCE) { @@ -149,30 +185,32 @@ acpi_aml_resolve_operands ( break; default: - status = AE_AML_OPERAND_TYPE; - goto cleanup; + return (AE_AML_OPERAND_TYPE); break; } } - } else { /* Invalid descriptor */ - status = AE_AML_OPERAND_TYPE; - goto cleanup; + return (AE_AML_OPERAND_TYPE); } /* - * Decode a character from the type string + * Get one argument type, point to the next */ this_arg_type = GET_CURRENT_ARG_TYPE (arg_types); INCREMENT_ARG_LIST (arg_types); + /* + * Handle cases where the object does not need to be + * resolved to a value + */ + switch (this_arg_type) { @@ -182,14 +220,16 @@ acpi_aml_resolve_operands ( /* Need an operand of type INTERNAL_TYPE_REFERENCE */ if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) /* direct name ptr OK as-is */ { - break; + goto next_operand; } - if (INTERNAL_TYPE_REFERENCE != object_type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; + status = acpi_aml_check_object_type (INTERNAL_TYPE_REFERENCE, + object_type, obj_desc); + if (ACPI_FAILURE (status)) { + return (status); } + if (AML_NAME_OP == obj_desc->reference.op_code) { /* * Convert an indirect name ptr to direct name ptr and put @@ -200,159 +240,120 @@ acpi_aml_resolve_operands ( acpi_cm_remove_reference (obj_desc); (*stack_ptr) = temp_handle; } - break; + goto next_operand; + break; - case ARGI_NUMBER: /* Number */ - /* Need an operand of type ACPI_TYPE_NUMBER */ + case ARGI_ANYTYPE: - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } + /* + * We don't want to resolve Index_op reference objects during + * a store because this would be an implicit De_ref_of operation. + * Instead, we just want to store the reference object. + * -- All others must be resolved below. + */ - if (ACPI_TYPE_NUMBER != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; + if ((opcode == AML_STORE_OP) && + ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) && + ((*stack_ptr)->reference.op_code == AML_INDEX_OP)) + { + goto next_operand; } break; + } - case ARGI_STRING: + /* + * Resolve this object to a value + */ - /* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */ + status = acpi_aml_resolve_to_value (stack_ptr, walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) && - (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type)) - { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - break; + /* + * Check the resulting object (value) type + */ + switch (this_arg_type) + { + /* + * For the simple cases, only one type of resolved object + * is allowed + */ + case ARGI_NUMBER: /* Number */ + + /* Need an operand of type ACPI_TYPE_NUMBER */ + type_needed = ACPI_TYPE_NUMBER; + break; case ARGI_BUFFER: /* Need an operand of type ACPI_TYPE_BUFFER */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - if (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + type_needed = ACPI_TYPE_BUFFER; break; - case ARGI_MUTEX: /* Need an operand of type ACPI_TYPE_MUTEX */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - if (ACPI_TYPE_MUTEX != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + type_needed = ACPI_TYPE_MUTEX; break; - case ARGI_EVENT: /* Need an operand of type ACPI_TYPE_EVENT */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - if (ACPI_TYPE_EVENT != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + type_needed = ACPI_TYPE_EVENT; break; - case ARGI_REGION: /* Need an operand of type ACPI_TYPE_REGION */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - if (ACPI_TYPE_REGION != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + type_needed = ACPI_TYPE_REGION; break; - - case ARGI_IF: /* If */ + case ARGI_IF: /* If */ /* Need an operand of type INTERNAL_TYPE_IF */ - if (INTERNAL_TYPE_IF != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + type_needed = INTERNAL_TYPE_IF; break; - case ARGI_PACKAGE: /* Package */ /* Need an operand of type ACPI_TYPE_PACKAGE */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - if (ACPI_TYPE_PACKAGE != (*stack_ptr)->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + type_needed = ACPI_TYPE_PACKAGE; break; - case ARGI_ANYTYPE: + /* Any operand type will do */ - /* - * We don't want to resolve Index_op reference objects during - * a store because this would be an implicit De_ref_of operation. - * Instead, we just want to store the reference object. - */ + type_needed = ACPI_TYPE_ANY; + break; - if ((opcode == AML_STORE_OP) && - ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) && - ((*stack_ptr)->reference.op_code == AML_INDEX_OP)) - { - break; - } - /* All others must be resolved */ + /* + * The more complex cases allow multiple resolved object types + */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } + case ARGI_STRING: - /* All types OK, so we don't perform any typechecks */ + /* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */ + if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) && + (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type)) + { + return (AE_AML_OPERAND_TYPE); + } + goto next_operand; break; @@ -366,11 +367,6 @@ acpi_aml_resolve_operands ( * error with a size of 4. */ - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - /* Need a buffer, string, package or Node reference */ if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) && @@ -378,8 +374,7 @@ acpi_aml_resolve_operands ( ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) && ((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE)) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; + return (AE_AML_OPERAND_TYPE); } /* @@ -387,44 +382,49 @@ acpi_aml_resolve_operands ( */ if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) { if (!(*stack_ptr)->reference.node) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; + return (AE_AML_OPERAND_TYPE); } } - + goto next_operand; break; case ARGI_COMPLEXOBJ: - status = acpi_aml_resolve_to_value (stack_ptr, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - /* Need a buffer or package */ if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) && ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE)) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; + return (AE_AML_OPERAND_TYPE); } + goto next_operand; break; - /* Unknown abbreviation passed in */ - default: - status = AE_BAD_PARAMETER; - goto cleanup; - } /* switch (*Types++) */ + /* Unknown type */ + return (AE_BAD_PARAMETER); + } + + + /* + * Make sure that the original object was resolved to the + * required object type (Simple cases only). + */ + status = acpi_aml_check_object_type (type_needed, + (*stack_ptr)->common.type, *stack_ptr); + if (ACPI_FAILURE (status)) { + return (status); + } + +next_operand: /* * If more operands needed, decrement Stack_ptr to point - * to next operand on stack (after checking for underflow). + * to next operand on stack */ if (GET_CURRENT_ARG_TYPE (arg_types)) { stack_ptr--; @@ -433,9 +433,7 @@ acpi_aml_resolve_operands ( } /* while (*Types) */ -cleanup: - - return (status); + return (status); } diff --git a/drivers/acpi/interpreter/amstore.c b/drivers/acpi/interpreter/amstore.c index f7f34cb4f..8887e0997 100644 --- a/drivers/acpi/interpreter/amstore.c +++ b/drivers/acpi/interpreter/amstore.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amstore - AML Interpreter object store support - * $Revision: 116 $ + * $Revision: 117 $ * *****************************************************************************/ diff --git a/drivers/acpi/interpreter/amstoren.c b/drivers/acpi/interpreter/amstoren.c index 123f791ad..91b2095c5 100644 --- a/drivers/acpi/interpreter/amstoren.c +++ b/drivers/acpi/interpreter/amstoren.c @@ -3,7 +3,7 @@ * * Module Name: amstoren - AML Interpreter object store support, * Store to Node (namespace object) - * $Revision: 21 $ + * $Revision: 24 $ * *****************************************************************************/ @@ -430,10 +430,20 @@ acpi_aml_store_object_to_node ( case ACPI_TYPE_FIELD_UNIT: + + /* + * If the Field Buffer and Index have not been previously evaluated, + * evaluate them and save the results. + */ + if (!(dest_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_field_unit_arguments (dest_desc); + if (ACPI_FAILURE (status)) { + return (status); + } + } + if ((!dest_desc->field_unit.container || - ACPI_TYPE_BUFFER != dest_desc->field_unit.container->common.type || - dest_desc->field_unit.sequence != - dest_desc->field_unit.container->buffer.sequence)) + ACPI_TYPE_BUFFER != dest_desc->field_unit.container->common.type)) { status = AE_AML_INTERNAL; goto clean_up_and_bail_out; @@ -487,7 +497,12 @@ acpi_aml_store_object_to_node ( case ACPI_TYPE_NUMBER: + dest_desc->number.value = val_desc->number.value; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (dest_desc, walk_state); break; diff --git a/drivers/acpi/interpreter/amstorob.c b/drivers/acpi/interpreter/amstorob.c index 734e49b15..f3a098bd2 100644 --- a/drivers/acpi/interpreter/amstorob.c +++ b/drivers/acpi/interpreter/amstorob.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amstorob - AML Interpreter object store support, store to object - * $Revision: 16 $ + * $Revision: 18 $ * *****************************************************************************/ @@ -294,6 +294,10 @@ acpi_aml_store_object_to_object ( case ACPI_TYPE_NUMBER: dest_desc->number.value = val_desc->number.value; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (dest_desc, walk_state); break; default: diff --git a/drivers/acpi/interpreter/amsystem.c b/drivers/acpi/interpreter/amsystem.c index 8bfe5a1cb..9ad72c161 100644 --- a/drivers/acpi/interpreter/amsystem.c +++ b/drivers/acpi/interpreter/amsystem.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amsystem - Interface to OS services - * $Revision: 51 $ + * $Revision: 52 $ * *****************************************************************************/ @@ -202,7 +202,7 @@ acpi_aml_system_acquire_mutex ( } status = acpi_aml_system_wait_semaphore (obj_desc->mutex.semaphore, - time_desc->number.value); + (u32) time_desc->number.value); return (status); } @@ -299,7 +299,7 @@ acpi_aml_system_wait_event ( if (obj_desc) { status = acpi_aml_system_wait_semaphore (obj_desc->event.semaphore, - time_desc->number.value); + (u32) time_desc->number.value); } diff --git a/drivers/acpi/interpreter/amutils.c b/drivers/acpi/interpreter/amutils.c index e88885652..4e1359888 100644 --- a/drivers/acpi/interpreter/amutils.c +++ b/drivers/acpi/interpreter/amutils.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amutils - interpreter/scanner utilities - * $Revision: 53 $ + * $Revision: 66 $ * *****************************************************************************/ @@ -131,24 +131,44 @@ acpi_aml_validate_object_type ( /******************************************************************************* * - * FUNCTION: Acpi_aml_buf_seq + * FUNCTION: Acpi_aml_truncate_for32bit_table * - * RETURN: The next buffer descriptor sequence number + * PARAMETERS: Obj_desc - Object to be truncated + * Walk_state - Current walk state + * (A method must be executing) * - * DESCRIPTION: Provide a unique sequence number for each Buffer descriptor - * allocated during the interpreter's existence. These numbers - * are used to relate Field_unit descriptors to the Buffers - * within which the fields are defined. + * RETURN: none * - * Just increment the global counter and return it. + * DESCRIPTION: Truncate a number to 32-bits if the currently executing method + * belongs to a 32-bit ACPI table. * ******************************************************************************/ -u32 -acpi_aml_buf_seq (void) +void +acpi_aml_truncate_for32bit_table ( + ACPI_OPERAND_OBJECT *obj_desc, + ACPI_WALK_STATE *walk_state) { - return (++acpi_gbl_buf_seq); + /* + * Object must be a valid number and we must be executing + * a control method + */ + + if ((!obj_desc) || + (obj_desc->common.type != ACPI_TYPE_NUMBER) || + (!walk_state->method_node)) + { + return; + } + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + /* + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper 32-bit field + */ + obj_desc->number.value &= (ACPI_INTEGER) ACPI_UINT32_MAX; + } } @@ -242,20 +262,18 @@ acpi_aml_release_global_lock ( u32 acpi_aml_digits_needed ( - u32 val, + ACPI_INTEGER val, u32 base) { u32 num_digits = 0; if (base < 1) { - /* impossible base */ - - REPORT_ERROR ("Aml_digits_needed: Impossible base"); + REPORT_ERROR (("Aml_digits_needed: Internal error - Invalid base\n")); } else { - for (num_digits = 1 + (val < 0) ; val /= base ; ++num_digits) { ; } + for (num_digits = 1 + (val < 0); (val = ACPI_DIVIDE (val,base)); ++num_digits) { ; } } return (num_digits); @@ -268,11 +286,11 @@ acpi_aml_digits_needed ( * * PARAMETERS: Value - Value to be converted * - * RETURN: Convert a 32-bit value to big-endian (swap the bytes) + * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) * ******************************************************************************/ -u32 +static u32 _ntohl ( u32 value) { @@ -307,7 +325,7 @@ _ntohl ( * PARAMETERS: Numeric_id - EISA ID to be converted * Out_string - Where to put the converted string (8 bytes) * - * RETURN: Convert a numeric EISA ID to string representation + * DESCRIPTION: Convert a numeric EISA ID to string representation * ******************************************************************************/ @@ -337,6 +355,39 @@ acpi_aml_eisa_id_to_string ( /******************************************************************************* * + * FUNCTION: Acpi_aml_unsigned_integer_to_string + * + * PARAMETERS: Value - Value to be converted + * Out_string - Where to put the converted string (8 bytes) + * + * RETURN: Convert a number to string representation + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_unsigned_integer_to_string ( + ACPI_INTEGER value, + NATIVE_CHAR *out_string) +{ + u32 count; + u32 digits_needed; + + + digits_needed = acpi_aml_digits_needed (value, 10); + + out_string[digits_needed] = '\0'; + + for (count = digits_needed; count > 0; count--) { + out_string[count-1] = (NATIVE_CHAR) ('0' + (ACPI_MODULO (value, 10))); + value = ACPI_DIVIDE (value, 10); + } + + return (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_aml_build_copy_internal_package_object * * PARAMETERS: *Source_obj - Pointer to the source package object @@ -376,8 +427,8 @@ acpi_aml_build_copy_internal_package_object ( level_ptr = ©_level[0]; current_depth = 0; - dest_obj->common.type = source_obj->common.type; - dest_obj->package.count = source_obj->package.count; + dest_obj->common.type = source_obj->common.type; + dest_obj->package.count = source_obj->package.count; /* @@ -391,7 +442,7 @@ acpi_aml_build_copy_internal_package_object ( if (!dest_obj->package.elements) { /* Package vector allocation failure */ - REPORT_ERROR ("Aml_build_copy_internal_package_object: Package vector allocation failure"); + REPORT_ERROR (("Aml_build_copy_internal_package_object: Package vector allocation failure\n")); return (AE_NO_MEMORY); } @@ -400,8 +451,8 @@ acpi_aml_build_copy_internal_package_object ( while (1) { this_index = level_ptr->index; - this_dest_obj = (ACPI_OPERAND_OBJECT *) level_ptr->dest_obj->package.elements[this_index]; - this_source_obj = (ACPI_OPERAND_OBJECT *) level_ptr->source_obj->package.elements[this_index]; + this_dest_obj = (ACPI_OPERAND_OBJECT *) level_ptr->dest_obj->package.elements[this_index]; + this_source_obj = (ACPI_OPERAND_OBJECT *) level_ptr->source_obj->package.elements[this_index]; if (IS_THIS_OBJECT_TYPE (this_source_obj, ACPI_TYPE_PACKAGE)) { /* diff --git a/drivers/acpi/ksyms.c b/drivers/acpi/ksyms.c new file mode 100644 index 000000000..13f4fe0e7 --- /dev/null +++ b/drivers/acpi/ksyms.c @@ -0,0 +1,91 @@ +/* + * ksyms.c - ACPI exported symbols + * + * Copyright (C) 2000 Andrew Grover + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/acpi.h> +#include "acpi.h" +#include "acdebug.h" + +extern int acpi_in_debugger; + +#define _COMPONENT OS_DEPENDENT + MODULE_NAME ("symbols") + +#ifdef ENABLE_DEBUGGER +EXPORT_SYMBOL(acpi_in_debugger); +EXPORT_SYMBOL(acpi_db_user_commands); +#endif + +EXPORT_SYMBOL(acpi_os_free); +EXPORT_SYMBOL(acpi_os_breakpoint); +EXPORT_SYMBOL(acpi_os_printf); +EXPORT_SYMBOL(acpi_os_callocate); +EXPORT_SYMBOL(acpi_os_sleep); +EXPORT_SYMBOL(acpi_os_sleep_usec); +EXPORT_SYMBOL(acpi_os_in8); +EXPORT_SYMBOL(acpi_os_out8); +EXPORT_SYMBOL(acpi_os_queue_for_execution); + +EXPORT_SYMBOL(acpi_dbg_layer); +EXPORT_SYMBOL(acpi_dbg_level); +EXPORT_SYMBOL(function_exit); +EXPORT_SYMBOL(function_trace); +EXPORT_SYMBOL(function_status_exit); +EXPORT_SYMBOL(function_value_exit); +EXPORT_SYMBOL(debug_print_raw); +EXPORT_SYMBOL(debug_print_prefix); + +EXPORT_SYMBOL(acpi_cm_strncmp); +EXPORT_SYMBOL(acpi_cm_memcpy); +EXPORT_SYMBOL(acpi_cm_memset); + +EXPORT_SYMBOL(acpi_get_handle); +EXPORT_SYMBOL(acpi_get_parent); +EXPORT_SYMBOL(acpi_get_type); +EXPORT_SYMBOL(acpi_get_name); +EXPORT_SYMBOL(acpi_get_object_info); +EXPORT_SYMBOL(acpi_get_next_object); +EXPORT_SYMBOL(acpi_evaluate_object); + +EXPORT_SYMBOL(acpi_install_notify_handler); +EXPORT_SYMBOL(acpi_remove_notify_handler); +EXPORT_SYMBOL(acpi_install_gpe_handler); +EXPORT_SYMBOL(acpi_remove_gpe_handler); +EXPORT_SYMBOL(acpi_install_address_space_handler); +EXPORT_SYMBOL(acpi_remove_address_space_handler); + +EXPORT_SYMBOL(acpi_get_current_resources); +EXPORT_SYMBOL(acpi_get_possible_resources); +EXPORT_SYMBOL(acpi_set_current_resources); + +EXPORT_SYMBOL(acpi_enable_event); +EXPORT_SYMBOL(acpi_disable_event); +EXPORT_SYMBOL(acpi_clear_event); + +EXPORT_SYMBOL(acpi_get_processor_throttling_info); +EXPORT_SYMBOL(acpi_get_processor_throttling_state); +EXPORT_SYMBOL(acpi_set_processor_throttling_state); + +EXPORT_SYMBOL(acpi_get_processor_cx_info); +EXPORT_SYMBOL(acpi_set_processor_sleep_state); +EXPORT_SYMBOL(acpi_processor_sleep); diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/namespace/Makefile +++ b/drivers/acpi/namespace/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index e04ffe4e9..27c02e22a 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 108 $ + * $Revision: 117 $ * ******************************************************************************/ @@ -87,8 +87,6 @@ acpi_ns_root_initialize (void) IMODE_LOAD_PASS2, NS_NO_UPSEARCH, NULL, &new_node); - if (ACPI_FAILURE (status) || - (!new_node)) /* * Name entered successfully. @@ -122,7 +120,7 @@ acpi_ns_root_initialize (void) case ACPI_TYPE_NUMBER: obj_desc->number.value = - (u32) STRTOUL (init_val->val, NULL, 10); + (ACPI_INTEGER) STRTOUL (init_val->val, NULL, 10); break; @@ -138,11 +136,7 @@ acpi_ns_root_initialize (void) */ obj_desc->string.pointer = acpi_cm_allocate ( (obj_desc->string.length + 1)); - if (!obj_desc->string.pointer) { - REPORT_ERROR ("Initial value string" - "allocation failure"); - acpi_cm_remove_reference (obj_desc); status = AE_NO_MEMORY; goto unlock_and_exit; @@ -190,7 +184,8 @@ acpi_ns_root_initialize (void) default: - REPORT_ERROR ("Unsupported initial type value"); + REPORT_ERROR (("Unsupported initial type value %X\n", + init_val->type)); acpi_cm_remove_reference (obj_desc); obj_desc = NULL; continue; @@ -214,14 +209,14 @@ unlock_and_exit: * * FUNCTION: Acpi_ns_lookup * - * PARAMETERS: Prefix_node - Search scope if name is not fully qualified + * PARAMETERS: Prefix_node - Search scope if name is not fully qualified * Pathname - Search pathname, in internal format * (as represented in the AML stream) * Type - Type associated with name * Interpreter_mode - IMODE_LOAD_PASS2 => add name if not found * Flags - Flags describing the search restrictions * Walk_state - Current state of the walk - * Return_node - Where the Node is placed (if found + * Return_node - Where the Node is placed (if found * or created successfully) * * RETURN: Status @@ -254,6 +249,9 @@ acpi_ns_lookup ( OBJECT_TYPE_INTERNAL type_to_check_for; OBJECT_TYPE_INTERNAL this_search_type; + DEBUG_ONLY_MEMBERS (u32 i) + + if (!return_node) { return (AE_BAD_PARAMETER); } @@ -379,8 +377,7 @@ acpi_ns_lookup ( if (!this_node) { /* Current scope has no parent scope */ - REPORT_ERROR ("Too many parent prefixes (^) - reached root"); - + REPORT_ERROR (("Too many parent prefixes (^) - reached root\n")); return (AE_NOT_FOUND); } @@ -442,7 +439,7 @@ acpi_ns_lookup ( this_search_type = type; } - /* Pluck and ACPI name from the front of the pathname */ + /* Pluck one ACPI name from the front of the pathname */ MOVE_UNALIGNED32_TO_32 (&simple_name, pathname); @@ -467,25 +464,29 @@ acpi_ns_lookup ( * If 1) This is the last segment (Num_segments == 0) * 2) and looking for a specific type * (Not checking for TYPE_ANY) - * 3) which is not a local type (TYPE_DEF_ANY) - * 4) which is not a local type (TYPE_SCOPE) - * 5) which is not a local type (TYPE_INDEX_FIELD_DEFN) - * 6) and type of object is known (not TYPE_ANY) - * 7) and object does not match request + * 3) Which is not an alias + * 4) which is not a local type (TYPE_DEF_ANY) + * 5) which is not a local type (TYPE_SCOPE) + * 6) which is not a local type (TYPE_INDEX_FIELD_DEFN) + * 7) and type of object is known (not TYPE_ANY) + * 8) and object does not match request * * Then we have a type mismatch. Just warn and ignore it. */ if ((num_segments == 0) && (type_to_check_for != ACPI_TYPE_ANY) && + (type_to_check_for != INTERNAL_TYPE_ALIAS) && (type_to_check_for != INTERNAL_TYPE_DEF_ANY) && (type_to_check_for != INTERNAL_TYPE_SCOPE) && (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) && - (this_node->type != ACPI_TYPE_ANY) && - (this_node->type != type_to_check_for)) + (this_node->type != ACPI_TYPE_ANY) && + (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ - REPORT_WARNING ("Type mismatch"); + REPORT_WARNING ( + ("Ns_lookup: %4.4s, type %X, checking for type %X\n", + &simple_name, this_node->type, type_to_check_for)); } /* diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 0b8272724..9f1d5377e 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 41 $ + * $Revision: 43 $ * ******************************************************************************/ @@ -434,7 +434,7 @@ acpi_ns_delete_namespace_subtree ( * ******************************************************************************/ -void +static void acpi_ns_remove_reference ( ACPI_NAMESPACE_NODE *node) { diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c deleted file mode 100644 index 117af81e3..000000000 --- a/drivers/acpi/namespace/nsdump.c +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** - * - * Module Name: nsdump - table dumping routines for debug - * $Revision: 78 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" - - -#define _COMPONENT NAMESPACE - MODULE_NAME ("nsdump") - - diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 2df17e94f..fbba7840c 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -2,7 +2,7 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 76 $ + * $Revision: 79 $ * ******************************************************************************/ @@ -99,7 +99,7 @@ acpi_ns_evaluate_relative ( /* Lookup the name in the namespace */ - scope_info.scope.node = prefix_node->child; + scope_info.scope.node = prefix_node; status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); @@ -432,28 +432,14 @@ acpi_ns_get_object_value ( } /* - * Just copy from the original to the return object + * Just copy from the original to the return object + * + * TBD: [Future] - need a low-level object copy that handles + * the reference count automatically. (Don't want to copy it) */ - switch (node->type) - { - case ACPI_TYPE_PROCESSOR: - obj_desc->processor.proc_id = val_desc->processor.proc_id; - obj_desc->processor.address = val_desc->processor.address; - obj_desc->processor.sys_handler = val_desc->processor.sys_handler; - obj_desc->processor.drv_handler = val_desc->processor.drv_handler; - obj_desc->processor.addr_handler = val_desc->processor.addr_handler; - - break; - - case ACPI_TYPE_POWER: - obj_desc->power_resource.system_level = val_desc->power_resource.system_level; - obj_desc->power_resource.resource_order = val_desc->power_resource.resource_order; - obj_desc->power_resource.sys_handler = val_desc->power_resource.sys_handler; - obj_desc->power_resource.drv_handler = val_desc->power_resource.drv_handler; - - break; - } + MEMCPY (obj_desc, val_desc, sizeof (ACPI_OPERAND_OBJECT)); + obj_desc->common.reference_count = 1; } @@ -483,9 +469,17 @@ acpi_ns_get_object_value ( * NOTE: we can get away with passing in NULL for a walk state * because Obj_desc is guaranteed to not be a reference to either * a method local or a method argument + * + * Even though we do not technically need to use the interpreter + * for this, we must enter it because we could hit an opregion. + * The opregion access code assumes it is in the interpreter. */ + acpi_aml_enter_interpreter(); + status = acpi_aml_resolve_to_value (&obj_desc, NULL); + + acpi_aml_exit_interpreter(); } /* diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c new file mode 100644 index 000000000..ddacd7b8c --- /dev/null +++ b/drivers/acpi/namespace/nsinit.c @@ -0,0 +1,271 @@ +/****************************************************************************** + * + * Module Name: nsinit - namespace initialization + * $Revision: 9 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "acnamesp.h" +#include "acdispat.h" + +#define _COMPONENT NAMESPACE + MODULE_NAME ("nsinit") + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_initialize_objects + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Walk the entire namespace and perform any necessary + * initialization on the objects found therein + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_initialize_objects ( + void) +{ + ACPI_STATUS status; + ACPI_INIT_WALK_INFO info; + + + info.field_count = 0; + info.field_init = 0; + info.op_region_count = 0; + info.op_region_init = 0; + info.object_count = 0; + + + /* Walk entire namespace from the supplied root */ + + status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, acpi_ns_init_one_object, + &info, NULL); + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_ns_initialize_devices + * + * PARAMETERS: None + * + * RETURN: ACPI_STATUS + * + * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. + * This means running _INI on all present devices. + * + * Also: Install PCI config space handler for all PCI root bridges. + * A PCI root bridge is found by searching for devices containing + * a HID with the value EISAID("PNP0A03") + * + *****************************************************************************/ + +ACPI_STATUS +acpi_ns_initialize_devices ( + u32 flags) +{ + ACPI_STATUS status; + ACPI_DEVICE_WALK_INFO info; + + + info.flags = flags; + info.device_count = 0; + info.num_STA = 0; + info.num_INI = 0; + + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + FALSE, acpi_ns_init_one_device, &info, NULL); + + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_init_one_object + * + * PARAMETERS: Obj_handle - Node + * Level - Current nesting level + * Context - Points to a init info struct + * Return_value - Not used + * + * RETURN: Status + * + * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object + * within the namespace. + * + * Currently, the only objects that require initialization are: + * 1) Methods + * 2) Op Regions + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_init_one_object ( + ACPI_HANDLE obj_handle, + u32 level, + void *context, + void **return_value) +{ + OBJECT_TYPE_INTERNAL type; + ACPI_STATUS status; + ACPI_INIT_WALK_INFO *info = (ACPI_INIT_WALK_INFO *) context; + ACPI_NAMESPACE_NODE *node = (ACPI_NAMESPACE_NODE *) obj_handle; + ACPI_OPERAND_OBJECT *obj_desc; + + + info->object_count++; + + + /* And even then, we are only interested in a few object types */ + + type = acpi_ns_get_type (obj_handle); + obj_desc = node->object; + if (!obj_desc) { + return (AE_OK); + } + + switch (type) + { + + case ACPI_TYPE_REGION: + + info->op_region_count++; + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + break; + } + + info->op_region_init++; + status = acpi_ds_get_region_arguments (obj_desc); + + break; + + + case ACPI_TYPE_FIELD_UNIT: + + info->field_count++; + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + break; + } + + info->field_init++; + status = acpi_ds_get_field_unit_arguments (obj_desc); + break; + + default: + break; + } + + /* + * We ignore errors from above, and always return OK, since + * we don't want to abort the walk on a single error. + */ + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_ns_init_one_device + * + * PARAMETERS: The usual "I'm a namespace callback" stuff + * + * RETURN: ACPI_STATUS + * + * DESCRIPTION: This is called once per device soon after ACPI is enabled + * to initialize each device. It determines if the device is + * present, and if so, calls _INI. + * + *****************************************************************************/ + +ACPI_STATUS +acpi_ns_init_one_device ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_NAMESPACE_NODE *node; + u32 flags; + ACPI_DEVICE_WALK_INFO *info = (ACPI_DEVICE_WALK_INFO *) context; + + + info->device_count++; + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + + node = acpi_ns_convert_handle_to_entry (obj_handle); + if (!node) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + /* + * Run _STA to determine if we can run _INI on the device. + */ + + status = acpi_cm_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (status); + } + + info->num_STA++; + + if (!(flags & 0x01)) { + /* don't look at children of a not present device */ + return(AE_CTRL_DEPTH); + } + + /* + * The device is present. Run _INI. + */ + + status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); + if (AE_NOT_FOUND == status) { + /* No _INI means device requires no initialization */ + status = AE_OK; + } + + else if (ACPI_FAILURE (status)) { + return (status); + } + + else { + info->num_INI++; + } + + return (status); +} diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 8faa8ea4f..28a26376d 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 28 $ + * $Revision: 33 $ * *****************************************************************************/ @@ -37,6 +37,123 @@ MODULE_NAME ("nsload") +/****************************************************************************** + * + * FUNCTION: Acpi_load_namespace + * + * PARAMETERS: Display_aml_during_load + * + * RETURN: Status + * + * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. + * (DSDT points to either the BIOS or a buffer.) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_load_namespace ( + void) +{ + ACPI_STATUS status; + + + /* There must be at least a DSDT installed */ + + if (acpi_gbl_DSDT == NULL) { + return (AE_NO_ACPI_TABLES); + } + + + /* + * Load the namespace. The DSDT is required, + * but the SSDT and PSDT tables are optional. + */ + + status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Ignore exceptions from these */ + + acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); + acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_one_parse_pass + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_one_complete_parse ( + u32 pass_number, + ACPI_TABLE_DESC *table_desc) +{ + ACPI_PARSE_DOWNWARDS descending_callback; + ACPI_PARSE_UPWARDS ascending_callback; + ACPI_PARSE_OBJECT *parse_root; + ACPI_STATUS status; + + + switch (pass_number) + { + case 1: + descending_callback = acpi_ds_load1_begin_op; + ascending_callback = acpi_ds_load1_end_op; + break; + + case 2: + descending_callback = acpi_ds_load2_begin_op; + ascending_callback = acpi_ds_load2_end_op; + break; + + case 3: + descending_callback = acpi_ds_exec_begin_op; + ascending_callback = acpi_ds_exec_end_op; + break; + + default: + return (AE_BAD_PARAMETER); + } + + /* Create and init a Root Node */ + + parse_root = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!parse_root) { + return (AE_NO_MEMORY); + } + + ((ACPI_PARSE2_OBJECT *) parse_root)->name = ACPI_ROOT_NAME; + + + /* Pass 1: Parse everything except control method bodies */ + + status = acpi_ps_parse_aml (parse_root, + table_desc->aml_pointer, + table_desc->aml_length, + ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, + NULL, NULL, NULL, + descending_callback, + ascending_callback); + + acpi_ps_delete_parse_tree (parse_root); + + return (status); +} + + /******************************************************************************* * * FUNCTION: Acpi_ns_parse_table @@ -69,32 +186,11 @@ acpi_ns_parse_table ( * performs another complete parse of the AML.. */ - /* Create and init a Root Node */ - - acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!acpi_gbl_parsed_namespace_root) { - return (AE_NO_MEMORY); - } - - ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME; - - - /* Pass 1: Parse everything except control method bodies */ - - status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root, - table_desc->aml_pointer, - table_desc->aml_length, - ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, - NULL, NULL, NULL, - acpi_ds_load1_begin_op, - acpi_ds_load1_end_op); - + status = acpi_ns_one_complete_parse (1, table_desc); if (ACPI_FAILURE (status)) { return (status); } - acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root); - /* * AML Parse, pass 2 @@ -106,34 +202,11 @@ acpi_ns_parse_table ( * parse objects are all cached. */ - /* Create and init a Root Node */ - - acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!acpi_gbl_parsed_namespace_root) { - return (AE_NO_MEMORY); - } - - ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME; - - - /* Pass 2: Resolve forward references */ - - status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root, - table_desc->aml_pointer, - table_desc->aml_length, - ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, - NULL, NULL, NULL, - acpi_ds_load2_begin_op, - acpi_ds_load2_end_op); - + status = acpi_ns_one_complete_parse (2, table_desc); if (ACPI_FAILURE (status)) { return (status); } - acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root); - acpi_gbl_parsed_namespace_root = NULL; - - return (status); } @@ -147,8 +220,7 @@ acpi_ns_parse_table ( * * RETURN: Status * - * DESCRIPTION: Mainline of the AML load/dump subsystem. Sets up the - * input engine, calls handler for outermost object type. + * DESCRIPTION: Load one ACPI table into the namespace * ****************************************************************************/ @@ -248,13 +320,6 @@ acpi_ns_load_table_by_type ( table_desc->table_id = TABLE_ID_DSDT; - /* Initialize the root of the namespace tree */ - - status = acpi_ns_root_initialize (); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - /* Now load the single DSDT */ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index 3c18cf87f..faf8fe56a 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 48 $ + * $Revision: 51 $ * ******************************************************************************/ @@ -86,7 +86,7 @@ acpi_ns_get_table_pathname ( name_buffer = acpi_cm_callocate (size + 1); if (!name_buffer) { - REPORT_ERROR ("Ns_get_table_pathname: allocation failure"); + REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n")); return (NULL); } @@ -170,6 +170,12 @@ acpi_ns_handle_to_pathname ( size += PATH_SEGMENT_LENGTH; } + /* Special case for size still 0 - no parent for "special" nodes */ + + if (!size) { + size = PATH_SEGMENT_LENGTH; + } + /* Set return length to the required path length */ path_length = size + 1; diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index df4c28239..6d41b91ce 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c @@ -2,7 +2,7 @@ * * Module Name: nsobject - Utilities for objects attached to namespace * table entries - * $Revision: 44 $ + * $Revision: 47 $ * ******************************************************************************/ @@ -73,29 +73,28 @@ acpi_ns_attach_object ( if (!acpi_gbl_root_node) { /* Name space not initialized */ - REPORT_ERROR ("Ns_attach_object: Name space not initialized"); + REPORT_ERROR (("Ns_attach_object: Namespace not initialized\n")); return (AE_NO_NAMESPACE); } if (!node) { /* Invalid handle */ - REPORT_ERROR ("Ns_attach_object: Null Named_obj handle"); + REPORT_ERROR (("Ns_attach_object: Null Named_obj handle\n")); return (AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ - REPORT_ERROR ("Ns_attach_object: Null object, but type" - "not ACPI_TYPE_ANY"); + REPORT_ERROR (("Ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n")); return (AE_BAD_PARAMETER); } if (!VALID_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED)) { /* Not a name handle */ - REPORT_ERROR ("Ns_attach_object: Invalid handle"); + REPORT_ERROR (("Ns_attach_object: Invalid handle\n")); return (AE_BAD_PARAMETER); } @@ -355,7 +354,6 @@ acpi_ns_get_attached_object ( if (!handle) { /* handle invalid */ - REPORT_WARNING ("Ns_get_attached_object: Null handle"); return (NULL); } diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index b6abbd782..001f57d9d 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nssearch - Namespace search - * $Revision: 57 $ + * $Revision: 62 $ * ******************************************************************************/ @@ -169,7 +169,7 @@ acpi_ns_search_node ( * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ns_search_parent_tree ( u32 target_name, ACPI_NAMESPACE_NODE *node, @@ -270,7 +270,7 @@ acpi_ns_search_and_enter ( /* Parameter validation */ if (!node || !target_name || !return_node) { - REPORT_ERROR ("Ns_search_and_enter: bad (null)parameter"); + REPORT_ERROR (("Ns_search_and_enter: bad (null) parameter\n")); return (AE_BAD_PARAMETER); } @@ -278,7 +278,7 @@ acpi_ns_search_and_enter ( /* Name must consist of printable characters */ if (!acpi_cm_valid_acpi_name (target_name)) { - REPORT_ERROR ("Ns_search_and_enter: Bad character in ACPI Name"); + REPORT_ERROR (("Ns_search_and_enter: Bad character in ACPI Name\n")); return (AE_BAD_CHARACTER); } @@ -290,6 +290,16 @@ acpi_ns_search_and_enter ( type, return_node); if (status != AE_NOT_FOUND) { /* + * If we found it AND the request specifies that a + * find is an error, return the error + */ + if ((status == AE_OK) && + (flags & NS_ERROR_IF_FOUND)) + { + status = AE_EXIST; + } + + /* * Either found it or there was an error * -- finished either way */ diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 3d5a98a07..593064dbb 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -2,7 +2,7 @@ * * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing * parents and siblings and Scope manipulation - * $Revision: 69 $ + * $Revision: 74 $ * *****************************************************************************/ @@ -93,7 +93,7 @@ acpi_ns_get_type ( { if (!handle) { - REPORT_WARNING ("Ns_get_type: Null handle"); + REPORT_WARNING (("Ns_get_type: Null handle\n")); return (ACPI_TYPE_ANY); } @@ -120,7 +120,7 @@ acpi_ns_local ( if (!acpi_cm_valid_object_type (type)) { /* Type code out of range */ - REPORT_WARNING ("Ns_local: Invalid Object Type"); + REPORT_WARNING (("Ns_local: Invalid Object Type\n")); return (NSP_NORMAL); } @@ -150,9 +150,10 @@ acpi_ns_internalize_name ( { NATIVE_CHAR *result = NULL; NATIVE_CHAR *internal_name; - u32 num_segments; + u32 num_segments = 0; u8 fully_qualified = FALSE; u32 i; + u32 num_carats = 0; if ((!external_name) || @@ -178,6 +179,16 @@ acpi_ns_internalize_name ( external_name++; } + else { + /* + * Handle Carat prefixes + */ + + while (*external_name == '^') { + num_carats++; + external_name++; + } + } /* * Determine the number of ACPI name "segments" by counting @@ -186,17 +197,19 @@ acpi_ns_internalize_name ( * + 1, and zero separators is ok. */ - num_segments = 1; - for (i = 0; external_name[i]; i++) { - if (acpi_ns_valid_path_separator (external_name[i])) { - num_segments++; + if (*external_name) { + num_segments = 1; + for (i = 0; external_name[i]; i++) { + if (acpi_ns_valid_path_separator (external_name[i])) { + num_segments++; + } } } /* We need a segment to store the internal version of the name */ - internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4); + internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4 + num_carats); if (!internal_name) { return (AE_NO_MEMORY); } @@ -206,14 +219,49 @@ acpi_ns_internalize_name ( if (fully_qualified) { internal_name[0] = '\\'; - internal_name[1] = AML_MULTI_NAME_PREFIX_OP; - internal_name[2] = (char) num_segments; - result = &internal_name[3]; + + if (num_segments <= 1) { + result = &internal_name[1]; + } + else if (num_segments == 2) { + internal_name[1] = AML_DUAL_NAME_PREFIX; + result = &internal_name[2]; + } + else { + internal_name[1] = AML_MULTI_NAME_PREFIX_OP; + internal_name[2] = (char) num_segments; + result = &internal_name[3]; + } + } + else { - internal_name[0] = AML_MULTI_NAME_PREFIX_OP; - internal_name[1] = (char) num_segments; - result = &internal_name[2]; + /* + * Not fully qualified. + * Handle Carats first, then append the name segments + */ + + i = 0; + if (num_carats) { + for (i = 0; i < num_carats; i++) { + internal_name[i] = '^'; + } + } + + if (num_segments == 1) { + result = &internal_name[i]; + } + + else if (num_segments == 2) { + internal_name[i] = AML_DUAL_NAME_PREFIX; + result = &internal_name[i+1]; + } + + else { + internal_name[i] = AML_MULTI_NAME_PREFIX_OP; + internal_name[i+1] = (char) num_segments; + result = &internal_name[i+2]; + } } @@ -271,6 +319,157 @@ acpi_ns_internalize_name ( /**************************************************************************** * + * FUNCTION: Acpi_ns_externalize_name + * + * PARAMETERS: *Internal_name - Internal representation of name + * **Converted_name - Where to return the resulting + * external representation of name + * + * RETURN: Status + * + * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) + * to its external form (e.g. "\_PR_.CPU0") + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ns_externalize_name ( + u32 internal_name_length, + char *internal_name, + u32 *converted_name_length, + char **converted_name) +{ + u32 prefix_length = 0; + u32 names_index = 0; + u32 names_count = 0; + u32 i = 0; + u32 j = 0; + + + if (!internal_name_length || + !internal_name || + !converted_name_length || + !converted_name) + { + return (AE_BAD_PARAMETER); + } + + + /* + * Check for a prefix (one '\' | one or more '^'). + */ + switch (internal_name[0]) + { + case '\\': + prefix_length = 1; + break; + + case '^': + for (i = 0; i < internal_name_length; i++) { + if (internal_name[i] != '^') { + prefix_length = i + 1; + } + } + + if (i == internal_name_length) { + prefix_length = i; + } + + break; + } + + /* + * Check for object names. Note that there could be 0-255 of these + * 4-byte elements. + */ + if (prefix_length < internal_name_length) { + switch (internal_name[prefix_length]) + { + + /* <count> 4-byte names */ + + case AML_MULTI_NAME_PREFIX_OP: + names_index = prefix_length + 2; + names_count = (u32) internal_name[prefix_length + 1]; + break; + + + /* two 4-byte names */ + + case AML_DUAL_NAME_PREFIX: + names_index = prefix_length + 1; + names_count = 2; + break; + + + /* Null_name */ + + case 0: + names_index = 0; + names_count = 0; + break; + + + /* one 4-byte name */ + + default: + names_index = prefix_length; + names_count = 1; + break; + } + } + + /* + * Calculate the length of Converted_name, which equals the length + * of the prefix, length of all object names, length of any required + * punctuation ('.') between object names, plus the NULL terminator. + */ + *converted_name_length = prefix_length + (4 * names_count) + + ((names_count > 0) ? (names_count - 1) : 0) + 1; + + /* + * Check to see if we're still in bounds. If not, there's a problem + * with Internal_name (invalid format). + */ + if (*converted_name_length > internal_name_length) { + REPORT_ERROR (("Ns_externalize_name: Invalid internal name\n")); + return (AE_BAD_PATHNAME); + } + + /* + * Build Converted_name... + */ + + (*converted_name) = acpi_cm_callocate (*converted_name_length); + if (!(*converted_name)) { + return (AE_NO_MEMORY); + } + + j = 0; + + for (i = 0; i < prefix_length; i++) { + (*converted_name)[j++] = internal_name[i]; + } + + if (names_count > 0) { + for (i = 0; i < names_count; i++) { + if (i > 0) { + (*converted_name)[j++] = '.'; + } + + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + } + } + + return (AE_OK); +} + + +/**************************************************************************** + * * FUNCTION: Acpi_ns_convert_handle_to_entry * * PARAMETERS: Handle - Handle to be converted to an Node @@ -425,7 +624,7 @@ acpi_ns_opens_scope ( if (!acpi_cm_valid_object_type (type)) { /* type code out of range */ - REPORT_WARNING ("Ns_opens_scope: Invalid Object Type"); + REPORT_WARNING (("Ns_opens_scope: Invalid Object Type\n")); return (NSP_NORMAL); } @@ -464,8 +663,6 @@ acpi_ns_get_node ( NATIVE_CHAR *internal_path = NULL; - scope_info.scope.node = start_node; - /* Ensure that the namespace has been initialized */ if (!acpi_gbl_root_node) { @@ -487,19 +684,9 @@ acpi_ns_get_node ( acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - /* NS_ALL means start from the root */ - - if (NS_ALL == scope_info.scope.node) { - scope_info.scope.node = acpi_gbl_root_node; - } + /* Setup lookup scope (search starting point) */ - else { - scope_info.scope.node = start_node; - if (!scope_info.scope.node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - } + scope_info.scope.node = start_node; /* Lookup the name in the namespace */ @@ -510,8 +697,6 @@ acpi_ns_get_node ( -unlock_and_exit: - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); /* Cleanup */ @@ -579,6 +764,10 @@ acpi_ns_get_parent_object ( { + if (!node) { + return (NULL); + } + /* * Walk to the end of this peer list. * The last entry is marked with a flag and the peer diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index dc02c6407..2947f7f06 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -2,7 +2,7 @@ * * Module Name: nsxfname - Public interfaces to the ACPI subsystem * ACPI Namespace oriented interfaces - * $Revision: 64 $ + * $Revision: 73 $ * *****************************************************************************/ @@ -38,60 +38,6 @@ MODULE_NAME ("nsxfname") -/****************************************************************************** - * - * FUNCTION: Acpi_load_namespace - * - * PARAMETERS: Display_aml_during_load - * - * RETURN: Status - * - * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. - * (DSDT points to either the BIOS or a buffer.) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_load_namespace ( - void) -{ - ACPI_STATUS status; - - - /* There must be at least a DSDT installed */ - - if (acpi_gbl_DSDT == NULL) { - return (AE_NO_ACPI_TABLES); - } - - - /* - * Load the namespace. The DSDT is required, - * but the SSDT and PSDT tables are optional. - */ - - status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Ignore exceptions from these */ - - acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); - acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); - - - /* - * Install the default Op_region handlers, ignore the return - * code right now. - */ - - acpi_ev_install_default_address_space_handlers (); - - return (status); -} - - /**************************************************************************** * * FUNCTION: Acpi_get_handle @@ -117,7 +63,7 @@ acpi_get_handle ( ACPI_HANDLE *ret_handle) { ACPI_STATUS status; - ACPI_NAMESPACE_NODE *node; + ACPI_NAMESPACE_NODE *node = NULL; ACPI_NAMESPACE_NODE *prefix_node = NULL; @@ -125,21 +71,21 @@ acpi_get_handle ( return (AE_BAD_PARAMETER); } + /* Convert a parent handle to a prefix node */ + if (parent) { acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - node = acpi_ns_convert_handle_to_entry (parent); - if (!node) { + prefix_node = acpi_ns_convert_handle_to_entry (parent); + if (!prefix_node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - prefix_node = node->child; acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); } /* Special case for root, since we can't search for it */ - /* TBD: [Investigate] Check for both forward and backslash?? */ if (STRCMP (pathname, NS_ROOT_PATH) == 0) { *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node); @@ -147,13 +93,12 @@ acpi_get_handle ( } /* - * Find the Node and convert to the user format + * Find the Node and convert to a handle */ - node = NULL; status = acpi_ns_get_node (pathname, prefix_node, &node); *ret_handle = NULL; - if(ACPI_SUCCESS(status)) { + if (ACPI_SUCCESS (status)) { *ret_handle = acpi_ns_convert_entry_to_handle (node); } @@ -253,42 +198,41 @@ unlock_and_exit: * * RETURN: Status * - * DESCRIPTION: Returns information about an object as gleaned from running - * several standard control methods. + * DESCRIPTION: Returns information about an object as gleaned from the + * namespace node and possibly by running several standard + * control methods (Such as in the case of a device.) * ******************************************************************************/ ACPI_STATUS acpi_get_object_info ( - ACPI_HANDLE device, + ACPI_HANDLE handle, ACPI_DEVICE_INFO *info) { DEVICE_ID hid; DEVICE_ID uid; ACPI_STATUS status; u32 device_status = 0; - u32 address = 0; - ACPI_NAMESPACE_NODE *device_node; + ACPI_INTEGER address = 0; + ACPI_NAMESPACE_NODE *node; /* Parameter validation */ - if (!device || !info) { + if (!handle || !info) { return (AE_BAD_PARAMETER); } acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - device_node = acpi_ns_convert_handle_to_entry (device); - if (!device_node) { + node = acpi_ns_convert_handle_to_entry (handle); + if (!node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - info->type = device_node->type; - info->name = device_node->name; - info->parent = acpi_ns_convert_entry_to_handle ( - acpi_ns_get_parent_object (device_node)); + info->type = node->type; + info->name = node->name; acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); @@ -300,34 +244,30 @@ acpi_get_object_info ( } - /* Get extra info for ACPI devices */ + /* + * Get extra info for ACPI devices only. Run the + * _HID, _UID, _STA, and _ADR methods. Note: none + * of these methods are required, so they may or may + * not be present. The Info->Valid bits are used + * to indicate which methods ran successfully. + */ info->valid = 0; /* Execute the _HID method and save the result */ - status = acpi_cm_execute_HID (device_node, &hid); + status = acpi_cm_execute_HID (node, &hid); if (ACPI_SUCCESS (status)) { - if (hid.type == STRING_PTR_DEVICE_ID) { - STRCPY (info->hardware_id, hid.data.string_ptr); - } - else { - STRCPY (info->hardware_id, hid.data.buffer); - } + STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id)); info->valid |= ACPI_VALID_HID; } /* Execute the _UID method and save the result */ - status = acpi_cm_execute_UID (device_node, &uid); + status = acpi_cm_execute_UID (node, &uid); if (ACPI_SUCCESS (status)) { - if (hid.type == STRING_PTR_DEVICE_ID) { - STRCPY (info->unique_id, uid.data.string_ptr); - } - else { - STRCPY (info->unique_id, uid.data.buffer); - } + STRCPY (info->unique_id, uid.buffer); info->valid |= ACPI_VALID_UID; } @@ -337,7 +277,7 @@ acpi_get_object_info ( * _STA is not always present */ - status = acpi_cm_execute_STA (device_node, &device_status); + status = acpi_cm_execute_STA (node, &device_status); if (ACPI_SUCCESS (status)) { info->current_status = device_status; info->valid |= ACPI_VALID_STA; @@ -349,7 +289,7 @@ acpi_get_object_info ( */ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, - device_node, &address); + node, &address); if (ACPI_SUCCESS (status)) { info->address = address; diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index 9b254ea99..b9f93fdcb 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -2,7 +2,7 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 65 $ + * $Revision: 75 $ * ******************************************************************************/ @@ -28,6 +28,7 @@ #include "acpi.h" #include "acinterp.h" #include "acnamesp.h" +#include "acdispat.h" #define _COMPONENT NAMESPACE @@ -484,6 +485,8 @@ unlock_and_exit: * Max_depth - Depth to which search is to reach * User_function - Called when an object of "Type" is found * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early * * RETURNS Return value from the User_function if terminated early. * Otherwise, returns NULL. @@ -544,3 +547,151 @@ acpi_walk_namespace ( } +/******************************************************************************* + * + * FUNCTION: Acpi_ns_get_device_callback + * + * PARAMETERS: Callback from Acpi_get_device + * + * RETURN: Status + * + * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non- + * present devices, or if they specified a HID, it filters based + * on that. + * + ******************************************************************************/ + +static ACPI_STATUS +acpi_ns_get_device_callback ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_NAMESPACE_NODE *node; + u32 flags; + DEVICE_ID device_id; + ACPI_GET_DEVICES_INFO *info; + + + info = context; + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + + node = acpi_ns_convert_handle_to_entry (obj_handle); + if (!node) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + /* + * Run _STA to determine if device is present + */ + + status = acpi_cm_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (status); + } + + if (!(flags & 0x01)) { + /* don't return at the device or children of the device if not there */ + + return (AE_CTRL_DEPTH); + } + + /* + * Filter based on device HID + */ + if (info->hid != NULL) { + status = acpi_cm_execute_HID (node, &device_id); + + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + + else if (ACPI_FAILURE (status)) { + return (status); + } + + if (STRNCMP (device_id.buffer, info->hid, sizeof (device_id.buffer)) != 0) { + return (AE_OK); + } + } + + info->user_function (obj_handle, nesting_level, info->context, return_value); + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_get_devices + * + * PARAMETERS: HID - HID to search for. Can be NULL. + * User_function - Called when a matching object is found + * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early + * + * RETURNS Return value from the User_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by Start_handle. + * The User_function is called whenever an object that matches + * the type parameter is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * This is a wrapper for Walk_namespace, but the callback performs + * additional filtering. Please see Acpi_get_device_callback. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_get_devices ( + NATIVE_CHAR *HID, + WALK_CALLBACK user_function, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_GET_DEVICES_INFO info; + + + /* Parameter validation */ + + if (!user_function) { + return (AE_BAD_PARAMETER); + } + + /* + * We're going to call their callback from OUR callback, so we need + * to know what it is, and their context parameter. + */ + info.context = context; + info.user_function = user_function; + info.hid = HID; + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + NS_WALK_UNLOCK, + acpi_ns_get_device_callback, &info, + return_value); + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + return (status); +}
\ No newline at end of file diff --git a/drivers/acpi/os.c b/drivers/acpi/os.c index b4ae03d05..7bf86171b 100644 --- a/drivers/acpi/os.c +++ b/drivers/acpi/os.c @@ -24,8 +24,8 @@ #include <linux/mm.h> #include <linux/pci.h> #include <linux/acpi.h> -#include <linux/delay.h> #include <asm/io.h> +#include <asm/delay.h> #include "acpi.h" #include "driver.h" @@ -36,16 +36,16 @@ static int acpi_irq_irq = 0; static OSD_HANDLER acpi_irq_handler = NULL; static void *acpi_irq_context = NULL; -char * -strupr(char *str) -{ - char *s = str; - while (*s) { - *s = TOUPPER(*s); - s++; - } - return str; -} +#ifdef ENABLE_DEBUGGER + +#include <linux/kdb.h> + +/* stuff for debugger support */ +int acpi_in_debugger = 0; +extern NATIVE_CHAR line_buf[80]; + +#endif + ACPI_STATUS acpi_os_initialize(void) @@ -79,7 +79,17 @@ acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args) { static char buffer[512]; int size = vsprintf(buffer, fmt, args); + +#ifdef ENABLE_DEBUGGER + if (acpi_in_debugger) { + kdb_printf("%s", buffer); + } else { + printk("%s", buffer); + } +#else printk("%s", buffer); +#endif + return size; } @@ -105,8 +115,13 @@ acpi_os_free(void *ptr) } ACPI_STATUS -acpi_os_map_memory(void *phys, u32 size, void **virt) +acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, u32 size, void **virt) { + if (phys > ULONG_MAX) { + printk(KERN_ERR "ACPI: Cannot map memory that high\n"); + return AE_ERROR; + } + if ((unsigned long) phys < virt_to_phys(high_memory)) { *virt = phys_to_virt((unsigned long) phys); return AE_OK; @@ -212,12 +227,48 @@ acpi_os_out32(ACPI_IO_ADDRESS port, u32 val) outl(val, port); } +UINT8 +acpi_os_mem_in8 (ACPI_PHYSICAL_ADDRESS phys_addr) +{ + return (*(u8*) (u32) phys_addr); +} + +UINT16 +acpi_os_mem_in16 (ACPI_PHYSICAL_ADDRESS phys_addr) +{ + return (*(u16*) (u32) phys_addr); +} + +UINT32 +acpi_os_mem_in32 (ACPI_PHYSICAL_ADDRESS phys_addr) +{ + return (*(u32*) (u32) phys_addr); +} + +void +acpi_os_mem_out8 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT8 value) +{ + *(u8*) (u32) phys_addr = value; +} + +void +acpi_os_mem_out16 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT16 value) +{ + *(u16*) (u32) phys_addr = value; +} + +void +acpi_os_mem_out32 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT32 value) +{ + *(u32*) (u32) phys_addr = value; +} + ACPI_STATUS acpi_os_read_pci_cfg_byte( - u32 bus, - u32 func, - u32 addr, - u8 * val) + u32 bus, + u32 func, + u32 addr, + u8 * val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -228,10 +279,10 @@ acpi_os_read_pci_cfg_byte( ACPI_STATUS acpi_os_read_pci_cfg_word( - u32 bus, - u32 func, - u32 addr, - u16 * val) + u32 bus, + u32 func, + u32 addr, + u16 * val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -242,10 +293,10 @@ acpi_os_read_pci_cfg_word( ACPI_STATUS acpi_os_read_pci_cfg_dword( - u32 bus, - u32 func, - u32 addr, - u32 * val) + u32 bus, + u32 func, + u32 addr, + u32 * val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -256,10 +307,10 @@ acpi_os_read_pci_cfg_dword( ACPI_STATUS acpi_os_write_pci_cfg_byte( - u32 bus, - u32 func, - u32 addr, - u8 val) + u32 bus, + u32 func, + u32 addr, + u8 val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -270,10 +321,10 @@ acpi_os_write_pci_cfg_byte( ACPI_STATUS acpi_os_write_pci_cfg_word( - u32 bus, - u32 func, - u32 addr, - u16 val) + u32 bus, + u32 func, + u32 addr, + u16 val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -284,10 +335,10 @@ acpi_os_write_pci_cfg_word( ACPI_STATUS acpi_os_write_pci_cfg_dword( - u32 bus, - u32 func, - u32 addr, - u32 val) + u32 bus, + u32 func, + u32 addr, + u32 val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -302,9 +353,9 @@ acpi_os_write_pci_cfg_dword( ACPI_STATUS acpi_os_queue_for_execution( - u32 priority, - OSD_EXECUTION_CALLBACK callback, - void *context) + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context) { if (acpi_run(callback, context)) return AE_ERROR; @@ -318,7 +369,8 @@ acpi_os_queue_for_execution( ACPI_STATUS acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle) { - *handle = (ACPI_HANDLE) 0; + /* a hack to fake out sems until we implement them */ + *handle = (ACPI_HANDLE) handle; return AE_OK; } @@ -362,6 +414,19 @@ acpi_os_dbg_assert(void *failure, void *file, u32 line, NATIVE_CHAR *msg) u32 acpi_os_get_line(NATIVE_CHAR *buffer) { + +#ifdef ENABLE_DEBUGGER + if (acpi_in_debugger) { + u32 chars; + + kdb_read(buffer, sizeof(line_buf)); + + /* remove the CR kdb includes */ + chars = strlen(buffer) - 1; + buffer[chars] = '\0'; + } +#endif + return 0; } diff --git a/drivers/acpi/parser/Makefile b/drivers/acpi/parser/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/parser/Makefile +++ b/drivers/acpi/parser/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 21315b331..35d623668 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 35 $ + * $Revision: 42 $ * *****************************************************************************/ @@ -33,20 +33,6 @@ MODULE_NAME ("psargs") -u32 -acpi_ps_pkg_length_encoding_size ( - u32 first_byte) -{ - - /* - * Bits 6-7 contain the number of bytes - * in the encoded package length (-1) - */ - - return ((first_byte >> 6) + 1); -} - - /******************************************************************************* * * FUNCTION: Acpi_ps_get_next_package_length @@ -61,55 +47,6 @@ acpi_ps_pkg_length_encoding_size ( ******************************************************************************/ u32 -xxx_acpi_ps_get_next_package_length ( - ACPI_PARSE_STATE *parser_state) -{ - u32 encoding_length; - u32 package_length = 0; - u8 *aml_ptr = parser_state->aml; - - - encoding_length = acpi_ps_pkg_length_encoding_size ((u32) GET8 (aml_ptr)); - - - switch (encoding_length) - { - case 1: /* 1-byte encoding (bits 0-5) */ - - package_length = ((u32) GET8 (aml_ptr) & 0x3f); - break; - - - case 2: /* 2-byte encoding (next byte + bits 0-3) */ - - package_length = ((((u32) GET8 (aml_ptr + 1)) << 4) | - (((u32) GET8 (aml_ptr)) & 0x0f)); - break; - - - case 3: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - - package_length = ((((u32) GET8 (aml_ptr + 2)) << 12) | - (((u32) GET8 (aml_ptr + 1)) << 4) | - (((u32) GET8 (aml_ptr)) & 0x0f)); - break; - - - case 4: /* 4-byte encoding (next 3 bytes + bits 0-3) */ - - package_length = ((((u32) GET8 (aml_ptr + 3)) << 20) | - (((u32) GET8 (aml_ptr + 2)) << 12) | - (((u32) GET8 (aml_ptr + 1)) << 4) | - (((u32) GET8 (aml_ptr)) & 0x0f)); - break; - } - - parser_state->aml += encoding_length; - - return (package_length); -} - -u32 acpi_ps_get_next_package_length ( ACPI_PARSE_STATE *parser_state) { @@ -125,32 +62,33 @@ acpi_ps_get_next_package_length ( { case 0: /* 1-byte encoding (bits 0-5) */ - length = (encoded_length & 0x3f); + length = (encoded_length & 0x3F); break; case 1: /* 2-byte encoding (next byte + bits 0-3) */ - length = (GET8 (parser_state->aml) << 4) | (encoded_length & 0xf); + length = ((GET8 (parser_state->aml) << 04) | + (encoded_length & 0x0F)); parser_state->aml++; break; case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - length = ( (GET8 (parser_state->aml + 1) << 12) - | (GET8 (parser_state->aml) << 4) - | (encoded_length & 0xf)); + length = ((GET8 (parser_state->aml + 1) << 12) | + (GET8 (parser_state->aml) << 04) | + (encoded_length & 0x0F)); parser_state->aml += 2; break; case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ - length = ( (GET8 (parser_state->aml + 2) << 20) - | (GET8 (parser_state->aml + 1) << 12) - | (GET8 (parser_state->aml) << 4) - | (encoded_length & 0xf)); + length = ((GET8 (parser_state->aml + 2) << 20) | + (GET8 (parser_state->aml + 1) << 12) | + (GET8 (parser_state->aml) << 04) | + (encoded_length & 0x0F)); parser_state->aml += 3; break; } @@ -442,6 +380,10 @@ acpi_ps_get_next_namepath ( name_op->node = method_node; acpi_ps_append_arg (arg, name_op); + if (!(ACPI_OPERAND_OBJECT *) method_node->object) { + return; + } + *arg_count = ((ACPI_OPERAND_OBJECT *) method_node->object)->method.param_count; } @@ -459,7 +401,7 @@ acpi_ps_get_next_namepath ( /* * Either we didn't find the object in the namespace, or the object is * something other than a control method. Just initialize the Op with the - * pathname + * pathname. */ acpi_ps_init_op (arg, AML_NAMEPATH_OP); diff --git a/drivers/acpi/parser/psfind.c b/drivers/acpi/parser/psfind.c deleted file mode 100644 index 95ffb3bb4..000000000 --- a/drivers/acpi/parser/psfind.c +++ /dev/null @@ -1,319 +0,0 @@ - -/****************************************************************************** - * - * Module Name: psfind - Parse tree search routine - * $Revision: 16 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" - -#define _COMPONENT PARSER - MODULE_NAME ("psfind") - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_get_parent - * - * PARAMETERS: Op - Get the parent of this Op - * - * RETURN: The Parent op. - * - * DESCRIPTION: Get op's parent - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT* -acpi_ps_get_parent ( - ACPI_PARSE_OBJECT *op) -{ - ACPI_PARSE_OBJECT *parent = op; - - - /* Traverse the tree upward (to root if necessary) */ - - while (parent) { - switch (parent->opcode) - { - case AML_SCOPE_OP: - case AML_PACKAGE_OP: - case AML_METHOD_OP: - case AML_DEVICE_OP: - case AML_POWER_RES_OP: - case AML_THERMAL_ZONE_OP: - - return (parent->parent); - } - - parent = parent->parent; - } - - return (parent); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_find_name - * - * PARAMETERS: Scope - Scope to search - * Name - ACPI name to search for - * Opcode - Opcode to search for - * - * RETURN: Op containing the name - * - * DESCRIPTION: Find name segment from a list of acpi_ops. Searches a single - * scope, no more. - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT * -acpi_ps_find_name ( - ACPI_PARSE_OBJECT *scope, - u32 name, - u32 opcode) -{ - ACPI_PARSE_OBJECT *op; - ACPI_PARSE_OBJECT *field; - - - /* search scope level for matching name segment */ - - op = acpi_ps_get_child (scope); - - while (op) { - - if (acpi_ps_is_field_op (op->opcode)) { - /* Field, search named fields */ - - field = acpi_ps_get_child (op); - while (field) { - if (acpi_ps_is_named_op (field->opcode) && - acpi_ps_get_name (field) == name && - (!opcode || field->opcode == opcode)) - { - return (field); - } - - field = field->next; - } - } - - else if (acpi_ps_is_create_field_op (op->opcode)) { - if (op->opcode == AML_CREATE_FIELD_OP) { - field = acpi_ps_get_arg (op, 3); - } - - else { - /* Create_xXXField, check name */ - - field = acpi_ps_get_arg (op, 2); - } - - if ((field) && - (field->value.string) && - (!STRNCMP (field->value.string, (char *) &name, ACPI_NAME_SIZE))) - { - return (op); - } - } - - else if ((acpi_ps_is_named_op (op->opcode)) && - (acpi_ps_get_name (op) == name) && - (!opcode || op->opcode == opcode)) - { - break; - } - - op = op->next; - } - - return (op); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_find - * - * PARAMETERS: Scope - Where to begin the search - * Path - ACPI Path to the named object - * Opcode - Opcode associated with the object - * Create - if TRUE, create the object if not found. - * - * RETURN: Op if found, NULL otherwise. - * - * DESCRIPTION: Find object within scope - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT* -acpi_ps_find ( - ACPI_PARSE_OBJECT *scope, - NATIVE_CHAR *path, - u16 opcode, - u32 create) -{ - u32 seg_count; - u32 name; - u32 name_op; - ACPI_PARSE_OBJECT *op = NULL; - u8 unprefixed = TRUE; - - - if (!scope || !path) { - return (NULL); - } - - - acpi_gbl_ps_find_count++; - - - /* Handle all prefixes in the name path */ - - while (acpi_ps_is_prefix_char (GET8 (path))) { - switch (GET8 (path)) - { - - case '\\': - - /* Could just use a global for "root scope" here */ - - while (scope->parent) { - scope = scope->parent; - } - - /* get first object within the scope */ - /* TBD: [Investigate] OR - set next in root scope to point to the same value as arg */ - - /* Scope = Scope->Value.Arg; */ - - break; - - - case '^': - - /* Go up to the next valid scoping Op (method, scope, etc.) */ - - if (acpi_ps_get_parent (scope)) { - scope = acpi_ps_get_parent (scope); - } - - break; - } - - unprefixed = FALSE; - path++; - } - - /* get name segment count */ - - switch (GET8 (path)) - { - case '\0': - seg_count = 0; - - /* Null name case */ - - if (unprefixed) { - op = NULL; - } - else { - op = scope; - } - - - return (op); - break; - - case AML_DUAL_NAME_PREFIX: - seg_count = 2; - path++; - break; - - case AML_MULTI_NAME_PREFIX_OP: - seg_count = GET8 (path + 1); - path += 2; - break; - - default: - seg_count = 1; - break; - } - - /* match each name segment */ - - while (scope && seg_count) { - MOVE_UNALIGNED32_TO_32 (&name, path); - path += 4; - seg_count --; - - if (seg_count) { - name_op = 0; - } - else { - name_op = opcode; - } - - op = acpi_ps_find_name (scope, name, name_op); - - if (!op) { - if (create) { - /* Create a new Scope level */ - - if (seg_count) { - op = acpi_ps_alloc_op (AML_SCOPE_OP); - } - else { - op = acpi_ps_alloc_op (opcode); - } - - if (op) { - acpi_ps_set_name (op, name); - acpi_ps_append_arg (scope, op); - - } - } - - else if (unprefixed) { - /* Search higher scopes for unprefixed name */ - - while (!op && scope->parent) { - scope = scope->parent; - op = acpi_ps_find_name (scope, name, opcode); - - } - } - - } - - unprefixed = FALSE; - scope = op; - } - - return (op); -} - - diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 8ce0154ab..a7f061363 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psopcode - Parser opcode information table - * $Revision: 20 $ + * $Revision: 24 $ * *****************************************************************************/ @@ -33,9 +33,6 @@ MODULE_NAME ("psopcode") -u8 acpi_gbl_aml_short_op_info_index[]; -u8 acpi_gbl_aml_long_op_info_index[]; - #define _UNK 0x6B /* * Reserved ASCII characters. Do not use any of these for @@ -55,112 +52,6 @@ u8 acpi_gbl_aml_long_op_info_index[]; /******************************************************************************* * - * FUNCTION: Acpi_ps_get_opcode_info - * - * PARAMETERS: Opcode - The AML opcode - * - * RETURN: A pointer to the info about the opcode. NULL if the opcode was - * not found in the table. - * - * DESCRIPTION: Find AML opcode description based on the opcode. - * NOTE: This procedure must ALWAYS return a valid pointer! - * - ******************************************************************************/ - -ACPI_OPCODE_INFO * -acpi_ps_get_opcode_info ( - u16 opcode) -{ - ACPI_OPCODE_INFO *op_info; - u8 upper_opcode; - u8 lower_opcode; - - - /* Split the 16-bit opcode into separate bytes */ - - upper_opcode = (u8) (opcode >> 8); - lower_opcode = (u8) opcode; - - /* Default is "unknown opcode" */ - - op_info = &acpi_gbl_aml_op_info [_UNK]; - - - /* - * Detect normal 8-bit opcode or extended 16-bit opcode - */ - - switch (upper_opcode) - { - case 0: - - /* Simple (8-bit) opcode: 0-255, can't index beyond table */ - - op_info = &acpi_gbl_aml_op_info [acpi_gbl_aml_short_op_info_index [lower_opcode]]; - break; - - - case AML_EXTOP: - - /* Extended (16-bit, prefix+opcode) opcode */ - - if (lower_opcode <= MAX_EXTENDED_OPCODE) { - op_info = &acpi_gbl_aml_op_info [acpi_gbl_aml_long_op_info_index [lower_opcode]]; - } - break; - - - case AML_LNOT_OP: - - /* This case is for the bogus opcodes LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL */ - /* TBD: [Investigate] remove this case? */ - - break; - - - default: - - break; - } - - - /* Get the Op info pointer for this opcode */ - - return (op_info); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_get_opcode_name - * - * PARAMETERS: Opcode - The AML opcode - * - * RETURN: A pointer to the name of the opcode (ASCII String) - * Note: Never returns NULL. - * - * DESCRIPTION: Translate an opcode into a human-readable string - * - ******************************************************************************/ - -NATIVE_CHAR * -acpi_ps_get_opcode_name ( - u16 opcode) -{ - ACPI_OPCODE_INFO *op; - - - op = acpi_ps_get_opcode_info (opcode); - - /* Always guaranteed to return a valid pointer */ - - DEBUG_ONLY_MEMBERS (return op->name); - return ("AE_NOT_CONFIGURED"); -} - - -/******************************************************************************* - * * NAME: Acpi_gbl_Aml_op_info * * DESCRIPTION: Opcode table. Each entry contains <opcode, type, name, operands> @@ -387,7 +278,7 @@ acpi_ps_get_opcode_name ( #define ARGI_REVISION_OP ARG_NONE #define ARGI_DEBUG_OP ARG_NONE #define ARGI_FATAL_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_REGION_OP ARGI_INVALID_OPCODE +#define ARGI_REGION_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) #define ARGI_DEF_FIELD_OP ARGI_INVALID_OPCODE #define ARGI_DEVICE_OP ARGI_INVALID_OPCODE #define ARGI_PROCESSOR_OP ARGI_INVALID_OPCODE @@ -412,7 +303,7 @@ acpi_ps_get_opcode_name ( */ -ACPI_OPCODE_INFO acpi_gbl_aml_op_info[] = +static ACPI_OPCODE_INFO aml_op_info[] = { /* Index Opcode Type Class Has Arguments? Name Parser Args Interpreter Args */ @@ -539,7 +430,7 @@ ACPI_OPCODE_INFO acpi_gbl_aml_op_info[] = * index into the table above */ -u8 acpi_gbl_aml_short_op_info_index[256] = +static u8 aml_short_op_info_index[256] = { /* 0 1 2 3 4 5 6 7 */ /* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK, @@ -577,7 +468,7 @@ u8 acpi_gbl_aml_short_op_info_index[256] = }; -u8 acpi_gbl_aml_long_op_info_index[NUM_EXTENDED_OPCODE] = +static u8 aml_long_op_info_index[NUM_EXTENDED_OPCODE] = { /* 0 1 2 3 4 5 6 7 */ /* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK, @@ -604,3 +495,108 @@ u8 acpi_gbl_aml_long_op_info_index[NUM_EXTENDED_OPCODE] = /* 0x00 */ +/******************************************************************************* + * + * FUNCTION: Acpi_ps_get_opcode_info + * + * PARAMETERS: Opcode - The AML opcode + * + * RETURN: A pointer to the info about the opcode. NULL if the opcode was + * not found in the table. + * + * DESCRIPTION: Find AML opcode description based on the opcode. + * NOTE: This procedure must ALWAYS return a valid pointer! + * + ******************************************************************************/ + +ACPI_OPCODE_INFO * +acpi_ps_get_opcode_info ( + u16 opcode) +{ + ACPI_OPCODE_INFO *op_info; + u8 upper_opcode; + u8 lower_opcode; + + + /* Split the 16-bit opcode into separate bytes */ + + upper_opcode = (u8) (opcode >> 8); + lower_opcode = (u8) opcode; + + /* Default is "unknown opcode" */ + + op_info = &aml_op_info [_UNK]; + + + /* + * Detect normal 8-bit opcode or extended 16-bit opcode + */ + + switch (upper_opcode) + { + case 0: + + /* Simple (8-bit) opcode: 0-255, can't index beyond table */ + + op_info = &aml_op_info [aml_short_op_info_index [lower_opcode]]; + break; + + + case AML_EXTOP: + + /* Extended (16-bit, prefix+opcode) opcode */ + + if (lower_opcode <= MAX_EXTENDED_OPCODE) { + op_info = &aml_op_info [aml_long_op_info_index [lower_opcode]]; + } + break; + + + case AML_LNOT_OP: + + /* This case is for the bogus opcodes LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL */ + /* TBD: [Investigate] remove this case? */ + + break; + + + default: + + break; + } + + + /* Get the Op info pointer for this opcode */ + + return (op_info); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ps_get_opcode_name + * + * PARAMETERS: Opcode - The AML opcode + * + * RETURN: A pointer to the name of the opcode (ASCII String) + * Note: Never returns NULL. + * + * DESCRIPTION: Translate an opcode into a human-readable string + * + ******************************************************************************/ + +NATIVE_CHAR * +acpi_ps_get_opcode_name ( + u16 opcode) +{ + ACPI_OPCODE_INFO *op; + + + op = acpi_ps_get_opcode_info (opcode); + + /* Always guaranteed to return a valid pointer */ + + return ("AE_NOT_CONFIGURED"); +} + + diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 8351e8b69..7471efdcb 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 51 $ + * $Revision: 71 $ * *****************************************************************************/ @@ -30,7 +30,7 @@ * generated parser to tightly constrain stack and dynamic memory * usage. At the same time, parsing is kept flexible and the code * fairly compact by parsing based on a list of AML opcode - * templates in Acpi_gbl_Aml_op_info[] + * templates in Aml_op_info[] */ #include "acpi.h" @@ -50,95 +50,6 @@ extern u32 acpi_gbl_scope_depth; /******************************************************************************* * - * FUNCTION: Acpi_ps_delete_completed_op - * - * PARAMETERS: State - Walk state - * Op - Completed op - * - * RETURN: AE_OK - * - * DESCRIPTION: Callback function for Acpi_ps_get_next_walk_op(). Used during - * Acpi_ps_delete_parse tree to delete Op objects when all sub-objects - * have been visited (and deleted.) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_ps_delete_completed_op ( - ACPI_WALK_STATE *state, - ACPI_PARSE_OBJECT *op) -{ - - acpi_ps_free_op (op); - return (AE_OK); -} - - -#ifndef PARSER_ONLY -/******************************************************************************* - * - * FUNCTION: Acpi_ps_delete_parse_tree - * - * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete - * - * RETURN: None - * - * DESCRIPTION: Delete a portion of or an entire parse tree. - * - ******************************************************************************/ - -void -acpi_ps_delete_parse_tree ( - ACPI_PARSE_OBJECT *subtree_root) -{ - ACPI_WALK_STATE *walk_state; - ACPI_WALK_LIST walk_list; - - - if (!subtree_root) { - return; - } - - /* Create and initialize a new walk list */ - - walk_list.walk_state = NULL; - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list); - if (!walk_state) { - return; - } - - walk_state->parser_state = NULL; - walk_state->parse_flags = 0; - walk_state->descending_callback = NULL; - walk_state->ascending_callback = NULL; - - - walk_state->origin = subtree_root; - walk_state->next_op = subtree_root; - - - /* Head downward in the tree */ - - walk_state->next_op_info = NEXT_OP_DOWNWARD; - - /* Visit all nodes in the subtree */ - - while (walk_state->next_op) { - acpi_ps_get_next_walk_op (walk_state, walk_state->next_op, - acpi_ps_delete_completed_op); - } - - /* We are done with this walk */ - - acpi_ds_delete_walk_state (walk_state); - - return; -} -#endif - - -/******************************************************************************* - * * FUNCTION: Acpi_ps_peek_opcode * * PARAMETERS: None @@ -149,7 +60,7 @@ acpi_ps_delete_parse_tree ( * ******************************************************************************/ -u32 +static u32 acpi_ps_get_opcode_size ( u32 opcode) { @@ -323,7 +234,7 @@ acpi_ps_find_object ( * ******************************************************************************/ -u8 +static u8 acpi_ps_complete_this_op ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op) @@ -344,11 +255,11 @@ acpi_ps_complete_this_op ( /* Delete this op and the subtree below it if asked to */ if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) && - (opcode_class != OPTYPE_CONSTANT) && - (opcode_class != OPTYPE_LITERAL) && + (opcode_class != OPTYPE_CONSTANT) && + (opcode_class != OPTYPE_LITERAL) && (opcode_class != OPTYPE_LOCAL_VARIABLE) && (opcode_class != OPTYPE_METHOD_ARGUMENT) && - (opcode_class != OPTYPE_DATA_TERM) && + (opcode_class != OPTYPE_DATA_TERM) && (op->opcode != AML_NAMEPATH_OP)) { /* Make sure that we only delete this subtree */ @@ -356,7 +267,7 @@ acpi_ps_complete_this_op ( if (op->parent) { /* * Check if we need to replace the operator and its subtree - * with a return value op + * with a return value op (placeholder op) */ parent_info = acpi_ps_get_opcode_info (op->parent->opcode); @@ -364,7 +275,29 @@ acpi_ps_complete_this_op ( switch (ACPI_GET_OP_CLASS (parent_info)) { case OPTYPE_CONTROL: /* IF, ELSE, WHILE only */ + break; + case OPTYPE_NAMED_OBJECT: /* Scope, method, etc. */ + + /* + * These opcodes contain Term_arg operands. The current + * op must be replace by a placeholder return op + */ + + if ((op->parent->opcode == AML_REGION_OP) || + (op->parent->opcode == AML_CREATE_FIELD_OP) || + (op->parent->opcode == AML_BIT_FIELD_OP) || + (op->parent->opcode == AML_BYTE_FIELD_OP) || + (op->parent->opcode == AML_WORD_FIELD_OP) || + (op->parent->opcode == AML_DWORD_FIELD_OP) || + (op->parent->opcode == AML_QWORD_FIELD_OP)) + { + replacement_op = acpi_ps_alloc_op (AML_RETURN_VALUE_OP); + if (!replacement_op) { + return (FALSE); + } + } + break; default: @@ -381,13 +314,13 @@ acpi_ps_complete_this_op ( /* This op is the first in the list */ if (replacement_op) { - replacement_op->parent = op->parent; + replacement_op->parent = op->parent; replacement_op->value.arg = NULL; - op->parent->value.arg = replacement_op; - replacement_op->next = op->next; + op->parent->value.arg = replacement_op; + replacement_op->next = op->next; } else { - op->parent->value.arg = op->next; + op->parent->value.arg = op->next; } } @@ -443,8 +376,7 @@ acpi_ps_complete_this_op ( * ******************************************************************************/ - -ACPI_STATUS +static ACPI_STATUS acpi_ps_next_parse_state ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op, @@ -452,6 +384,8 @@ acpi_ps_next_parse_state ( { ACPI_PARSE_STATE *parser_state = walk_state->parser_state; ACPI_STATUS status = AE_CTRL_PENDING; + u8 *start; + u32 package_length; switch (callback_status) @@ -490,10 +424,12 @@ acpi_ps_next_parse_state ( * Predicate of an IF was true, and we are at the matching ELSE. * Just close out this package * - * Parser_state->Aml is modified by the package length procedure + * Note: Parser_state->Aml is modified by the package length procedure + * TBD: [Investigate] perhaps it shouldn't, too much trouble */ - parser_state->aml = (parser_state->aml + - acpi_ps_get_next_package_length (parser_state)) -1; + start = parser_state->aml; + package_length = acpi_ps_get_next_package_length (parser_state); + parser_state->aml = start + package_length; break; @@ -528,7 +464,7 @@ acpi_ps_next_parse_state ( /* Will return value (if any) be used by the caller? */ - walk_state->return_used = acpi_ds_is_result_used (op); + walk_state->return_used = acpi_ds_is_result_used (op, walk_state); break; @@ -573,24 +509,59 @@ acpi_ps_parse_loop ( u16 opcode; ACPI_PARSE_OBJECT pre_op; ACPI_PARSE_STATE *parser_state; + u8 *aml_op_start; parser_state = walk_state->parser_state; - if (walk_state->prev_op) { - op = walk_state->prev_op; - arg_types = walk_state->prev_arg_types; +#ifndef PARSER_ONLY + if (walk_state->walk_type & WALK_METHOD_RESTART) { + /* We are restarting a preempted control method */ + + if (acpi_ps_has_completed_scope (parser_state)) { + /* + * We must check if a predicate to an IF or WHILE statement + * was just completed + */ + if ((parser_state->scope->parse_scope.op) && + ((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) || + (parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) && + (walk_state->control_state) && + (walk_state->control_state->common.state == + CONTROL_PREDICATE_EXECUTING)) + { + + /* + * A predicate was just completed, get the value of the + * predicate and branch based on that value + */ + + status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE); + status = acpi_ps_next_parse_state (walk_state, op, status); + } + + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); + } + + else if (walk_state->prev_op) { + /* We were in the middle of an op */ + + op = walk_state->prev_op; + arg_types = walk_state->prev_arg_types; + } } +#endif /* * Iterative parsing loop, while there is more aml to process: */ - while (parser_state->aml < parser_state->aml_end) { + while ((parser_state->aml < parser_state->aml_end) || (op)) { if (!op) { /* Get the next opcode from the AML stream */ + aml_op_start = parser_state->aml; aml_offset = parser_state->aml - parser_state->aml_start; - opcode = acpi_ps_peek_opcode (parser_state); + opcode = acpi_ps_peek_opcode (parser_state); /* * First cut to determine what we have found: @@ -625,7 +596,9 @@ acpi_ps_parse_loop ( /* The opcode is unrecognized. Just skip unknown opcodes */ - parser_state->aml += acpi_ps_get_opcode_size (opcode); + /* Assume one-byte bad opcode */ + + parser_state->aml++; continue; } @@ -677,25 +650,26 @@ acpi_ps_parse_loop ( deferred_op = acpi_ps_to_extended_op (op); if (deferred_op) { /* - * Skip parsing of control method or opregion body, + * Defer final parsing of an Operation_region body, * because we don't have enough info in the first pass - * to parse them correctly. + * to parse it correctly (i.e., there may be method + * calls within the Term_arg elements of the body. * - * Backup to beginning of Op_region declaration (2 for - * Opcode, 4 for name) + * However, we must continue parsing because + * the opregion is not a standalone package -- + * we don't know where the end is at this point. * - * Body_length is unknown until we parse the body + * (Length is unknown until parse of the body complete) */ - deferred_op->data = parser_state->aml - 6; + deferred_op->data = aml_op_start; deferred_op->length = 0; } } } - else { - + else { /* Not a named opcode, just allocate Op and append to parent */ op = acpi_ps_alloc_op (opcode); @@ -703,6 +677,23 @@ acpi_ps_parse_loop ( return (AE_NO_MEMORY); } + + if ((op->opcode == AML_CREATE_FIELD_OP) || + (op->opcode == AML_BIT_FIELD_OP) || + (op->opcode == AML_BYTE_FIELD_OP) || + (op->opcode == AML_WORD_FIELD_OP) || + (op->opcode == AML_DWORD_FIELD_OP)) + { + /* + * Backup to beginning of Create_xXXfield declaration + * Body_length is unknown until we parse the body + */ + deferred_op = (ACPI_PARSE2_OBJECT *) op; + + deferred_op->data = aml_op_start; + deferred_op->length = 0; + } + acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op); if ((walk_state->descending_callback != NULL)) { @@ -728,7 +719,11 @@ acpi_ps_parse_loop ( } + /* Start Arg_count at zero because we don't know if there are any args yet */ + arg_count = 0; + + if (arg_types) /* Are there any arguments that must be processed? */ { /* get arguments */ @@ -761,12 +756,11 @@ acpi_ps_parse_loop ( arg = acpi_ps_get_next_arg (parser_state, GET_CURRENT_ARG_TYPE (arg_types), &arg_count); - if (arg) { arg->aml_offset = aml_offset; + acpi_ps_append_arg (op, arg); } - acpi_ps_append_arg (op, arg); INCREMENT_ARG_LIST (arg_types); } @@ -800,6 +794,10 @@ acpi_ps_parse_loop ( } } + + /* + * Zero Arg_count means that all arguments for this op have been processed + */ if (!arg_count) { /* completed Op, prepare for next */ @@ -821,11 +819,27 @@ acpi_ps_parse_loop ( */ deferred_op->length = parser_state->aml - - deferred_op->data; + deferred_op->data; } } } + if ((op->opcode == AML_CREATE_FIELD_OP) || + (op->opcode == AML_BIT_FIELD_OP) || + (op->opcode == AML_BYTE_FIELD_OP) || + (op->opcode == AML_WORD_FIELD_OP) || + (op->opcode == AML_DWORD_FIELD_OP) || + (op->opcode == AML_QWORD_FIELD_OP)) + { + /* + * Backup to beginning of Create_xXXfield declaration (1 for + * Opcode) + * + * Body_length is unknown until we parse the body + */ + deferred_op = (ACPI_PARSE2_OBJECT *) op; + deferred_op->length = parser_state->aml - deferred_op->data; + } /* This op complete, notify the dispatcher */ @@ -841,6 +855,9 @@ acpi_ps_parse_loop ( close_this_op: + /* + * Finished one argument of the containing scope + */ parser_state->scope->parse_scope.arg_count--; /* Close this Op (may result in parse subtree deletion) */ @@ -850,18 +867,58 @@ close_this_op: } - if (status == AE_CTRL_END) { - acpi_ps_pop_scope (parser_state, &op, &arg_types); + switch (status) + { + case AE_OK: + break; + + + case AE_CTRL_TRANSFER: + + /* + * We are about to transfer to a called method. + */ + walk_state->prev_op = op; + walk_state->prev_arg_types = arg_types; + return (status); + break; + + + case AE_CTRL_END: + + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); + status = walk_state->ascending_callback (walk_state, op); status = acpi_ps_next_parse_state (walk_state, op, status); + acpi_ps_complete_this_op (walk_state, op); op = NULL; status = AE_OK; - } + break; + + + case AE_CTRL_TERMINATE: + + status = AE_OK; + + /* Clean up */ + do + { + if (op) { + acpi_ps_complete_this_op (walk_state, op); + } + + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); + } while (op); + + return (status); + break; + + + default: /* All other non-AE_OK status */ - else if (ACPI_FAILURE (status)) { if (op == NULL) { - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } walk_state->prev_op = op; walk_state->prev_arg_types = arg_types; @@ -870,27 +927,15 @@ close_this_op: * TEMP: */ - if (status == AE_CTRL_TERMINATE) { - status = AE_OK; - - /* Clean up */ - do - { - if (op) { - acpi_ps_complete_this_op (walk_state, op); - } - - acpi_ps_pop_scope (parser_state, &op, &arg_types); - } while (op); - } return (status); + break; } /* This scope complete? */ if (acpi_ps_has_completed_scope (parser_state)) { - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } else { @@ -899,6 +944,9 @@ close_this_op: } + + /* Arg_count is non-zero */ + else { /* complex argument, push Op and prepare for argument */ @@ -937,7 +985,7 @@ close_this_op: acpi_ps_complete_this_op (walk_state, op); } - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } while (op); @@ -953,7 +1001,7 @@ close_this_op: acpi_ps_complete_this_op (walk_state, op); } - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } while (op); @@ -996,7 +1044,6 @@ acpi_ps_parse_aml ( ACPI_WALK_LIST *prev_walk_list = acpi_gbl_current_walk_list; ACPI_OPERAND_OBJECT *return_desc; ACPI_OPERAND_OBJECT *mth_desc = NULL; - ACPI_NAMESPACE_NODE *start_node; /* Create and initialize a new parser state */ @@ -1034,19 +1081,16 @@ acpi_ps_parse_aml ( if (method_node) { - start_node = method_node; parser_state->start_node = method_node; walk_state->walk_type = WALK_METHOD; - if (start_node) { - /* Push start scope on scope stack and make it current */ - - status = acpi_ds_scope_stack_push (start_node, ACPI_TYPE_METHOD, walk_state); - if (ACPI_FAILURE (status)) { - return (status); - } + /* Push start scope on scope stack and make it current */ + status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state); + if (ACPI_FAILURE (status)) { + return (status); } + /* Init arguments if this is a control method */ /* TBD: [Restructure] add walkstate as a param */ @@ -1057,6 +1101,8 @@ acpi_ps_parse_aml ( /* Setup the current scope */ node = parser_state->start_op->node; + parser_state->start_node = node; + if (node) { /* Push start scope on scope stack and make it current */ @@ -1145,6 +1191,7 @@ acpi_ps_parse_aml ( */ acpi_ds_restart_control_method (walk_state, return_desc); + walk_state->walk_type |= WALK_METHOD_RESTART; } /* diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index 727afaa08..2e8926ad1 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psscope - Parser scope stack management routines - * $Revision: 18 $ + * $Revision: 22 $ * *****************************************************************************/ @@ -118,7 +118,7 @@ acpi_ps_init_scope ( * * PARAMETERS: Parser_state - Current parser state object * Op - Current op to be pushed - * Next_arg - Next op argument (to be pushed) + * Remaining_args - List of args remaining * Arg_count - Fixed or variable number of args * * RETURN: Status @@ -175,8 +175,9 @@ acpi_ps_push_scope ( * * PARAMETERS: Parser_state - Current parser state object * Op - Where the popped op is returned - * Next_arg - Where the popped "next argument" is + * Arg_list - Where the popped "next argument" is * returned + * Arg_count - Count of objects in Arg_list * * RETURN: Status * @@ -188,7 +189,8 @@ void acpi_ps_pop_scope ( ACPI_PARSE_STATE *parser_state, ACPI_PARSE_OBJECT **op, - u32 *arg_list) + u32 *arg_list, + u32 *arg_count) { ACPI_GENERIC_STATE *scope = parser_state->scope; @@ -204,6 +206,7 @@ acpi_ps_pop_scope ( *op = scope->parse_scope.op; *arg_list = scope->parse_scope.arg_list; + *arg_count = scope->parse_scope.arg_count; parser_state->pkg_end = scope->parse_scope.pkg_end; /* All done with this scope state structure */ @@ -216,6 +219,7 @@ acpi_ps_pop_scope ( *op = NULL; *arg_list = 0; + *arg_count = 0; } diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index 55a897414..a22bb646d 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: pstree - Parser op tree manipulation/traversal/search - * $Revision: 23 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -287,114 +287,3 @@ acpi_ps_get_depth_next ( } -/******************************************************************************* - * - * FUNCTION: Acpi_ps_fetch_prefix - * - * PARAMETERS: Scope - Op to fetch prefix for - * Path - A namestring containing the prefix - * io - Direction flag - * - * RETURN: Op referenced by the prefix - * - * DESCRIPTION: Fetch and handle path prefix ('\\' or '^') - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT * -acpi_ps_fetch_prefix ( - ACPI_PARSE_OBJECT *scope, - NATIVE_CHAR **path, - u32 io) -{ - u32 prefix = io ? GET8 (*path):**path; - - - switch (prefix) - { - case '\\': - case '/': - - /* go to the root */ - - *path += 1; - while (scope->parent) { - scope = scope->parent; - } - break; - - - case '^': - - /* go up one level */ - - *path += 1; - scope = scope->parent; - break; - } - - if (scope && !scope->parent) { - /* searching from the root, start with its children */ - - scope = acpi_ps_get_child (scope); - } - - return (scope); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_fetch_name - * - * PARAMETERS: Path - A string containing the name segment - * io - Direction flag - * - * RETURN: The 4-s8 ASCII ACPI Name as a u32 - * - * DESCRIPTION: Fetch ACPI name segment (dot-delimited) - * - ******************************************************************************/ - -u32 -acpi_ps_fetch_name ( - NATIVE_CHAR **path, - u32 io) -{ - u32 name = 0; - NATIVE_CHAR *nm; - u32 i; - NATIVE_CHAR ch; - - - if (io) { - /* Get the name from the path pointer */ - - MOVE_UNALIGNED32_TO_32 (&name, *path); - *path += 4; - } - - else { - if (**path == '.') { - *path += 1; - } - - nm = (NATIVE_CHAR *) &name; - for (i = 0; i < 4; i++) { - ch = **path; - if (ch && ch != '.') { - *nm = ch; - *path += 1; - } - - else { - *nm = '_'; - } - nm++; - } - } - - return (name); -} - - diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index d190a2755..3bac4a647 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 29 $ + * $Revision: 30 $ * *****************************************************************************/ @@ -460,7 +460,12 @@ acpi_ps_is_deferred_op ( u16 opcode) { return ((u8) - (opcode == AML_METHOD_OP || + (opcode == AML_METHOD_OP || + opcode == AML_CREATE_FIELD_OP || + opcode == AML_BIT_FIELD_OP || + opcode == AML_BYTE_FIELD_OP || + opcode == AML_WORD_FIELD_OP || + opcode == AML_DWORD_FIELD_OP || opcode == AML_REGION_OP)); } diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index 77a287d6d..04a75917d 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: pswalk - Parser routines to walk parsed op tree(s) - * $Revision: 45 $ + * $Revision: 50 $ * *****************************************************************************/ @@ -42,8 +42,6 @@ * PARAMETERS: Walk_state - Current state of the walk * Op - Current Op to be walked * Ascending_callback - Procedure called when Op is complete - * Prev_op - Where the previous Op is stored - * Next_op - Where the next Op in the walk is stored * * RETURN: Status * @@ -90,112 +88,40 @@ acpi_ps_get_next_walk_op ( status = ascending_callback (walk_state, op); - switch (status) - { - case AE_CTRL_TERMINATE: + /* + * If we are back to the starting point, the walk is complete. + */ + if (op == walk_state->origin) { + /* Reached the point of origin, the walk is complete */ - /* - * A control method was terminated via a RETURN statement. - * The walk of this method is complete. - */ - walk_state->prev_op = walk_state->origin; + walk_state->prev_op = op; walk_state->next_op = NULL; - return (AE_OK); - break; - - - case AE_CTRL_FALSE: - - /* - * Either an IF/WHILE Predicate was false or we encountered a BREAK - * opcode. In both cases, we do not execute the rest of the - * package; We simply close out the parent (finishing the walk of - * this branch of the tree) and continue execution at the parent - * level. - */ - - next = parent->next; - status = AE_OK; - - /* - * If there is a sibling to the parent, we must close out the - * parent now, because we are going to continue to go downward (to - * the sibling) in the parse tree. - */ - if (next) { - status = ascending_callback (walk_state, parent); - - /* The parent sibling will be next */ - - walk_state->prev_op = op; - walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; - - /* Continue downward */ - - return (AE_OK); - } - - /* - * Drop into the loop below because we are moving upwards in - * the tree - */ - - break; - - - default: - /* - * If we are back to the starting point, the walk is complete. - */ - if (op == walk_state->origin) { - /* Reached the point of origin, the walk is complete */ - - walk_state->prev_op = op; - walk_state->next_op = NULL; - - return (status); - } - - /* - * Check for a sibling to the current op. A sibling means - * we are still going "downward" in the tree. - */ - - if (next) { - /* There is a sibling, it will be next */ - - walk_state->prev_op = op; - walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; + return (status); + } - /* Continue downward */ + /* + * Check for a sibling to the current op. A sibling means + * we are still going "downward" in the tree. + */ - return (status); - } + if (next) { + /* There is a sibling, it will be next */ - /* - * No sibling, but check status. - * Abort on error from callback routine - */ - if (ACPI_FAILURE (status)) { - /* Next op will be the parent */ + walk_state->prev_op = op; + walk_state->next_op = next; + walk_state->next_op_info = NEXT_OP_DOWNWARD; - walk_state->prev_op = op; - walk_state->next_op = parent; - walk_state->next_op_info = NEXT_OP_UPWARD; + /* Continue downward */ - return (status); - } + return (status); + } - /* - * Drop into the loop below because we are moving upwards in - * the tree - */ - break; - } + /* + * Drop into the loop below because we are moving upwards in + * the tree + */ } else { @@ -221,69 +147,6 @@ acpi_ps_get_next_walk_op ( status = ascending_callback (walk_state, parent); - - switch (status) - { - case AE_CTRL_FALSE: - - /* - * Either an IF/WHILE Predicate was false or we encountered a - * BREAK opcode. In both cases, we do not execute the rest of the - * package; We simply close out the parent (finishing the walk of - * this branch of the tree) and continue execution at the parent - * level. - */ - - parent = grand_parent; - next = grand_parent->next; - grand_parent = grand_parent->parent; - - status = ascending_callback (walk_state, parent); - - /* Now continue to the next node in the tree */ - - break; - - - case AE_CTRL_TRUE: - - /* - * Predicate of a WHILE was true and the loop just completed an - * execution. Go back to the start of the loop and reevaluate the - * predicate. - */ - - op = walk_state->control_state->control.predicate_op; - - walk_state->control_state->common.state = CONTROL_PREDICATE_EXECUTING; - - /* - * Acpi_evaluate the predicate again (next) - * Because we will traverse WHILE tree again - */ - - walk_state->prev_op = op->parent; - walk_state->next_op = op; - walk_state->next_op_info = NEXT_OP_DOWNWARD; - - return (AE_OK); - break; - - - case AE_CTRL_TERMINATE: - - /* - * A control method was terminated via a RETURN statement. - * The walk of this method is complete. - */ - walk_state->prev_op = walk_state->origin; - walk_state->next_op = NULL; - - return (AE_OK); - break; - } - - /* * If we are back to the starting point, the walk is complete. */ @@ -296,7 +159,6 @@ acpi_ps_get_next_walk_op ( return (status); } - /* * If there is a sibling to this parent (it is not the starting point * Op), then we will visit it. @@ -311,18 +173,6 @@ acpi_ps_get_next_walk_op ( return (status); } - /* - * No sibling, check for an error from closing the parent - * (Also, AE_PENDING if a method call was encountered) - */ - if (ACPI_FAILURE (status)) { - walk_state->prev_op = parent; - walk_state->next_op = grand_parent; - walk_state->next_op_info = NEXT_OP_UPWARD; - - return (status); - } - /* No siblings, no errors, just move up one more level in the tree */ op = parent; @@ -342,251 +192,88 @@ acpi_ps_get_next_walk_op ( /******************************************************************************* * - * FUNCTION: Acpi_ps_walk_loop + * FUNCTION: Acpi_ps_delete_completed_op * - * PARAMETERS: Walk_list - State of the walk - * Start_op - Starting Op of the subtree to be walked - * Descending_callback - Procedure called when a new Op is - * encountered - * Ascending_callback - Procedure called when Op is complete + * PARAMETERS: State - Walk state + * Op - Completed op * - * RETURN: Status + * RETURN: AE_OK * - * DESCRIPTION: Perform a walk of the parsed AML tree. Begins and terminates at - * the Start_op. + * DESCRIPTION: Callback function for Acpi_ps_get_next_walk_op(). Used during + * Acpi_ps_delete_parse tree to delete Op objects when all sub-objects + * have been visited (and deleted.) * ******************************************************************************/ -ACPI_STATUS -acpi_ps_walk_loop ( - ACPI_WALK_LIST *walk_list, - ACPI_PARSE_OBJECT *start_op, - ACPI_PARSE_DOWNWARDS descending_callback, - ACPI_PARSE_UPWARDS ascending_callback) +static ACPI_STATUS +acpi_ps_delete_completed_op ( + ACPI_WALK_STATE *state, + ACPI_PARSE_OBJECT *op) { - ACPI_STATUS status = AE_OK; - ACPI_WALK_STATE *walk_state; - ACPI_PARSE_OBJECT *op = start_op; - - - walk_state = acpi_ds_get_current_walk_state (walk_list); - - - /* Walk entire subtree, visiting all nodes depth-first */ - - while (op) { - if (walk_state->next_op_info != NEXT_OP_UPWARD) { - status = descending_callback (op->opcode, op, walk_state, NULL); - } - - /* - * A TRUE exception means that an ELSE was detected, but the IF - * predicate evaluated TRUE. - */ - if (status == AE_CTRL_TRUE) { - /* - * Ignore the entire ELSE block by moving on to the the next opcode. - * And we do that by simply going up in the tree (either to the next - * sibling or to the parent) from here. - */ - - walk_state->next_op_info = NEXT_OP_UPWARD; - } - - /* Get the next node (op) in the depth-first walk */ - - status = acpi_ps_get_next_walk_op (walk_state, op, ascending_callback); - - /* - * A PENDING exception means that a control method invocation has been - * detected - */ - - if (status == AE_CTRL_PENDING) { - /* Transfer control to the called control method */ - - status = acpi_ds_call_control_method (walk_list, walk_state, op); - - /* - * If the transfer to the new method method call worked, a new walk - * state was created -- get it - */ - - walk_state = acpi_ds_get_current_walk_state (walk_list); - } - - /* Abort the walk on any exception */ - - if (ACPI_FAILURE (status)) { - return (status); - } - - op = walk_state->next_op; - } + acpi_ps_free_op (op); return (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ps_walk_parsed_aml - * - * PARAMETERS: Start_op - Starting Op of the subtree to be walked - * End_op - Where to terminate the walk - * Descending_callback - Procedure called when a new Op is - * encountered - * Ascending_callback - Procedure called when Op is complete + * FUNCTION: Acpi_ps_delete_parse_tree * - * RETURN: Status + * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete * - * DESCRIPTION: Top level interface to walk the parsed AML tree. Handles - * preemption of executing control methods. + * RETURN: None * - * NOTE: The End_op is usually only different from the Start_op if - * we don't want to visit the Start_op during the tree descent. + * DESCRIPTION: Delete a portion of or an entire parse tree. * ******************************************************************************/ -ACPI_STATUS -acpi_ps_walk_parsed_aml ( - ACPI_PARSE_OBJECT *start_op, - ACPI_PARSE_OBJECT *end_op, - ACPI_OPERAND_OBJECT *mth_desc, - ACPI_NAMESPACE_NODE *start_node, - ACPI_OPERAND_OBJECT **params, - ACPI_OPERAND_OBJECT **caller_return_desc, - ACPI_OWNER_ID owner_id, - ACPI_PARSE_DOWNWARDS descending_callback, - ACPI_PARSE_UPWARDS ascending_callback) +void +acpi_ps_delete_parse_tree ( + ACPI_PARSE_OBJECT *subtree_root) { - ACPI_PARSE_OBJECT *op; ACPI_WALK_STATE *walk_state; - ACPI_OPERAND_OBJECT *return_desc; - ACPI_STATUS status; ACPI_WALK_LIST walk_list; - ACPI_WALK_LIST *prev_walk_list; - /* Parameter Validation */ - - if (!start_op || !end_op) { - return (AE_BAD_PARAMETER); + if (!subtree_root) { + return; } - /* Initialize a new walk list */ + /* Create and initialize a new walk list */ walk_list.walk_state = NULL; - - walk_state = acpi_ds_create_walk_state (owner_id, end_op, mth_desc, &walk_list); + walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list); if (!walk_state) { - return (AE_NO_MEMORY); - } - - /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter - */ - prev_walk_list = acpi_gbl_current_walk_list; - acpi_gbl_current_walk_list = &walk_list; - - if (start_node) { - /* Push start scope on scope stack and make it current */ - - status = acpi_ds_scope_stack_push (start_node, ACPI_TYPE_METHOD, walk_state); - if (ACPI_FAILURE (status)) { - return (status); - } - + return; } - if (mth_desc) { - /* Init arguments if this is a control method */ - /* TBD: [Restructure] add walkstate as a param */ + walk_state->parser_state = NULL; + walk_state->parse_flags = 0; + walk_state->descending_callback = NULL; + walk_state->ascending_callback = NULL; - acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state); - } - op = start_op; - status = AE_OK; + walk_state->origin = subtree_root; + walk_state->next_op = subtree_root; - /* - * Execute the walk loop as long as there is a valid Walk State. This - * handles nested control method invocations without recursion. - */ + /* Head downward in the tree */ - while (walk_state) { - if (ACPI_SUCCESS (status)) { - status = acpi_ps_walk_loop (&walk_list, op, descending_callback, - ascending_callback); - } + walk_state->next_op_info = NEXT_OP_DOWNWARD; - /* We are done with this walk, move on to the parent if any */ - - BREAKPOINT3; - - walk_state = acpi_ds_pop_walk_state (&walk_list); - - /* Extract return value before we delete Walk_state */ - - return_desc = walk_state->return_desc; - - /* Reset the current scope to the beginning of scope stack */ - - acpi_ds_scope_stack_clear (walk_state); - - /* - * If we just returned from the execution of a control method, - * there's lots of cleanup to do - */ + /* Visit all nodes in the subtree */ - if (walk_state->method_desc) { - acpi_ds_terminate_control_method (walk_state); - } - - /* Delete this walk state and all linked control states */ - - acpi_ds_delete_walk_state (walk_state); - - /* Check if we have restarted a preempted walk */ - - walk_state = acpi_ds_get_current_walk_state (&walk_list); - if (walk_state && - ACPI_SUCCESS (status)) - { - /* There is another walk state, restart it */ - - /* - * If the method returned value is not used by the parent, - * The object is deleted - */ - - acpi_ds_restart_control_method (walk_state, return_desc); - - /* Get the next Op to process */ - - op = walk_state->next_op; - } - - /* - * Just completed a 1st-level method, save the final internal return - * value (if any) - */ - - else if (caller_return_desc) { - *caller_return_desc = return_desc; /* NULL if no return value */ - } - - else if (return_desc) { - /* Caller doesn't want it, must delete it */ - - acpi_cm_remove_reference (return_desc); - } + while (walk_state->next_op) { + acpi_ps_get_next_walk_op (walk_state, walk_state->next_op, + acpi_ps_delete_completed_op); } + /* We are done with this walk */ - acpi_gbl_current_walk_list = prev_walk_list; + acpi_ds_delete_walk_state (walk_state); - return (status); + return; } diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 70451d318..a33ace051 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psxface - Parser external interfaces - * $Revision: 36 $ + * $Revision: 37 $ * *****************************************************************************/ @@ -40,11 +40,13 @@ * * FUNCTION: Acpi_psx_execute * - * PARAMETERS: Obj_desc - A method object containing both the AML + * PARAMETERS: Method_node - A method object containing both the AML * address and length. * **Params - List of parameters to pass to method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. + * **Return_obj_desc - Return object from execution of the + * method. * * RETURN: Status * diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c new file mode 100644 index 000000000..0422bf94d --- /dev/null +++ b/drivers/acpi/power.c @@ -0,0 +1,137 @@ +/* + * power.c - Overall power driver. Also handles AC adapter device. + * + * Copyright (C) 2000 Andrew Grover + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/proc_fs.h> +#include "acpi.h" +#include "driver.h" + +#define _COMPONENT OS_DEPENDENT + MODULE_NAME ("power") + +int acpi_cmbatt_init(void); +int acpi_cmbatt_terminate(void); + +/* ACPI-specific defines */ +#define ACPI_AC_ADAPTER_HID "ACPI0003" + +static int ac_count = 0; +static ACPI_HANDLE ac_handle = 0; + +/* + * We found a device with the correct HID + */ +static ACPI_STATUS +acpi_found_ac_adapter(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +{ + ACPI_DEVICE_INFO info; + + if (ac_count > 0) { + printk(KERN_ERR "AC Adapter: more than one!\n"); + return (AE_OK); + } + + if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { + printk(KERN_ERR "AC Adapter: Could not get AC Adapter object info\n"); + return (AE_OK); + } + + if (!(info.valid & ACPI_VALID_STA)) { + printk(KERN_ERR "AC Adapter: Battery _STA invalid\n"); + return AE_OK; + } + + printk(KERN_INFO "AC Adapter: found\n"); + + ac_handle = handle; + + ac_count++; + + return AE_OK; +} + +static int +proc_read_ac_adapter_status(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + ACPI_OBJECT obj; + ACPI_BUFFER buf; + + char *p = page; + int len; + + buf.length = sizeof(obj); + buf.pointer = &obj; + if (!ACPI_SUCCESS(acpi_evaluate_object(ac_handle, "_PSR", NULL, &buf)) + || obj.type != ACPI_TYPE_NUMBER) { + p += sprintf(p, "Could not read AC status\n"); + goto end; + } + + if (obj.number.value) + p += sprintf(p, "on-line\n"); + else + p += sprintf(p, "off-line\n"); + +end: + len = (p - page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +int +acpi_power_init(void) +{ + acpi_get_devices(ACPI_AC_ADAPTER_HID, + acpi_found_ac_adapter, + NULL, + NULL); + + if (!proc_mkdir("power", NULL)) + return 0; + + if (ac_handle) { + create_proc_read_entry("power/ac", 0, NULL, + proc_read_ac_adapter_status, NULL); + } + + acpi_cmbatt_init(); + + return 0; +} + +int +acpi_power_terminate(void) +{ + acpi_cmbatt_terminate(); + + if (ac_handle) { + remove_proc_entry("power/ac", NULL); + } + + remove_proc_entry("power", NULL); + + return 0; +} diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/resources/Makefile +++ b/drivers/acpi/resources/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 6b0234481..e48666113 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -1,12 +1,12 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsaddr - Acpi_rs_address16_resource * Acpi_rs_address16_stream * Acpi_rs_address32_resource * Acpi_rs_address32_stream - * $Revision: 9 $ + * $Revision: 12 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -28,16 +28,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsaddr") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_address16_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -53,7 +54,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address16_resource ( @@ -253,11 +254,11 @@ acpi_rs_address16_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_address16_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -268,7 +269,7 @@ acpi_rs_address16_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address16_stream ( @@ -350,7 +351,6 @@ acpi_rs_address16_stream ( */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.min_address_range); - buffer += 2; /* @@ -358,7 +358,6 @@ acpi_rs_address16_stream ( */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.max_address_range); - buffer += 2; /* @@ -366,7 +365,6 @@ acpi_rs_address16_stream ( */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.address_translation_offset); - buffer += 2; /* @@ -374,7 +372,6 @@ acpi_rs_address16_stream ( */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.address_length); - buffer += 2; /* @@ -418,11 +415,12 @@ acpi_rs_address16_stream ( return (AE_OK); } -/*************************************************************************** + +/******************************************************************************* + * * FUNCTION: Acpi_rs_address32_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -438,7 +436,7 @@ acpi_rs_address16_stream ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address32_resource ( @@ -641,11 +639,11 @@ acpi_rs_address32_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_address32_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -656,7 +654,7 @@ acpi_rs_address32_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address32_stream ( @@ -676,7 +674,6 @@ acpi_rs_address32_stream ( * The descriptor field is static */ *buffer = 0x87; - buffer += 1; /* @@ -684,7 +681,6 @@ acpi_rs_address32_stream ( */ length_field = (u16 *)buffer; - buffer += 2; /* @@ -693,22 +689,17 @@ acpi_rs_address32_stream ( temp8 = (u8) (linked_list->data.address32.resource_type & 0x03); *buffer = temp8; - buffer += 1; /* * Set the general flags */ temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01); - temp8 |= (linked_list->data.address32.decode & 0x01) << 1; - temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2; - temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3; *buffer = temp8; - buffer += 1; /* @@ -747,7 +738,6 @@ acpi_rs_address32_stream ( */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.min_address_range); - buffer += 4; /* @@ -755,7 +745,6 @@ acpi_rs_address32_stream ( */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.max_address_range); - buffer += 4; /* @@ -763,7 +752,6 @@ acpi_rs_address32_stream ( */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset); - buffer += 4; /* @@ -771,7 +759,6 @@ acpi_rs_address32_stream ( */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.address_length); - buffer += 4; /* @@ -781,7 +768,6 @@ acpi_rs_address32_stream ( temp8 = (u8) linked_list->data.address32.resource_source_index; *buffer = temp8; - buffer += 1; temp_pointer = (NATIVE_CHAR *) buffer; diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 7d1a75c80..2874aa3d0 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -1,10 +1,10 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length * Acpi_rs_calculate_list_length - * $Revision: 9 $ + * $Revision: 16 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -26,16 +26,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rscalc") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_calculate_byte_stream_length * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Size_needed - u32 pointer of the size buffer needed * to properly return the parsed data * @@ -45,7 +46,7 @@ * the size buffer needed to hold the linked list that conveys * the resource data. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_calculate_byte_stream_length ( @@ -279,15 +280,14 @@ acpi_rs_calculate_byte_stream_length ( *size_needed = byte_stream_size_needed; return (AE_OK); - -} /* Acpi_rs_calculate_byte_stream_length */ +} -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_calculate_list_length * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource byte stream + * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream * Byte_stream_buffer_length - Size of Byte_stream_buffer * Size_needed - u32 pointer of the size buffer * needed to properly return the @@ -299,7 +299,7 @@ acpi_rs_calculate_byte_stream_length ( * the size buffer needed to hold the linked list that conveys * the resource data. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_calculate_list_length ( @@ -344,7 +344,6 @@ acpi_rs_calculate_list_length ( structure_size = sizeof (MEMORY24_RESOURCE) + RESOURCE_LENGTH_NO_DATA; - break; case LARGE_VENDOR_DEFINED: @@ -481,7 +480,6 @@ acpi_rs_calculate_list_length ( * Interrupt table length to the Temp8 variable. */ buffer += 3; - temp8 = *buffer; /* @@ -521,7 +519,7 @@ acpi_rs_calculate_list_length ( break; -/* 64-bit not currently supported */ +/* TBD: [Future] 64-bit not currently supported */ /* case 0x8A: break; @@ -555,7 +553,6 @@ acpi_rs_calculate_list_length ( * trailing bytes */ buffer = byte_stream_buffer; - temp8 = *buffer; if(temp8 & 0x01) { @@ -587,7 +584,6 @@ acpi_rs_calculate_list_length ( structure_size = sizeof (IO_RESOURCE) + RESOURCE_LENGTH_NO_DATA + (number_of_interrupts * sizeof (u32)); - break; @@ -621,7 +617,6 @@ acpi_rs_calculate_list_length ( structure_size = sizeof (DMA_RESOURCE) + RESOURCE_LENGTH_NO_DATA + (number_of_channels * sizeof (u32)); - break; @@ -634,7 +629,6 @@ acpi_rs_calculate_list_length ( * Determine if it there are two or three trailing bytes */ buffer = byte_stream_buffer; - temp8 = *buffer; if(temp8 & 0x01) { @@ -657,7 +651,6 @@ acpi_rs_calculate_list_length ( * End Dependent Functions Resource */ bytes_consumed = 1; - structure_size = RESOURCE_LENGTH; break; @@ -667,7 +660,6 @@ acpi_rs_calculate_list_length ( * IO Port Resource */ bytes_consumed = 8; - structure_size = sizeof (IO_RESOURCE) + RESOURCE_LENGTH_NO_DATA; break; @@ -679,7 +671,6 @@ acpi_rs_calculate_list_length ( * Fixed IO Port Resource */ bytes_consumed = 4; - structure_size = sizeof (FIXED_IO_RESOURCE) + RESOURCE_LENGTH_NO_DATA; break; @@ -700,7 +691,6 @@ acpi_rs_calculate_list_length ( * Ensure a 32-bit boundry for the structure */ temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); - structure_size = sizeof (VENDOR_RESOURCE) + RESOURCE_LENGTH_NO_DATA + (temp8 * sizeof (u8)); @@ -713,7 +703,6 @@ acpi_rs_calculate_list_length ( * End Tag */ bytes_consumed = 2; - structure_size = RESOURCE_LENGTH; break; @@ -749,14 +738,14 @@ acpi_rs_calculate_list_length ( *size_needed = buffer_size; return (AE_OK); +} -} /* Acpi_rs_calculate_list_length */ -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_calculate_pci_routing_table_length * - * PARAMETERS: - * Package_object - Pointer to the package object + * PARAMETERS: Package_object - Pointer to the package object * Buffer_size_needed - u32 pointer of the size buffer * needed to properly return the * parsed data @@ -767,17 +756,22 @@ acpi_rs_calculate_list_length ( * calculates the size of the corresponding linked list of * descriptions. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_calculate_pci_routing_table_length ( ACPI_OPERAND_OBJECT *package_object, u32 *buffer_size_needed) { - u32 number_of_elements; - u32 temp_size_needed; - ACPI_OPERAND_OBJECT **top_object_list; - u32 index; + u32 number_of_elements; + u32 temp_size_needed = 0; + ACPI_OPERAND_OBJECT **top_object_list; + u32 index; + ACPI_OPERAND_OBJECT *package_element; + ACPI_OPERAND_OBJECT **sub_object_list; + u8 name_found; + u32 table_index; + number_of_elements = package_object->package.count; @@ -791,8 +785,6 @@ acpi_rs_calculate_pci_routing_table_length ( * NOTE: The Number_of_elements is incremented by one to add an end * table structure that is essentially a structure of zeros. */ - temp_size_needed = (number_of_elements + 1) * - (sizeof (PCI_ROUTING_TABLE) - 1); /* * But each PRT_ENTRY structure has a pointer to a string and @@ -801,11 +793,6 @@ acpi_rs_calculate_pci_routing_table_length ( top_object_list = package_object->package.elements; for (index = 0; index < number_of_elements; index++) { - ACPI_OPERAND_OBJECT *package_element; - ACPI_OPERAND_OBJECT **sub_object_list; - u8 name_found; - u32 table_index; - /* * Dereference the sub-package */ @@ -835,6 +822,8 @@ acpi_rs_calculate_pci_routing_table_length ( } } + temp_size_needed += (sizeof (PCI_ROUTING_TABLE) - 1); + /* * Was a String type found? */ @@ -844,7 +833,6 @@ acpi_rs_calculate_pci_routing_table_length ( * terminating NULL */ temp_size_needed += (*sub_object_list)->string.length; - temp_size_needed = ROUND_UP_TO_32_bITS (temp_size_needed); } else { @@ -855,13 +843,19 @@ acpi_rs_calculate_pci_routing_table_length ( temp_size_needed += sizeof(u32); } + + /* Round up the size since each element must be aligned */ + + temp_size_needed = ROUND_UP_TO_64_bITS (temp_size_needed); + /* * Point to the next ACPI_OPERAND_OBJECT */ top_object_list++; } - *buffer_size_needed = temp_size_needed; + + *buffer_size_needed = temp_size_needed + sizeof (PCI_ROUTING_TABLE); return (AE_OK); -}
\ No newline at end of file +} diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 01b3909da..bc95686a7 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -1,11 +1,11 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rscreate - Acpi_rs_create_resource_list * Acpi_rs_create_pci_routing_table * Acpi_rs_create_byte_stream - * $Revision: 16 $ + * $Revision: 22 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -182,11 +182,12 @@ acpi_rs_create_pci_routing_table ( * contain a u32 Address, a u8 Pin, a Name and a u8 * Source_index. */ - top_object_list = package_object->package.elements; + top_object_list = package_object->package.elements; + number_of_elements = package_object->package.count; + user_prt = (PCI_ROUTING_TABLE *) buffer; - number_of_elements = package_object->package.count; - user_prt = (PCI_ROUTING_TABLE *) buffer; + buffer = ROUND_PTR_UP_TO_8 (buffer, u8); for (index = 0; index < number_of_elements; index++) { /* @@ -198,6 +199,7 @@ acpi_rs_create_pci_routing_table ( buffer += user_prt->length; user_prt = (PCI_ROUTING_TABLE *) buffer; + /* * Fill in the Length field with the information we * have at this point. @@ -237,7 +239,7 @@ acpi_rs_create_pci_routing_table ( if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { user_prt->data.pin = - (*sub_object_list)->number.value; + (u32) (*sub_object_list)->number.value; } else { @@ -257,8 +259,6 @@ acpi_rs_create_pci_routing_table ( * Add to the Length field the length of the string */ user_prt->length += (*sub_object_list)->string.length; - user_prt->length = - ROUND_UP_TO_32_bITS (user_prt->length); } else { @@ -280,6 +280,10 @@ acpi_rs_create_pci_routing_table ( } } + /* Now align the current length */ + + user_prt->length = ROUND_UP_TO_64_bITS (user_prt->length); + /* * Dereference the Source Index */ @@ -287,7 +291,7 @@ acpi_rs_create_pci_routing_table ( if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { user_prt->data.source_index = - (*sub_object_list)->number.value; + (u32) (*sub_object_list)->number.value; } else { @@ -314,7 +318,6 @@ acpi_rs_create_pci_routing_table ( *output_buffer_length = buffer_size_needed; return (AE_OK); - } @@ -393,6 +396,5 @@ acpi_rs_create_byte_stream ( } return (AE_OK); - } diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index ae697840c..073f4ddd4 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsdump - Functions do dump out the resource structures. - * $Revision: 10 $ + * $Revision: 13 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -25,12 +25,13 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsdump") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_irq * @@ -64,11 +65,11 @@ acpi_rs_dump_irq ( SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive"); - acpi_os_printf ("\t\t%d Interrupts ( ", + acpi_os_printf ("\t\t%X Interrupts ( ", irq_data->number_of_interrupts); for (index = 0; index < irq_data->number_of_interrupts; index++) { - acpi_os_printf ("%d ", irq_data->interrupts[index]); + acpi_os_printf ("%X ", irq_data->interrupts[index]); } acpi_os_printf (")\n"); @@ -76,7 +77,7 @@ acpi_rs_dump_irq ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_dma * @@ -144,11 +145,11 @@ acpi_rs_dump_dma ( break; } - acpi_os_printf ("\t\t_number of Channels: %d ( ", + acpi_os_printf ("\t\t_number of Channels: %X ( ", dma_data->number_of_channels); for (index = 0; index < dma_data->number_of_channels; index++) { - acpi_os_printf ("%d ", dma_data->channels[index]); + acpi_os_printf ("%X ", dma_data->channels[index]); } acpi_os_printf (")\n"); @@ -156,7 +157,7 @@ acpi_rs_dump_dma ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_start_dependent_functions * @@ -221,7 +222,7 @@ acpi_rs_dump_start_dependent_functions ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_io * @@ -245,23 +246,23 @@ acpi_rs_dump_io ( acpi_os_printf ("\t\t%d bit decode\n", DECODE_16 == io_data->io_decode ? 16 : 10); - acpi_os_printf ("\t\t_range minimum base: 0x%08x\n", + acpi_os_printf ("\t\t_range minimum base: %08X\n", io_data->min_base_address); - acpi_os_printf ("\t\t_range maximum base: 0x%08x\n", + acpi_os_printf ("\t\t_range maximum base: %08X\n", io_data->max_base_address); - acpi_os_printf ("\t\t_alignment: 0x%08x\n", + acpi_os_printf ("\t\t_alignment: %08X\n", io_data->alignment); - acpi_os_printf ("\t\t_range Length: 0x%08x\n", + acpi_os_printf ("\t\t_range Length: %08X\n", io_data->range_length); return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_fixed_io * @@ -281,17 +282,17 @@ acpi_rs_dump_fixed_io ( acpi_os_printf ("\t_fixed Io Resource\n"); - acpi_os_printf ("\t\t_range base address: 0x%08x", + acpi_os_printf ("\t\t_range base address: %08X", fixed_io_data->base_address); - acpi_os_printf ("\t\t_range length: 0x%08x", + acpi_os_printf ("\t\t_range length: %08X", fixed_io_data->range_length); return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_vendor_specific * @@ -313,10 +314,10 @@ acpi_rs_dump_vendor_specific ( acpi_os_printf ("\t_vendor Specific Resource\n"); - acpi_os_printf ("\t\t_length: 0x%08x\n", vendor_data->length); + acpi_os_printf ("\t\t_length: %08X\n", vendor_data->length); for (index = 0; index < vendor_data->length; index++) { - acpi_os_printf ("\t\t_byte %d: 0x%08x\n", + acpi_os_printf ("\t\t_byte %X: %08X\n", index, vendor_data->reserved[index]); } @@ -324,7 +325,7 @@ acpi_rs_dump_vendor_specific ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_memory24 * @@ -350,23 +351,23 @@ acpi_rs_dump_memory24 ( memory24_data->read_write_attribute ? "/Write" : " only"); - acpi_os_printf ("\t\t_range minimum base: 0x%08x\n", + acpi_os_printf ("\t\t_range minimum base: %08X\n", memory24_data->min_base_address); - acpi_os_printf ("\t\t_range maximum base: 0x%08x\n", + acpi_os_printf ("\t\t_range maximum base: %08X\n", memory24_data->max_base_address); - acpi_os_printf ("\t\t_alignment: 0x%08x\n", + acpi_os_printf ("\t\t_alignment: %08X\n", memory24_data->alignment); - acpi_os_printf ("\t\t_range length: 0x%08x\n", + acpi_os_printf ("\t\t_range length: %08X\n", memory24_data->range_length); return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_memory32 * @@ -392,23 +393,23 @@ acpi_rs_dump_memory32 ( memory32_data->read_write_attribute ? "/Write" : " only"); - acpi_os_printf ("\t\t_range minimum base: 0x%08x\n", + acpi_os_printf ("\t\t_range minimum base: %08X\n", memory32_data->min_base_address); - acpi_os_printf ("\t\t_range maximum base: 0x%08x\n", + acpi_os_printf ("\t\t_range maximum base: %08X\n", memory32_data->max_base_address); - acpi_os_printf ("\t\t_alignment: 0x%08x\n", + acpi_os_printf ("\t\t_alignment: %08X\n", memory32_data->alignment); - acpi_os_printf ("\t\t_range length: 0x%08x\n", + acpi_os_printf ("\t\t_range length: %08X\n", memory32_data->range_length); return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_fixed_memory32 * @@ -434,17 +435,17 @@ acpi_rs_dump_fixed_memory32 ( fixed_memory32_data->read_write_attribute ? "/Write" : " Only"); - acpi_os_printf ("\t\t_range base address: 0x%08x\n", + acpi_os_printf ("\t\t_range base address: %08X\n", fixed_memory32_data->range_base_address); - acpi_os_printf ("\t\t_range length: 0x%08x\n", + acpi_os_printf ("\t\t_range length: %08X\n", fixed_memory32_data->range_length); return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_address16 * @@ -561,23 +562,23 @@ acpi_rs_dump_address16 ( ADDRESS_FIXED == address16_data->max_address_fixed ? "" : "not"); - acpi_os_printf ("\t\t_granularity: 0x%08x\n", + acpi_os_printf ("\t\t_granularity: %08X\n", address16_data->granularity); - acpi_os_printf ("\t\t_address range min: 0x%08x\n", + acpi_os_printf ("\t\t_address range min: %08X\n", address16_data->min_address_range); - acpi_os_printf ("\t\t_address range max: 0x%08x\n", + acpi_os_printf ("\t\t_address range max: %08X\n", address16_data->max_address_range); - acpi_os_printf ("\t\t_address translation offset: 0x%08x\n", + acpi_os_printf ("\t\t_address translation offset: %08X\n", address16_data->address_translation_offset); - acpi_os_printf ("\t\t_address Length: 0x%08x\n", + acpi_os_printf ("\t\t_address Length: %08X\n", address16_data->address_length); if (0xFF != address16_data->resource_source_index) { - acpi_os_printf ("\t\t_resource Source Index: %d\n", + acpi_os_printf ("\t\t_resource Source Index: %X\n", address16_data->resource_source_index); acpi_os_printf ("\t\t_resource Source: %s\n", address16_data->resource_source); @@ -587,7 +588,7 @@ acpi_rs_dump_address16 ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_address32 * @@ -703,23 +704,23 @@ acpi_rs_dump_address32 ( ADDRESS_FIXED == address32_data->max_address_fixed ? "" : "not "); - acpi_os_printf ("\t\t_granularity: 0x%08x\n", + acpi_os_printf ("\t\t_granularity: %08X\n", address32_data->granularity); - acpi_os_printf ("\t\t_address range min: 0x%08x\n", + acpi_os_printf ("\t\t_address range min: %08X\n", address32_data->min_address_range); - acpi_os_printf ("\t\t_address range max: 0x%08x\n", + acpi_os_printf ("\t\t_address range max: %08X\n", address32_data->max_address_range); - acpi_os_printf ("\t\t_address translation offset: 0x%08x\n", + acpi_os_printf ("\t\t_address translation offset: %08X\n", address32_data->address_translation_offset); - acpi_os_printf ("\t\t_address Length: 0x%08x\n", + acpi_os_printf ("\t\t_address Length: %08X\n", address32_data->address_length); if(0xFF != address32_data->resource_source_index) { - acpi_os_printf ("\t\t_resource Source Index: %d\n", + acpi_os_printf ("\t\t_resource Source Index: %X\n", address32_data->resource_source_index); acpi_os_printf ("\t\t_resource Source: %s\n", address32_data->resource_source); @@ -729,7 +730,7 @@ acpi_rs_dump_address32 ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_extended_irq * @@ -767,17 +768,17 @@ acpi_rs_dump_extended_irq ( SHARED == ext_irq_data->shared_exclusive ? "Shared" : "Exclusive"); - acpi_os_printf ("\t\t_interrupts : %d ( ", + acpi_os_printf ("\t\t_interrupts : %X ( ", ext_irq_data->number_of_interrupts); for (index = 0; index < ext_irq_data->number_of_interrupts; index++) { - acpi_os_printf ("%d ", ext_irq_data->interrupts[index]); + acpi_os_printf ("%X ", ext_irq_data->interrupts[index]); } acpi_os_printf (")\n"); if(0xFF != ext_irq_data->resource_source_index) { - acpi_os_printf ("\t\t_resource Source Index: %d", + acpi_os_printf ("\t\t_resource Source Index: %X", ext_irq_data->resource_source_index); acpi_os_printf ("\t\t_resource Source: %s", ext_irq_data->resource_source); @@ -787,7 +788,7 @@ acpi_rs_dump_extended_irq ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_resource_list * @@ -886,7 +887,7 @@ acpi_rs_dump_resource_list ( return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_irq_list * @@ -912,16 +913,16 @@ acpi_rs_dump_irq_list ( prt_element = (PCI_ROUTING_TABLE *)buffer; while (!done) { - acpi_os_printf ("\t_pCI IRQ Routing Table structure %x.\n", count++); + acpi_os_printf ("\t_pCI IRQ Routing Table structure %X.\n", count++); - acpi_os_printf ("\t\t_address: 0x%x\n", + acpi_os_printf ("\t\t_address: %X\n", prt_element->data.address); - acpi_os_printf ("\t\t_pin: 0x%x\n", prt_element->data.pin); + acpi_os_printf ("\t\t_pin: %X\n", prt_element->data.pin); acpi_os_printf ("\t\t_source: %s\n", prt_element->data.source); - acpi_os_printf ("\t\t_source_index: 0x%x\n", + acpi_os_printf ("\t\t_source_index: %X\n", prt_element->data.source_index); buffer += prt_element->length; diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 4620bbf0a..0d6c507c0 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsio - Acpi_rs_io_resource * Acpi_rs_fixed_io_resource @@ -6,9 +6,9 @@ * Acpi_rs_fixed_io_stream * Acpi_rs_dma_resource * Acpi_rs_dma_stream - * $Revision: 7 $ + * $Revision: 10 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -30,16 +30,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsio") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_io_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -55,7 +56,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_io_resource ( @@ -133,11 +134,11 @@ acpi_rs_io_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_io_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -153,7 +154,7 @@ acpi_rs_io_resource ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_io_resource ( @@ -207,11 +208,11 @@ acpi_rs_fixed_io_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_io_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -222,7 +223,7 @@ acpi_rs_fixed_io_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_io_stream ( @@ -239,7 +240,6 @@ acpi_rs_io_stream ( * The descriptor field is static */ *buffer = 0x47; - buffer += 1; /* @@ -248,7 +248,6 @@ acpi_rs_io_stream ( temp8 = (u8) (linked_list->data.io.io_decode & 0x01); *buffer = temp8; - buffer += 1; /* @@ -256,8 +255,7 @@ acpi_rs_io_stream ( */ temp16 = (u16) linked_list->data.io.min_base_address; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -265,8 +263,7 @@ acpi_rs_io_stream ( */ temp16 = (u16) linked_list->data.io.max_base_address; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -275,7 +272,6 @@ acpi_rs_io_stream ( temp8 = (u8) linked_list->data.io.alignment; *buffer = temp8; - buffer += 1; /* @@ -284,7 +280,6 @@ acpi_rs_io_stream ( temp8 = (u8) linked_list->data.io.range_length; *buffer = temp8; - buffer += 1; /* @@ -297,11 +292,11 @@ acpi_rs_io_stream ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_io_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -312,7 +307,7 @@ acpi_rs_io_stream ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_io_stream ( @@ -337,8 +332,7 @@ acpi_rs_fixed_io_stream ( */ temp16 = (u16) linked_list->data.fixed_io.base_address; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -347,7 +341,6 @@ acpi_rs_fixed_io_stream ( temp8 = (u8) linked_list->data.fixed_io.range_length; *buffer = temp8; - buffer += 1; /* @@ -360,11 +353,11 @@ acpi_rs_fixed_io_stream ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_dma_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -380,7 +373,7 @@ acpi_rs_fixed_io_stream ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_dma_resource ( @@ -402,14 +395,12 @@ acpi_rs_dma_resource ( * The number of bytes consumed are Constant */ *bytes_consumed = 3; - output_struct->id = dma; /* * Point to the 8-bits of Byte 1 */ buffer += 1; - temp8 = *buffer; /* Decode the IRQ bits */ @@ -431,9 +422,8 @@ acpi_rs_dma_resource ( /* * Point to Byte 2 */ - buffer += 1; - - temp8 = *buffer; + buffer += 1; + temp8 = *buffer; /* * Check for transfer preference (Bits[1:0]) @@ -468,11 +458,11 @@ acpi_rs_dma_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_dma_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -483,7 +473,7 @@ acpi_rs_dma_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_dma_stream ( @@ -501,9 +491,7 @@ acpi_rs_dma_stream ( * The descriptor field is static */ *buffer = 0x2A; - buffer += 1; - temp8 = 0; /* @@ -518,20 +506,16 @@ acpi_rs_dma_stream ( } *buffer = temp8; - buffer += 1; /* * Set the DMA Info */ temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); - temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); - temp8 |= (linked_list->data.dma.transfer & 0x03); *buffer = temp8; - buffer += 1; /* diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index a5749d5c2..28a3a5045 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -1,12 +1,12 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsirq - Acpi_rs_irq_resource, * Acpi_rs_irq_stream * Acpi_rs_extended_irq_resource * Acpi_rs_extended_irq_stream - * $Revision: 8 $ + * $Revision: 11 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -28,16 +28,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsirq") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_irq_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -53,7 +54,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_irq_resource ( @@ -77,9 +78,7 @@ acpi_rs_irq_resource ( * (Bits:0-1) */ temp8 = *buffer; - *bytes_consumed = (temp8 & 0x03) + 1; - output_struct->id = irq; /* @@ -91,6 +90,7 @@ acpi_rs_irq_resource ( output_struct->data.irq.number_of_interrupts = 0; /* Decode the IRQ bits */ + for (i = 0, index = 0; index < 16; index++) { if((temp16 >> index) & 0x01) { output_struct->data.irq.interrupts[i] = index; @@ -109,7 +109,6 @@ acpi_rs_irq_resource ( */ if (4 == *bytes_consumed) { buffer += 2; - temp8 = *buffer; /* @@ -166,11 +165,11 @@ acpi_rs_irq_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_irq_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -181,7 +180,7 @@ acpi_rs_irq_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_irq_stream ( @@ -213,7 +212,6 @@ acpi_rs_irq_stream ( } buffer += 1; - temp16 = 0; /* @@ -227,8 +225,7 @@ acpi_rs_irq_stream ( temp16 |= 0x1 << temp8; } - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -236,7 +233,6 @@ acpi_rs_irq_stream ( */ if (IRQinfo_byte_needed) { temp8 = 0; - temp8 = (u8) ((linked_list->data.irq.shared_exclusive & 0x01) << 4); @@ -251,7 +247,6 @@ acpi_rs_irq_stream ( } *buffer = temp8; - buffer += 1; } @@ -265,11 +260,11 @@ acpi_rs_irq_stream ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_extended_irq_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -285,7 +280,7 @@ acpi_rs_irq_stream ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_extended_irq_resource ( @@ -450,11 +445,11 @@ acpi_rs_extended_irq_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_extended_irq_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -463,9 +458,9 @@ acpi_rs_extended_irq_resource ( * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code * * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_extended_irq_stream ( @@ -518,7 +513,6 @@ acpi_rs_extended_irq_stream ( temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; *buffer = temp8; - buffer += 1; for (index = 0; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 095325c43..8e39ddded 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -1,10 +1,10 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rslist - Acpi_rs_byte_stream_to_list * Acpi_list_to_byte_stream - * $Revision: 6 $ + * $Revision: 8 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -32,11 +32,11 @@ MODULE_NAME ("rslist") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_byte_stream_to_list * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource byte stream + * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream * Byte_stream_buffer_length - Length of Byte_stream_buffer * Output_buffer - Pointer to the buffer that will * contain the output structures @@ -46,7 +46,7 @@ * DESCRIPTION: Takes the resource byte stream and parses it, creating a * linked list of resources in the caller's output buffer * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_byte_stream_to_list ( @@ -157,7 +157,7 @@ acpi_rs_byte_stream_to_list ( break; -/* 64-bit not currently supported */ +/* TBD: [Future] 64-bit not currently supported */ /* case 0x8A: break; @@ -309,15 +309,14 @@ acpi_rs_byte_stream_to_list ( } return (AE_OK); - -} /* Acpi_rs_byte_stream_to_list */ +} -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_list_to_byte_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Byte_steam_size_needed - Calculated size of the byte stream * needed from calling * Acpi_rs_calculate_byte_stream_length() @@ -332,7 +331,7 @@ acpi_rs_byte_stream_to_list ( * DESCRIPTION: Takes the resource linked list and parses it, creating a * byte stream of resources in the caller's output buffer * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_list_to_byte_stream ( @@ -503,6 +502,5 @@ acpi_rs_list_to_byte_stream ( } return (AE_OK); - -} /* Acpi_rs_list_to_byte_stream */ +} diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index 7d1c7b8a3..8aa4914f4 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsmem24 - Acpi_rs_memory24_resource * Acpi_rs_memory24_stream @@ -6,9 +6,9 @@ * Acpi_rs_fixed_memory32_resource * Acpi_rs_memory32_range_stream * Acpi_rs_fixed_memory32_stream - * $Revision: 7 $ + * $Revision: 10 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -30,16 +30,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsmemory") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory24_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -55,7 +56,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory24_resource ( @@ -78,54 +79,42 @@ acpi_rs_memory24_resource ( buffer += 1; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - *bytes_consumed = temp16 + 3; - output_struct->id = memory24; /* * Check Byte 3 the Read/Write bit */ temp8 = *buffer; - buffer += 1; - output_struct->data.memory24.read_write_attribute = temp8 & 0x01; /* * Get Min_base_address (Bytes 4-5) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - output_struct->data.memory24.min_base_address = temp16; /* * Get Max_base_address (Bytes 6-7) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - output_struct->data.memory24.max_base_address = temp16; /* * Get Alignment (Bytes 8-9) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - output_struct->data.memory24.alignment = temp16; /* * Get Range_length (Bytes 10-11) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - output_struct->data.memory24.range_length = temp16; /* @@ -142,11 +131,11 @@ acpi_rs_memory24_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory24_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -157,7 +146,7 @@ acpi_rs_memory24_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory24_stream ( @@ -174,16 +163,13 @@ acpi_rs_memory24_stream ( * The descriptor field is static */ *buffer = 0x81; - buffer += 1; /* * The length field is static */ temp16 = 0x09; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); - buffer += 2; /* @@ -227,11 +213,11 @@ acpi_rs_memory24_stream ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory32_range_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -247,7 +233,7 @@ acpi_rs_memory24_stream ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory32_range_resource ( @@ -332,11 +318,11 @@ acpi_rs_memory32_range_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_memory32_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -352,7 +338,7 @@ acpi_rs_memory32_range_resource ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_memory32_resource ( @@ -414,11 +400,11 @@ acpi_rs_fixed_memory32_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory32_range_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -429,7 +415,7 @@ acpi_rs_fixed_memory32_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory32_range_stream ( @@ -497,11 +483,11 @@ acpi_rs_memory32_range_stream ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_memory32_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -512,7 +498,7 @@ acpi_rs_memory32_range_stream ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_memory32_stream ( diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index c86700abb..01bbb377e 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsmisc - Acpi_rs_end_tag_resource * Acpi_rs_end_tag_stream @@ -8,9 +8,9 @@ * Acpi_rs_end_dependent_functions_resource * Acpi_rs_start_dependent_functions_stream * Acpi_rs_end_dependent_functions_stream - * $Revision: 7 $ + * $Revision: 10 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -32,16 +32,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsmisc") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_tag_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -57,7 +58,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_tag_resource ( @@ -94,11 +95,11 @@ acpi_rs_end_tag_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_tag_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -109,7 +110,7 @@ acpi_rs_end_tag_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_tag_stream ( @@ -125,7 +126,6 @@ acpi_rs_end_tag_stream ( * The descriptor field is static */ *buffer = 0x79; - buffer += 1; /* @@ -135,7 +135,6 @@ acpi_rs_end_tag_stream ( temp8 = 0; *buffer = temp8; - buffer += 1; /* @@ -147,11 +146,12 @@ acpi_rs_end_tag_stream ( return (AE_OK); } -/*************************************************************************** + +/******************************************************************************* + * * FUNCTION: Acpi_rs_vendor_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -167,7 +167,7 @@ acpi_rs_end_tag_stream ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_vendor_resource ( @@ -230,7 +230,6 @@ acpi_rs_vendor_resource ( } output_struct->id = vendor_specific; - output_struct->data.vendor_specific.length = temp16; for (index = 0; index < temp16; index++) { @@ -259,11 +258,11 @@ acpi_rs_vendor_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_vendor_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -274,7 +273,7 @@ acpi_rs_vendor_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_vendor_stream ( @@ -300,13 +299,11 @@ acpi_rs_vendor_stream ( * Set the descriptor field and length bytes */ *buffer = 0x84; - buffer += 1; temp16 = (u16) linked_list->data.vendor_specific.length; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; } @@ -319,11 +316,9 @@ acpi_rs_vendor_stream ( * Set the descriptor field */ temp8 = 0x70; - temp8 |= linked_list->data.vendor_specific.length; *buffer = temp8; - buffer += 1; } @@ -332,6 +327,7 @@ acpi_rs_vendor_stream ( */ for (index = 0; index < linked_list->data.vendor_specific.length; index++) { temp8 = linked_list->data.vendor_specific.reserved[index]; + *buffer = temp8; buffer += 1; } @@ -345,11 +341,12 @@ acpi_rs_vendor_stream ( return (AE_OK); } -/*************************************************************************** + +/******************************************************************************* + * * FUNCTION: Acpi_rs_start_dependent_functions_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -365,7 +362,7 @@ acpi_rs_vendor_stream ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_start_dependent_functions_resource ( @@ -441,11 +438,11 @@ acpi_rs_start_dependent_functions_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_dependent_functions_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -461,7 +458,7 @@ acpi_rs_start_dependent_functions_resource ( * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_dependent_functions_resource ( @@ -498,11 +495,11 @@ acpi_rs_end_dependent_functions_resource ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_start_dependent_functions_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -513,7 +510,8 @@ acpi_rs_end_dependent_functions_resource ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ + ACPI_STATUS acpi_rs_start_dependent_functions_stream ( RESOURCE *linked_list, @@ -537,18 +535,15 @@ acpi_rs_start_dependent_functions_stream ( } else { *buffer = 0x31; - buffer += 1; /* * Set the Priority Byte Definition */ temp8 = 0; - temp8 = (u8) ((linked_list->data.start_dependent_functions.performance_robustness & 0x03) << 2); - temp8 |= (linked_list->data.start_dependent_functions.compatibility_priority & 0x03); @@ -568,11 +563,11 @@ acpi_rs_start_dependent_functions_stream ( } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_dependent_functions_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -583,7 +578,7 @@ acpi_rs_start_dependent_functions_stream ( * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_dependent_functions_stream ( @@ -599,7 +594,6 @@ acpi_rs_end_dependent_functions_stream ( * The descriptor field is static */ *buffer = 0x38; - buffer += 1; /* diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 659b2fe40..0a3f76668 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsutils - Utilities for the resource manager - * $Revision: 10 $ + * $Revision: 12 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -33,7 +33,7 @@ MODULE_NAME ("rsutils") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_get_prt_method_data * @@ -117,7 +117,7 @@ cleanup: } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_get_crs_method_data * @@ -200,7 +200,7 @@ cleanup: } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_get_prs_method_data * @@ -281,7 +281,7 @@ cleanup: } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_set_srs_method_data * @@ -310,6 +310,7 @@ acpi_rs_set_srs_method_data ( u8 *byte_stream = NULL; u32 buffer_size_needed = 0; + /* already validated params, so we won't repeat here */ /* @@ -325,7 +326,6 @@ acpi_rs_set_srs_method_data ( status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, &buffer_size_needed); - /* * We expect a return of AE_BUFFER_OVERFLOW * if not, exit with the error @@ -338,7 +338,6 @@ acpi_rs_set_srs_method_data ( * Allocate the buffer needed */ byte_stream = acpi_cm_callocate(buffer_size_needed); - if (NULL == byte_stream) { return (AE_NO_MEMORY); } @@ -349,7 +348,6 @@ acpi_rs_set_srs_method_data ( status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, &buffer_size_needed); - if (ACPI_FAILURE (status)) { goto cleanup; } diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index f09643399..8691f8200 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsxface - Public interfaces to the ACPI subsystem - * $Revision: 7 $ + * $Revision: 8 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -33,7 +33,7 @@ MODULE_NAME ("rsxface") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_get_irq_routing_table * @@ -83,7 +83,7 @@ acpi_get_irq_routing_table ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_get_current_resources * @@ -134,7 +134,7 @@ acpi_get_current_resources ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_get_possible_resources * @@ -142,7 +142,7 @@ acpi_get_current_resources ( * device we are querying * Ret_buffer - a pointer to a buffer to receive the * resources for the device - * + * * RETURN: Status - the status of the call * * DESCRIPTION: This function is called to get a list of the possible resources @@ -182,7 +182,7 @@ acpi_get_possible_resources ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_set_current_resources * diff --git a/drivers/acpi/sys.c b/drivers/acpi/sys.c index d4206631e..13648c255 100644 --- a/drivers/acpi/sys.c +++ b/drivers/acpi/sys.c @@ -27,16 +27,14 @@ #define _COMPONENT OS_DEPENDENT MODULE_NAME ("sys") -#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb)) -#define ACPI_SLP_TYPA(value) \ - ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) -#define ACPI_SLP_TYPB(value) \ - ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) +#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb)) +#define ACPI_SLP_TYPA(value) ((value) >> 8) +#define ACPI_SLP_TYPB(value) ((value) & 0xff) struct acpi_enter_sx_ctx { wait_queue_head_t wait; - int state; + unsigned int state; }; volatile acpi_sstate_t acpi_sleep_state = ACPI_S0; @@ -49,10 +47,8 @@ static void acpi_enter_sx_async(void *context) { struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context; - struct acpi_facp *facp = &acpi_facp; ACPI_OBJECT_LIST arg_list; ACPI_OBJECT arg; - u16 value; /* * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. @@ -69,34 +65,26 @@ acpi_enter_sx_async(void *context) acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL); - // clear wake status - acpi_write_pm1_status(facp, ACPI_WAK); - + // clear wake status by writing a 1 + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1); + acpi_sleep_state = ctx->state; // set ACPI_SLP_TYPA/b and ACPI_SLP_EN - __cli(); - if (facp->pm1a_cnt) { - value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK; - value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state]) - | ACPI_SLP_EN); - outw(value, facp->pm1a_cnt); - } - if (facp->pm1b_cnt) { - value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK; - value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state]) - | ACPI_SLP_EN); - outw(value, facp->pm1b_cnt); - } - __sti(); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_TYPE_A, + ACPI_SLP_TYPA(acpi_slptyp[ctx->state])); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_TYPE_B, + ACPI_SLP_TYPB(acpi_slptyp[ctx->state])); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_EN, 1); if (ctx->state != ACPI_S1) { + /* we should have just shut off - what are we doing here? */ printk(KERN_ERR "ACPI: S%d failed\n", ctx->state); goto out; } // wait until S1 is entered - while (!(acpi_read_pm1_status(facp) & ACPI_WAK)) + while (!(acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, WAK_STS))) safe_halt(); // run the _WAK method @@ -125,7 +113,7 @@ acpi_power_off(void) { struct acpi_enter_sx_ctx ctx; - if (acpi_facp.hdr.signature != ACPI_FACP_SIG + if ((STRNCMP(acpi_fadt.header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) || acpi_slptyp[ACPI_S5] == ACPI_INVALID) return; @@ -141,44 +129,59 @@ int acpi_enter_sx(acpi_sstate_t state) { struct acpi_enter_sx_ctx ctx; + DECLARE_WAITQUEUE(wait, current); + int ret = 0; - if (acpi_facp.hdr.signature != ACPI_FACP_SIG + if ((STRNCMP(acpi_fadt.header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) || acpi_slptyp[state] == ACPI_INVALID) return -EINVAL; init_waitqueue_head(&ctx.wait); ctx.state = state; + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&ctx.wait, &wait); + if (acpi_os_queue_for_execution(0, acpi_enter_sx_async, &ctx)) - return -1; + ret = -1; - interruptible_sleep_on(&ctx.wait); - if (signal_pending(current)) - return -ERESTARTSYS; + if (!ret) + schedule(); - return 0; + set_current_state(TASK_RUNNING); + remove_wait_queue(&ctx.wait, &wait); + + if (!ret && signal_pending(current)) + ret = -ERESTARTSYS; + + return ret; } int acpi_sys_init(void) { - u8 sx, typa, typb; + u8 sx; + u8 type_a; + u8 type_b; + + printk(KERN_INFO "ACPI: System firmware supports:"); for (sx = ACPI_S0; sx <= ACPI_S5; sx++) { int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1); if (ACPI_SUCCESS( acpi_hw_obtain_sleep_type_register_data(ca_sx, - &typa, - &typb))) - acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb); - else + &type_a, + &type_b))) { + + acpi_slptyp[sx] = ACPI_SLP_TYP(type_a, type_b); + printk(" S%d", sx); + } + else { acpi_slptyp[sx] = ACPI_INVALID; + } } - if (acpi_slptyp[ACPI_S1] != ACPI_INVALID) - printk(KERN_INFO "ACPI: S1 supported\n"); - if (acpi_slptyp[ACPI_S5] != ACPI_INVALID) - printk(KERN_INFO "ACPI: S5 supported\n"); - + printk("\n"); + pm_power_off = acpi_power_off; return 0; diff --git a/drivers/acpi/table.c b/drivers/acpi/table.c index 5123b94ff..8379b4204 100644 --- a/drivers/acpi/table.c +++ b/drivers/acpi/table.c @@ -1,5 +1,5 @@ /* - * tables.c - ACPI tables, chipset, and errata handling + * table.c - ACPI tables, chipset, and errata handling * * Copyright (C) 2000 Andrew Henroid * @@ -27,250 +27,39 @@ #include "driver.h" #define _COMPONENT OS_DEPENDENT - MODULE_NAME ("tables") + MODULE_NAME ("table") -struct acpi_facp acpi_facp; - -#define ACPI_DUMMY_CHECKSUM 9 -#define ACPI_DUMMY_PBLK 51 - -static u8 acpi_dummy_dsdt[] = -{ - 0x44, 0x53, 0x44, 0x54, // "DSDT" - 0x38, 0x00, 0x00, 0x00, // length - 0x01, // revision - 0x00, // checksum - 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX" - 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY" - 0x01, 0x00, 0x00, 0x00, // OEM rev - 0x4c, 0x4e, 0x55, 0x58, // "LNUX" - 0x01, 0x00, 0x00, 0x00, // creator rev - 0x10, // Scope - 0x13, // PkgLength - 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_ - 0x5b, 0x83, // Processor - 0x0b, // PkgLength - 0x43, 0x50, 0x55, 0x30, // CPU0 - 0x00, // ID - 0x00, 0x00, 0x00, 0x00, // PBLK - 0x06 // PBLK size -}; - -/* - * Calculate and set ACPI table checksum - */ -static void -acpi_set_checksum(u8 *table, int size) -{ - int i, sum = 0; - for (i = 0; i < size; i++) - sum += (int) table[i]; - sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff)); - table[ACPI_DUMMY_CHECKSUM] = sum; -} - -/* - * Init PIIX4 device, create a fake FACP - */ -static int -acpi_init_piix4(struct pci_dev *dev) -{ - u32 base, pblk; - u16 cmd; - u8 pmregmisc; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (!(cmd & PCI_COMMAND_IO)) - return -ENODEV; - - pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc); - if (!(pmregmisc & ACPI_PIIX4_PMIOSE)) - return -ENODEV; - - base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES); - if (!base) - return -ENODEV; - - printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); - - memset(&acpi_facp, 0, sizeof(acpi_facp)); - acpi_facp.hdr.signature = ACPI_FACP_SIG; - acpi_facp.hdr.length = sizeof(acpi_facp); - acpi_facp.int_model = ACPI_PIIX4_INT_MODEL; - acpi_facp.sci_int = ACPI_PIIX4_SCI_INT; - acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD; - acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE; - acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE; - acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ; - acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT; - acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT; - acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT; - acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR; - acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0; - acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN; - acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN; - acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN; - acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN; - acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN; - acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; - acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; - - acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); - acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); - - pblk = base + ACPI_PIIX4_P_BLK; - memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); - acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); - acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); - - return 0; -} +FADT_DESCRIPTOR acpi_fadt; /* - * Init VIA ACPI device and create a fake FACP + * Fetch the fadt information */ static int -acpi_init_via(struct pci_dev *dev) -{ - u32 base, pblk; - u8 tmp, irq; - - pci_read_config_byte(dev, 0x41, &tmp); - if (!(tmp & 0x80)) - return -ENODEV; - - base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES); - if (!base) { - base = pci_resource_start(dev, PCI_BASE_ADDRESS_4); - if (!base) - return -ENODEV; - } - - pci_read_config_byte(dev, 0x42, &irq); - - printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); - - memset(&acpi_facp, 0, sizeof(acpi_facp)); - acpi_facp.hdr.signature = ACPI_FACP_SIG; - acpi_facp.hdr.length = sizeof(acpi_facp); - acpi_facp.int_model = ACPI_VIA_INT_MODEL; - acpi_facp.sci_int = irq; - acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD; - acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE; - acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE; - acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT; - acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT; - acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR; - acpi_facp.gpe0 = base + ACPI_VIA_GPE0; - - acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN; - acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN; - acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN; - acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN; - acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; - acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; - - acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET; - acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH; - - acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM; - acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM; - acpi_facp.century = ACPI_VIA_CENTURY; - - acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); - acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); - - pblk = base + ACPI_VIA_P_BLK; - memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); - acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); - acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); - - return 0; -} - -typedef enum -{ - CH_UNKNOWN = 0, - CH_INTEL_PIIX4, - CH_VIA_586, - CH_VIA_686A, -} acpi_chip_t; - -/* indexed by value of each enum in acpi_chip_t */ -const static struct -{ - int (*chip_init)(struct pci_dev *dev); -} acpi_chip_info[] = -{ - {NULL,}, - {acpi_init_piix4}, - {acpi_init_via}, - {acpi_init_via}, -}; - -static struct pci_device_id acpi_pci_tbl[] = -{ - {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, - {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586}, - {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A}, - {0,} /* terminate list */ -}; - -static int -acpi_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - return acpi_chip_info[id->driver_data].chip_init(dev); -} - -static struct pci_driver acpi_driver = -{ - name: "acpi", - id_table: acpi_pci_tbl, - probe: acpi_probe, -}; -static int acpi_driver_registered = 0; - -/* - * Locate a known ACPI chipset - */ -static int -acpi_find_chipset(void) -{ - if (pci_register_driver(&acpi_driver) < 1) - return -ENODEV; - acpi_driver_registered = 1; - return 0; -} - -/* - * Fetch the FACP information - */ -static int -acpi_fetch_facp(void) +acpi_fetch_fadt(void) { ACPI_BUFFER buffer; - memset(&acpi_facp, 0, sizeof(acpi_facp)); - buffer.pointer = &acpi_facp; - buffer.length = sizeof(acpi_facp); - if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) { - printk(KERN_ERR "ACPI: missing FACP\n"); + memset(&acpi_fadt, 0, sizeof(acpi_fadt)); + buffer.pointer = &acpi_fadt; + buffer.length = sizeof(acpi_fadt); + if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) { + printk(KERN_ERR "ACPI: missing fadt\n"); return -ENODEV; } - if (acpi_facp.p_lvl2_lat - && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) { + if (acpi_fadt.plvl2_lat + && acpi_fadt.plvl2_lat <= ACPI_MAX_P_LVL2_LAT) { acpi_c2_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat); acpi_c2_enter_latency - = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); + = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); } - if (acpi_facp.p_lvl3_lat - && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) { + if (acpi_fadt.plvl3_lat + && acpi_fadt.plvl3_lat <= ACPI_MAX_P_LVL3_LAT) { acpi_c3_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat); acpi_c3_enter_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5); } return 0; @@ -280,24 +69,19 @@ acpi_fetch_facp(void) * Find and load ACPI tables */ int -acpi_load_tables(void) +acpi_find_and_load_tables(u64 rsdp) { - if (ACPI_SUCCESS(acpi_load_firmware_tables())) + if (ACPI_SUCCESS(acpi_load_tables(rsdp))) { - printk(KERN_INFO "ACPI: support found\n"); + printk(KERN_INFO "ACPI: System description tables loaded\n"); } - else if (acpi_find_chipset()) { - acpi_terminate(); - return -1; - } - - if (acpi_fetch_facp()) { + else { + printk(KERN_INFO "ACPI: System description table load failed\n"); acpi_terminate(); return -1; } - if (!ACPI_SUCCESS(acpi_load_namespace())) { - printk(KERN_ERR "ACPI: namespace load failed\n"); + if (acpi_fetch_fadt()) { acpi_terminate(); return -1; } diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile index edd897133..751ef5de8 100644 --- a/drivers/acpi/tables/Makefile +++ b/drivers/acpi/tables/Makefile @@ -2,26 +2,14 @@ # Makefile for all Linux ACPI interpreter subdirectories # -SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) -MOD_IN_SUB_DIRS := -ALL_SUB_DIRS := $(SUB_DIRS) - O_TARGET := ../$(shell basename `pwd`).o -O_OBJS := -M_OBJS := -ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) +obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c)) EXTRA_CFLAGS += -I../include EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) - O_OBJS := $(ACPI_OBJS) -endif - include $(TOPDIR)/Rules.make clean: diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c new file mode 100644 index 000000000..624926d27 --- /dev/null +++ b/drivers/acpi/tables/tbconvrt.c @@ -0,0 +1,553 @@ +/****************************************************************************** + * + * Module Name: tbconvrt - ACPI Table conversion utilities + * $Revision: 15 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "achware.h" +#include "actables.h" +#include "actbl.h" + + +#define _COMPONENT TABLE_MANAGER + MODULE_NAME ("tbconvrt") + + +/* + * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions) + * + * 1) Address space + * 2) Length in bytes -- convert to length in bits + * 3) Bit offset is zero + * 4) Reserved field is zero + * 5) Expand address to 64 bits + */ +#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d) {a.address_space_id = (u8) d;\ + a.register_bit_width = (u8) MUL_8 (b);\ + a.register_bit_offset = 0;\ + a.reserved = 0;\ + a.address = (UINT64) c;} + + +/* ACPI V1.0 entries -- address space is always I/O */ + +#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c) ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ADDRESS_SPACE_SYSTEM_IO) + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_convert_to_xsdt + * + * PARAMETERS: + * + * RETURN: + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_convert_to_xsdt ( + ACPI_TABLE_DESC *table_info, + u32 *number_of_tables) +{ + u32 table_size; + u32 pointer_size; + u32 i; + XSDT_DESCRIPTOR *new_table; + + +#ifndef _IA64 + + if (acpi_gbl_RSDP->revision < 2) { + pointer_size = sizeof (u32); + } + + else +#endif + { + pointer_size = sizeof (UINT64); + } + + /* + * Determine the number of tables pointed to by the RSDT/XSDT. + * This is defined by the ACPI Specification to be the number of + * pointers contained within the RSDT/XSDT. The size of the pointers + * is architecture-dependent. + */ + + table_size = table_info->pointer->length; + *number_of_tables = (table_size - + sizeof (ACPI_TABLE_HEADER)) / pointer_size; + + /* Compute size of the converted XSDT */ + + table_size = (*number_of_tables * sizeof (UINT64)) + sizeof (ACPI_TABLE_HEADER); + + + /* Allocate an XSDT */ + + new_table = acpi_cm_callocate (table_size); + if (!new_table) { + return (AE_NO_MEMORY); + } + + /* Copy the header and set the length */ + + MEMCPY (new_table, table_info->pointer, sizeof (ACPI_TABLE_HEADER)); + new_table->header.length = table_size; + + /* Copy the table pointers */ + + for (i = 0; i < *number_of_tables; i++) { + if (acpi_gbl_RSDP->revision < 2) { +#ifdef _IA64 + new_table->table_offset_entry[i] = + ((RSDT_DESCRIPTOR_REV071 *) table_info->pointer)->table_offset_entry[i]; +#else + new_table->table_offset_entry[i] = + ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]; +#endif + } + else { + new_table->table_offset_entry[i] = + ((XSDT_DESCRIPTOR *) table_info->pointer)->table_offset_entry[i]; + } + } + + + /* Delete the original table (either mapped or in a buffer) */ + + acpi_tb_delete_single_table (table_info); + + + /* Point the table descriptor to the new table */ + + table_info->pointer = (ACPI_TABLE_HEADER *) new_table; + table_info->base_pointer = (ACPI_TABLE_HEADER *) new_table; + table_info->length = table_size; + table_info->allocation = ACPI_MEM_ALLOCATED; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_convert_table_fadt + * + * PARAMETERS: + * + * RETURN: + * + * DESCRIPTION: + * Converts BIOS supplied 1.0 and 0.71 ACPI FADT to an intermediate + * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply + * copied to the intermediate FADT. The ACPI CA software uses this + * intermediate FADT. Thus a significant amount of special #ifdef + * type codeing is saved. This intermediate FADT will need to be + * freed at some point. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_convert_table_fadt (void) +{ + +#ifdef _IA64 + FADT_DESCRIPTOR_REV071 *FADT71; + u8 pm1_address_space; + u8 pm2_address_space; + u8 pm_timer_address_space; + u8 gpe0address_space; + u8 gpe1_address_space; +#else + FADT_DESCRIPTOR_REV1 *FADT1; +#endif + + FADT_DESCRIPTOR_REV2 *FADT2; + ACPI_TABLE_DESC *table_desc; + + + /* Acpi_gbl_FADT is valid */ + /* Allocate and zero the 2.0 buffer */ + + FADT2 = acpi_cm_callocate (sizeof (FADT_DESCRIPTOR_REV2)); + if (FADT2 == NULL) { + return (AE_NO_MEMORY); + } + + + /* The ACPI FADT revision number is FADT2_REVISION_ID=3 */ + /* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */ + + if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) { + /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ + + *FADT2 = *((FADT_DESCRIPTOR_REV2*) acpi_gbl_FADT); + + } + + else { + +#ifdef _IA64 + /* + * For the 64-bit case only, a revision ID less than V2.0 means the + * tables are the 0.71 extensions + */ + + /* The BIOS stored FADT should agree with Revision 0.71 */ + + FADT71 = (FADT_DESCRIPTOR_REV071 *) acpi_gbl_FADT; + + /* Copy the table header*/ + + FADT2->header = FADT71->header; + + /* Copy the common fields */ + + FADT2->sci_int = FADT71->sci_int; + FADT2->acpi_enable = FADT71->acpi_enable; + FADT2->acpi_disable = FADT71->acpi_disable; + FADT2->S4_bios_req = FADT71->S4_bios_req; + FADT2->plvl2_lat = FADT71->plvl2_lat; + FADT2->plvl3_lat = FADT71->plvl3_lat; + FADT2->day_alrm = FADT71->day_alrm; + FADT2->mon_alrm = FADT71->mon_alrm; + FADT2->century = FADT71->century; + FADT2->gpe1_base = FADT71->gpe1_base; + + /* + * We still use the block length registers even though + * the GAS structure should obsolete them. This is because + * these registers are byte lengths versus the GAS which + * contains a bit width + */ + FADT2->pm1_evt_len = FADT71->pm1_evt_len; + FADT2->pm1_cnt_len = FADT71->pm1_cnt_len; + FADT2->pm2_cnt_len = FADT71->pm2_cnt_len; + FADT2->pm_tm_len = FADT71->pm_tm_len; + FADT2->gpe0blk_len = FADT71->gpe0blk_len; + FADT2->gpe1_blk_len = FADT71->gpe1_blk_len; + FADT2->gpe1_base = FADT71->gpe1_base; + + /* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/ + + FADT2->wb_invd = FADT71->flush_cash; + FADT2->proc_c1 = FADT71->proc_c1; + FADT2->plvl2_up = FADT71->plvl2_up; + FADT2->pwr_button = FADT71->pwr_button; + FADT2->sleep_button = FADT71->sleep_button; + FADT2->fixed_rTC = FADT71->fixed_rTC; + FADT2->rtcs4 = FADT71->rtcs4; + FADT2->tmr_val_ext = FADT71->tmr_val_ext; + FADT2->dock_cap = FADT71->dock_cap; + + + /* We should not use these next two addresses */ + /* Since our buffer is pre-zeroed nothing to do for */ + /* the next three data items in the structure */ + /* FADT2->Firmware_ctrl = 0; */ + /* FADT2->Dsdt = 0; */ + + /* System Interrupt Model isn't used in ACPI 2.0*/ + /* FADT2->Reserved1 = 0; */ + + /* This field is set by the OEM to convey the preferred */ + /* power management profile to OSPM. It doesn't have any*/ + /* 0.71 equivalence. Since we don't know what kind of */ + /* 64-bit system this is, we will pick unspecified. */ + + FADT2->prefer_PM_profile = PM_UNSPECIFIED; + + + /* Port address of SMI command port */ + /* We shouldn't use this port because IA64 doesn't */ + /* have or use SMI. It has PMI. */ + + FADT2->smi_cmd = (u32)(FADT71->smi_cmd & 0xFFFFFFFF); + + + /* processor performance state control*/ + /* The value OSPM writes to the SMI_CMD register to assume */ + /* processor performance state control responsibility. */ + /* There isn't any equivalence in 0.71 */ + /* Again this should be meaningless for IA64 */ + /* FADT2->Pstate_cnt = 0; */ + + /* The 32-bit Power management and GPE registers are */ + /* not valid in IA-64 and we are not going to use them */ + /* so leaving them pre-zeroed. */ + + /* Support for the _CST object and C States change notification.*/ + /* This data item hasn't any 0.71 equivalence so leaving it zero.*/ + /* FADT2->Cst_cnt = 0; */ + + /* number of flush strides that need to be read */ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Flush_size = 0; */ + + /* Processor's memory cache line width, in bytes */ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Flush_stride = 0; */ + + /* Processor’s duty cycle index in processor's P_CNT reg*/ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Duty_offset = 0; */ + + /* Processor’s duty cycle value bit width in P_CNT register.*/ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Duty_width = 0; */ + + + /* Since there isn't any equivalence in 0.71 */ + /* and since Big_sur had to support legacy */ + + FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + + /* Copy to ACPI 2.0 64-BIT Extended Addresses */ + + FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl; + FADT2->Xdsdt = FADT71->dsdt; + + + /* Extract the address space IDs */ + + pm1_address_space = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE) >> 1); + pm2_address_space = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2); + pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3); + gpe0address_space = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE) >> 4); + gpe1_address_space = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE) >> 5); + + /* + * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures, + * in this order: + * + * PM 1_a Events + * PM 1_b Events + * PM 1_a Control + * PM 1_b Control + * PM 2 Control + * PM Timer Control + * GPE Block 0 + * GPE Block 1 + */ + + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len, FADT71->pm_tmr_blk, pm_timer_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk, FADT71->gpe0blk_len, FADT71->gpe0blk, gpe0address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk, FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space); + +#else + + /* ACPI 1.0 FACS */ + + + /* The BIOS stored FADT should agree with Revision 1.0 */ + + FADT1 = (FADT_DESCRIPTOR_REV1*) acpi_gbl_FADT; + + /* + * Copy the table header and the common part of the tables + * The 2.0 table is an extension of the 1.0 table, so the + * entire 1.0 table can be copied first, then expand some + * fields to 64 bits. + */ + + MEMCPY (FADT2, FADT1, sizeof (FADT_DESCRIPTOR_REV1)); + + + /* Convert table pointers to 64-bit fields */ + + FADT2->Xfirmware_ctrl = (UINT64) FADT1->firmware_ctrl; + FADT2->Xdsdt = (UINT64) FADT1->dsdt; + + /* System Interrupt Model isn't used in ACPI 2.0*/ + /* FADT2->Reserved1 = 0; */ + + /* This field is set by the OEM to convey the preferred */ + /* power management profile to OSPM. It doesn't have any*/ + /* 1.0 equivalence. Since we don't know what kind of */ + /* 32-bit system this is, we will pick unspecified. */ + + FADT2->prefer_PM_profile = PM_UNSPECIFIED; + + + /* Processor Performance State Control. This is the value */ + /* OSPM writes to the SMI_CMD register to assume processor */ + /* performance state control responsibility. There isn't */ + /* any equivalence in 1.0. So leave it zeroed. */ + + FADT2->pstate_cnt = 0; + + + /* Support for the _CST object and C States change notification.*/ + /* This data item hasn't any 1.0 equivalence so leaving it zero.*/ + + FADT2->cst_cnt = 0; + + + /* Since there isn't any equivalence in 1.0 and since it */ + /* is highly likely that a 1.0 system has legacy support. */ + + FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + + + /* + * Convert the V1.0 Block addresses to V2.0 GAS structures + * in this order: + * + * PM 1_a Events + * PM 1_b Events + * PM 1_a Control + * PM 1_b Control + * PM 2 Control + * PM Timer Control + * GPE Block 0 + * GPE Block 1 + */ + + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len, FADT1->pm_tmr_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk, FADT1->gpe0blk_len, FADT1->gpe0blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk, FADT1->gpe1_blk_len, FADT1->gpe1_blk); +#endif + } + + + /* + * Global FADT pointer will point to the common V2.0 FADT + */ + acpi_gbl_FADT = FADT2; + + + /* Free the original table */ + + table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT]; + acpi_tb_delete_single_table (table_desc); + + + /* Install the new table */ + + table_desc->pointer = (ACPI_TABLE_HEADER *) acpi_gbl_FADT; + table_desc->base_pointer = acpi_gbl_FADT; + table_desc->allocation = ACPI_MEM_ALLOCATED; + table_desc->length = sizeof (FADT_DESCRIPTOR_REV2); + + + /* Dump the FADT Header */ + + /* Dump the entire FADT */ + + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_convert_table_facs + * + * PARAMETERS: + * + * RETURN: + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_build_common_facs ( + ACPI_TABLE_DESC *table_info) +{ + ACPI_COMMON_FACS *common_facs; + +#ifdef _IA64 + FACS_DESCRIPTOR_REV071 *FACS71; +#else + FACS_DESCRIPTOR_REV1 *FACS1; +#endif + + FACS_DESCRIPTOR_REV2 *FACS2; + + + /* Allocate a common FACS */ + + common_facs = acpi_cm_callocate (sizeof (ACPI_COMMON_FACS)); + if (!common_facs) { + return (AE_NO_MEMORY); + } + + + /* Copy fields to the new FACS */ + + if (acpi_gbl_RSDP->revision < 2) { +#ifdef _IA64 + /* 0.71 FACS */ + + FACS71 = (FACS_DESCRIPTOR_REV071 *) acpi_gbl_FACS; + + common_facs->global_lock = (u32 *) &(FACS71->global_lock); + common_facs->firmware_waking_vector = &FACS71->firmware_waking_vector; + common_facs->vector_width = 64; +#else + /* ACPI 1.0 FACS */ + + FACS1 = (FACS_DESCRIPTOR_REV1 *) acpi_gbl_FACS; + + common_facs->global_lock = &(FACS1->global_lock); + common_facs->firmware_waking_vector = (UINT64 *) &FACS1->firmware_waking_vector; + common_facs->vector_width = 32; + +#endif + } + + else { + /* ACPI 2.0 FACS */ + + FACS2 = (FACS_DESCRIPTOR_REV2 *) acpi_gbl_FACS; + + common_facs->global_lock = &(FACS2->global_lock); + common_facs->firmware_waking_vector = &FACS2->Xfirmware_waking_vector; + common_facs->vector_width = 64; + } + + + /* Set the global FACS pointer to point to the common FACS */ + + + acpi_gbl_FACS = common_facs; + + return (AE_OK); +} + + diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 19a8f0a2a..2cf8eede7 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbget - ACPI Table get* routines - * $Revision: 22 $ + * $Revision: 40 $ * *****************************************************************************/ @@ -32,6 +32,7 @@ #define _COMPONENT TABLE_MANAGER MODULE_NAME ("tbget") +#define RSDP_CHECKSUM_LENGTH 20 /******************************************************************************* * @@ -127,7 +128,7 @@ acpi_tb_get_table_ptr ( ACPI_STATUS acpi_tb_get_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, ACPI_TABLE_HEADER *buffer_ptr, ACPI_TABLE_DESC *table_info) { @@ -239,9 +240,10 @@ acpi_tb_get_all_tables ( MEMSET (&table_info, 0, sizeof (ACPI_TABLE_DESC)); - /* Get the table via the RSDT */ + /* Get the table via the XSDT */ - status = acpi_tb_get_table ((void *) acpi_gbl_RSDT->table_offset_entry[index], + status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) + acpi_gbl_XSDT->table_offset_entry[index], table_ptr, &table_info); /* Ignore a table that failed verification */ @@ -266,15 +268,25 @@ acpi_tb_get_all_tables ( * determine if there are enough tables to continue. */ - acpi_tb_delete_single_table (&table_info); + acpi_tb_uninstall_table (&table_info); } } /* + * Convert the FADT to a common format. This allows earlier revisions of the + * table to coexist with newer versions, using common access code. + */ + status = acpi_tb_convert_table_fadt (); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* * Get the minimum set of ACPI tables, namely: * - * 1) FACP (via RSDT in loop above) + * 1) FADT (via RSDT in loop above) * 2) FACS * 3) DSDT * @@ -282,8 +294,8 @@ acpi_tb_get_all_tables ( /* - * Get the FACS (must have the FACP first, from loop above) - * Acpi_tb_get_table_facs will fail if FACP pointer is not valid + * Get the FACS (must have the FADT first, from loop above) + * Acpi_tb_get_table_facs will fail if FADT pointer is not valid */ status = acpi_tb_get_table_facs (table_ptr, &table_info); @@ -291,6 +303,7 @@ acpi_tb_get_all_tables ( return (status); } + /* Install the FACS */ status = acpi_tb_install_table (table_ptr, &table_info); @@ -298,10 +311,22 @@ acpi_tb_get_all_tables ( return (status); } + /* + * Create the common FACS pointer table + * (Contains pointers to the original table) + */ - /* Get the DSDT (We know that the FACP if valid now) */ + status = acpi_tb_build_common_facs (&table_info); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* + * Get the DSDT (We know that the FADT is valid now) + */ - status = acpi_tb_get_table ((void *) acpi_gbl_FACP->dsdt, table_ptr, &table_info); + status = acpi_tb_get_table (acpi_gbl_FADT->Xdsdt, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return (status); } @@ -321,9 +346,265 @@ acpi_tb_get_all_tables ( * Initialize the capabilities flags. * Assumes that platform supports ACPI_MODE since we have tables! */ - acpi_gbl_system_flags |= acpi_hw_get_mode_capabilities (); + + /* Always delete the RSDP mapping, we are done with it */ + + acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP); + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_verify_rsdp + * + * PARAMETERS: Number_of_tables - Where the table count is placed + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_verify_rsdp ( + ACPI_PHYSICAL_ADDRESS rsdp_physical_address) +{ + ACPI_TABLE_DESC table_info; + ACPI_STATUS status; + u8 *table_ptr; + + + /* + * Obtain access to the RSDP structure + */ + status = acpi_os_map_memory (rsdp_physical_address, + sizeof (RSDP_DESCRIPTOR), + (void **) &table_ptr); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* + * The signature and checksum must both be correct + */ + if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { + /* Nope, BAD Signature */ + + status = AE_BAD_SIGNATURE; + goto cleanup; + } + + if (acpi_tb_checksum (table_ptr, RSDP_CHECKSUM_LENGTH) != 0) { + /* Nope, BAD Checksum */ + + status = AE_BAD_CHECKSUM; + goto cleanup; + } + + /* TBD: Check extended checksum if table version >= 2 */ + + /* The RSDP supplied is OK */ + + table_info.pointer = (ACPI_TABLE_HEADER *) table_ptr; + table_info.length = sizeof (RSDP_DESCRIPTOR); + table_info.allocation = ACPI_MEM_MAPPED; + table_info.base_pointer = table_ptr; + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + + /* Save the RSDP in a global for easy access */ + + acpi_gbl_RSDP = (RSDP_DESCRIPTOR *) table_info.pointer; + return (status); + + + /* Error exit */ +cleanup: + + acpi_os_unmap_memory (table_ptr, sizeof (RSDP_DESCRIPTOR)); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_get_table_rsdt + * + * PARAMETERS: Number_of_tables - Where the table count is placed + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_get_table_rsdt ( + u32 *number_of_tables) +{ + ACPI_TABLE_DESC table_info; + ACPI_STATUS status = AE_OK; + ACPI_PHYSICAL_ADDRESS physical_address; + u32 signature_length; + char *table_signature; + + + /* + * Get the RSDT from the RSDP + */ + + /* + * For RSDP revision 0 or 1, we use the RSDT. + * For RSDP revision 2 (and above), we use the XSDT + */ + if (acpi_gbl_RSDP->revision < 2) { +#ifdef _IA64 + /* 0.71 RSDP has 64bit Rsdt address field */ + physical_address = ((RSDP_DESCRIPTOR_REV071 *)acpi_gbl_RSDP)->rsdt_physical_address; +#else + physical_address = acpi_gbl_RSDP->rsdt_physical_address; +#endif + table_signature = RSDT_SIG; + signature_length = sizeof (RSDT_SIG) -1; + } + else { + physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->xsdt_physical_address; + table_signature = XSDT_SIG; + signature_length = sizeof (XSDT_SIG) -1; + } + + + /* Get the RSDT/XSDT */ + + status = acpi_tb_get_table (physical_address, NULL, &table_info); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* Check the RSDT or XSDT signature */ + + if (STRNCMP ((char *) table_info.pointer, table_signature, + signature_length)) + { + /* Invalid RSDT or XSDT signature */ + + REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n", + table_signature)); + + return (status); + } + + + /* Valid RSDT signature, verify the checksum */ + + status = acpi_tb_verify_table_checksum (table_info.pointer); + + + /* Convert and/or copy to an XSDT structure */ + + status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info); + if (ACPI_FAILURE (status)) { + return (status); + } + + acpi_gbl_XSDT = (XSDT_DESCRIPTOR *) table_info.pointer; + + return (status); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_tb_get_table_facs + * + * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from + * buffer rather than searching memory + * *Table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Returns a pointer to the FACS as defined in FADT. This + * function assumes the global variable FADT has been + * correctly initialized. The value of FADT->Firmware_ctrl + * into a far pointer which is returned. + * + *****************************************************************************/ + +ACPI_STATUS +acpi_tb_get_table_facs ( + ACPI_TABLE_HEADER *buffer_ptr, + ACPI_TABLE_DESC *table_info) +{ + void *table_ptr = NULL; + u32 size; + u8 allocation; + ACPI_STATUS status = AE_OK; + + + /* Must have a valid FADT pointer */ + + if (!acpi_gbl_FADT) { + return (AE_NO_ACPI_TABLES); + } + + size = sizeof (FACS_DESCRIPTOR); + if (buffer_ptr) { + /* + * Getting table from a file -- allocate a buffer and + * read the table. + */ + table_ptr = acpi_cm_allocate (size); + if(!table_ptr) { + return (AE_NO_MEMORY); + } + + MEMCPY (table_ptr, buffer_ptr, size); + + /* Save allocation type */ + + allocation = ACPI_MEM_ALLOCATED; + } + + else { + /* Just map the physical memory to our address space */ + + status = acpi_tb_map_acpi_table (acpi_gbl_FADT->Xfirmware_ctrl, + &size, &table_ptr); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Save allocation type */ + + allocation = ACPI_MEM_MAPPED; + } + + + /* Return values */ + + table_info->pointer = table_ptr; + table_info->length = size; + table_info->allocation = allocation; + table_info->base_pointer = table_ptr; + return (status); } diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 56e211ecf..b3926a0e3 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbinstal - ACPI table installation and removal - * $Revision: 29 $ + * $Revision: 34 $ * *****************************************************************************/ @@ -307,7 +307,7 @@ acpi_tb_delete_acpi_tables (void) * Memory can either be mapped or allocated */ - for (type = 0; type < ACPI_TABLE_MAX; type++) { + for (type = 0; type < NUM_ACPI_TABLES; type++) { acpi_tb_delete_acpi_table (type); } @@ -352,35 +352,24 @@ acpi_tb_delete_acpi_table ( acpi_gbl_RSDP = NULL; break; - case ACPI_TABLE_APIC: - acpi_gbl_APIC = NULL; - break; - case ACPI_TABLE_DSDT: acpi_gbl_DSDT = NULL; break; - case ACPI_TABLE_FACP: - acpi_gbl_FACP = NULL; + case ACPI_TABLE_FADT: + acpi_gbl_FADT = NULL; break; case ACPI_TABLE_FACS: acpi_gbl_FACS = NULL; break; - case ACPI_TABLE_PSDT: - break; - - case ACPI_TABLE_RSDT: - acpi_gbl_RSDT = NULL; + case ACPI_TABLE_XSDT: + acpi_gbl_XSDT = NULL; break; case ACPI_TABLE_SSDT: - break; - - case ACPI_TABLE_SBST: - acpi_gbl_SBST = NULL; - + case ACPI_TABLE_PSDT: default: break; } @@ -424,7 +413,7 @@ acpi_tb_free_acpi_tables_of_type ( */ for (i = 0; i < count; i++) { - table_desc = acpi_tb_delete_single_table (table_desc); + table_desc = acpi_tb_uninstall_table (table_desc); } return; @@ -439,37 +428,20 @@ acpi_tb_free_acpi_tables_of_type ( * * RETURN: None. * - * DESCRIPTION: Free the memory associated with an internal ACPI table that - * is either installed or has never been installed. - * Table mutex should be locked. + * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where + * the table was allocated a buffer or was mapped. * ******************************************************************************/ -ACPI_TABLE_DESC * +void acpi_tb_delete_single_table ( ACPI_TABLE_DESC *table_desc) { - ACPI_TABLE_DESC *next_desc; - if (!table_desc) { - return (NULL); - } - - - /* Unlink the descriptor */ - - if (table_desc->prev) { - table_desc->prev->next = table_desc->next; - } - - if (table_desc->next) { - table_desc->next->prev = table_desc->prev; + return; } - - /* Free the memory allocated for the table itself */ - if (table_desc->pointer) { /* Valid table, determine type of memory allocation */ @@ -477,7 +449,6 @@ acpi_tb_delete_single_table ( { case ACPI_MEM_NOT_ALLOCATED: - break; @@ -493,10 +464,52 @@ acpi_tb_delete_single_table ( break; } } +} - /* Free the table descriptor (Don't delete the list head, tho) */ +/******************************************************************************* + * + * FUNCTION: Acpi_tb_uninstall_table + * + * PARAMETERS: Table_info - A table info struct + * + * RETURN: None. + * + * DESCRIPTION: Free the memory associated with an internal ACPI table that + * is either installed or has never been installed. + * Table mutex should be locked. + * + ******************************************************************************/ +ACPI_TABLE_DESC * +acpi_tb_uninstall_table ( + ACPI_TABLE_DESC *table_desc) +{ + ACPI_TABLE_DESC *next_desc; + + + if (!table_desc) { + return (NULL); + } + + + /* Unlink the descriptor */ + + if (table_desc->prev) { + table_desc->prev->next = table_desc->next; + } + + if (table_desc->next) { + table_desc->next->prev = table_desc->prev; + } + + + /* Free the memory allocated for the table itself */ + + acpi_tb_delete_single_table (table_desc); + + + /* Free the table descriptor (Don't delete the list head, tho) */ if ((table_desc->prev) == (table_desc->next)) { diff --git a/drivers/acpi/tables/tbtable.c b/drivers/acpi/tables/tbtable.c deleted file mode 100644 index fe006bf2e..000000000 --- a/drivers/acpi/tables/tbtable.c +++ /dev/null @@ -1,392 +0,0 @@ -/****************************************************************************** - * - * Module Name: tbtable - ACPI tables: FACP, FACS, and RSDP utilities - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "achware.h" -#include "actables.h" - - -#define _COMPONENT TABLE_MANAGER - MODULE_NAME ("tbtable") - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_get_table_rsdt - * - * PARAMETERS: Number_of_tables - Where the table count is placed - * - * RETURN: Status - * - * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_tb_get_table_rsdt ( - u32 *number_of_tables) -{ - ACPI_STATUS status = AE_OK; - ACPI_TABLE_DESC table_info; - - - /* Get the RSDP */ - - status = acpi_tb_find_rsdp (&table_info); - if (ACPI_FAILURE (status)) { - REPORT_WARNING ("RSDP structure not found"); - return (AE_NO_ACPI_TABLES); - } - - /* Save the table pointers and allocation info */ - - status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); - if (ACPI_FAILURE (status)) { - return (status); - } - - acpi_gbl_RSDP = (ROOT_SYSTEM_DESCRIPTOR_POINTER *) table_info.pointer; - - - /* - * RSDP structure was found; Now get the RSDT - */ - - status = acpi_tb_get_table ((void *) acpi_gbl_RSDP->rsdt_physical_address, NULL, - &table_info); - if (ACPI_FAILURE (status)) { - if (status == AE_BAD_SIGNATURE) { - /* Invalid RSDT signature */ - - REPORT_ERROR ("Invalid signature where RSDP indicates RSDT should be located"); - - } - REPORT_ERROR ("Unable to locate RSDT"); - - return (status); - } - - - /* Always delete the RSDP mapping */ - - acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP); - - /* Save the table pointers and allocation info */ - - status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDT, &table_info); - if (ACPI_FAILURE (status)) { - return (status); - } - - acpi_gbl_RSDT = (ROOT_SYSTEM_DESCRIPTION_TABLE *) table_info.pointer; - - - /* Valid RSDT signature, verify the checksum */ - - status = acpi_tb_verify_table_checksum ((ACPI_TABLE_HEADER *) acpi_gbl_RSDT); - - /* - * Determine the number of tables pointed to by the RSDT. - * This is defined by the ACPI Specification to be the number of - * pointers contained within the RSDT. The size of the pointers - * is architecture-dependent. - */ - - *number_of_tables = ((acpi_gbl_RSDT->header.length - - sizeof (ACPI_TABLE_HEADER)) / sizeof (void *)); - - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_scan_memory_for_rsdp - * - * PARAMETERS: Start_address - Starting pointer for search - * Length - Maximum length to search - * - * RETURN: Pointer to the RSDP if found, otherwise NULL. - * - * DESCRIPTION: Search a block of memory for the RSDP signature - * - ******************************************************************************/ - -u8 * -acpi_tb_scan_memory_for_rsdp ( - u8 *start_address, - u32 length) -{ - u32 offset; - u8 *mem_rover; - - - /* Search from given start addr for the requested length */ - - for (offset = 0, mem_rover = start_address; - offset < length; - offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) - { - - /* The signature and checksum must both be correct */ - - if (STRNCMP ((NATIVE_CHAR *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && - acpi_tb_checksum (mem_rover, - sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)) == 0) - { - /* If so, we have found the RSDP */ - - return (mem_rover); - } - } - - /* Searched entire block, no RSDP was found */ - - return (NULL); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_find_rsdp - * - * PARAMETERS: *Buffer_ptr - If == NULL, read data from buffer - * rather than searching memory - * *Table_info - Where the table info is returned - * - * RETURN: Status - * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. - * - * NOTE: The RSDP must be either in the first 1_k of the Extended - * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section - * 5.2.2; assertion #421). - * - ******************************************************************************/ - -ACPI_STATUS -acpi_tb_find_rsdp ( - ACPI_TABLE_DESC *table_info) -{ - u8 *table_ptr; - u8 *mem_rover; - ACPI_STATUS status = AE_OK; - - if (acpi_gbl_acpi_init_data.RSDP_physical_address) { - /* - * RSDP address was supplied as part of the initialization data - */ - - status = acpi_os_map_memory(acpi_gbl_acpi_init_data.RSDP_physical_address, - sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER), - (void **)&table_ptr); - - if (ACPI_FAILURE (status)) { - return (status); - } - - if (!table_ptr) { - return (AE_NO_MEMORY); - } - - /* - * The signature and checksum must both be correct - */ - - if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { - /* Nope, BAD Signature */ - acpi_os_unmap_memory (table_ptr, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)); - return (AE_BAD_SIGNATURE); - } - - /* The signature and checksum must both be correct */ - - if (acpi_tb_checksum (table_ptr, - sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)) != 0) - { - /* Nope, BAD Checksum */ - acpi_os_unmap_memory (table_ptr, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)); - return (AE_BAD_CHECKSUM); - } - - /* RSDP supplied is OK */ - /* If so, we have found the RSDP */ - - table_info->pointer = (ACPI_TABLE_HEADER *) table_ptr; - table_info->length = sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER); - table_info->allocation = ACPI_MEM_MAPPED; - table_info->base_pointer = table_ptr; - - return (AE_OK); - } - - /* - * Search memory for RSDP. First map low physical memory. - */ - - status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE, - (void **)&table_ptr); - - if (ACPI_FAILURE (status)) { - return (status); - } - - /* - * 1) Search EBDA (low memory) paragraphs - */ - - if (NULL != (mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, - LO_RSDP_WINDOW_SIZE))) - { - /* Found it, return pointer and don't delete the mapping */ - - table_info->pointer = (ACPI_TABLE_HEADER *) mem_rover; - table_info->length = LO_RSDP_WINDOW_SIZE; - table_info->allocation = ACPI_MEM_MAPPED; - table_info->base_pointer = table_ptr; - - return (AE_OK); - } - - /* This mapping is no longer needed */ - - acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE); - - - /* - * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h - */ - - status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE, - (void **)&table_ptr); - - if (ACPI_FAILURE (status)) { - return (status); - } - - if (NULL != (mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, - HI_RSDP_WINDOW_SIZE))) - { - /* Found it, return pointer and don't delete the mapping */ - - table_info->pointer = (ACPI_TABLE_HEADER *) mem_rover; - table_info->length = HI_RSDP_WINDOW_SIZE; - table_info->allocation = ACPI_MEM_MAPPED; - table_info->base_pointer = table_ptr; - - return (AE_OK); - } - - /* This mapping is no longer needed */ - - acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE); - - - /* RSDP signature was not found */ - - return (AE_NOT_FOUND); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_tb_get_table_facs - * - * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from - * buffer rather than searching memory - * *Table_info - Where the table info is returned - * - * RETURN: Status - * - * DESCRIPTION: Returns a pointer to the FACS as defined in FACP. This - * function assumes the global variable FACP has been - * correctly initialized. The value of FACP->Firmware_ctrl - * into a far pointer which is returned. - * - *****************************************************************************/ - -ACPI_STATUS -acpi_tb_get_table_facs ( - ACPI_TABLE_HEADER *buffer_ptr, - ACPI_TABLE_DESC *table_info) -{ - void *table_ptr = NULL; - u32 size; - u8 allocation; - ACPI_STATUS status = AE_OK; - - - /* Must have a valid FACP pointer */ - - if (!acpi_gbl_FACP) { - return (AE_NO_ACPI_TABLES); - } - - size = sizeof (FIRMWARE_ACPI_CONTROL_STRUCTURE); - if (buffer_ptr) { - /* - * Getting table from a file -- allocate a buffer and - * read the table. - */ - table_ptr = acpi_cm_allocate (size); - if(!table_ptr) { - return (AE_NO_MEMORY); - } - - MEMCPY (table_ptr, buffer_ptr, size); - - /* Save allocation type */ - - allocation = ACPI_MEM_ALLOCATED; - } - - else { - /* Just map the physical memory to our address space */ - - status = acpi_tb_map_acpi_table ((void *) acpi_gbl_FACP->firmware_ctrl, - &size, &table_ptr); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Save allocation type */ - - allocation = ACPI_MEM_MAPPED; - } - - - /* Return values */ - - table_info->pointer = table_ptr; - table_info->length = size; - table_info->allocation = allocation; - table_info->base_pointer = table_ptr; - - return (status); -} - diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 2a6b7da4b..baae6fb4c 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbutils - Table manipulation utilities - * $Revision: 26 $ + * $Revision: 31 $ * *****************************************************************************/ @@ -107,7 +107,9 @@ acpi_tb_system_table_pointer ( /* Check for a pointer within the DSDT */ - if (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT)) { + if ((acpi_gbl_DSDT) && + (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT))) + { return (TRUE); } @@ -186,7 +188,7 @@ acpi_tb_validate_table_header ( MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature); if (!acpi_cm_valid_acpi_name (signature)) { - REPORT_WARNING ("Invalid table signature found"); + REPORT_WARNING (("Invalid table signature found\n")); return (AE_BAD_SIGNATURE); } @@ -194,7 +196,7 @@ acpi_tb_validate_table_header ( /* Validate the table length */ if (table_header->length < sizeof (ACPI_TABLE_HEADER)) { - REPORT_WARNING ("Invalid table header length found"); + REPORT_WARNING (("Invalid table header length found\n")); return (AE_BAD_HEADER); } @@ -220,7 +222,7 @@ acpi_tb_validate_table_header ( ACPI_STATUS acpi_tb_map_acpi_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, u32 *size, void **logical_address) { @@ -294,18 +296,20 @@ ACPI_STATUS acpi_tb_verify_table_checksum ( ACPI_TABLE_HEADER *table_header) { - u8 check_sum; + u8 checksum; ACPI_STATUS status = AE_OK; /* Compute the checksum on the table */ - check_sum = acpi_tb_checksum (table_header, table_header->length); + checksum = acpi_tb_checksum (table_header, table_header->length); /* Return the appropriate exception */ - if (check_sum) { - REPORT_ERROR ("Invalid ACPI table checksum"); + if (checksum) { + REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n", + checksum, &table_header->signature)); + status = AE_BAD_CHECKSUM; } diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index e1946e572..ee9eba62a 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -2,7 +2,7 @@ * * Module Name: tbxface - Public interfaces to the ACPI subsystem * ACPI table oriented interfaces - * $Revision: 24 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -37,43 +37,69 @@ /******************************************************************************* * - * FUNCTION: Acpi_load_firmware_tables + * FUNCTION: Acpi_load_tables * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: This function is called to load the ACPI tables from BIOS + * DESCRIPTION: This function is called to load the ACPI tables from the + * provided RSDT * ******************************************************************************/ ACPI_STATUS -acpi_load_firmware_tables (void) +acpi_load_tables ( + ACPI_PHYSICAL_ADDRESS rsdp_physical_address) { ACPI_STATUS status = AE_OK; u32 number_of_tables = 0; - /* Get the RSDT first */ + /* Map and validate the RSDP */ - status = acpi_tb_get_table_rsdt (&number_of_tables); + status = acpi_tb_verify_rsdp (rsdp_physical_address); if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: RSDP Failed validation: %s\n", + acpi_cm_format_exception (status))); goto error_exit; } + /* Get the RSDT via the RSDP */ + + status = acpi_tb_get_table_rsdt (&number_of_tables); + if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %s\n", + acpi_cm_format_exception (status))); + goto error_exit; + } /* Now get the rest of the tables */ status = acpi_tb_get_all_tables (number_of_tables, NULL); if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", + acpi_cm_format_exception (status))); goto error_exit; } + /* Load the namespace from the tables */ + + status = acpi_ns_load_namespace (); + if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: Could not load namespace: %s\n", + acpi_cm_format_exception (status))); + goto error_exit; + } + return (AE_OK); error_exit: + REPORT_ERROR (("Acpi_load_tables: Could not load tables: %s\n", + acpi_cm_format_exception (status))); + return (status); } @@ -110,7 +136,7 @@ acpi_load_table ( /* Copy the table to a local buffer */ - status = acpi_tb_get_table (NULL, table_ptr, &table_info); + status = acpi_tb_get_table (0, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return (status); } @@ -119,9 +145,22 @@ acpi_load_table ( status = acpi_tb_install_table (NULL, &table_info); if (ACPI_FAILURE (status)) { - /* TBD: [Errors] must free table allocated by Acpi_tb_get_table */ + /* Free table allocated by Acpi_tb_get_table */ + + acpi_tb_delete_single_table (&table_info); + return (status); + } + + + status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); + if (ACPI_FAILURE (status)) { + /* Uninstall table and free the buffer */ + + acpi_tb_uninstall_table (table_info.installed_desc); + return (status); } + return (status); } @@ -289,12 +328,11 @@ acpi_get_table ( /* - * Must have a buffer + * If we have a buffer, we must have a length too */ if ((instance == 0) || (!ret_buffer) || - (!ret_buffer->pointer) || - (!ret_buffer->length)) + ((!ret_buffer->pointer) && (ret_buffer->length))) { return (AE_BAD_PARAMETER); } @@ -331,7 +369,7 @@ acpi_get_table ( /* * RSD PTR is the only "table" without a header */ - ret_buf_len = sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER); + ret_buf_len = sizeof (RSDP_DESCRIPTOR); } else { ret_buf_len = tbl_ptr->length; diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c new file mode 100644 index 000000000..4c31f1c37 --- /dev/null +++ b/drivers/acpi/tables/tbxfroot.c @@ -0,0 +1,214 @@ +/****************************************************************************** + * + * Module Name: tbxfroot - Find the root ACPI table (RSDT) + * $Revision: 33 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "achware.h" +#include "actables.h" + + +#define _COMPONENT TABLE_MANAGER + MODULE_NAME ("tbxfroot") + +#define RSDP_CHECKSUM_LENGTH 20 + + +/******************************************************************************* + * + * FUNCTION: Acpi_find_root_pointer + * + * PARAMETERS: **Rsdp_physical_address - Where to place the RSDP address + * + * RETURN: Status, Physical address of the RSDP + * + * DESCRIPTION: Find the RSDP + * + ******************************************************************************/ + +ACPI_STATUS +acpi_find_root_pointer ( + ACPI_PHYSICAL_ADDRESS *rsdp_physical_address) +{ + ACPI_TABLE_DESC table_info; + ACPI_STATUS status; + + + /* Get the RSDP */ + + status = acpi_tb_find_rsdp (&table_info); + if (ACPI_FAILURE (status)) { + return (AE_NO_ACPI_TABLES); + } + + *rsdp_physical_address = table_info.physical_address; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_scan_memory_for_rsdp + * + * PARAMETERS: Start_address - Starting pointer for search + * Length - Maximum length to search + * + * RETURN: Pointer to the RSDP if found, otherwise NULL. + * + * DESCRIPTION: Search a block of memory for the RSDP signature + * + ******************************************************************************/ + +u8 * +acpi_tb_scan_memory_for_rsdp ( + u8 *start_address, + u32 length) +{ + u32 offset; + u8 *mem_rover; + + + /* Search from given start addr for the requested length */ + + for (offset = 0, mem_rover = start_address; + offset < length; + offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) + { + + /* The signature and checksum must both be correct */ + + if (STRNCMP ((NATIVE_CHAR *) mem_rover, + RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && + acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0) + { + /* If so, we have found the RSDP */ + + return (mem_rover); + } + } + + /* Searched entire block, no RSDP was found */ + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_find_rsdp + * + * PARAMETERS: *Buffer_ptr - If == NULL, read data from buffer + * rather than searching memory + * *Table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor + * pointer structure. If it is found, set *RSDP to point to it. + * + * NOTE: The RSDP must be either in the first 1_k of the Extended + * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section + * 5.2.2; assertion #421). + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_find_rsdp ( + ACPI_TABLE_DESC *table_info) +{ + u8 *table_ptr; + u8 *mem_rover; + UINT64 phys_addr; + ACPI_STATUS status = AE_OK; + + + /* + * Search memory for RSDP. First map low physical memory. + */ + + status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE, + (void **)&table_ptr); + + if (ACPI_FAILURE (status)) { + return (status); + } + + /* + * 1) Search EBDA (low memory) paragraphs + */ + + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, LO_RSDP_WINDOW_SIZE); + + /* This mapping is no longer needed */ + + acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE); + + if (mem_rover) { + /* Found it, return the physical address */ + + phys_addr = LO_RSDP_WINDOW_BASE; + phys_addr += (mem_rover - table_ptr); + + table_info->physical_address = phys_addr; + + return (AE_OK); + } + + + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h + */ + + status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE, + (void **)&table_ptr); + + if (ACPI_FAILURE (status)) { + return (status); + } + + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, HI_RSDP_WINDOW_SIZE); + + /* This mapping is no longer needed */ + + acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE); + + if (mem_rover) { + /* Found it, return the physical address */ + + phys_addr = HI_RSDP_WINDOW_BASE; + phys_addr += (mem_rover - table_ptr); + + table_info->physical_address = phys_addr; + + return (AE_OK); + } + + + /* RSDP signature was not found */ + + return (AE_NOT_FOUND); +} + + |