parser.rs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. use super::{
  2. opcodes,
  3. stream::AmlStream,
  4. value::{AmlValue, FieldFlags, RegionSpace},
  5. AmlError,
  6. };
  7. use crate::{Acpi, AcpiHandler};
  8. use alloc::string::String;
  9. use bit_field::BitField;
  10. use core::str;
  11. /// This is used internally by the parser to keep track of what we know about a field before we can
  12. /// add it to the namespace.
  13. struct FieldInfo {
  14. pub name: String,
  15. pub length: u64,
  16. }
  17. /// This is used internally by the parser. Often, we're only interested in offset of the end of the
  18. /// current explicit-length structure, so we know when to stop parsing it. However, various
  19. /// constants (e.g. the size of fields) are also encoded as PkgLengths, and so sometimes we want to
  20. /// access the raw data as well.
  21. struct PkgLength {
  22. pub raw_length: u32,
  23. pub end_offset: u32,
  24. }
  25. pub(crate) struct AmlParser<'s, 'a, 'h, H>
  26. where
  27. H: AcpiHandler + 'h,
  28. {
  29. acpi: &'a mut Acpi,
  30. handler: &'h mut H,
  31. scope: String,
  32. stream: AmlStream<'s>,
  33. }
  34. /// This macro takes a parser and one or more parsing functions and tries to parse the next part of
  35. /// the stream with each one. If a parsing function fails, it rolls back the stream and tries the
  36. /// next one. If none of the functions can parse the next part of the stream, we error on the
  37. /// unexpected byte.
  38. macro_rules! try_parse {
  39. ($parser: expr, $($function: path),+) => {{
  40. $(if let Some(value) = $parser.try_parse($function)? {
  41. Ok(value)
  42. } else)+ {
  43. Err(AmlError::UnexpectedByte($parser.stream.peek()?))
  44. }
  45. }}
  46. }
  47. impl<'s, 'a, 'h, H> AmlParser<'s, 'a, 'h, H>
  48. where
  49. H: AcpiHandler,
  50. {
  51. pub(crate) fn parse(
  52. acpi: &'a mut Acpi,
  53. handler: &'h mut H,
  54. scope: &str,
  55. stream: AmlStream<'s>,
  56. ) -> Result<(), AmlError> {
  57. let mut parser = AmlParser { acpi, handler, scope: String::from(scope), stream };
  58. let end_offset = parser.stream.len() as u32;
  59. parser.parse_term_list(end_offset)
  60. }
  61. /// Consume the next byte in the stream and check if it fulfils the given predicate. If it
  62. /// does, returns `Ok(the consumed char)`. If it doesn't, returns
  63. /// `Err(AmlError::UnexpectedByte(the consumed char)`. If there's an error consuming the char,
  64. /// it will forward the error on from that.
  65. fn consume_byte<F>(&mut self, predicate: F) -> Result<u8, AmlError>
  66. where
  67. F: Fn(u8) -> bool,
  68. {
  69. let byte = self.stream.next()?;
  70. match predicate(byte) {
  71. true => Ok(byte),
  72. false => Err(AmlError::UnexpectedByte(byte)),
  73. }
  74. }
  75. fn consume_opcode(&mut self, opcode: u8) -> Result<(), AmlError> {
  76. self.consume_byte(matches_byte(opcode))?;
  77. Ok(())
  78. }
  79. fn consume_ext_opcode(&mut self, ext_opcode: u8) -> Result<(), AmlError> {
  80. self.consume_byte(matches_byte(opcodes::EXT_OPCODE_PREFIX))?;
  81. self.consume_byte(matches_byte(ext_opcode))?;
  82. Ok(())
  83. }
  84. /// Try to parse the next part of the stream with the given parsing function. This returns any
  85. /// `AmlError` as an `Err`, except `AmlError::UnexpectedByte`, to which it will return
  86. /// `Ok(None)`. A successful parse gives `Ok(Some(...))`. On failure, this also reverts any
  87. /// changes made to the stream, so it's as if the parsing function never run.
  88. fn try_parse<T, F>(&mut self, parsing_function: F) -> Result<Option<T>, AmlError>
  89. where
  90. F: Fn(&mut Self) -> Result<T, AmlError>,
  91. {
  92. let stream = self.stream.clone();
  93. match parsing_function(self) {
  94. Ok(result) => Ok(Some(result)),
  95. Err(AmlError::UnexpectedByte(_)) => {
  96. self.stream = stream;
  97. Ok(None)
  98. }
  99. Err(error) => Err(error),
  100. }
  101. }
  102. fn parse_term_list(&mut self, end_offset: u32) -> Result<(), AmlError> {
  103. /*
  104. * TermList := Nothing | <TermObj TermList>
  105. *
  106. * Because TermLists don't have PkgLengths, we pass the offset to stop at from whatever
  107. * explicit-length object we were parsing before.
  108. */
  109. while self.stream.offset() <= end_offset {
  110. self.parse_term_object()?;
  111. }
  112. Ok(())
  113. }
  114. fn parse_term_object(&mut self) -> Result<(), AmlError> {
  115. /*
  116. * TermObj := NameSpaceModifierObj | NamedObj | Type1Opcode | Type2Opcode
  117. * NameSpaceModifierObj := DefAlias | DefName | DefScope
  118. * NamedObj := DefBankField | DefCreateBitField | DefCreateByteField |
  119. * DefCreateDWordField | DefCreateField | DefCreateQWordField |
  120. * DefCreateWordField | DefDataRegion | DefExternal | DefOpRegion |
  121. * DefPowerRes | DefProcessor | DefThermalZone
  122. */
  123. try_parse!(
  124. self,
  125. AmlParser::parse_def_scope,
  126. AmlParser::parse_def_op_region,
  127. AmlParser::parse_def_field //,
  128. // AmlParser::parse_type1_opcode TODO: reenable when we can parse them
  129. )
  130. }
  131. fn parse_def_scope(&mut self) -> Result<(), AmlError> {
  132. /*
  133. * DefScope := 0x10 PkgLength NameString TermList
  134. */
  135. self.consume_opcode(opcodes::SCOPE_OP)?;
  136. trace!("Parsing scope op");
  137. let scope_end_offset = self.parse_pkg_length()?.end_offset;
  138. let name_string = self.parse_name_string()?;
  139. let containing_scope = self.scope.clone();
  140. self.scope = name_string;
  141. let _term_list = self.parse_term_list(scope_end_offset)?;
  142. self.scope = containing_scope;
  143. Ok(())
  144. }
  145. fn parse_def_op_region(&mut self) -> Result<(), AmlError> {
  146. /*
  147. * DefOpRegion := ExtOpPrefix 0x80 NameString RegionSpace RegionOffset RegionLen
  148. * RegionSpace := ByteData (where 0x00 = SystemMemory
  149. * 0x01 = SystemIO
  150. * 0x02 = PciConfig
  151. * 0x03 = EmbeddedControl
  152. * 0x04 = SMBus
  153. * 0x05 = SystemCMOS
  154. * 0x06 = PciBarTarget
  155. * 0x07 = IPMI
  156. * 0x08 = GeneralPurposeIO
  157. * 0x09 = GenericSerialBus
  158. * 0x80-0xff = OEM Defined)
  159. * ByteData := 0x00 - 0xff
  160. * RegionOffset := TermArg => Integer
  161. * RegionLen := TermArg => Integer
  162. */
  163. self.consume_ext_opcode(opcodes::EXT_OP_REGION_OP)?;
  164. info!("Parsing op region");
  165. let name = self.parse_name_string()?;
  166. info!("name: {}", name);
  167. let region_space = match self.stream.next()? {
  168. 0x00 => RegionSpace::SystemMemory,
  169. 0x01 => RegionSpace::SystemIo,
  170. 0x02 => RegionSpace::PciConfig,
  171. 0x03 => RegionSpace::EmbeddedControl,
  172. 0x04 => RegionSpace::SMBus,
  173. 0x05 => RegionSpace::SystemCmos,
  174. 0x06 => RegionSpace::PciBarTarget,
  175. 0x07 => RegionSpace::IPMI,
  176. 0x08 => RegionSpace::GeneralPurposeIo,
  177. 0x09 => RegionSpace::GenericSerialBus,
  178. space @ 0x80..0xff => RegionSpace::OemDefined(space),
  179. byte => return Err(AmlError::UnexpectedByte(byte)),
  180. };
  181. info!("region space: {:?}", region_space);
  182. let offset = self.parse_term_arg()?.as_integer()?;
  183. info!("region offset: {}", offset);
  184. let length = self.parse_term_arg()?.as_integer()?;
  185. info!("region len: {}", length);
  186. // Insert it into the namespace
  187. let namespace_path = self.resolve_path(&name)?;
  188. self.acpi.namespace.insert(
  189. // self.resolve_path(name)?, TODO: I thought this would work with nll?
  190. namespace_path,
  191. AmlValue::OpRegion { region: region_space, offset, length },
  192. );
  193. Ok(())
  194. }
  195. fn parse_def_field(&mut self) -> Result<(), AmlError> {
  196. /*
  197. * DefField = ExtOpPrefix 0x81 PkgLength NameString FieldFlags FieldList
  198. * FieldList := Nothing | <FieldElement FieldList>
  199. * FieldElement := NamedField | ReservedField | AccessField | ExtendedAccessField |
  200. * ConnectField
  201. * ReservedField := 0x00 PkgLength
  202. * AccessField := 0x01 AccessType AccessAttrib
  203. * AccessType := ByteData
  204. * AccessAttrib := ByteData
  205. * ConnectField := <0x02 NameString> | <0x02 BufferData>
  206. */
  207. self.consume_ext_opcode(opcodes::EXT_FIELD_OP)?;
  208. trace!("Parsing DefField");
  209. let end_offset = self.parse_pkg_length()?.end_offset;
  210. trace!("end offset: {}", end_offset);
  211. let name = self.parse_name_string()?;
  212. trace!("name: {}", name);
  213. let flags = FieldFlags::new(self.stream.next()?);
  214. trace!("Field flags: {:?}", flags);
  215. while self.stream.offset() < end_offset {
  216. // TODO: parse other field types
  217. let info = try_parse!(self, AmlParser::parse_named_field)?;
  218. // TODO: add field name to this (info.name)?
  219. let namespace_path = self.resolve_path(&name)?;
  220. self.acpi.namespace.insert(
  221. namespace_path,
  222. AmlValue::Field {
  223. flags,
  224. offset: 0, // TODO: calculate offset
  225. length: info.length,
  226. },
  227. );
  228. }
  229. Ok(())
  230. }
  231. fn parse_named_field(&mut self) -> Result<FieldInfo, AmlError> {
  232. /*
  233. * NamedField := NameSeg PkgLength
  234. *
  235. * This encodes the size of the field using a PkgLength - it doesn't mark the length of
  236. * an explicit-length structure!
  237. */
  238. let name = String::from(name_seg_to_string(&self.parse_name_seg()?)?);
  239. let length = self.parse_pkg_length()?.raw_length as u64;
  240. info!("Adding named field called {:?} with size {}", name, length);
  241. Ok(FieldInfo { name, length })
  242. }
  243. fn parse_def_buffer(&mut self) -> Result<AmlValue, AmlError> {
  244. unimplemented!(); // TODO
  245. }
  246. fn parse_term_arg(&mut self) -> Result<AmlValue, AmlError> {
  247. /*
  248. * TermArg := Type2Opcode | DataObject | ArgObj | LocalObj
  249. * DataObject := ComputationalData | DefPackage | DefVarPackage
  250. */
  251. if let Some(result) = self.try_parse(AmlParser::parse_computational_data)? {
  252. Ok(result)
  253. } else {
  254. Err(AmlError::UnexpectedByte(self.stream.next()?))
  255. }
  256. }
  257. fn parse_computational_data(&mut self) -> Result<AmlValue, AmlError> {
  258. /*
  259. * ComputationalData := ByteConst | WordConst | DWordConst | QWordConst | String |
  260. * ConstObj | RevisionOp | DefBuffer
  261. * ByteConst := 0x0a ByteData
  262. * WordConst := 0x0b WordData
  263. * DWordConst := 0x0c DWordData
  264. * QWordConst := 0x0e QWordData
  265. * String := 0x0d AsciiCharList NullChar
  266. * ConstObj := ZeroOp(0x00) | OneOp(0x01) | OnesOp(0xff)
  267. * RevisionOp := ExtOpPrefix(0x5B) 0x30
  268. */
  269. match self.stream.peek()? {
  270. opcodes::BYTE_CONST => {
  271. self.consume_opcode(opcodes::BYTE_CONST)?;
  272. Ok(AmlValue::Integer(self.stream.next()? as u64))
  273. }
  274. opcodes::WORD_CONST => {
  275. self.consume_opcode(opcodes::WORD_CONST)?;
  276. Ok(AmlValue::Integer(self.stream.next_u16()? as u64))
  277. }
  278. opcodes::DWORD_CONST => {
  279. self.consume_opcode(opcodes::DWORD_CONST)?;
  280. Ok(AmlValue::Integer(self.stream.next_u16()? as u64))
  281. }
  282. opcodes::QWORD_CONST => {
  283. self.consume_opcode(opcodes::QWORD_CONST)?;
  284. Ok(AmlValue::Integer(self.stream.next_u16()? as u64))
  285. }
  286. opcodes::STRING_PREFIX => {
  287. self.consume_opcode(opcodes::STRING_PREFIX)?;
  288. unimplemented!(); // TODO
  289. }
  290. opcodes::ZERO_OP => {
  291. self.consume_opcode(opcodes::ZERO_OP)?;
  292. Ok(AmlValue::Integer(0))
  293. }
  294. opcodes::ONE_OP => {
  295. self.consume_opcode(opcodes::ONE_OP)?;
  296. Ok(AmlValue::Integer(1))
  297. }
  298. opcodes::ONES_OP => {
  299. self.consume_opcode(opcodes::ONES_OP)?;
  300. Ok(AmlValue::Integer(u64::max_value()))
  301. }
  302. opcodes::EXT_OPCODE_PREFIX if self.stream.lookahead(1)? == opcodes::EXT_REVISION_OP => {
  303. unimplemented!(); // TODO
  304. }
  305. _ => self.parse_def_buffer(),
  306. }
  307. }
  308. fn parse_type1_opcode(&mut self) -> Result<(), AmlError> {
  309. /*
  310. * Type1Opcode := DefBreak | DefBreakPoint | DefContinue | DefFatal | DefIfElse | DefLoad
  311. * | DefNoop | DefNotify | DefRelease | DefReset | DefReturn |
  312. * DefSignal | DefSleep | DefStall | DefUnload | DefWhile
  313. */
  314. unimplemented!(); // TODO
  315. }
  316. /// Parse a PkgLength. Returns the offset into the stream to stop parsing whatever object the
  317. /// PkgLength describes at.
  318. // TODO: think hard about whether we actually need to minus the length now because we use
  319. // `next()`? Isn't this already handled?
  320. fn parse_pkg_length(&mut self) -> Result<PkgLength, AmlError> {
  321. /*
  322. * PkgLength := PkgLeadByte |
  323. * <PkgLeadByte ByteData> |
  324. * <PkgLeadByte ByteData ByteData> |
  325. * <PkgLeadByte ByteData ByteData ByteData>
  326. */
  327. let lead_byte = self.stream.next()?;
  328. let byte_data_count = lead_byte.get_bits(6..8);
  329. if byte_data_count == 0 {
  330. let length = u32::from(lead_byte.get_bits(0..6));
  331. let end_offset = self.stream.offset() + length - 1; // Minus 1 to remove the PkgLength byte
  332. trace!(
  333. "Parsed 1-byte PkgLength with length {}, so ends at {}(current offset={}",
  334. length,
  335. end_offset,
  336. self.stream.offset()
  337. );
  338. return Ok(PkgLength { raw_length: length, end_offset });
  339. }
  340. let mut length = u32::from(lead_byte.get_bits(0..4));
  341. for i in 0..byte_data_count {
  342. length += u32::from(self.stream.next()?) << (4 + i * 8);
  343. }
  344. // Minus `byte_data_count + 1` to not include the PkgLength in the remaining bytes
  345. let end_offset = self.stream.offset() + length - byte_data_count as u32 - 1;
  346. trace!(
  347. "Parsed PkgLength with length {}, so ends at {}(current offset={})",
  348. length,
  349. end_offset,
  350. self.stream.offset()
  351. );
  352. Ok(PkgLength { raw_length: length, end_offset })
  353. }
  354. fn parse_name_string(&mut self) -> Result<String, AmlError> {
  355. /*
  356. * NameString := <RootChar('\') NamePath> | <PrefixPath NamePath>
  357. * PrefixPath := Nothing | <'^' PrefixPath>
  358. */
  359. match self.stream.peek()? {
  360. b'\\' => {
  361. /*
  362. * NameString := RootChar NamePath
  363. */
  364. self.stream.next()?;
  365. Ok(String::from("\\") + &self.parse_name_path()?)
  366. }
  367. b'^' => {
  368. unimplemented!();
  369. }
  370. _ => self.parse_name_path(),
  371. }
  372. }
  373. fn parse_name_path(&mut self) -> Result<String, AmlError> {
  374. /*
  375. * NamePath := NameSeg | DualNamePath | MultiNamePath | NullPath
  376. * DualNamePath := DualNamePrefix NameSeg NameSeg
  377. * MultiNamePath := MultiNamePrefix SegCount{ByteData} NameSeg(..SegCount)
  378. */
  379. match self.stream.peek()? {
  380. opcodes::NULL_NAME => {
  381. self.stream.next()?;
  382. Ok(String::from(""))
  383. }
  384. opcodes::DUAL_NAME_PREFIX => {
  385. self.stream.next()?;
  386. let first = self.parse_name_seg()?;
  387. let second = self.parse_name_seg()?;
  388. Ok(String::from(str::from_utf8(&first).unwrap()) + str::from_utf8(&second).unwrap())
  389. }
  390. opcodes::MULTI_NAME_PREFIX => {
  391. // TODO
  392. unimplemented!();
  393. }
  394. _ => Ok(String::from(str::from_utf8(&self.parse_name_seg()?).unwrap())),
  395. }
  396. }
  397. fn parse_name_seg(&mut self) -> Result<[u8; 4], AmlError> {
  398. /*
  399. * NameSeg := <LeadNameChar NameChar NameChar NameChar>
  400. */
  401. Ok([
  402. self.consume_byte(is_lead_name_char)?,
  403. self.consume_byte(is_name_char)?,
  404. self.consume_byte(is_name_char)?,
  405. self.consume_byte(is_name_char)?,
  406. ])
  407. }
  408. /// Resolve a given path and the current scope to an absolute path in the namespace.
  409. fn resolve_path(&mut self, mut path: &str) -> Result<String, AmlError> {
  410. /*
  411. * TODO: how should we handle '.' as they appear in paths?
  412. */
  413. let original_path = path.clone();
  414. // If the scope to resolve is from the root of the namespace, or the current scope is
  415. // nothing, just return the given scope
  416. if self.scope == "" || path.starts_with("\\") {
  417. return Ok(String::from(path));
  418. }
  419. // "^"s at the start of a path specify to go up one level from the current scope, to its
  420. // parent object
  421. let mut namespace_object = self.scope.clone();
  422. while path.starts_with("^") {
  423. path = &path[1..];
  424. if namespace_object.pop() == None {
  425. return Err(AmlError::InvalidPath(String::from(original_path)));
  426. }
  427. }
  428. Ok(namespace_object + &path)
  429. }
  430. }
  431. fn matches_byte(byte: u8) -> impl Fn(u8) -> bool {
  432. move |x| x == byte
  433. }
  434. fn is_lead_name_char(byte: u8) -> bool {
  435. (byte >= b'A' && byte <= b'Z') || byte == b'_'
  436. }
  437. fn is_digit_char(byte: u8) -> bool {
  438. byte >= b'0' && byte <= b'9'
  439. }
  440. fn is_name_char(byte: u8) -> bool {
  441. is_lead_name_char(byte) || is_digit_char(byte)
  442. }
  443. fn name_seg_to_string<'a>(seg: &'a [u8; 4]) -> Result<&'a str, AmlError> {
  444. match str::from_utf8(seg) {
  445. Ok(seg_str) => Ok(seg_str),
  446. Err(_) => Err(AmlError::InvalidNameSeg(*seg)),
  447. }
  448. }