2#ifndef PEDIGREE_MACHINE_PC_ACPI_S5_H
3#define PEDIGREE_MACHINE_PC_ACPI_S5_H
11inline bool mayHaveSleepHooks(
const uint8_t* bytes,
size_t length) {
14 for (
size_t i = 0; i + 4 <= length; ++i) {
15 if (bytes[i] ==
'_' && bytes[i + 2] ==
'T' && bytes[i + 3] ==
'S' &&
16 (bytes[i + 1] ==
'P' || bytes[i + 1] ==
'T' || bytes[i + 1] ==
'G'))
22inline bool package(
const uint8_t*& cursor,
const uint8_t* end,
const uint8_t*& packageEnd) {
25 const uint8_t* start = cursor;
26 const uint8_t lead = *cursor++;
27 const unsigned extra = lead >> 6;
28 if (
size_t(end - cursor) < extra || (extra && (lead & 0x30)))
30 size_t length = lead & (extra ? 0x0f : 0x3f);
31 for (
unsigned i = 0; i < extra; ++i)
32 length |=
size_t(*cursor++) << (4 + 8 * i);
33 if (length <
size_t(cursor - start) || length > size_t(end - start))
35 packageEnd = start + length;
39inline bool integer(
const uint8_t*& cursor,
const uint8_t* end, uint64_t& value) {
42 const uint8_t op = *cursor++;
43 if (op == 0 || op == 1 || op == 0xff) {
44 value = op == 0xff ? UINT64_MAX : op;
47 const unsigned bytes = op == 0x0a ? 1 : op == 0x0b ? 2 : op == 0x0c ? 4 : op == 0x0e ? 8 : 0;
48 if (!bytes ||
size_t(end - cursor) < bytes)
51 for (
unsigned i = 0; i < bytes; ++i)
52 value |= uint64_t(*cursor++) << (8 * i);
62inline bool name(
const uint8_t*& cursor,
const uint8_t* end,
bool atRoot,
Name& result) {
66 if (*cursor ==
'\\') {
70 while (cursor != end && *cursor ==
'^') {
80 }
else if (*cursor == 0x2e) {
83 }
else if (*cursor == 0x2f) {
90 if (
size_t(end - cursor) < count * 4)
93 root && count == 1 && cursor[0] ==
'_' && cursor[1] ==
'S' && cursor[2] ==
'5' &&
96 for (
unsigned i = 0; i < count * 4; ++i) {
97 const uint8_t c = *cursor++;
98 if (c !=
'_' && !(c >=
'A' && c <=
'Z') && !(i % 4 && c >=
'0' && c <=
'9'))
104inline bool data(
const uint8_t*& cursor,
const uint8_t* end) {
107 const uint8_t op = *cursor;
108 if (op == 0x11 || op == 0x12 || op == 0x13) {
110 const uint8_t* packageEnd;
111 if (!package(cursor, end, packageEnd))
117 while (++cursor != end)
124 if (op == 0 || op == 1 || op == 0xff || op == 0x0a || op == 0x0b || op == 0x0c || op == 0x0e) {
126 return integer(cursor, end, value);
129 return name(cursor, end,
false, ignored);
132inline bool find(
const uint8_t* cursor,
const uint8_t* end, uint8_t& typeA, uint8_t& typeB,
133 bool atRoot =
true,
unsigned depth = 0) {
136 while (cursor != end) {
137 const uint8_t op = *cursor++;
140 if (!name(cursor, end, atRoot,
object) || cursor == end)
142 if (
object.s5 && *cursor == 0x12) {
144 const uint8_t* packageEnd;
145 if (!package(cursor, end, packageEnd) || cursor == packageEnd)
147 const unsigned count = *cursor++;
149 if (count < 2 || !integer(cursor, packageEnd, a) || !integer(cursor, packageEnd, b) ||
152 for (
unsigned i = 2; i < count; ++i) {
154 if (!integer(cursor, packageEnd, reserved))
157 if (cursor != packageEnd)
163 if (!data(cursor, end))
165 }
else if (op == 0x10 || op == 0x14 || op == 0xa0 || op == 0xa1 || op == 0xa2) {
166 const uint8_t* packageEnd;
167 if (!package(cursor, end, packageEnd))
170 if (!name(cursor, packageEnd, atRoot,
object))
172 if (find(cursor, packageEnd, typeA, typeB,
object.rootScope, depth + 1))
176 }
else if (op == 0x06) {
177 if (!name(cursor, end, atRoot,
object) || !name(cursor, end, atRoot,
object))
179 }
else if (op == 0x15) {
180 if (!name(cursor, end, atRoot,
object) || end - cursor < 2)
183 }
else if (op == 0x5b) {
186 const uint8_t ext = *cursor++;
187 if (ext >= 0x81 && ext <= 0x87) {
188 const uint8_t* packageEnd;
189 if (!package(cursor, end, packageEnd))
192 }
else if (ext == 0x80 || ext == 0x01 || ext == 0x02) {
193 if (!name(cursor, end, atRoot,
object))
200 if (ext == 0x80 && (!data(cursor, end) || !data(cursor, end)))
205 }
else if (op != 0xa3) {