Kaynağa Gözat

Merge #67

67: Parse prefix chars in NameStrings and make HPET fields public r=IsaacWoods a=IsaacWoods

Fixes #66 

This should fix an error encountered if a `NameString` actually uses prefix chars (`^`). Also makes the fields of the `HpetInfo` struct public, which was requested on Gitter.

bors r+

Co-authored-by: Isaac Woods <isaacwoods.home@gmail.com>
bors[bot] 5 yıl önce
ebeveyn
işleme
6c95f64883
5 değiştirilmiş dosya ile 54 ekleme ve 12 silme
  1. 1 1
      acpi/Cargo.toml
  2. 6 7
      acpi/src/hpet.rs
  3. 1 1
      aml/Cargo.toml
  4. 25 3
      aml/src/name_object.rs
  5. 21 0
      aml/src/parser.rs

+ 1 - 1
acpi/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "acpi"
-version = "0.6.0"
+version = "0.7.0"
 authors = ["Isaac Woods"]
 repository = "https://github.com/rust-osdev/acpi"
 description = "Library for parsing ACPI tables"

+ 6 - 7
acpi/src/hpet.rs

@@ -14,13 +14,12 @@ pub enum PageProtection {
 /// Information about the High Precision Event Timer
 #[derive(Debug)]
 pub struct HpetInfo {
-    event_timer_block_id: u32,
-    base_address: usize,
-    hpet_number: u8,
-    /// The minimum number of clock ticks that can be set without losing interrupts (for timers in
-    /// Periodic Mode)
-    clock_tick_unit: u16,
-    page_protection: PageProtection,
+    pub event_timer_block_id: u32,
+    pub base_address: usize,
+    pub hpet_number: u8,
+    /// The minimum number of clock ticks that can be set without losing interrupts (for timers in Periodic Mode)
+    pub clock_tick_unit: u16,
+    pub page_protection: PageProtection,
 }
 
 #[repr(C, packed)]

+ 1 - 1
aml/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "aml"
-version = "0.6.0"
+version = "0.7.0"
 authors = ["Isaac Woods"]
 repository = "https://github.com/rust-osdev/acpi"
 description = "Library for parsing AML"

+ 25 - 3
aml/src/name_object.rs

@@ -2,7 +2,7 @@ use crate::{
     misc::{arg_obj, debug_obj, local_obj, ArgNum, LocalNum},
     namespace::{AmlName, NameComponent},
     opcode::{opcode, DUAL_NAME_PREFIX, MULTI_NAME_PREFIX, NULL_NAME, PREFIX_CHAR, ROOT_CHAR},
-    parser::{choice, comment_scope_verbose, consume, n_of, take, Parser},
+    parser::{choice, comment_scope_verbose, consume, n_of, take, take_while, Parser},
     AmlContext,
     AmlError,
 };
@@ -60,6 +60,13 @@ where
         Ok(AmlName(name))
     });
 
+    let prefix_path =
+        take_while(opcode(PREFIX_CHAR)).then(name_path()).map(|(num_prefix_chars, ref name_path)| {
+            let mut name = alloc::vec![NameComponent::Prefix; num_prefix_chars];
+            name.extend_from_slice(name_path);
+            Ok(AmlName(name))
+        });
+
     // TODO: combinator to select a parser based on a peeked byte?
     comment_scope_verbose("NameString", move |input: &'a [u8], context| {
         let first_char = match input.first() {
@@ -67,10 +74,9 @@ where
             None => return Err((input, context, AmlError::UnexpectedEndOfStream)),
         };
 
-        // TODO: parse <PrefixPath NamePath> where there are actually PrefixChars
         match first_char {
             ROOT_CHAR => root_name_string.parse(input, context),
-            PREFIX_CHAR => unimplemented!(),
+            PREFIX_CHAR => prefix_path.parse(input, context),
             _ => name_path().map(|path| Ok(AmlName(path))).parse(input, context),
         }
     })
@@ -257,4 +263,20 @@ mod tests {
             &[]
         );
     }
+
+    #[test]
+    fn test_prefix_path() {
+        let mut context = AmlContext::new();
+
+        check_ok!(
+            name_string().parse(&[b'^', b'A', b'B', b'C', b'D'], &mut context),
+            AmlName::from_str("^ABCD").unwrap(),
+            &[]
+        );
+        check_ok!(
+            name_string().parse(&[b'^', b'^', b'^', b'A', b'B', b'C', b'D'], &mut context),
+            AmlName::from_str("^^^ABCD").unwrap(),
+            &[]
+        );
+    }
 }

+ 21 - 0
aml/src/parser.rs

@@ -191,6 +191,27 @@ where
     }
 }
 
+pub fn take_while<'a, 'c, P, R>(parser: P) -> impl Parser<'a, 'c, usize>
+where
+    'c: 'a,
+    P: Parser<'a, 'c, R>,
+{
+    move |mut input: &'a [u8], mut context: &'c mut AmlContext| {
+        let mut num_passed = 0;
+        loop {
+            match parser.parse(input, context) {
+                Ok((new_input, new_context, _)) => {
+                    input = new_input;
+                    context = new_context;
+                    num_passed += 1;
+                }
+                Err((_, context, AmlError::WrongParser)) => return Ok((input, context, num_passed)),
+                Err((_, context, err)) => return Err((input, context, err)),
+            }
+        }
+    }
+}
+
 pub fn consume<'a, 'c, F>(condition: F) -> impl Parser<'a, 'c, u8>
 where
     'c: 'a,