ACPIhalt: Add more ACPI opcodes.
The AML parser implements only a small subset of possible AML opcodes. On the Fujitsu Lifebook E744 this and another bug in the parser (incorrect handling of TermArg data types) would lead to the laptop not turning off (_S5 not found). * grub-core/commands/acpihalt.c: Support OpAlias in the AML parser; in skip_ext_op(), handle some Type2Opcodes more correctly (TermArgs aren't always simply strings!); Add function to skip TermArgs * include/grub/acpi.h: Add new opcodes
This commit is contained in:
parent
41c6f91fce
commit
0f1f95c7b7
3 changed files with 87 additions and 3 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2014-09-21 Valentin Dornauer <valentin@unimplemented.org>
|
||||||
|
|
||||||
|
The AML parser implements only a small subset of possible AML
|
||||||
|
opcodes. On the Fujitsu Lifebook E744 this and another bug in
|
||||||
|
the parser (incorrect handling of TermArg data types) would lead
|
||||||
|
to the laptop not turning off (_S5 not found).
|
||||||
|
|
||||||
|
* grub-core/commands/acpihalt.c: Support OpAlias in the AML parser;
|
||||||
|
in skip_ext_op(), handle some Type2Opcodes more correctly (TermArgs
|
||||||
|
aren't always simply strings!); Add function to skip TermArgs
|
||||||
|
* include/grub/acpi.h: Add new opcodes
|
||||||
|
|
||||||
2014-09-21 Vladimir Serbinenko <phcoder@gmail.com>
|
2014-09-21 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/normal/main.c: Don't drop to rescue console in
|
* grub-core/normal/main.c: Don't drop to rescue console in
|
||||||
|
|
|
@ -135,6 +135,49 @@ skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline grub_uint32_t
|
||||||
|
skip_term (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||||
|
{
|
||||||
|
grub_uint32_t add;
|
||||||
|
const grub_uint8_t *ptr0 = ptr;
|
||||||
|
|
||||||
|
switch(*ptr)
|
||||||
|
{
|
||||||
|
case GRUB_ACPI_OPCODE_ADD:
|
||||||
|
case GRUB_ACPI_OPCODE_AND:
|
||||||
|
case GRUB_ACPI_OPCODE_CONCAT:
|
||||||
|
case GRUB_ACPI_OPCODE_CONCATRES:
|
||||||
|
case GRUB_ACPI_OPCODE_DIVIDE:
|
||||||
|
case GRUB_ACPI_OPCODE_INDEX:
|
||||||
|
case GRUB_ACPI_OPCODE_LSHIFT:
|
||||||
|
case GRUB_ACPI_OPCODE_MOD:
|
||||||
|
case GRUB_ACPI_OPCODE_MULTIPLY:
|
||||||
|
case GRUB_ACPI_OPCODE_NAND:
|
||||||
|
case GRUB_ACPI_OPCODE_NOR:
|
||||||
|
case GRUB_ACPI_OPCODE_OR:
|
||||||
|
case GRUB_ACPI_OPCODE_RSHIFT:
|
||||||
|
case GRUB_ACPI_OPCODE_SUBTRACT:
|
||||||
|
case GRUB_ACPI_OPCODE_TOSTRING:
|
||||||
|
case GRUB_ACPI_OPCODE_XOR:
|
||||||
|
/*
|
||||||
|
* Parameters for these opcodes: TermArg, TermArg Target, see ACPI
|
||||||
|
* spec r5.0, page 828f.
|
||||||
|
*/
|
||||||
|
ptr++;
|
||||||
|
ptr += add = skip_term (ptr, end);
|
||||||
|
if (!add)
|
||||||
|
return 0;
|
||||||
|
ptr += add = skip_term (ptr, end);
|
||||||
|
if (!add)
|
||||||
|
return 0;
|
||||||
|
ptr += skip_name_string (ptr, end);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return skip_data_ref_object (ptr, end);
|
||||||
|
}
|
||||||
|
return ptr - ptr0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline grub_uint32_t
|
static inline grub_uint32_t
|
||||||
skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||||
{
|
{
|
||||||
|
@ -156,10 +199,10 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr += skip_name_string (ptr, end);
|
ptr += skip_name_string (ptr, end);
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr += add = skip_data_ref_object (ptr, end);
|
ptr += add = skip_term (ptr, end);
|
||||||
if (!add)
|
if (!add)
|
||||||
return 0;
|
return 0;
|
||||||
ptr += add = skip_data_ref_object (ptr, end);
|
ptr += add = skip_term (ptr, end);
|
||||||
if (!add)
|
if (!add)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -180,6 +223,7 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||||
return ptr - ptr0;
|
return ptr - ptr0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
|
get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
|
||||||
grub_uint8_t *scope, int scope_len)
|
grub_uint8_t *scope, int scope_len)
|
||||||
|
@ -250,6 +294,17 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
|
||||||
if (!add)
|
if (!add)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
case GRUB_ACPI_OPCODE_ALIAS:
|
||||||
|
ptr++;
|
||||||
|
/* We need to skip two name strings */
|
||||||
|
ptr += add = skip_name_string (ptr, end);
|
||||||
|
if (!add)
|
||||||
|
return -1;
|
||||||
|
ptr += add = skip_name_string (ptr, end);
|
||||||
|
if (!add)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case GRUB_ACPI_OPCODE_SCOPE:
|
case GRUB_ACPI_OPCODE_SCOPE:
|
||||||
{
|
{
|
||||||
int scope_sleep_type;
|
int scope_sleep_type;
|
||||||
|
|
|
@ -191,7 +191,8 @@ void grub_acpi_halt (void);
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
GRUB_ACPI_OPCODE_ZERO = 0, GRUB_ACPI_OPCODE_ONE = 1,
|
GRUB_ACPI_OPCODE_ZERO = 0, GRUB_ACPI_OPCODE_ONE = 1,
|
||||||
GRUB_ACPI_OPCODE_NAME = 8, GRUB_ACPI_OPCODE_BYTE_CONST = 0x0a,
|
GRUB_ACPI_OPCODE_NAME = 8, GRUB_ACPI_OPCODE_ALIAS = 0x06,
|
||||||
|
GRUB_ACPI_OPCODE_BYTE_CONST = 0x0a,
|
||||||
GRUB_ACPI_OPCODE_WORD_CONST = 0x0b,
|
GRUB_ACPI_OPCODE_WORD_CONST = 0x0b,
|
||||||
GRUB_ACPI_OPCODE_DWORD_CONST = 0x0c,
|
GRUB_ACPI_OPCODE_DWORD_CONST = 0x0c,
|
||||||
GRUB_ACPI_OPCODE_STRING_CONST = 0x0d,
|
GRUB_ACPI_OPCODE_STRING_CONST = 0x0d,
|
||||||
|
@ -199,6 +200,22 @@ enum
|
||||||
GRUB_ACPI_OPCODE_BUFFER = 0x11,
|
GRUB_ACPI_OPCODE_BUFFER = 0x11,
|
||||||
GRUB_ACPI_OPCODE_PACKAGE = 0x12,
|
GRUB_ACPI_OPCODE_PACKAGE = 0x12,
|
||||||
GRUB_ACPI_OPCODE_METHOD = 0x14, GRUB_ACPI_OPCODE_EXTOP = 0x5b,
|
GRUB_ACPI_OPCODE_METHOD = 0x14, GRUB_ACPI_OPCODE_EXTOP = 0x5b,
|
||||||
|
GRUB_ACPI_OPCODE_ADD = 0x72,
|
||||||
|
GRUB_ACPI_OPCODE_CONCAT = 0x73,
|
||||||
|
GRUB_ACPI_OPCODE_SUBTRACT = 0x74,
|
||||||
|
GRUB_ACPI_OPCODE_MULTIPLY = 0x77,
|
||||||
|
GRUB_ACPI_OPCODE_DIVIDE = 0x78,
|
||||||
|
GRUB_ACPI_OPCODE_LSHIFT = 0x79,
|
||||||
|
GRUB_ACPI_OPCODE_RSHIFT = 0x7a,
|
||||||
|
GRUB_ACPI_OPCODE_AND = 0x7b,
|
||||||
|
GRUB_ACPI_OPCODE_NAND = 0x7c,
|
||||||
|
GRUB_ACPI_OPCODE_OR = 0x7d,
|
||||||
|
GRUB_ACPI_OPCODE_NOR = 0x7e,
|
||||||
|
GRUB_ACPI_OPCODE_XOR = 0x7f,
|
||||||
|
GRUB_ACPI_OPCODE_CONCATRES = 0x84,
|
||||||
|
GRUB_ACPI_OPCODE_MOD = 0x85,
|
||||||
|
GRUB_ACPI_OPCODE_INDEX = 0x88,
|
||||||
|
GRUB_ACPI_OPCODE_TOSTRING = 0x9c,
|
||||||
GRUB_ACPI_OPCODE_CREATE_WORD_FIELD = 0x8b,
|
GRUB_ACPI_OPCODE_CREATE_WORD_FIELD = 0x8b,
|
||||||
GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD = 0x8c,
|
GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD = 0x8c,
|
||||||
GRUB_ACPI_OPCODE_IF = 0xa0, GRUB_ACPI_OPCODE_ONES = 0xff
|
GRUB_ACPI_OPCODE_IF = 0xa0, GRUB_ACPI_OPCODE_ONES = 0xff
|
||||||
|
|
Loading…
Reference in a new issue