namespace.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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. pub struct Namespace {
  24. /// This is a running count of ids, which are never reused. This is incremented every time we
  25. /// add a new object to the namespace. We can then remove objects, freeing their memory, without
  26. /// risking using the same id for two objects.
  27. next_handle: AmlHandle,
  28. /// This maps handles to actual values, and is used to access the actual AML values.
  29. object_map: BTreeMap<AmlHandle, AmlValue>,
  30. /// This maps names to handles, and should be used when you don't already have the handle to a
  31. /// value.
  32. // XXX: in the future, this could be replaced with a better data structure that doesn't store
  33. // the entire name for each id. Instead, it would be a tree-like structure that stores each
  34. // name segment, with a list of objects and their names, and a list of child scopes at that
  35. // level.
  36. name_map: BTreeMap<AmlName, AmlHandle>,
  37. }
  38. impl Namespace {
  39. pub fn new() -> Namespace {
  40. Namespace { next_handle: AmlHandle(0), object_map: BTreeMap::new(), name_map: BTreeMap::new() }
  41. }
  42. /// Add a value to the namespace at the given path, which must be a normalized, absolute AML
  43. /// name. If you want to add at a path relative to a given scope, use `add_at_resolved_path`
  44. /// instead.
  45. pub fn add(&mut self, path: AmlName, value: AmlValue) -> Result<AmlHandle, AmlError> {
  46. assert!(path.is_absolute());
  47. assert!(path.is_normal());
  48. if self.name_map.contains_key(&path) {
  49. return Err(AmlError::NameCollision(path.clone()));
  50. }
  51. let handle = self.next_handle;
  52. self.next_handle.increment();
  53. self.object_map.insert(handle, value);
  54. self.name_map.insert(path, handle);
  55. Ok(handle)
  56. }
  57. /// Helper method for adding a value to the namespace at a path that is relative to the given
  58. /// scope. This operation involves a lot of error handling in parts of the parser, so is
  59. /// encapsulated here.
  60. pub fn add_at_resolved_path(
  61. &mut self,
  62. path: AmlName,
  63. scope: &AmlName,
  64. value: AmlValue,
  65. ) -> Result<AmlHandle, AmlError> {
  66. self.add(path.resolve(scope)?, value)
  67. }
  68. pub fn get(&self, handle: AmlHandle) -> Result<&AmlValue, AmlError> {
  69. self.object_map.get(&handle).ok_or(AmlError::HandleDoesNotExist(handle))
  70. }
  71. pub fn get_by_path(&self, path: &AmlName) -> Result<&AmlValue, AmlError> {
  72. let handle = self.name_map.get(path).ok_or(AmlError::ObjectDoesNotExist(path.as_string()))?;
  73. self.get(*handle).map_err(|_| AmlError::ObjectDoesNotExist(path.as_string()))
  74. }
  75. /// Search for an object at the given path of the namespace, applying the search rules
  76. /// described in §5.3 of the ACPI specification, if they are applicable.
  77. pub fn search(&self, path: &AmlName, starting_scope: &AmlName) -> Result<&AmlValue, AmlError> {
  78. if path.search_rules_apply() {
  79. /*
  80. * If search rules apply, we need to recursively look through the namespace. If the
  81. * given name does not occur in the current scope, we look at the parent scope, until
  82. * we either find the name, or reach the root of the namespace.
  83. */
  84. let mut scope = starting_scope.clone();
  85. assert!(scope.is_absolute());
  86. loop {
  87. // Search for the name at this namespace level. If we find it, we're done.
  88. if let Ok(value) = self.get_by_path(&path.resolve(&scope).unwrap()) {
  89. return Ok(value);
  90. }
  91. // If we don't find it, go up a level in the namespace and search for it there,
  92. // recursively.
  93. match scope.parent() {
  94. Ok(parent) => scope = parent,
  95. // If we still haven't found the value and have run out of parents, return `None`.
  96. Err(AmlError::RootHasNoParent) => {
  97. return Err(AmlError::ObjectDoesNotExist(path.as_string()))
  98. }
  99. Err(err) => return Err(err),
  100. }
  101. }
  102. } else {
  103. // If search rules don't apply, simply resolve it against the starting scope
  104. self.get_by_path(&path.resolve(starting_scope)?)
  105. }
  106. }
  107. }
  108. impl fmt::Debug for Namespace {
  109. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  110. for (name, handle) in self.name_map.iter() {
  111. write!(f, "{}: {:?}\n", name, self.object_map.get(handle).unwrap())?;
  112. }
  113. Ok(())
  114. }
  115. }
  116. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
  117. pub struct AmlName(pub(crate) Vec<NameComponent>);
  118. impl AmlName {
  119. pub fn root() -> AmlName {
  120. AmlName(alloc::vec![NameComponent::Root])
  121. }
  122. pub fn from_name_seg(seg: NameSeg) -> AmlName {
  123. AmlName(alloc::vec![NameComponent::Segment(seg)])
  124. }
  125. /// Convert a string representation of an AML name into an `AmlName`. Returns `None` if the
  126. /// passed string is not a valid AML path.
  127. pub fn from_str(mut string: &str) -> Option<AmlName> {
  128. if string.len() == 0 {
  129. return None;
  130. }
  131. let mut components = Vec::new();
  132. // If it starts with a \, make it an absolute name
  133. if string.starts_with('\\') {
  134. components.push(NameComponent::Root);
  135. string = &string[1..];
  136. }
  137. if string.len() > 0 {
  138. // Divide the rest of it into segments, and parse those
  139. for mut part in string.split('.') {
  140. // Handle prefix chars
  141. while part.starts_with('^') {
  142. components.push(NameComponent::Prefix);
  143. part = &part[1..];
  144. }
  145. components.push(NameComponent::Segment(NameSeg::from_str(part)?));
  146. }
  147. }
  148. Some(AmlName(components))
  149. }
  150. pub fn as_string(&self) -> String {
  151. self.0
  152. .iter()
  153. .fold(String::new(), |name, component| match component {
  154. NameComponent::Root => name + "\\",
  155. NameComponent::Prefix => name + "^",
  156. NameComponent::Segment(seg) => name + seg.as_str() + ".",
  157. })
  158. .trim_end_matches('.')
  159. .to_string()
  160. }
  161. /// An AML path is normal if it does not contain any prefix elements ("^" characters, when
  162. /// expressed as a string).
  163. pub fn is_normal(&self) -> bool {
  164. !self.0.contains(&NameComponent::Prefix)
  165. }
  166. pub fn is_absolute(&self) -> bool {
  167. self.0.first() == Some(&NameComponent::Root)
  168. }
  169. /// Special rules apply when searching for certain paths (specifically, those that are made up
  170. /// of a single name segment). Returns `true` if those rules apply.
  171. pub fn search_rules_apply(&self) -> bool {
  172. if self.0.len() != 1 {
  173. return false;
  174. }
  175. match self.0[0] {
  176. NameComponent::Segment(_) => true,
  177. _ => false,
  178. }
  179. }
  180. /// Normalize an AML path, resolving prefix chars. Returns `None` if the path normalizes to an
  181. /// invalid path (e.g. `\^_FOO`)
  182. pub fn normalize(self) -> Result<AmlName, AmlError> {
  183. // TODO: currently, this doesn't do anything. Work out a nice way of handling prefix chars.
  184. // If the name can't be normalized, emit AmlError::InvalidNormalizedName
  185. Ok(self)
  186. }
  187. /// Get the parent of this `AmlName`. For example, the parent of `\_SB.PCI0._PRT` is `\_SB.PCI0`. The root
  188. /// path has no parent, and so returns `None`.
  189. pub fn parent(&self) -> Result<AmlName, AmlError> {
  190. // Firstly, normalize the path so we don't have to deal with prefix chars
  191. let mut normalized_self = self.clone().normalize()?;
  192. match normalized_self.0.last() {
  193. None | Some(NameComponent::Root) => Err(AmlError::RootHasNoParent),
  194. Some(NameComponent::Segment(_)) => {
  195. normalized_self.0.pop();
  196. Ok(normalized_self)
  197. }
  198. Some(NameComponent::Prefix) => unreachable!(), // Prefix chars are removed by normalization
  199. }
  200. }
  201. /// Resolve this path against a given scope, making it absolute. If the path is absolute, it is
  202. /// returned directly. The path is also normalized.
  203. pub fn resolve(&self, scope: &AmlName) -> Result<AmlName, AmlError> {
  204. assert!(scope.is_absolute());
  205. if self.is_absolute() {
  206. return Ok(self.clone());
  207. }
  208. let mut resolved_path = scope.clone();
  209. resolved_path.0.extend_from_slice(&(self.0));
  210. resolved_path.normalize()
  211. }
  212. }
  213. impl fmt::Display for AmlName {
  214. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  215. write!(f, "{}", self.as_string())
  216. }
  217. }
  218. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
  219. pub enum NameComponent {
  220. Root,
  221. Prefix,
  222. Segment(NameSeg),
  223. }
  224. #[cfg(test)]
  225. mod tests {
  226. use super::*;
  227. #[test]
  228. fn test_aml_name_from_str() {
  229. assert_eq!(AmlName::from_str(""), None);
  230. assert_eq!(AmlName::from_str("\\"), Some(AmlName::root()));
  231. assert_eq!(
  232. AmlName::from_str("\\_SB.PCI0"),
  233. Some(AmlName(alloc::vec![
  234. NameComponent::Root,
  235. NameComponent::Segment(NameSeg([b'_', b'S', b'B', b'_'])),
  236. NameComponent::Segment(NameSeg([b'P', b'C', b'I', b'0']))
  237. ]))
  238. );
  239. assert_eq!(
  240. AmlName::from_str("\\_SB.^^^PCI0"),
  241. Some(AmlName(alloc::vec![
  242. NameComponent::Root,
  243. NameComponent::Segment(NameSeg([b'_', b'S', b'B', b'_'])),
  244. NameComponent::Prefix,
  245. NameComponent::Prefix,
  246. NameComponent::Prefix,
  247. NameComponent::Segment(NameSeg([b'P', b'C', b'I', b'0']))
  248. ]))
  249. );
  250. }
  251. #[test]
  252. fn test_is_normal() {
  253. assert_eq!(AmlName::root().is_normal(), true);
  254. assert_eq!(AmlName::from_str("\\_SB.PCI0.VGA").unwrap().is_normal(), true);
  255. assert_eq!(AmlName::from_str("\\_SB.^PCI0.VGA").unwrap().is_normal(), false);
  256. assert_eq!(AmlName::from_str("\\^_SB.^^PCI0.VGA").unwrap().is_normal(), false);
  257. assert_eq!(AmlName::from_str("_SB.^^PCI0.VGA").unwrap().is_normal(), false);
  258. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().is_normal(), true);
  259. }
  260. #[test]
  261. fn test_is_absolute() {
  262. assert_eq!(AmlName::root().is_absolute(), true);
  263. assert_eq!(AmlName::from_str("\\_SB.PCI0.VGA").unwrap().is_absolute(), true);
  264. assert_eq!(AmlName::from_str("\\_SB.^PCI0.VGA").unwrap().is_absolute(), true);
  265. assert_eq!(AmlName::from_str("\\^_SB.^^PCI0.VGA").unwrap().is_absolute(), true);
  266. assert_eq!(AmlName::from_str("_SB.^^PCI0.VGA").unwrap().is_absolute(), false);
  267. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().is_absolute(), false);
  268. }
  269. #[test]
  270. fn test_search_rules_apply() {
  271. assert_eq!(AmlName::root().search_rules_apply(), false);
  272. assert_eq!(AmlName::from_str("\\_SB").unwrap().search_rules_apply(), false);
  273. assert_eq!(AmlName::from_str("^VGA").unwrap().search_rules_apply(), false);
  274. assert_eq!(AmlName::from_str("_SB.PCI0.VGA").unwrap().search_rules_apply(), false);
  275. assert_eq!(AmlName::from_str("VGA").unwrap().search_rules_apply(), true);
  276. assert_eq!(AmlName::from_str("_SB").unwrap().search_rules_apply(), true);
  277. }
  278. #[test]
  279. fn test_aml_name_parent() {
  280. assert_eq!(AmlName::from_str("\\").unwrap().parent(), Err(AmlError::RootHasNoParent));
  281. assert_eq!(AmlName::from_str("\\_SB").unwrap().parent(), Ok(AmlName::root()));
  282. assert_eq!(
  283. AmlName::from_str("\\_SB.PCI0").unwrap().parent(),
  284. Ok(AmlName::from_str("\\_SB").unwrap())
  285. );
  286. assert_eq!(AmlName::from_str("\\_SB.PCI0").unwrap().parent().unwrap().parent(), Ok(AmlName::root()));
  287. }
  288. }