term_object.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. use crate::{
  2. misc::{arg_obj, local_obj},
  3. name_object::{name_seg, name_string},
  4. namespace::{AmlName, LevelType},
  5. opcode::{self, ext_opcode, opcode},
  6. parser::{
  7. choice,
  8. comment_scope,
  9. make_parser_concrete,
  10. take,
  11. take_to_end_of_pkglength,
  12. take_u16,
  13. take_u32,
  14. take_u64,
  15. try_with_context,
  16. ParseResult,
  17. Parser,
  18. },
  19. pkg_length::{pkg_length, PkgLength},
  20. type1::type1_opcode,
  21. type2::{def_buffer, def_package, type2_opcode},
  22. value::{AmlValue, FieldFlags, MethodFlags, RegionSpace},
  23. AmlContext,
  24. AmlError,
  25. AmlHandle,
  26. DebugVerbosity,
  27. };
  28. use alloc::string::String;
  29. use core::str;
  30. /// `TermList`s are usually found within explicit-length objects (so they have a `PkgLength`
  31. /// elsewhere in the structure), so this takes a number of bytes to parse.
  32. pub fn term_list<'a, 'c>(list_length: PkgLength) -> impl Parser<'a, 'c, ()>
  33. where
  34. 'c: 'a,
  35. {
  36. /*
  37. * TermList := Nothing | <TermObj TermList>
  38. */
  39. move |mut input: &'a [u8], mut context: &'c mut AmlContext| {
  40. while list_length.still_parsing(input) {
  41. // TODO: currently, we ignore the value of the expression. We may need to propagate
  42. // this.
  43. let (new_input, new_context, _) = term_object().parse(input, context)?;
  44. input = new_input;
  45. context = new_context;
  46. }
  47. Ok((input, context, ()))
  48. }
  49. }
  50. pub fn term_object<'a, 'c>() -> impl Parser<'a, 'c, Option<AmlValue>>
  51. where
  52. 'c: 'a,
  53. {
  54. /*
  55. * TermObj := NamespaceModifierObj | NamedObj | Type1Opcode | Type2Opcode
  56. */
  57. comment_scope(
  58. DebugVerbosity::AllScopes,
  59. "TermObj",
  60. choice!(
  61. namespace_modifier().map(|()| Ok(None)),
  62. named_obj().map(|()| Ok(None)),
  63. type1_opcode().map(|()| Ok(None)),
  64. type2_opcode().map(|value| Ok(Some(value)))
  65. ),
  66. )
  67. }
  68. pub fn namespace_modifier<'a, 'c>() -> impl Parser<'a, 'c, ()>
  69. where
  70. 'c: 'a,
  71. {
  72. /*
  73. * NamespaceModifierObj := DefAlias | DefName | DefScope
  74. */
  75. choice!(def_name(), def_scope())
  76. }
  77. pub fn named_obj<'a, 'c>() -> impl Parser<'a, 'c, ()>
  78. where
  79. 'c: 'a,
  80. {
  81. /*
  82. * NamedObj := DefBankField | DefCreateBitField | DefCreateByteField | DefCreateDWordField |
  83. * DefCreateField | DefCreateQWordField | DefCreateWordField | DefDataRegion |
  84. * DefExternal | DefOpRegion | DefPowerRes | DefProcessor | DefThermalZone |
  85. * DefMethod | DefMutex
  86. *
  87. * XXX: DefMethod and DefMutex (at least) are not included in any rule in the AML grammar,
  88. * but are defined in the NamedObj section so we assume they're part of NamedObj
  89. */
  90. comment_scope(
  91. DebugVerbosity::AllScopes,
  92. "NamedObj",
  93. choice!(def_op_region(), def_field(), def_method(), def_device(), def_processor(), def_mutex()),
  94. )
  95. }
  96. pub fn def_name<'a, 'c>() -> impl Parser<'a, 'c, ()>
  97. where
  98. 'c: 'a,
  99. {
  100. /*
  101. * DefName := 0x08 NameString DataRefObject
  102. */
  103. opcode(opcode::DEF_NAME_OP)
  104. .then(comment_scope(
  105. DebugVerbosity::Scopes,
  106. "DefName",
  107. name_string().then(data_ref_object()).map_with_context(|(name, data_ref_object), context| {
  108. try_with_context!(
  109. context,
  110. context.namespace.add_value_at_resolved_path(name, &context.current_scope, data_ref_object,)
  111. );
  112. (Ok(()), context)
  113. }),
  114. ))
  115. .discard_result()
  116. }
  117. pub fn def_scope<'a, 'c>() -> impl Parser<'a, 'c, ()>
  118. where
  119. 'c: 'a,
  120. {
  121. /*
  122. * DefScope := 0x10 PkgLength NameString TermList
  123. */
  124. opcode(opcode::DEF_SCOPE_OP)
  125. .then(comment_scope(
  126. DebugVerbosity::Scopes,
  127. "DefScope",
  128. pkg_length()
  129. .then(name_string())
  130. .map_with_context(|(length, name), context| {
  131. let previous_scope = context.current_scope.clone();
  132. context.current_scope = try_with_context!(context, name.resolve(&context.current_scope));
  133. context.comment(
  134. DebugVerbosity::Scopes,
  135. &(String::from("Scope name: ") + &context.current_scope.as_string()),
  136. );
  137. try_with_context!(
  138. context,
  139. context.namespace.add_level(context.current_scope.clone(), LevelType::Scope)
  140. );
  141. (Ok((length, previous_scope)), context)
  142. })
  143. .feed(|(pkg_length, previous_scope)| {
  144. term_list(pkg_length).map(move |_| Ok(previous_scope.clone()))
  145. })
  146. .map_with_context(|previous_scope, context| {
  147. context.current_scope = previous_scope;
  148. (Ok(()), context)
  149. }),
  150. ))
  151. .discard_result()
  152. }
  153. pub fn def_op_region<'a, 'c>() -> impl Parser<'a, 'c, ()>
  154. where
  155. 'c: 'a,
  156. {
  157. /*
  158. * DefOpRegion := ExtOpPrefix 0x80 NameString RegionSpace RegionOffset RegionLen
  159. * RegionSpace := ByteData (where 0x00 = SystemMemory
  160. * 0x01 = SystemIO
  161. * 0x02 = PciConfig
  162. * 0x03 = EmbeddedControl
  163. * 0x04 = SMBus
  164. * 0x05 = SystemCMOS
  165. * 0x06 = PciBarTarget
  166. * 0x07 = IPMI
  167. * 0x08 = GeneralPurposeIO
  168. * 0x09 = GenericSerialBus
  169. * 0x80-0xff = OEM Defined)
  170. * ByteData := 0x00 - 0xff
  171. * RegionOffset := TermArg => Integer
  172. * RegionLen := TermArg => Integer
  173. */
  174. ext_opcode(opcode::EXT_DEF_OP_REGION_OP)
  175. .then(comment_scope(
  176. DebugVerbosity::Scopes,
  177. "DefOpRegion",
  178. name_string().then(take()).then(term_arg()).then(term_arg()).map_with_context(
  179. |(((name, space), offset), length), context| {
  180. let region = match space {
  181. 0x00 => RegionSpace::SystemMemory,
  182. 0x01 => RegionSpace::SystemIo,
  183. 0x02 => RegionSpace::PciConfig,
  184. 0x03 => RegionSpace::EmbeddedControl,
  185. 0x04 => RegionSpace::SMBus,
  186. 0x05 => RegionSpace::SystemCmos,
  187. 0x06 => RegionSpace::PciBarTarget,
  188. 0x07 => RegionSpace::IPMI,
  189. 0x08 => RegionSpace::GeneralPurposeIo,
  190. 0x09 => RegionSpace::GenericSerialBus,
  191. space @ 0x80..=0xff => RegionSpace::OemDefined(space),
  192. byte => return (Err(AmlError::InvalidRegionSpace(byte)), context),
  193. };
  194. let offset = match offset.as_integer(context) {
  195. Ok(offset) => offset,
  196. Err(err) => return (Err(err), context),
  197. };
  198. let length = match length.as_integer(context) {
  199. Ok(length) => length,
  200. Err(err) => return (Err(err), context),
  201. };
  202. let parent_device = match region {
  203. RegionSpace::PciConfig | RegionSpace::IPMI | RegionSpace::GenericSerialBus => {
  204. let resolved_path = try_with_context!(context, name.resolve(&context.current_scope));
  205. Some(try_with_context!(context, resolved_path.parent()))
  206. }
  207. _ => None,
  208. };
  209. try_with_context!(
  210. context,
  211. context.namespace.add_value_at_resolved_path(
  212. name,
  213. &context.current_scope,
  214. AmlValue::OpRegion { region, offset, length, parent_device }
  215. )
  216. );
  217. (Ok(()), context)
  218. },
  219. ),
  220. ))
  221. .discard_result()
  222. }
  223. pub fn def_field<'a, 'c>() -> impl Parser<'a, 'c, ()>
  224. where
  225. 'c: 'a,
  226. {
  227. /*
  228. * DefField = ExtOpPrefix 0x81 PkgLength NameString FieldFlags FieldList
  229. * FieldFlags := ByteData
  230. */
  231. let opregion_as_handle = name_string().map_with_context(|region_name, context| {
  232. /*
  233. * We search for the opregion that this field is referencing here as we already have the correct starting
  234. * scope. If we leave this to later, it becomes much harder as we also need to know the field's scope.
  235. */
  236. let (_, handle) =
  237. try_with_context!(context, context.namespace.search(&region_name, &context.current_scope));
  238. (Ok(handle), context)
  239. });
  240. ext_opcode(opcode::EXT_DEF_FIELD_OP)
  241. .then(comment_scope(
  242. DebugVerbosity::Scopes,
  243. "DefField",
  244. pkg_length().then(opregion_as_handle).then(take()).feed(|((list_length, region_handle), flags)| {
  245. move |mut input: &'a [u8], mut context: &'c mut AmlContext| -> ParseResult<'a, 'c, ()> {
  246. /*
  247. * FieldList := Nothing | <FieldElement FieldList>
  248. */
  249. // TODO: can this pattern be expressed as a combinator
  250. let mut current_offset = 0;
  251. while list_length.still_parsing(input) {
  252. let (new_input, new_context, field_length) =
  253. field_element(region_handle, FieldFlags::new(flags), current_offset)
  254. .parse(input, context)?;
  255. input = new_input;
  256. context = new_context;
  257. current_offset += field_length;
  258. }
  259. Ok((input, context, ()))
  260. }
  261. }),
  262. ))
  263. .discard_result()
  264. }
  265. /// Parses a `FieldElement`. Takes the current offset within the field list, and returns the length
  266. /// of the field element parsed.
  267. pub fn field_element<'a, 'c>(
  268. region_handle: AmlHandle,
  269. flags: FieldFlags,
  270. current_offset: u64,
  271. ) -> impl Parser<'a, 'c, u64>
  272. where
  273. 'c: 'a,
  274. {
  275. /*
  276. * FieldElement := NamedField | ReservedField | AccessField | ExtendedAccessField |
  277. * ConnectField
  278. * NamedField := NameSeg PkgLength
  279. * ReservedField := 0x00 PkgLength
  280. * AccessField := 0x01 AccessType AccessAttrib
  281. * ConnectField := <0x02 NameString> | <0x02 BufferData>
  282. * ExtendedAccessField := 0x03 AccessType ExtendedAccessAttrib AccessLength
  283. *
  284. * AccessType := ByteData
  285. * AccessAttrib := ByteData
  286. *
  287. * XXX: The spec says a ConnectField can be <0x02 BufferData>, but BufferData isn't an AML
  288. * object (it seems to be defined in ASL). We treat BufferData as if it was encoded like
  289. * DefBuffer, and this seems to work so far.
  290. */
  291. // TODO: parse ConnectField and ExtendedAccessField
  292. /*
  293. * Reserved fields shouldn't actually be added to the namespace; they seem to show gaps in
  294. * the operation region that aren't used for anything.
  295. */
  296. let reserved_field =
  297. opcode(opcode::RESERVED_FIELD).then(pkg_length()).map(|((), length)| Ok(length.raw_length as u64));
  298. // TODO: work out what to do with an access field
  299. // let access_field = opcode(opcode::ACCESS_FIELD)
  300. // .then(take())
  301. // .then(take())
  302. // .map_with_context(|(((), access_type), access_attrib), context| (Ok( , context));
  303. let named_field = name_seg().then(pkg_length()).map_with_context(move |(name_seg, length), context| {
  304. try_with_context!(
  305. context,
  306. context.namespace.add_value_at_resolved_path(
  307. AmlName::from_name_seg(name_seg),
  308. &context.current_scope,
  309. AmlValue::Field {
  310. region: region_handle,
  311. flags,
  312. offset: current_offset,
  313. length: length.raw_length as u64,
  314. },
  315. )
  316. );
  317. (Ok(length.raw_length as u64), context)
  318. });
  319. choice!(reserved_field, named_field)
  320. }
  321. pub fn def_method<'a, 'c>() -> impl Parser<'a, 'c, ()>
  322. where
  323. 'c: 'a,
  324. {
  325. /*
  326. * DefMethod := 0x14 PkgLength NameString MethodFlags TermList
  327. * MethodFlags := ByteData (where bits 0-2: ArgCount (0 to 7)
  328. * bit 3: SerializeFlag (0 = Not Serialized, 1 = Serialized)
  329. * bits 4-7: SyncLevel (0x00 to 0x0f))
  330. */
  331. opcode(opcode::DEF_METHOD_OP)
  332. .then(comment_scope(
  333. DebugVerbosity::Scopes,
  334. "DefMethod",
  335. pkg_length()
  336. .then(name_string())
  337. .then(take())
  338. .feed(|((length, name), flags)| {
  339. take_to_end_of_pkglength(length).map(move |code| Ok((name.clone(), flags, code)))
  340. })
  341. .map_with_context(|(name, flags, code), context| {
  342. try_with_context!(
  343. context,
  344. context.namespace.add_value_at_resolved_path(
  345. name,
  346. &context.current_scope,
  347. AmlValue::Method { flags: MethodFlags::new(flags), code: code.to_vec() },
  348. )
  349. );
  350. (Ok(()), context)
  351. }),
  352. ))
  353. .discard_result()
  354. }
  355. pub fn def_device<'a, 'c>() -> impl Parser<'a, 'c, ()>
  356. where
  357. 'c: 'a,
  358. {
  359. /*
  360. * DefDevice := ExtOpPrefix 0x82 PkgLength NameString TermList
  361. */
  362. ext_opcode(opcode::EXT_DEF_DEVICE_OP)
  363. .then(comment_scope(
  364. DebugVerbosity::Scopes,
  365. "DefDevice",
  366. pkg_length()
  367. .then(name_string())
  368. .map_with_context(|(length, name), context| {
  369. let resolved_name = try_with_context!(context, name.clone().resolve(&context.current_scope));
  370. try_with_context!(
  371. context,
  372. context.namespace.add_level(resolved_name.clone(), LevelType::Device)
  373. );
  374. let previous_scope = context.current_scope.clone();
  375. context.current_scope = resolved_name;
  376. (Ok((length, previous_scope)), context)
  377. })
  378. .feed(|(length, previous_scope)| term_list(length).map(move |_| Ok(previous_scope.clone())))
  379. .map_with_context(|previous_scope, context| {
  380. context.current_scope = previous_scope;
  381. (Ok(()), context)
  382. }),
  383. ))
  384. .discard_result()
  385. }
  386. pub fn def_processor<'a, 'c>() -> impl Parser<'a, 'c, ()>
  387. where
  388. 'c: 'a,
  389. {
  390. /*
  391. * DefProcessor := ExtOpPrefix 0x83 PkgLength NameString ProcID PblkAddress PblkLen TermList
  392. * ProcID := ByteData
  393. * PblkAddress := DWordData
  394. * PblkLen := ByteData
  395. */
  396. ext_opcode(opcode::EXT_DEF_PROCESSOR_OP)
  397. .then(comment_scope(
  398. DebugVerbosity::Scopes,
  399. "DefProcessor",
  400. pkg_length()
  401. .then(name_string())
  402. .then(take())
  403. .then(take_u32())
  404. .then(take())
  405. .map_with_context(|((((pkg_length, name), proc_id), pblk_address), pblk_len), context| {
  406. /*
  407. * Legacy `Processor` objects contain data within themselves, and can also have sub-objects,
  408. * so we add both a level for the sub-objects, and a value for the data.
  409. */
  410. let resolved_name = try_with_context!(context, name.resolve(&context.current_scope));
  411. try_with_context!(
  412. context,
  413. context.namespace.add_level(resolved_name.clone(), LevelType::Processor)
  414. );
  415. try_with_context!(
  416. context,
  417. context.namespace.add_value(
  418. resolved_name.clone(),
  419. AmlValue::Processor { id: proc_id, pblk_address, pblk_len }
  420. )
  421. );
  422. let previous_scope = context.current_scope.clone();
  423. context.current_scope = resolved_name;
  424. (Ok((previous_scope, pkg_length)), context)
  425. })
  426. .feed(move |(previous_scope, pkg_length)| {
  427. term_list(pkg_length).map(move |_| Ok(previous_scope.clone()))
  428. })
  429. .map_with_context(|previous_scope, context| {
  430. context.current_scope = previous_scope;
  431. (Ok(()), context)
  432. }),
  433. ))
  434. .discard_result()
  435. }
  436. pub fn def_mutex<'a, 'c>() -> impl Parser<'a, 'c, ()>
  437. where
  438. 'c: 'a,
  439. {
  440. /*
  441. * DefMutex := ExtOpPrefix 0x01 NameString SyncFlags
  442. * SyncFlags := ByteData (where bits 0-3: SyncLevel
  443. * bits 4-7: Reserved)
  444. */
  445. ext_opcode(opcode::EXT_DEF_MUTEX_OP)
  446. .then(comment_scope(
  447. DebugVerbosity::Scopes,
  448. "DefMutex",
  449. name_string().then(take()).map_with_context(|(name, sync_level), context| {
  450. try_with_context!(
  451. context,
  452. context.namespace.add_value_at_resolved_path(
  453. name,
  454. &context.current_scope,
  455. AmlValue::Mutex { sync_level }
  456. )
  457. );
  458. (Ok(()), context)
  459. }),
  460. ))
  461. .discard_result()
  462. }
  463. pub fn term_arg<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
  464. where
  465. 'c: 'a,
  466. {
  467. /*
  468. * TermArg := Type2Opcode | DataObject | ArgObj | LocalObj
  469. */
  470. comment_scope(
  471. DebugVerbosity::AllScopes,
  472. "TermArg",
  473. choice!(
  474. data_object(),
  475. arg_obj().map_with_context(|arg_num, context| {
  476. (Ok(try_with_context!(context, context.current_arg(arg_num)).clone()), context)
  477. }),
  478. local_obj().map_with_context(|local_num, context| {
  479. (Ok(try_with_context!(context, context.local(local_num)).clone()), context)
  480. }),
  481. make_parser_concrete!(type2_opcode())
  482. ),
  483. )
  484. }
  485. pub fn data_ref_object<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
  486. where
  487. 'c: 'a,
  488. {
  489. /*
  490. * DataRefObject := DataObject | ObjectReference | DDBHandle
  491. */
  492. comment_scope(DebugVerbosity::AllScopes, "DataRefObject", choice!(data_object()))
  493. }
  494. pub fn data_object<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
  495. where
  496. 'c: 'a,
  497. {
  498. /*
  499. * DataObject := DefPackage | DefVarPackage | ComputationalData
  500. *
  501. * The order of the parsers are important here, as DefPackage and DefVarPackage can be
  502. * accidently parsed as ComputationalDatas.
  503. */
  504. // TODO: this doesn't yet parse DefVarPackage
  505. comment_scope(DebugVerbosity::AllScopes, "DataObject", choice!(def_package(), computational_data()))
  506. }
  507. pub fn computational_data<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
  508. where
  509. 'c: 'a,
  510. {
  511. /*
  512. * ComputationalData := ByteConst | WordConst | DWordConst | QWordConst | String |
  513. * ConstObj | RevisionOp | DefBuffer
  514. * ByteConst := 0x0a ByteData
  515. * WordConst := 0x0b WordData
  516. * DWordConst := 0x0c DWordData
  517. * QWordConst := 0x0e QWordData
  518. * String := 0x0d AsciiCharList NullChar
  519. * ConstObj := ZeroOp(0x00) | OneOp(0x01) | OnesOp(0xff)
  520. * RevisionOp := ExtOpPrefix(0x5b) 0x30
  521. */
  522. let const_parser = |input: &'a [u8], context: &'c mut AmlContext| {
  523. let string_parser = |input: &'a [u8], context| -> ParseResult<'a, 'c, AmlValue> {
  524. /*
  525. * Using `position` isn't very efficient here, but is probably fine because the
  526. * strings are usually quite short.
  527. */
  528. let nul_position = match input.iter().position(|&c| c == b'\0') {
  529. Some(position) => position,
  530. None => return Err((input, context, AmlError::UnterminatedStringConstant)),
  531. };
  532. let string = String::from(match str::from_utf8(&input[0..nul_position]) {
  533. Ok(string) => string,
  534. Err(_) => return Err((input, context, AmlError::InvalidStringConstant)),
  535. });
  536. Ok((&input[(nul_position + 1)..], context, AmlValue::String(string)))
  537. };
  538. let (new_input, context, op) = take().parse(input, context)?;
  539. match op {
  540. opcode::BYTE_CONST => {
  541. take().map(|value| Ok(AmlValue::Integer(value as u64))).parse(new_input, context)
  542. }
  543. opcode::WORD_CONST => {
  544. take_u16().map(|value| Ok(AmlValue::Integer(value as u64))).parse(new_input, context)
  545. }
  546. opcode::DWORD_CONST => {
  547. take_u32().map(|value| Ok(AmlValue::Integer(value as u64))).parse(new_input, context)
  548. }
  549. opcode::QWORD_CONST => take_u64().map(|value| Ok(AmlValue::Integer(value))).parse(new_input, context),
  550. opcode::STRING_PREFIX => string_parser.parse(new_input, context),
  551. opcode::ZERO_OP => Ok((new_input, context, AmlValue::Integer(0))),
  552. opcode::ONE_OP => Ok((new_input, context, AmlValue::Integer(1))),
  553. opcode::ONES_OP => Ok((new_input, context, AmlValue::Integer(u64::max_value()))),
  554. _ => Err((input, context, AmlError::WrongParser)),
  555. }
  556. };
  557. comment_scope(
  558. DebugVerbosity::AllScopes,
  559. "ComputationalData",
  560. choice!(
  561. ext_opcode(opcode::EXT_REVISION_OP).map(|_| Ok(AmlValue::Integer(crate::AML_INTERPRETER_REVISION))),
  562. const_parser,
  563. make_parser_concrete!(def_buffer())
  564. ),
  565. )
  566. }
  567. #[cfg(test)]
  568. mod test {
  569. use super::*;
  570. use crate::test_utils::*;
  571. #[test]
  572. fn test_computational_data() {
  573. let mut context = make_test_context();
  574. check_ok!(
  575. computational_data().parse(&[0x00, 0x34, 0x12], &mut context),
  576. AmlValue::Integer(0),
  577. &[0x34, 0x12]
  578. );
  579. check_ok!(
  580. computational_data().parse(&[0x01, 0x18, 0xf3], &mut context),
  581. AmlValue::Integer(1),
  582. &[0x18, 0xf3]
  583. );
  584. check_ok!(
  585. computational_data().parse(&[0xff, 0x98, 0xc3], &mut context),
  586. AmlValue::Integer(u64::max_value()),
  587. &[0x98, 0xc3]
  588. );
  589. check_ok!(
  590. computational_data().parse(&[0x5b, 0x30], &mut context),
  591. AmlValue::Integer(crate::AML_INTERPRETER_REVISION),
  592. &[]
  593. );
  594. check_ok!(computational_data().parse(&[0x0a, 0xf3, 0x35], &mut context), AmlValue::Integer(0xf3), &[0x35]);
  595. check_ok!(computational_data().parse(&[0x0b, 0xf3, 0x35], &mut context), AmlValue::Integer(0x35f3), &[]);
  596. check_ok!(
  597. computational_data().parse(&[0x0c, 0xf3, 0x35, 0x12, 0x65, 0xff, 0x00], &mut context),
  598. AmlValue::Integer(0x651235f3),
  599. &[0xff, 0x00]
  600. );
  601. check_ok!(
  602. computational_data()
  603. .parse(&[0x0e, 0xf3, 0x35, 0x12, 0x65, 0xff, 0x00, 0x67, 0xde, 0x28], &mut context),
  604. AmlValue::Integer(0xde6700ff651235f3),
  605. &[0x28]
  606. );
  607. check_ok!(
  608. computational_data().parse(&[0x0d, b'A', b'B', b'C', b'D', b'\0', 0xff, 0xf5], &mut context),
  609. AmlValue::String(String::from("ABCD")),
  610. &[0xff, 0xf5]
  611. );
  612. }
  613. }