namespace.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  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. }
  28. pub struct NamespaceLevel {
  29. typ: LevelType,
  30. children: BTreeMap<NameSeg, NamespaceLevel>,
  31. values: BTreeMap<NameSeg, AmlHandle>,
  32. }
  33. impl NamespaceLevel {
  34. pub(crate) fn new(typ: LevelType) -> NamespaceLevel {
  35. NamespaceLevel { typ, children: BTreeMap::new(), values: BTreeMap::new() }
  36. }
  37. }
  38. pub struct Namespace {
  39. /// This is a running count of ids, which are never reused. This is incremented every time we
  40. /// add a new object to the namespace. We can then remove objects, freeing their memory, without
  41. /// risking using the same id for two objects.
  42. next_handle: AmlHandle,
  43. /// This maps handles to actual values, and is used to access the actual AML values. When removing a value
  44. /// from the object map, care must be taken to also remove references to its handle in the level data
  45. /// structure, as invalid handles will cause panics.
  46. object_map: BTreeMap<AmlHandle, AmlValue>,
  47. /// Holds the first level of the namespace - containing items such as `\_SB`. Subsequent levels are held
  48. /// recursively inside this structure. It holds handles to references, which need to be indexed into
  49. /// `object_map` to acctually access the object.
  50. root: NamespaceLevel,
  51. }
  52. impl Namespace {
  53. pub fn new() -> Namespace {
  54. Namespace {
  55. next_handle: AmlHandle(0),
  56. object_map: BTreeMap::new(),
  57. root: NamespaceLevel::new(LevelType::Scope),
  58. }
  59. }
  60. /// Add a new level to the namespace. A "level" is a `NameSeg` that can hold objects (currently, `Scope`s
  61. /// and `Devices`). Once a level has been created, AML values can be added to it with `add_value`.
  62. ///
  63. /// ### Note
  64. /// At first glance, you might expect `DefDevice` to add a value of type `Device`. However, because all
  65. /// `Devices` do is hold other values, we model them as namespace levels, and so they must be created
  66. /// accordingly.
  67. pub fn add_level(&mut self, path: AmlName, typ: LevelType) -> Result<(), AmlError> {
  68. assert!(path.is_absolute());
  69. let path = path.normalize()?;
  70. /*
  71. * We need to handle a special case here: if a `Scope(\) { ... }` appears in the AML, the parser will
  72. * try and recreate the root scope. Instead of handling this specially in the parser, we just
  73. * return nicely here.
  74. */
  75. if path != AmlName::root() {
  76. let (level, last_seg) = self.get_level_for_path_mut(&path)?;
  77. /*
  78. * If the level has already been added, we don't need to add it again. The parser can try to add it
  79. * multiple times if the ASL contains multiple blocks that add to the same scope/device.
  80. */
  81. if !level.children.contains_key(&last_seg) {
  82. level.children.insert(last_seg, NamespaceLevel::new(typ));
  83. }
  84. }
  85. Ok(())
  86. }
  87. /// Add a value to the namespace at the given path, which must be a normalized, absolute AML
  88. /// name. If you want to add at a path relative to a given scope, use `add_at_resolved_path`
  89. /// instead.
  90. pub fn add_value(&mut self, path: AmlName, value: AmlValue) -> Result<AmlHandle, AmlError> {
  91. assert!(path.is_absolute());
  92. let path = path.normalize()?;
  93. let handle = self.next_handle;
  94. self.next_handle.increment();
  95. self.object_map.insert(handle, value);
  96. let (level, last_seg) = self.get_level_for_path_mut(&path)?;
  97. match level.values.insert(last_seg, handle) {
  98. None => Ok(handle),
  99. Some(_) => Err(AmlError::NameCollision(path)),
  100. }
  101. }
  102. /// Helper method for adding a value to the namespace at a path that is relative to the given
  103. /// scope. This operation involves a lot of error handling in parts of the parser, so is
  104. /// encapsulated here.
  105. pub fn add_value_at_resolved_path(
  106. &mut self,
  107. path: AmlName,
  108. scope: &AmlName,
  109. value: AmlValue,
  110. ) -> Result<AmlHandle, AmlError> {
  111. self.add_value(path.resolve(scope)?, value)
  112. }
  113. pub fn get(&self, handle: AmlHandle) -> Result<&AmlValue, AmlError> {
  114. Ok(self.object_map.get(&handle).unwrap())
  115. }
  116. pub fn get_mut(&mut self, handle: AmlHandle) -> Result<&mut AmlValue, AmlError> {
  117. Ok(self.object_map.get_mut(&handle).unwrap())
  118. }
  119. pub fn get_by_path(&self, path: &AmlName) -> Result<&AmlValue, AmlError> {
  120. let (level, last_seg) = self.get_level_for_path(path)?;
  121. let &handle = level.values.get(&last_seg).ok_or(AmlError::ValueDoesNotExist(path.clone()))?;
  122. Ok(self.get(handle).unwrap())
  123. }
  124. pub fn get_by_path_mut(&mut self, path: &AmlName) -> Result<&mut AmlValue, AmlError> {
  125. let (level, last_seg) = self.get_level_for_path(path)?;
  126. let &handle = level.values.get(&last_seg).ok_or(AmlError::ValueDoesNotExist(path.clone()))?;
  127. Ok(self.get_mut(handle).unwrap())
  128. }
  129. /// Search for an object at the given path of the namespace, applying the search rules
  130. /// described in §5.3 of the ACPI specification, if they are applicable. Returns the resolved name, and the
  131. /// handle of the first valid object, if found.
  132. pub fn search(&self, path: &AmlName, starting_scope: &AmlName) -> Result<(AmlName, AmlHandle), AmlError> {
  133. if path.search_rules_apply() {
  134. /*
  135. * If search rules apply, we need to recursively look through the namespace. If the
  136. * given name does not occur in the current scope, we look at the parent scope, until
  137. * we either find the name, or reach the root of the namespace.
  138. */
  139. let mut scope = starting_scope.clone();
  140. assert!(scope.is_absolute());
  141. loop {
  142. // Search for the name at this namespace level. If we find it, we're done.
  143. let name = path.resolve(&scope)?;
  144. let (level, last_seg) = self.get_level_for_path(&name)?;
  145. if let Some(&handle) = level.values.get(&last_seg) {
  146. return Ok((name, handle));
  147. }
  148. // If we don't find it, go up a level in the namespace and search for it there,
  149. // recursively.
  150. match scope.parent() {
  151. Ok(parent) => scope = parent,
  152. // If we still haven't found the value and have run out of parents, return `None`.
  153. Err(AmlError::RootHasNoParent) => return Err(AmlError::ValueDoesNotExist(path.clone())),
  154. Err(err) => return Err(err),
  155. }
  156. }
  157. } else {
  158. // If search rules don't apply, simply resolve it against the starting scope
  159. let name = path.resolve(starting_scope)?;
  160. let (level, last_seg) = self.get_level_for_path(&path.resolve(starting_scope)?)?;
  161. if let Some(&handle) = level.values.get(&last_seg) {
  162. Ok((name, handle))
  163. } else {
  164. Err(AmlError::ValueDoesNotExist(path.clone()))
  165. }
  166. }
  167. }
  168. fn get_level_for_path(&self, path: &AmlName) -> Result<(&NamespaceLevel, NameSeg), AmlError> {
  169. let (last_seg, levels) = path.0[1..].split_last().unwrap();
  170. let last_seg = last_seg.as_segment().unwrap();
  171. // TODO: this helps with diagnostics, but requires a heap allocation just in case we need to error.
  172. let mut traversed_path = AmlName::root();
  173. let mut current_level = &self.root;
  174. for level in levels {
  175. traversed_path.0.push(*level);
  176. current_level = current_level
  177. .children
  178. .get(&level.as_segment().unwrap())
  179. .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
  180. }
  181. Ok((current_level, last_seg))
  182. }
  183. fn get_level_for_path_mut(&mut self, path: &AmlName) -> Result<(&mut NamespaceLevel, NameSeg), AmlError> {
  184. let (last_seg, levels) = path.0[1..].split_last().unwrap();
  185. let last_seg = last_seg.as_segment().unwrap();
  186. // TODO: this helps with diagnostics, but requires a heap allocation just in case we need to error. We can
  187. // improve this by changing the `levels` interation into an `enumerate()`, and then using the index to
  188. // create the correct path on the error path
  189. let mut traversed_path = AmlName::root();
  190. let mut current_level = &mut self.root;
  191. for level in levels {
  192. traversed_path.0.push(*level);
  193. current_level = current_level
  194. .children
  195. .get_mut(&level.as_segment().unwrap())
  196. .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
  197. }
  198. Ok((current_level, last_seg))
  199. }
  200. }
  201. impl fmt::Debug for Namespace {
  202. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  203. const INDENT_PER_LEVEL: usize = 4;
  204. fn print_level(
  205. namespace: &Namespace,
  206. f: &mut fmt::Formatter<'_>,
  207. level_name: &str,
  208. level: &NamespaceLevel,
  209. indent: usize,
  210. ) -> fmt::Result {
  211. writeln!(f, "{:indent$}{}:", "", level_name, indent = indent)?;
  212. for (name, handle) in level.values.iter() {
  213. writeln!(
  214. f,
  215. "{:indent$}{}: {:?}",
  216. "",
  217. name.as_str(),
  218. namespace.object_map.get(handle).unwrap(),
  219. indent = indent + INDENT_PER_LEVEL
  220. )?;
  221. }
  222. for (name, sub_level) in level.children.iter() {
  223. print_level(namespace, f, name.as_str(), sub_level, indent + INDENT_PER_LEVEL)?;
  224. }
  225. Ok(())
  226. };
  227. print_level(self, f, "\\", &self.root, 0)
  228. }
  229. }
  230. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
  231. pub struct AmlName(pub(crate) Vec<NameComponent>);
  232. impl AmlName {
  233. pub fn root() -> AmlName {
  234. AmlName(alloc::vec![NameComponent::Root])
  235. }
  236. pub fn from_name_seg(seg: NameSeg) -> AmlName {
  237. AmlName(alloc::vec![NameComponent::Segment(seg)])
  238. }
  239. /// Convert a string representation of an AML name into an `AmlName`.
  240. pub fn from_str(mut string: &str) -> Result<AmlName, AmlError> {
  241. if string.len() == 0 {
  242. return Err(AmlError::EmptyNamesAreInvalid);
  243. }
  244. let mut components = Vec::new();
  245. // If it starts with a \, make it an absolute name
  246. if string.starts_with('\\') {
  247. components.push(NameComponent::Root);
  248. string = &string[1..];
  249. }
  250. if string.len() > 0 {
  251. // Divide the rest of it into segments, and parse those
  252. for mut part in string.split('.') {
  253. // Handle prefix chars
  254. while part.starts_with('^') {
  255. components.push(NameComponent::Prefix);
  256. part = &part[1..];
  257. }
  258. components.push(NameComponent::Segment(NameSeg::from_str(part)?));
  259. }
  260. }
  261. Ok(AmlName(components))
  262. }
  263. pub fn as_string(&self) -> String {
  264. self.0
  265. .iter()
  266. .fold(String::new(), |name, component| match component {
  267. NameComponent::Root => name + "\\",
  268. NameComponent::Prefix => name + "^",
  269. NameComponent::Segment(seg) => name + seg.as_str() + ".",
  270. })
  271. .trim_end_matches('.')
  272. .to_string()
  273. }
  274. /// An AML path is normal if it does not contain any prefix elements ("^" characters, when
  275. /// expressed as a string).
  276. pub fn is_normal(&self) -> bool {
  277. !self.0.contains(&NameComponent::Prefix)
  278. }
  279. pub fn is_absolute(&self) -> bool {
  280. self.0.first() == Some(&NameComponent::Root)
  281. }
  282. /// Special rules apply when searching for certain paths (specifically, those that are made up
  283. /// of a single name segment). Returns `true` if those rules apply.
  284. pub fn search_rules_apply(&self) -> bool {
  285. if self.0.len() != 1 {
  286. return false;
  287. }
  288. match self.0[0] {
  289. NameComponent::Segment(_) => true,
  290. _ => false,
  291. }
  292. }
  293. /// Normalize an AML path, resolving prefix chars. Returns `AmlError::InvalidNormalizedName` if the path
  294. /// normalizes to an invalid path (e.g. `\^_FOO`)
  295. pub fn normalize(self) -> Result<AmlName, AmlError> {
  296. /*
  297. * If the path is already normal, just return it as-is. This avoids an unneccessary heap allocation and
  298. * free.
  299. */
  300. if self.is_normal() {
  301. return Ok(self);
  302. }
  303. Ok(AmlName(self.0.iter().try_fold(Vec::new(), |mut name, &component| match component {
  304. seg @ NameComponent::Segment(_) => {
  305. name.push(seg);
  306. Ok(name)
  307. }
  308. NameComponent::Root => {
  309. name.push(NameComponent::Root);
  310. Ok(name)
  311. }
  312. NameComponent::Prefix => {
  313. if let Some(NameComponent::Segment(_)) = name.iter().last() {
  314. name.pop().unwrap();
  315. Ok(name)
  316. } else {
  317. Err(AmlError::InvalidNormalizedName(self.clone()))
  318. }
  319. }
  320. })?))
  321. }
  322. /// Get the parent of this `AmlName`. For example, the parent of `\_SB.PCI0._PRT` is `\_SB.PCI0`. The root
  323. /// path has no parent, and so returns `None`.
  324. pub fn parent(&self) -> Result<AmlName, AmlError> {
  325. // Firstly, normalize the path so we don't have to deal with prefix chars
  326. let mut normalized_self = self.clone().normalize()?;
  327. match normalized_self.0.last() {
  328. None | Some(NameComponent::Root) => Err(AmlError::RootHasNoParent),
  329. Some(NameComponent::Segment(_)) => {
  330. normalized_self.0.pop();
  331. Ok(normalized_self)
  332. }
  333. Some(NameComponent::Prefix) => unreachable!(), // Prefix chars are removed by normalization
  334. }
  335. }
  336. /// Resolve this path against a given scope, making it absolute. If the path is absolute, it is
  337. /// returned directly. The path is also normalized.
  338. pub fn resolve(&self, scope: &AmlName) -> Result<AmlName, AmlError> {
  339. assert!(scope.is_absolute());
  340. if self.is_absolute() {
  341. return Ok(self.clone());
  342. }
  343. let mut resolved_path = scope.clone();
  344. resolved_path.0.extend_from_slice(&(self.0));
  345. resolved_path.normalize()
  346. }
  347. }
  348. impl fmt::Display for AmlName {
  349. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  350. write!(f, "{}", self.as_string())
  351. }
  352. }
  353. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
  354. pub enum NameComponent {
  355. Root,
  356. Prefix,
  357. Segment(NameSeg),
  358. }
  359. impl NameComponent {
  360. pub fn as_segment(self) -> Result<NameSeg, ()> {
  361. match self {
  362. NameComponent::Segment(seg) => Ok(seg),
  363. NameComponent::Root | NameComponent::Prefix => Err(()),
  364. }
  365. }
  366. }
  367. #[cfg(test)]
  368. mod tests {
  369. use super::*;
  370. #[test]
  371. fn test_aml_name_from_str() {
  372. assert_eq!(AmlName::from_str(""), Err(AmlError::EmptyNamesAreInvalid));
  373. assert_eq!(AmlName::from_str("\\"), Ok(AmlName::root()));
  374. assert_eq!(
  375. AmlName::from_str("\\_SB.PCI0"),
  376. Ok(AmlName(alloc::vec![
  377. NameComponent::Root,
  378. NameComponent::Segment(NameSeg([b'_', b'S', b'B', b'_'])),
  379. NameComponent::Segment(NameSeg([b'P', b'C', b'I', b'0']))
  380. ]))
  381. );
  382. assert_eq!(
  383. AmlName::from_str("\\_SB.^^^PCI0"),
  384. Ok(AmlName(alloc::vec![
  385. NameComponent::Root,
  386. NameComponent::Segment(NameSeg([b'_', b'S', b'B', b'_'])),
  387. NameComponent::Prefix,
  388. NameComponent::Prefix,
  389. NameComponent::Prefix,
  390. NameComponent::Segment(NameSeg([b'P', b'C', b'I', b'0']))
  391. ]))
  392. );
  393. }
  394. #[test]
  395. fn test_is_normal() {
  396. assert_eq!(AmlName::root().is_normal(), true);
  397. assert_eq!(AmlName::from_str("\\_SB.PCI0.VGA").unwrap().is_normal(), true);
  398. assert_eq!(AmlName::from_str("\\_SB.^PCI0.VGA").unwrap().is_normal(), false);
  399. assert_eq!(AmlName::from_str("\\^_SB.^^PCI0.VGA").unwrap().is_normal(), false);
  400. assert_eq!(AmlName::from_str("_SB.^^PCI0.VGA").unwrap().is_normal(), false);
  401. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().is_normal(), true);
  402. }
  403. #[test]
  404. fn test_normalization() {
  405. assert_eq!(
  406. AmlName::from_str("\\_SB.PCI0").unwrap().normalize(),
  407. Ok(AmlName::from_str("\\_SB.PCI0").unwrap())
  408. );
  409. assert_eq!(
  410. AmlName::from_str("\\_SB.^PCI0").unwrap().normalize(),
  411. Ok(AmlName::from_str("\\PCI0").unwrap())
  412. );
  413. assert_eq!(
  414. AmlName::from_str("\\_SB.PCI0.^^FOO").unwrap().normalize(),
  415. Ok(AmlName::from_str("\\FOO").unwrap())
  416. );
  417. assert_eq!(
  418. AmlName::from_str("_SB.PCI0.^FOO.BAR").unwrap().normalize(),
  419. Ok(AmlName::from_str("_SB.FOO.BAR").unwrap())
  420. );
  421. assert_eq!(
  422. AmlName::from_str("\\^_SB").unwrap().normalize(),
  423. Err(AmlError::InvalidNormalizedName(AmlName::from_str("\\^_SB").unwrap()))
  424. );
  425. assert_eq!(
  426. AmlName::from_str("\\_SB.PCI0.FOO.^^^^BAR").unwrap().normalize(),
  427. Err(AmlError::InvalidNormalizedName(AmlName::from_str("\\_SB.PCI0.FOO.^^^^BAR").unwrap()))
  428. );
  429. }
  430. #[test]
  431. fn test_is_absolute() {
  432. assert_eq!(AmlName::root().is_absolute(), true);
  433. assert_eq!(AmlName::from_str("\\_SB.PCI0.VGA").unwrap().is_absolute(), true);
  434. assert_eq!(AmlName::from_str("\\_SB.^PCI0.VGA").unwrap().is_absolute(), true);
  435. assert_eq!(AmlName::from_str("\\^_SB.^^PCI0.VGA").unwrap().is_absolute(), true);
  436. assert_eq!(AmlName::from_str("_SB.^^PCI0.VGA").unwrap().is_absolute(), false);
  437. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().is_absolute(), false);
  438. }
  439. #[test]
  440. fn test_search_rules_apply() {
  441. assert_eq!(AmlName::root().search_rules_apply(), false);
  442. assert_eq!(AmlName::from_str("\\_SB").unwrap().search_rules_apply(), false);
  443. assert_eq!(AmlName::from_str("^VGA").unwrap().search_rules_apply(), false);
  444. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().search_rules_apply(), false);
  445. assert_eq!(AmlName::from_str("VGA").unwrap().search_rules_apply(), true);
  446. assert_eq!(AmlName::from_str("_SB").unwrap().search_rules_apply(), true);
  447. }
  448. #[test]
  449. fn test_aml_name_parent() {
  450. assert_eq!(AmlName::from_str("\\").unwrap().parent(), Err(AmlError::RootHasNoParent));
  451. assert_eq!(AmlName::from_str("\\_SB").unwrap().parent(), Ok(AmlName::root()));
  452. assert_eq!(AmlName::from_str("\\_SB.PCI0").unwrap().parent(), Ok(AmlName::from_str("\\_SB").unwrap()));
  453. assert_eq!(AmlName::from_str("\\_SB.PCI0").unwrap().parent().unwrap().parent(), Ok(AmlName::root()));
  454. }
  455. }