2
0

namespace.rs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. use crate::{name_object::NameSeg, value::AmlValue, AmlError};
  2. use alloc::{
  3. collections::BTreeMap,
  4. string::{String, ToString},
  5. vec::Vec,
  6. };
  7. use core::fmt;
  8. /// A handle is used to refer to an AML value without actually borrowing it until you need to
  9. /// access it (this makes borrowing situation much easier as you only have to consider who's
  10. /// borrowing the namespace). They can also be cached to avoid expensive namespace lookups.
  11. ///
  12. /// Handles are never reused (the handle to a removed object will never be reused to point to a new
  13. /// object). This ensures handles cached by the library consumer will never point to an object they
  14. /// did not originally point to, but also means that, in theory, we can run out of handles on a
  15. /// very-long-running system (we are yet to see if this is a problem, practically).
  16. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
  17. pub struct AmlHandle(u32);
  18. impl AmlHandle {
  19. pub(self) fn increment(&mut self) {
  20. self.0 += 1;
  21. }
  22. }
  23. #[derive(Clone, Copy, PartialEq, Eq, Debug)]
  24. pub enum LevelType {
  25. Scope,
  26. Device,
  27. /// A legacy `Processor` object's sub-objects are stored in a level of this type. Modern tables define
  28. /// processors as `Device`s.
  29. Processor,
  30. /// A `PowerResource` object's sub-objects are stored in a level of this type.
  31. PowerResource,
  32. /// A `ThermalZone` object's sub-objects are stored in a level of this type.
  33. ThermalZone,
  34. /// A level of this type is created at the same path as the name of a method when it is invoked. It can be
  35. /// used by the method to store local variables.
  36. MethodLocals,
  37. }
  38. #[derive(Clone, Debug)]
  39. pub struct NamespaceLevel {
  40. pub typ: LevelType,
  41. pub children: BTreeMap<NameSeg, NamespaceLevel>,
  42. pub values: BTreeMap<NameSeg, AmlHandle>,
  43. }
  44. impl NamespaceLevel {
  45. pub(crate) fn new(typ: LevelType) -> NamespaceLevel {
  46. NamespaceLevel { typ, children: BTreeMap::new(), values: BTreeMap::new() }
  47. }
  48. }
  49. #[derive(Clone)]
  50. pub struct Namespace {
  51. /// This is a running count of ids, which are never reused. This is incremented every time we
  52. /// add a new object to the namespace. We can then remove objects, freeing their memory, without
  53. /// risking using the same id for two objects.
  54. next_handle: AmlHandle,
  55. /// This maps handles to actual values, and is used to access the actual AML values. When removing a value
  56. /// from the object map, care must be taken to also remove references to its handle in the level data
  57. /// structure, as invalid handles will cause panics.
  58. object_map: BTreeMap<AmlHandle, AmlValue>,
  59. /// Holds the first level of the namespace - containing items such as `\_SB`. Subsequent levels are held
  60. /// recursively inside this structure. It holds handles to references, which need to be indexed into
  61. /// `object_map` to acctually access the object.
  62. root: NamespaceLevel,
  63. }
  64. impl Namespace {
  65. pub fn new() -> Namespace {
  66. Namespace {
  67. next_handle: AmlHandle(0),
  68. object_map: BTreeMap::new(),
  69. root: NamespaceLevel::new(LevelType::Scope),
  70. }
  71. }
  72. /// Add a new level to the namespace. A "level" is named by a single `NameSeg`, and can contain values, and
  73. /// also other further sub-levels. Once a level has been created, AML values can be added to it with
  74. /// `add_value`.
  75. ///
  76. /// ### Note
  77. /// At first glance, you might expect `DefDevice` to add a value of type `Device`. However, because all
  78. /// `Devices` do is hold other values, we model them as namespace levels, and so they must be created
  79. /// accordingly.
  80. pub fn add_level(&mut self, path: AmlName, typ: LevelType) -> Result<(), AmlError> {
  81. assert!(path.is_absolute());
  82. let path = path.normalize()?;
  83. /*
  84. * We need to handle a special case here: if a `Scope(\) { ... }` appears in the AML, the parser will
  85. * try and recreate the root scope. Instead of handling this specially in the parser, we just
  86. * return nicely here.
  87. */
  88. if path != AmlName::root() {
  89. let (level, last_seg) = self.get_level_for_path_mut(&path)?;
  90. /*
  91. * If the level has already been added, we don't need to add it again. The parser can try to add it
  92. * multiple times if the ASL contains multiple blocks that add to the same scope/device.
  93. */
  94. if !level.children.contains_key(&last_seg) {
  95. level.children.insert(last_seg, NamespaceLevel::new(typ));
  96. }
  97. }
  98. Ok(())
  99. }
  100. pub fn remove_level(&mut self, path: AmlName) -> Result<(), AmlError> {
  101. assert!(path.is_absolute());
  102. let path = path.normalize()?;
  103. if path != AmlName::root() {
  104. let (level, last_seg) = self.get_level_for_path_mut(&path)?;
  105. match level.children.remove(&last_seg) {
  106. Some(_) => Ok(()),
  107. None => Err(AmlError::LevelDoesNotExist(path)),
  108. }
  109. } else {
  110. Err(AmlError::TriedToRemoveRootNamespace)
  111. }
  112. }
  113. /// Add a value to the namespace at the given path, which must be a normalized, absolute AML
  114. /// name. If you want to add at a path relative to a given scope, use `add_at_resolved_path`
  115. /// instead.
  116. pub fn add_value(&mut self, path: AmlName, value: AmlValue) -> Result<AmlHandle, AmlError> {
  117. assert!(path.is_absolute());
  118. let path = path.normalize()?;
  119. let handle = self.next_handle;
  120. self.next_handle.increment();
  121. self.object_map.insert(handle, value);
  122. let (level, last_seg) = self.get_level_for_path_mut(&path)?;
  123. match level.values.insert(last_seg, handle) {
  124. None => Ok(handle),
  125. Some(_) => Err(AmlError::NameCollision(path)),
  126. }
  127. }
  128. /// Helper method for adding a value to the namespace at a path that is relative to the given
  129. /// scope. This operation involves a lot of error handling in parts of the parser, so is
  130. /// encapsulated here.
  131. pub fn add_value_at_resolved_path(
  132. &mut self,
  133. path: AmlName,
  134. scope: &AmlName,
  135. value: AmlValue,
  136. ) -> Result<AmlHandle, AmlError> {
  137. self.add_value(path.resolve(scope)?, value)
  138. }
  139. pub fn get(&self, handle: AmlHandle) -> Result<&AmlValue, AmlError> {
  140. Ok(self.object_map.get(&handle).unwrap())
  141. }
  142. pub fn get_mut(&mut self, handle: AmlHandle) -> Result<&mut AmlValue, AmlError> {
  143. Ok(self.object_map.get_mut(&handle).unwrap())
  144. }
  145. pub fn get_handle(&self, path: &AmlName) -> Result<AmlHandle, AmlError> {
  146. let (level, last_seg) = self.get_level_for_path(path)?;
  147. Ok(*level.values.get(&last_seg).ok_or(AmlError::ValueDoesNotExist(path.clone()))?)
  148. }
  149. pub fn get_by_path(&self, path: &AmlName) -> Result<&AmlValue, AmlError> {
  150. let handle = self.get_handle(path)?;
  151. Ok(self.get(handle).unwrap())
  152. }
  153. pub fn get_by_path_mut(&mut self, path: &AmlName) -> Result<&mut AmlValue, AmlError> {
  154. let handle = self.get_handle(path)?;
  155. Ok(self.get_mut(handle).unwrap())
  156. }
  157. /// Search for an object at the given path of the namespace, applying the search rules described in §5.3 of the
  158. /// ACPI specification, if they are applicable. Returns the resolved name, and the handle of the first valid
  159. /// object, if found.
  160. pub fn search(&self, path: &AmlName, starting_scope: &AmlName) -> Result<(AmlName, AmlHandle), AmlError> {
  161. if path.search_rules_apply() {
  162. /*
  163. * If search rules apply, we need to recursively look through the namespace. If the
  164. * given name does not occur in the current scope, we look at the parent scope, until
  165. * we either find the name, or reach the root of the namespace.
  166. */
  167. let mut scope = starting_scope.clone();
  168. assert!(scope.is_absolute());
  169. loop {
  170. // Search for the name at this namespace level. If we find it, we're done.
  171. let name = path.resolve(&scope)?;
  172. match self.get_level_for_path(&name) {
  173. Ok((level, last_seg)) => {
  174. if let Some(&handle) = level.values.get(&last_seg) {
  175. return Ok((name, handle));
  176. }
  177. }
  178. /*
  179. * This error is caught specially to avoid a case that seems bizzare but is quite useful - when
  180. * the passed starting scope doesn't exist. Certain methods return values that reference names
  181. * from the point of view of the method, so it makes sense for the starting scope to be inside
  182. * the method. However, because we have destroyed all the objects created by the method
  183. * dynamically, the level no longer exists.
  184. *
  185. * To avoid erroring here, we simply continue to the parent scope. If the whole scope doesn't
  186. * exist, this will error when we get to the root, so this seems unlikely to introduce bugs.
  187. */
  188. Err(AmlError::LevelDoesNotExist(_)) => (),
  189. Err(err) => return Err(err),
  190. }
  191. // If we don't find it, go up a level in the namespace and search for it there recursively
  192. match scope.parent() {
  193. Ok(parent) => scope = parent,
  194. // If we still haven't found the value and have run out of parents, return `None`.
  195. Err(AmlError::RootHasNoParent) => return Err(AmlError::ValueDoesNotExist(path.clone())),
  196. Err(err) => return Err(err),
  197. }
  198. }
  199. } else {
  200. // If search rules don't apply, simply resolve it against the starting scope
  201. let name = path.resolve(starting_scope)?;
  202. // TODO: the fuzzer crashes when path is `\` and the scope is also `\`. This means that name is `\`,
  203. // which then trips up get_level_for_path. I don't know where to best solve this: we could check for
  204. // specific things that crash `search`, or look for a more general solution.
  205. let (level, last_seg) = self.get_level_for_path(&path.resolve(starting_scope)?)?;
  206. if let Some(&handle) = level.values.get(&last_seg) {
  207. Ok((name, handle))
  208. } else {
  209. Err(AmlError::ValueDoesNotExist(path.clone()))
  210. }
  211. }
  212. }
  213. pub fn search_for_level(&self, level_name: &AmlName, starting_scope: &AmlName) -> Result<AmlName, AmlError> {
  214. if level_name.search_rules_apply() {
  215. let mut scope = starting_scope.clone().normalize()?;
  216. assert!(scope.is_absolute());
  217. loop {
  218. let name = level_name.resolve(&scope)?;
  219. if let Ok((level, last_seg)) = self.get_level_for_path(&name) {
  220. if let Some(_) = level.children.get(&last_seg) {
  221. return Ok(name);
  222. }
  223. }
  224. // If we don't find it, move the scope up a level and search for it there recursively
  225. match scope.parent() {
  226. Ok(parent) => scope = parent,
  227. Err(AmlError::RootHasNoParent) => return Err(AmlError::LevelDoesNotExist(level_name.clone())),
  228. Err(err) => return Err(err),
  229. }
  230. }
  231. } else {
  232. Ok(level_name.clone())
  233. }
  234. }
  235. fn get_level_for_path(&self, path: &AmlName) -> Result<(&NamespaceLevel, NameSeg), AmlError> {
  236. assert_ne!(*path, AmlName::root());
  237. let (last_seg, levels) = path.0[1..].split_last().unwrap();
  238. let last_seg = last_seg.as_segment().unwrap();
  239. // TODO: this helps with diagnostics, but requires a heap allocation just in case we need to error.
  240. let mut traversed_path = AmlName::root();
  241. let mut current_level = &self.root;
  242. for level in levels {
  243. traversed_path.0.push(*level);
  244. current_level = current_level
  245. .children
  246. .get(&level.as_segment().unwrap())
  247. .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
  248. }
  249. Ok((current_level, last_seg))
  250. }
  251. /// Split an absolute path into a bunch of level segments (used to traverse the level data structure), and a
  252. /// last segment to index into that level. This must not be called on `\\`.
  253. fn get_level_for_path_mut(&mut self, path: &AmlName) -> Result<(&mut NamespaceLevel, NameSeg), AmlError> {
  254. assert_ne!(*path, AmlName::root());
  255. let (last_seg, levels) = path.0[1..].split_last().unwrap();
  256. let last_seg = last_seg.as_segment().unwrap();
  257. // TODO: this helps with diagnostics, but requires a heap allocation just in case we need to error. We can
  258. // improve this by changing the `levels` interation into an `enumerate()`, and then using the index to
  259. // create the correct path on the error path
  260. let mut traversed_path = AmlName::root();
  261. let mut current_level = &mut self.root;
  262. for level in levels {
  263. traversed_path.0.push(*level);
  264. current_level = current_level
  265. .children
  266. .get_mut(&level.as_segment().unwrap())
  267. .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
  268. }
  269. Ok((current_level, last_seg))
  270. }
  271. /// Traverse the namespace, calling `f` on each namespace level. `f` returns a `Result<bool, AmlError>` -
  272. /// errors terminate the traversal and are propagated, and the `bool` on the successful path marks whether the
  273. /// children of the level should also be traversed.
  274. pub fn traverse<F>(&mut self, mut f: F) -> Result<(), AmlError>
  275. where
  276. F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
  277. {
  278. fn traverse_level<F>(level: &NamespaceLevel, scope: &AmlName, f: &mut F) -> Result<(), AmlError>
  279. where
  280. F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
  281. {
  282. for (name, ref child) in level.children.iter() {
  283. let name = AmlName::from_name_seg(*name).resolve(scope)?;
  284. if f(&name, child)? {
  285. traverse_level(child, &name, f)?;
  286. }
  287. }
  288. Ok(())
  289. }
  290. if f(&AmlName::root(), &self.root)? {
  291. traverse_level(&self.root, &AmlName::root(), &mut f)?;
  292. }
  293. Ok(())
  294. }
  295. }
  296. impl fmt::Debug for Namespace {
  297. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  298. const INDENT_PER_LEVEL: usize = 4;
  299. fn print_level(
  300. namespace: &Namespace,
  301. f: &mut fmt::Formatter<'_>,
  302. level_name: &str,
  303. level: &NamespaceLevel,
  304. indent: usize,
  305. ) -> fmt::Result {
  306. writeln!(f, "{:indent$}{}:", "", level_name, indent = indent)?;
  307. for (name, handle) in level.values.iter() {
  308. writeln!(
  309. f,
  310. "{:indent$}{}: {:?}",
  311. "",
  312. name.as_str(),
  313. namespace.object_map.get(handle).unwrap(),
  314. indent = indent + INDENT_PER_LEVEL
  315. )?;
  316. }
  317. for (name, sub_level) in level.children.iter() {
  318. print_level(namespace, f, name.as_str(), sub_level, indent + INDENT_PER_LEVEL)?;
  319. }
  320. Ok(())
  321. }
  322. print_level(self, f, "\\", &self.root, 0)
  323. }
  324. }
  325. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
  326. pub struct AmlName(Vec<NameComponent>);
  327. impl AmlName {
  328. pub fn root() -> AmlName {
  329. AmlName(alloc::vec![NameComponent::Root])
  330. }
  331. pub fn from_name_seg(seg: NameSeg) -> AmlName {
  332. AmlName(alloc::vec![NameComponent::Segment(seg)])
  333. }
  334. pub fn from_components(components: Vec<NameComponent>) -> AmlName {
  335. assert!(components.len() > 0);
  336. AmlName(components)
  337. }
  338. /// Convert a string representation of an AML name into an `AmlName`.
  339. pub fn from_str(mut string: &str) -> Result<AmlName, AmlError> {
  340. if string.len() == 0 {
  341. return Err(AmlError::EmptyNamesAreInvalid);
  342. }
  343. let mut components = Vec::new();
  344. // If it starts with a \, make it an absolute name
  345. if string.starts_with('\\') {
  346. components.push(NameComponent::Root);
  347. string = &string[1..];
  348. }
  349. if string.len() > 0 {
  350. // Divide the rest of it into segments, and parse those
  351. for mut part in string.split('.') {
  352. // Handle prefix chars
  353. while part.starts_with('^') {
  354. components.push(NameComponent::Prefix);
  355. part = &part[1..];
  356. }
  357. components.push(NameComponent::Segment(NameSeg::from_str(part)?));
  358. }
  359. }
  360. Ok(AmlName(components))
  361. }
  362. pub fn as_string(&self) -> String {
  363. self.0
  364. .iter()
  365. .fold(String::new(), |name, component| match component {
  366. NameComponent::Root => name + "\\",
  367. NameComponent::Prefix => name + "^",
  368. NameComponent::Segment(seg) => name + seg.as_str() + ".",
  369. })
  370. .trim_end_matches('.')
  371. .to_string()
  372. }
  373. /// An AML path is normal if it does not contain any prefix elements ("^" characters, when
  374. /// expressed as a string).
  375. pub fn is_normal(&self) -> bool {
  376. !self.0.contains(&NameComponent::Prefix)
  377. }
  378. pub fn is_absolute(&self) -> bool {
  379. self.0.first() == Some(&NameComponent::Root)
  380. }
  381. /// Special rules apply when searching for certain paths (specifically, those that are made up
  382. /// of a single name segment). Returns `true` if those rules apply.
  383. pub fn search_rules_apply(&self) -> bool {
  384. if self.0.len() != 1 {
  385. return false;
  386. }
  387. match self.0[0] {
  388. NameComponent::Segment(_) => true,
  389. _ => false,
  390. }
  391. }
  392. /// Normalize an AML path, resolving prefix chars. Returns `AmlError::InvalidNormalizedName` if the path
  393. /// normalizes to an invalid path (e.g. `\^_FOO`)
  394. pub fn normalize(self) -> Result<AmlName, AmlError> {
  395. /*
  396. * If the path is already normal, just return it as-is. This avoids an unneccessary heap allocation and
  397. * free.
  398. */
  399. if self.is_normal() {
  400. return Ok(self);
  401. }
  402. Ok(AmlName(self.0.iter().try_fold(Vec::new(), |mut name, &component| match component {
  403. seg @ NameComponent::Segment(_) => {
  404. name.push(seg);
  405. Ok(name)
  406. }
  407. NameComponent::Root => {
  408. name.push(NameComponent::Root);
  409. Ok(name)
  410. }
  411. NameComponent::Prefix => {
  412. if let Some(NameComponent::Segment(_)) = name.iter().last() {
  413. name.pop().unwrap();
  414. Ok(name)
  415. } else {
  416. Err(AmlError::InvalidNormalizedName(self.clone()))
  417. }
  418. }
  419. })?))
  420. }
  421. /// Get the parent of this `AmlName`. For example, the parent of `\_SB.PCI0._PRT` is `\_SB.PCI0`. The root
  422. /// path has no parent, and so returns `None`.
  423. pub fn parent(&self) -> Result<AmlName, AmlError> {
  424. // Firstly, normalize the path so we don't have to deal with prefix chars
  425. let mut normalized_self = self.clone().normalize()?;
  426. match normalized_self.0.last() {
  427. None | Some(NameComponent::Root) => Err(AmlError::RootHasNoParent),
  428. Some(NameComponent::Segment(_)) => {
  429. normalized_self.0.pop();
  430. Ok(normalized_self)
  431. }
  432. Some(NameComponent::Prefix) => unreachable!(), // Prefix chars are removed by normalization
  433. }
  434. }
  435. /// Resolve this path against a given scope, making it absolute. If the path is absolute, it is
  436. /// returned directly. The path is also normalized.
  437. pub fn resolve(&self, scope: &AmlName) -> Result<AmlName, AmlError> {
  438. assert!(scope.is_absolute());
  439. if self.is_absolute() {
  440. return Ok(self.clone());
  441. }
  442. let mut resolved_path = scope.clone();
  443. resolved_path.0.extend_from_slice(&(self.0));
  444. resolved_path.normalize()
  445. }
  446. }
  447. impl fmt::Display for AmlName {
  448. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  449. write!(f, "{}", self.as_string())
  450. }
  451. }
  452. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
  453. pub enum NameComponent {
  454. Root,
  455. Prefix,
  456. Segment(NameSeg),
  457. }
  458. impl NameComponent {
  459. pub fn as_segment(self) -> Result<NameSeg, ()> {
  460. match self {
  461. NameComponent::Segment(seg) => Ok(seg),
  462. NameComponent::Root | NameComponent::Prefix => Err(()),
  463. }
  464. }
  465. }
  466. #[cfg(test)]
  467. mod tests {
  468. use super::*;
  469. use crate::test_utils::crudely_cmp_values;
  470. #[test]
  471. fn test_aml_name_from_str() {
  472. assert_eq!(AmlName::from_str(""), Err(AmlError::EmptyNamesAreInvalid));
  473. assert_eq!(AmlName::from_str("\\"), Ok(AmlName::root()));
  474. assert_eq!(
  475. AmlName::from_str("\\_SB.PCI0"),
  476. Ok(AmlName(alloc::vec![
  477. NameComponent::Root,
  478. NameComponent::Segment(NameSeg([b'_', b'S', b'B', b'_'])),
  479. NameComponent::Segment(NameSeg([b'P', b'C', b'I', b'0']))
  480. ]))
  481. );
  482. assert_eq!(
  483. AmlName::from_str("\\_SB.^^^PCI0"),
  484. Ok(AmlName(alloc::vec![
  485. NameComponent::Root,
  486. NameComponent::Segment(NameSeg([b'_', b'S', b'B', b'_'])),
  487. NameComponent::Prefix,
  488. NameComponent::Prefix,
  489. NameComponent::Prefix,
  490. NameComponent::Segment(NameSeg([b'P', b'C', b'I', b'0']))
  491. ]))
  492. );
  493. }
  494. #[test]
  495. fn test_is_normal() {
  496. assert_eq!(AmlName::root().is_normal(), true);
  497. assert_eq!(AmlName::from_str("\\_SB.PCI0.VGA").unwrap().is_normal(), true);
  498. assert_eq!(AmlName::from_str("\\_SB.^PCI0.VGA").unwrap().is_normal(), false);
  499. assert_eq!(AmlName::from_str("\\^_SB.^^PCI0.VGA").unwrap().is_normal(), false);
  500. assert_eq!(AmlName::from_str("_SB.^^PCI0.VGA").unwrap().is_normal(), false);
  501. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().is_normal(), true);
  502. }
  503. #[test]
  504. fn test_normalization() {
  505. assert_eq!(
  506. AmlName::from_str("\\_SB.PCI0").unwrap().normalize(),
  507. Ok(AmlName::from_str("\\_SB.PCI0").unwrap())
  508. );
  509. assert_eq!(
  510. AmlName::from_str("\\_SB.^PCI0").unwrap().normalize(),
  511. Ok(AmlName::from_str("\\PCI0").unwrap())
  512. );
  513. assert_eq!(
  514. AmlName::from_str("\\_SB.PCI0.^^FOO").unwrap().normalize(),
  515. Ok(AmlName::from_str("\\FOO").unwrap())
  516. );
  517. assert_eq!(
  518. AmlName::from_str("_SB.PCI0.^FOO.BAR").unwrap().normalize(),
  519. Ok(AmlName::from_str("_SB.FOO.BAR").unwrap())
  520. );
  521. assert_eq!(
  522. AmlName::from_str("\\^_SB").unwrap().normalize(),
  523. Err(AmlError::InvalidNormalizedName(AmlName::from_str("\\^_SB").unwrap()))
  524. );
  525. assert_eq!(
  526. AmlName::from_str("\\_SB.PCI0.FOO.^^^^BAR").unwrap().normalize(),
  527. Err(AmlError::InvalidNormalizedName(AmlName::from_str("\\_SB.PCI0.FOO.^^^^BAR").unwrap()))
  528. );
  529. }
  530. #[test]
  531. fn test_is_absolute() {
  532. assert_eq!(AmlName::root().is_absolute(), true);
  533. assert_eq!(AmlName::from_str("\\_SB.PCI0.VGA").unwrap().is_absolute(), true);
  534. assert_eq!(AmlName::from_str("\\_SB.^PCI0.VGA").unwrap().is_absolute(), true);
  535. assert_eq!(AmlName::from_str("\\^_SB.^^PCI0.VGA").unwrap().is_absolute(), true);
  536. assert_eq!(AmlName::from_str("_SB.^^PCI0.VGA").unwrap().is_absolute(), false);
  537. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().is_absolute(), false);
  538. }
  539. #[test]
  540. fn test_search_rules_apply() {
  541. assert_eq!(AmlName::root().search_rules_apply(), false);
  542. assert_eq!(AmlName::from_str("\\_SB").unwrap().search_rules_apply(), false);
  543. assert_eq!(AmlName::from_str("^VGA").unwrap().search_rules_apply(), false);
  544. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().search_rules_apply(), false);
  545. assert_eq!(AmlName::from_str("VGA").unwrap().search_rules_apply(), true);
  546. assert_eq!(AmlName::from_str("_SB").unwrap().search_rules_apply(), true);
  547. }
  548. #[test]
  549. fn test_aml_name_parent() {
  550. assert_eq!(AmlName::from_str("\\").unwrap().parent(), Err(AmlError::RootHasNoParent));
  551. assert_eq!(AmlName::from_str("\\_SB").unwrap().parent(), Ok(AmlName::root()));
  552. assert_eq!(AmlName::from_str("\\_SB.PCI0").unwrap().parent(), Ok(AmlName::from_str("\\_SB").unwrap()));
  553. assert_eq!(AmlName::from_str("\\_SB.PCI0").unwrap().parent().unwrap().parent(), Ok(AmlName::root()));
  554. }
  555. #[test]
  556. fn test_namespace() {
  557. let mut namespace = Namespace::new();
  558. /*
  559. * This should succeed but do nothing.
  560. */
  561. assert_eq!(namespace.add_level(AmlName::from_str("\\").unwrap(), LevelType::Scope), Ok(()));
  562. /*
  563. * Add `\_SB`, also testing that adding a level twice succeeds.
  564. */
  565. assert_eq!(namespace.add_level(AmlName::from_str("\\_SB").unwrap(), LevelType::Scope), Ok(()));
  566. assert_eq!(namespace.add_level(AmlName::from_str("\\_SB").unwrap(), LevelType::Scope), Ok(()));
  567. /*
  568. * Add a device under a level that already exists.
  569. */
  570. assert_eq!(namespace.add_level(AmlName::from_str("\\_SB.PCI0").unwrap(), LevelType::Device), Ok(()));
  571. /*
  572. * Add some deeper scopes.
  573. */
  574. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO").unwrap(), LevelType::Scope), Ok(()));
  575. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR").unwrap(), LevelType::Scope), Ok(()));
  576. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR.BAZ").unwrap(), LevelType::Scope), Ok(()));
  577. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR.BAZ").unwrap(), LevelType::Scope), Ok(()));
  578. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR.BAZ.QUX").unwrap(), LevelType::Scope), Ok(()));
  579. /*
  580. * Add some things to the scopes to query later.
  581. */
  582. assert!(namespace.add_value(AmlName::from_str("\\MOO").unwrap(), AmlValue::Boolean(true)).is_ok());
  583. assert!(namespace.add_value(AmlName::from_str("\\FOO.BAR.A").unwrap(), AmlValue::Integer(12345)).is_ok());
  584. assert!(namespace.add_value(AmlName::from_str("\\FOO.BAR.B").unwrap(), AmlValue::Integer(6)).is_ok());
  585. assert!(namespace
  586. .add_value(AmlName::from_str("\\FOO.BAR.C").unwrap(), AmlValue::String(String::from("hello, world!")))
  587. .is_ok());
  588. /*
  589. * Get objects using their absolute paths.
  590. */
  591. assert!(crudely_cmp_values(
  592. namespace.get_by_path(&AmlName::from_str("\\MOO").unwrap()).unwrap(),
  593. &AmlValue::Boolean(true)
  594. ));
  595. assert!(crudely_cmp_values(
  596. namespace.get_by_path(&AmlName::from_str("\\FOO.BAR.A").unwrap()).unwrap(),
  597. &AmlValue::Integer(12345)
  598. ));
  599. assert!(crudely_cmp_values(
  600. namespace.get_by_path(&AmlName::from_str("\\FOO.BAR.B").unwrap()).unwrap(),
  601. &AmlValue::Integer(6)
  602. ));
  603. assert!(crudely_cmp_values(
  604. namespace.get_by_path(&AmlName::from_str("\\FOO.BAR.C").unwrap()).unwrap(),
  605. &AmlValue::String(String::from("hello, world!"))
  606. ));
  607. /*
  608. * Search for some objects that should use search rules.
  609. */
  610. {
  611. let (name, _) = namespace
  612. .search(&AmlName::from_str("MOO").unwrap(), &AmlName::from_str("\\FOO.BAR.BAZ").unwrap())
  613. .unwrap();
  614. assert_eq!(name, AmlName::from_str("\\MOO").unwrap());
  615. }
  616. {
  617. let (name, _) = namespace
  618. .search(&AmlName::from_str("A").unwrap(), &AmlName::from_str("\\FOO.BAR").unwrap())
  619. .unwrap();
  620. assert_eq!(name, AmlName::from_str("\\FOO.BAR.A").unwrap());
  621. }
  622. {
  623. let (name, _) = namespace
  624. .search(&AmlName::from_str("A").unwrap(), &AmlName::from_str("\\FOO.BAR.BAZ.QUX").unwrap())
  625. .unwrap();
  626. assert_eq!(name, AmlName::from_str("\\FOO.BAR.A").unwrap());
  627. }
  628. }
  629. #[test]
  630. fn test_get_level_for_path() {
  631. let mut namespace = Namespace::new();
  632. // Add some scopes
  633. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO").unwrap(), LevelType::Scope), Ok(()));
  634. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR").unwrap(), LevelType::Scope), Ok(()));
  635. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR.BAZ").unwrap(), LevelType::Scope), Ok(()));
  636. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR.BAZ").unwrap(), LevelType::Scope), Ok(()));
  637. assert_eq!(namespace.add_level(AmlName::from_str("\\FOO.BAR.BAZ.QUX").unwrap(), LevelType::Scope), Ok(()));
  638. {
  639. let (_, last_seg) =
  640. namespace.get_level_for_path(&AmlName::from_str("\\FOO.BAR.BAZ").unwrap()).unwrap();
  641. assert_eq!(last_seg, NameSeg::from_str("BAZ").unwrap());
  642. }
  643. {
  644. let (_, last_seg) = namespace.get_level_for_path(&AmlName::from_str("\\FOO").unwrap()).unwrap();
  645. assert_eq!(last_seg, NameSeg::from_str("FOO").unwrap());
  646. }
  647. }
  648. }