namespce.c 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710
  1. /*++
  2. Copyright (c) 2012 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. namespce.c
  9. Abstract:
  10. This module implements support for the ACPI namespace.
  11. Author:
  12. Evan Green 13-Nov-2012
  13. Environment:
  14. Kernel
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/kernel/driver.h>
  20. #include "acpip.h"
  21. #include "amlos.h"
  22. #include "amlops.h"
  23. #include "oprgn.h"
  24. #include "namespce.h"
  25. //
  26. // --------------------------------------------------------------------- Macros
  27. //
  28. //
  29. // This macro determines whether or not an ACPI object is one of the interger
  30. // constants.
  31. //
  32. #define IS_ACPI_CONSTANT(_AcpiObject) \
  33. (((_AcpiObject) == &AcpiZero) || \
  34. ((_AcpiObject) == &AcpiOne) || \
  35. ((_AcpiObject) == &AcpiOnes32) || \
  36. ((_AcpiObject) == &AcpiOnes64))
  37. //
  38. // ---------------------------------------------------------------- Definitions
  39. //
  40. //
  41. // Define the name of the system bus ACPI object.
  42. //
  43. #define ACPI_SYSTEM_BUS_OBJECT_NAME_STRING "_SB_"
  44. //
  45. // Define the name of the processor object.
  46. //
  47. #define ACPI_PROCESSOR_OBJECT_NAME_STRING "_PR_"
  48. //
  49. // Define the name of the General Purpose Event block object.
  50. //
  51. #define ACPI_GENERAL_PURPOSE_EVENT_OBJECT_NAME_STRING "_GPE"
  52. //
  53. // Define the name of the Operating System name object.
  54. //
  55. #define ACPI_OPERATING_SYSTEM_NAME_OBJECT_NAME_STRING "_OS_"
  56. //
  57. // ------------------------------------------------------ Data Type Definitions
  58. //
  59. //
  60. // ----------------------------------------------- Internal Function Prototypes
  61. //
  62. VOID
  63. AcpipDestroyNamespaceObject (
  64. PACPI_OBJECT Object
  65. );
  66. PACPI_OBJECT
  67. AcpipGetPartialNamespaceObject (
  68. PSTR Name,
  69. ULONG Length,
  70. PACPI_OBJECT CurrentScope
  71. );
  72. KSTATUS
  73. AcpipPullOffLastName (
  74. PSTR Name,
  75. PULONG LastName,
  76. PULONG LastNameOffset
  77. );
  78. VOID
  79. AcpipDebugOutputObject (
  80. PACPI_OBJECT Object
  81. );
  82. //
  83. // -------------------------------------------------------------------- Globals
  84. //
  85. //
  86. // Store a pointer to the root object.
  87. //
  88. PACPI_OBJECT AcpiNamespaceRoot = NULL;
  89. //
  90. // Store a pointer to the \_SB object.
  91. //
  92. PACPI_OBJECT AcpiSystemBusRoot = NULL;
  93. //
  94. // Store a pointer to the old \_PR object.
  95. //
  96. PACPI_OBJECT AcpiProcessorRoot = NULL;
  97. //
  98. // ------------------------------------------------------------------ Functions
  99. //
  100. KSTATUS
  101. AcpipInitializeNamespace (
  102. VOID
  103. )
  104. /*++
  105. Routine Description:
  106. This routine initializes the ACPI global namespace.
  107. Arguments:
  108. None.
  109. Return Value:
  110. Status code.
  111. --*/
  112. {
  113. PACPI_OBJECT GeneralEventObject;
  114. PACPI_OBJECT OperatingSystem;
  115. ULONG OperatingSystemStringLength;
  116. KSTATUS Status;
  117. GeneralEventObject = NULL;
  118. OperatingSystem = NULL;
  119. if (AcpiNamespaceRoot != NULL) {
  120. return STATUS_SUCCESS;
  121. }
  122. AcpiNamespaceRoot = AcpipCreateNamespaceObject(NULL,
  123. AcpiObjectUninitialized,
  124. NULL,
  125. NULL,
  126. 0);
  127. if (AcpiNamespaceRoot == NULL) {
  128. return STATUS_UNSUCCESSFUL;
  129. }
  130. //
  131. // Create the objects defined by the ACPI specificiation to exist.
  132. //
  133. AcpiSystemBusRoot = AcpipCreateNamespaceObject(
  134. NULL,
  135. AcpiObjectDevice,
  136. ACPI_SYSTEM_BUS_OBJECT_NAME_STRING,
  137. NULL,
  138. 0);
  139. if (AcpiSystemBusRoot == NULL) {
  140. Status = STATUS_UNSUCCESSFUL;
  141. goto InitializeNamespaceEnd;
  142. }
  143. AcpipObjectReleaseReference(AcpiSystemBusRoot);
  144. AcpiProcessorRoot = AcpipCreateNamespaceObject(
  145. NULL,
  146. AcpiObjectUninitialized,
  147. ACPI_PROCESSOR_OBJECT_NAME_STRING,
  148. NULL,
  149. 0);
  150. if (AcpiProcessorRoot == NULL) {
  151. Status = STATUS_UNSUCCESSFUL;
  152. goto InitializeNamespaceEnd;
  153. }
  154. AcpipObjectReleaseReference(AcpiProcessorRoot);
  155. GeneralEventObject = AcpipCreateNamespaceObject(
  156. NULL,
  157. AcpiObjectUninitialized,
  158. ACPI_GENERAL_PURPOSE_EVENT_OBJECT_NAME_STRING,
  159. NULL,
  160. 0);
  161. if (GeneralEventObject == NULL) {
  162. Status = STATUS_UNSUCCESSFUL;
  163. goto InitializeNamespaceEnd;
  164. }
  165. AcpipObjectReleaseReference(GeneralEventObject);
  166. OperatingSystemStringLength = RtlStringLength(ACPI_OPERATING_SYSTEM_NAME);
  167. OperatingSystem = AcpipCreateNamespaceObject(
  168. NULL,
  169. AcpiObjectString,
  170. ACPI_OPERATING_SYSTEM_NAME_OBJECT_NAME_STRING,
  171. ACPI_OPERATING_SYSTEM_NAME,
  172. OperatingSystemStringLength + 1);
  173. if (OperatingSystem == NULL) {
  174. Status = STATUS_UNSUCCESSFUL;
  175. goto InitializeNamespaceEnd;
  176. }
  177. AcpipObjectReleaseReference(OperatingSystem);
  178. Status = STATUS_SUCCESS;
  179. InitializeNamespaceEnd:
  180. if (!KSUCCESS(Status)) {
  181. if (AcpiNamespaceRoot != NULL) {
  182. AcpipObjectReleaseReference(AcpiNamespaceRoot);
  183. AcpiNamespaceRoot = NULL;
  184. }
  185. if (AcpiSystemBusRoot != NULL) {
  186. AcpipObjectReleaseReference(AcpiSystemBusRoot);
  187. AcpiSystemBusRoot = NULL;
  188. }
  189. if (AcpiProcessorRoot != NULL) {
  190. AcpipObjectReleaseReference(AcpiProcessorRoot);
  191. AcpiProcessorRoot = NULL;
  192. }
  193. if (GeneralEventObject != NULL) {
  194. AcpipObjectReleaseReference(GeneralEventObject);
  195. }
  196. if (OperatingSystem != NULL) {
  197. AcpipObjectReleaseReference(OperatingSystem);
  198. }
  199. }
  200. return Status;
  201. }
  202. PACPI_OBJECT
  203. AcpipGetNamespaceRoot (
  204. VOID
  205. )
  206. /*++
  207. Routine Description:
  208. This routine returns the namespace root object. This routine does not
  209. modify the reference count of the object.
  210. Arguments:
  211. None.
  212. Return Value:
  213. Returns a pointer to the ACPI object on success.
  214. NULL on failure.
  215. --*/
  216. {
  217. return AcpiNamespaceRoot;
  218. }
  219. PACPI_OBJECT
  220. AcpipGetSystemBusRoot (
  221. VOID
  222. )
  223. /*++
  224. Routine Description:
  225. This routine returns the system bus namespace object at \_SB. This routine
  226. does not modify the reference count of the object.
  227. Arguments:
  228. None.
  229. Return Value:
  230. Returns a pointer to the ACPI object on success.
  231. NULL on failure.
  232. --*/
  233. {
  234. return AcpiSystemBusRoot;
  235. }
  236. PACPI_OBJECT
  237. AcpipGetProcessorRoot (
  238. VOID
  239. )
  240. /*++
  241. Routine Description:
  242. This routine returns the processor namespace directory at \_PR. This
  243. routine does not modify the reference count of the object.
  244. Arguments:
  245. None.
  246. Return Value:
  247. Returns a pointer to the ACPI object on success.
  248. NULL on failure.
  249. --*/
  250. {
  251. return AcpiProcessorRoot;
  252. }
  253. PACPI_OBJECT
  254. AcpipFindNamedObject (
  255. PACPI_OBJECT ParentObject,
  256. ULONG Name
  257. )
  258. /*++
  259. Routine Description:
  260. This routine attempts to find and return an object of the given name under
  261. a given namespace object.
  262. Arguments:
  263. ParentObject - Supplies a pointer to the namespace object whose children
  264. should be searched.
  265. Name - Supplies the name of the object to search for.
  266. Return Value:
  267. Returns a pointer to the ACPI object on success. Its reference count is not
  268. incremented.
  269. NULL on failure.
  270. --*/
  271. {
  272. PLIST_ENTRY CurrentEntry;
  273. PACPI_OBJECT Object;
  274. CurrentEntry = ParentObject->ChildListHead.Next;
  275. while (CurrentEntry != &(ParentObject->ChildListHead)) {
  276. Object = LIST_VALUE(CurrentEntry, ACPI_OBJECT, SiblingListEntry);
  277. CurrentEntry = CurrentEntry->Next;
  278. if (Object->Name == Name) {
  279. return Object;
  280. }
  281. }
  282. return NULL;
  283. }
  284. PACPI_OBJECT
  285. AcpipCreateNamespaceObject (
  286. PAML_EXECUTION_CONTEXT Context,
  287. ACPI_OBJECT_TYPE Type,
  288. PSTR Name,
  289. PVOID Buffer,
  290. ULONG BufferSize
  291. )
  292. /*++
  293. Routine Description:
  294. This routine creates an ACPI namespace object.
  295. Arguments:
  296. Context - Supplies a pointer to the ACPI execution context. If the name
  297. parameter is supplied, this parameter is required. Otherwise, it is
  298. optional.
  299. Type - Supplies the type of namespace object to create.
  300. Name - Supplies the name string of the object. Supply NULL to create a
  301. nameless object.
  302. Buffer - Supplies a pointer to a buffer that is used in different ways
  303. depending on the type being created.
  304. BufferSize - Supplies a buffer size that is used in different ways depending
  305. on the type of object being created. If NULL is passed in but a non-zero
  306. buffer size is supplied, a zero-filled buffer of the given size will be
  307. created. For string buffers, the size includes the null terminator.
  308. Return Value:
  309. Returns a pointer to the ACPI object on success.
  310. NULL on failure.
  311. --*/
  312. {
  313. PACPI_OBJECT CurrentScope;
  314. PVOID NewBuffer;
  315. ULONG NewName;
  316. PACPI_OBJECT NewObject;
  317. ULONG PackageCount;
  318. ULONG PackageIndex;
  319. PACPI_OBJECT PackageObject;
  320. PACPI_OBJECT ParentObject;
  321. ULONG ParentPathOffset;
  322. PACPI_POWER_RESOURCE_OBJECT PowerResource;
  323. KSTATUS Status;
  324. PACPI_UNRESOLVED_NAME_OBJECT UnresolvedName;
  325. ULONG UnresolvedNameLength;
  326. CurrentScope = NULL;
  327. NewBuffer = NULL;
  328. NewName = 0;
  329. NewObject = NULL;
  330. ParentObject = NULL;
  331. if (Name != NULL) {
  332. if (Context != NULL) {
  333. CurrentScope = Context->CurrentScope;
  334. }
  335. if (CurrentScope == NULL) {
  336. CurrentScope = AcpiNamespaceRoot;
  337. }
  338. //
  339. // Separate out the name of the object from its path, and get the
  340. // parent object.
  341. //
  342. Status = AcpipPullOffLastName(Name, &NewName, &ParentPathOffset);
  343. if (!KSUCCESS(Status)) {
  344. goto CreateNamespaceObjectEnd;
  345. }
  346. if (ParentPathOffset == 0) {
  347. ParentObject = CurrentScope;
  348. } else {
  349. ParentObject = AcpipGetPartialNamespaceObject(Name,
  350. ParentPathOffset,
  351. CurrentScope);
  352. if (ParentObject == NULL) {
  353. Status = STATUS_PATH_NOT_FOUND;
  354. goto CreateNamespaceObjectEnd;
  355. }
  356. }
  357. }
  358. //
  359. // Allocate the new object.
  360. //
  361. NewObject = AcpipAllocateMemory(sizeof(ACPI_OBJECT));
  362. if (NewObject == NULL) {
  363. Status = STATUS_INSUFFICIENT_RESOURCES;
  364. goto CreateNamespaceObjectEnd;
  365. }
  366. //
  367. // Initialize the object depending on the type.
  368. //
  369. NewObject->ReferenceCount = 1;
  370. INITIALIZE_LIST_HEAD(&(NewObject->ChildListHead));
  371. NewObject->Parent = ParentObject;
  372. NewObject->Type = Type;
  373. NewObject->Name = NewName;
  374. switch (NewObject->Type) {
  375. //
  376. // Create an integer object. Copy up to a 64-bit value if the buffer was
  377. // supplied.
  378. //
  379. case AcpiObjectInteger:
  380. if (Buffer != NULL) {
  381. if (BufferSize < sizeof(ULONGLONG)) {
  382. NewObject->U.Integer.Value = 0;
  383. RtlCopyMemory(&(NewObject->U.Integer.Value),
  384. Buffer,
  385. BufferSize);
  386. } else {
  387. NewObject->U.Integer.Value = *((PULONGLONG)Buffer);
  388. }
  389. }
  390. break;
  391. //
  392. // Create a string object. The buffer size determines the size of the string
  393. // buffer, including the null-terminating character. If the buffer itself
  394. // is non-null, it will be copied into the new object.
  395. //
  396. case AcpiObjectString:
  397. if (BufferSize == 0) {
  398. NewObject->U.String.String = NULL;
  399. } else {
  400. NewBuffer = AcpipAllocateMemory(BufferSize);
  401. if (NewBuffer == NULL) {
  402. Status = STATUS_INSUFFICIENT_RESOURCES;
  403. goto CreateNamespaceObjectEnd;
  404. }
  405. NewObject->U.String.String = NewBuffer;
  406. if (Buffer != NULL) {
  407. RtlCopyMemory(NewObject->U.String.String, Buffer, BufferSize);
  408. } else {
  409. RtlZeroMemory(NewBuffer, BufferSize);
  410. }
  411. }
  412. break;
  413. //
  414. // Create a buffer object. The buffer size is used to allocate the buffer,
  415. // and if the buffer itself is non-null, its contents are copied in.
  416. //
  417. case AcpiObjectBuffer:
  418. NewObject->U.Buffer.Buffer = NULL;
  419. NewObject->U.Buffer.Length = 0;
  420. if (BufferSize != 0) {
  421. NewBuffer = AcpipAllocateMemory(BufferSize);
  422. if (NewBuffer == NULL) {
  423. Status = STATUS_INSUFFICIENT_RESOURCES;
  424. goto CreateNamespaceObjectEnd;
  425. }
  426. NewObject->U.Buffer.Buffer = NewBuffer;
  427. NewObject->U.Buffer.Length = BufferSize;
  428. if (Buffer != NULL) {
  429. RtlCopyMemory(NewObject->U.Buffer.Buffer, Buffer, BufferSize);
  430. } else {
  431. RtlZeroMemory(NewBuffer, BufferSize);
  432. }
  433. }
  434. break;
  435. //
  436. // Create a package object. The buffer size divided by the size of a
  437. // pointer determines the count of the array, and the buffer contains the
  438. // initial list. Each element on the list will have its reference count
  439. // incremented.
  440. //
  441. case AcpiObjectPackage:
  442. NewObject->U.Package.Array = NULL;
  443. NewObject->U.Package.ElementCount = 0;
  444. if (BufferSize != 0) {
  445. NewBuffer = AcpipAllocateMemory(BufferSize);
  446. if (NewBuffer == NULL) {
  447. Status = STATUS_INSUFFICIENT_RESOURCES;
  448. goto CreateNamespaceObjectEnd;
  449. }
  450. NewObject->U.Package.Array = NewBuffer;
  451. NewObject->U.Package.ElementCount = BufferSize /
  452. sizeof(PACPI_OBJECT);
  453. if (Buffer != NULL) {
  454. RtlCopyMemory(NewBuffer, Buffer, BufferSize);
  455. PackageCount = NewObject->U.Package.ElementCount;
  456. for (PackageIndex = 0;
  457. PackageIndex < PackageCount;
  458. PackageIndex += 1) {
  459. PackageObject = NewObject->U.Package.Array[PackageIndex];
  460. AcpipObjectAddReference(PackageObject);
  461. }
  462. } else {
  463. RtlZeroMemory(NewBuffer, BufferSize);
  464. }
  465. }
  466. break;
  467. case AcpiObjectFieldUnit:
  468. if ((Buffer != NULL) &&
  469. (BufferSize == sizeof(ACPI_FIELD_UNIT_OBJECT))) {
  470. RtlCopyMemory(&(NewObject->U.FieldUnit),
  471. Buffer,
  472. sizeof(ACPI_FIELD_UNIT_OBJECT));
  473. //
  474. // Increment the reference count on the bank register if supplied.
  475. //
  476. if (NewObject->U.FieldUnit.BankRegister != NULL) {
  477. AcpipObjectAddReference(NewObject->U.FieldUnit.BankRegister);
  478. ASSERT(NewObject->U.FieldUnit.BankValue != NULL);
  479. AcpipObjectAddReference(NewObject->U.FieldUnit.BankValue);
  480. }
  481. //
  482. // Increment the reference count on the bank register if supplied.
  483. //
  484. if (NewObject->U.FieldUnit.IndexRegister != NULL) {
  485. AcpipObjectAddReference(NewObject->U.FieldUnit.IndexRegister);
  486. ASSERT(NewObject->U.FieldUnit.DataRegister != NULL);
  487. AcpipObjectAddReference(NewObject->U.FieldUnit.DataRegister);
  488. }
  489. if (NewObject->U.FieldUnit.OperationRegion != NULL) {
  490. AcpipObjectAddReference(NewObject->U.FieldUnit.OperationRegion);
  491. }
  492. }
  493. break;
  494. case AcpiObjectDevice:
  495. NewObject->U.Device.OsDevice = NULL;
  496. NewObject->U.Device.DeviceContext = NULL;
  497. NewObject->U.Device.IsPciBus = FALSE;
  498. NewObject->U.Device.IsDeviceStarted = FALSE;
  499. break;
  500. case AcpiObjectEvent:
  501. NewObject->U.Event.OsEvent = AcpipCreateEvent();
  502. if (NewObject->U.Event.OsEvent == NULL) {
  503. Status = STATUS_UNSUCCESSFUL;
  504. goto CreateNamespaceObjectEnd;
  505. }
  506. break;
  507. case AcpiObjectMethod:
  508. if ((Buffer != NULL) &&
  509. (BufferSize == sizeof(ACPI_METHOD_OBJECT))) {
  510. RtlCopyMemory(&(NewObject->U.Method),
  511. Buffer,
  512. sizeof(ACPI_METHOD_OBJECT));
  513. ASSERT(NewObject->U.Method.OsMutex == NULL);
  514. if (NewObject->U.Method.Serialized != FALSE) {
  515. NewObject->U.Method.OsMutex =
  516. AcpipCreateMutex(NewObject->U.Method.SyncLevel);
  517. if (NewObject->U.Method.OsMutex == NULL) {
  518. Status = STATUS_UNSUCCESSFUL;
  519. goto CreateNamespaceObjectEnd;
  520. }
  521. }
  522. }
  523. break;
  524. case AcpiObjectMutex:
  525. NewObject->U.Mutex.OsMutex = AcpipCreateMutex(0);
  526. if (NewObject->U.Mutex.OsMutex == NULL) {
  527. Status = STATUS_UNSUCCESSFUL;
  528. goto CreateNamespaceObjectEnd;
  529. }
  530. break;
  531. case AcpiObjectOperationRegion:
  532. RtlZeroMemory(&(NewObject->U.OperationRegion),
  533. sizeof(ACPI_OPERATION_REGION_OBJECT));
  534. break;
  535. case AcpiObjectPowerResource:
  536. if ((Buffer != NULL) &&
  537. (BufferSize == sizeof(ACPI_POWER_RESOURCE_OBJECT))) {
  538. PowerResource = (PACPI_POWER_RESOURCE_OBJECT)Buffer;
  539. RtlCopyMemory(&(NewObject->U.PowerResource),
  540. PowerResource,
  541. sizeof(ACPI_POWER_RESOURCE_OBJECT));
  542. }
  543. break;
  544. case AcpiObjectProcessor:
  545. if ((Buffer != NULL) &&
  546. (BufferSize == sizeof(ACPI_PROCESSOR_OBJECT))) {
  547. RtlCopyMemory(&(NewObject->U.Processor),
  548. Buffer,
  549. sizeof(ACPI_PROCESSOR_OBJECT));
  550. }
  551. break;
  552. case AcpiObjectBufferField:
  553. if ((Buffer != NULL) &&
  554. (BufferSize == sizeof(ACPI_BUFFER_FIELD_OBJECT))) {
  555. RtlCopyMemory(&(NewObject->U.BufferField),
  556. Buffer,
  557. sizeof(ACPI_BUFFER_FIELD_OBJECT));
  558. if (NewObject->U.BufferField.DestinationObject != NULL) {
  559. AcpipObjectAddReference(
  560. NewObject->U.BufferField.DestinationObject);
  561. }
  562. }
  563. break;
  564. case AcpiObjectAlias:
  565. if ((Buffer != NULL) &&
  566. (BufferSize == sizeof(ACPI_ALIAS_OBJECT))) {
  567. RtlCopyMemory(&(NewObject->U.Alias),
  568. Buffer,
  569. sizeof(ACPI_ALIAS_OBJECT));
  570. if (NewObject->U.Alias.DestinationObject != NULL) {
  571. AcpipObjectAddReference(NewObject->U.Alias.DestinationObject);
  572. }
  573. } else {
  574. RtlZeroMemory(&(NewObject->U.Alias), sizeof(ACPI_ALIAS_OBJECT));
  575. }
  576. break;
  577. case AcpiObjectUnresolvedName:
  578. ASSERT((Buffer != NULL) &&
  579. (BufferSize == sizeof(ACPI_UNRESOLVED_NAME_OBJECT)));
  580. UnresolvedName = (PACPI_UNRESOLVED_NAME_OBJECT)Buffer;
  581. UnresolvedNameLength = RtlStringLength(UnresolvedName->Name);
  582. NewObject->U.UnresolvedName.Name =
  583. AcpipAllocateMemory(UnresolvedNameLength + 1);
  584. if (NewObject->U.UnresolvedName.Name == NULL) {
  585. Status = STATUS_INSUFFICIENT_RESOURCES;
  586. goto CreateNamespaceObjectEnd;
  587. }
  588. RtlStringCopy(NewObject->U.UnresolvedName.Name,
  589. UnresolvedName->Name,
  590. UnresolvedNameLength + 1);
  591. NewObject->U.UnresolvedName.Scope = UnresolvedName->Scope;
  592. AcpipObjectAddReference(UnresolvedName->Scope);
  593. break;
  594. //
  595. // Other objects need no additional data.
  596. //
  597. case AcpiObjectUninitialized:
  598. case AcpiObjectThermalZone:
  599. case AcpiObjectDebug:
  600. break;
  601. default:
  602. ASSERT(FALSE);
  603. Status = STATUS_INVALID_PARAMETER;
  604. goto CreateNamespaceObjectEnd;
  605. }
  606. //
  607. // Link the object into the parent if one was supplied. Linking it into the
  608. // tree adds a reference count to the object, since when the method is
  609. // finished or the definition block is unloaded, all objects in the
  610. // namespace will be released.
  611. //
  612. NewObject->DestructorListEntry.Next = NULL;
  613. if (ParentObject != NULL) {
  614. NewObject->ReferenceCount += 1;
  615. INSERT_BEFORE(&(NewObject->SiblingListEntry),
  616. &(ParentObject->ChildListHead));
  617. if (Context != NULL) {
  618. //
  619. // The object is being added to the global namespace, so destroy it
  620. // when the definition block is unloaded.
  621. //
  622. if (Context->DestructorListHead != NULL) {
  623. INSERT_BEFORE(&(NewObject->DestructorListEntry),
  624. Context->DestructorListHead);
  625. //
  626. // A method is executing, so add it to the list of objects created
  627. // under the method.
  628. //
  629. } else {
  630. INSERT_BEFORE(
  631. &(NewObject->DestructorListEntry),
  632. &(Context->CurrentMethod->CreatedObjectsListHead));
  633. }
  634. }
  635. } else {
  636. NewObject->SiblingListEntry.Next = NULL;
  637. }
  638. Status = STATUS_SUCCESS;
  639. CreateNamespaceObjectEnd:
  640. if (!KSUCCESS(Status)) {
  641. if (NewBuffer != NULL) {
  642. AcpipFreeMemory(NewBuffer);
  643. }
  644. if (NewObject != NULL) {
  645. AcpipFreeMemory(NewObject);
  646. NewObject = NULL;
  647. }
  648. }
  649. return NewObject;
  650. }
  651. VOID
  652. AcpipObjectAddReference (
  653. PACPI_OBJECT Object
  654. )
  655. /*++
  656. Routine Description:
  657. This routine adds one to the reference count of a given ACPI object.
  658. Arguments:
  659. Object - Supplies a pointer to the object.
  660. Return Value:
  661. None.
  662. --*/
  663. {
  664. Object->ReferenceCount += 1;
  665. return;
  666. }
  667. VOID
  668. AcpipObjectReleaseReference (
  669. PACPI_OBJECT Object
  670. )
  671. /*++
  672. Routine Description:
  673. This routine subtracts one from the reference count of the given object. If
  674. this causes the reference count to hit zero, the object will be destroyed.
  675. Arguments:
  676. Object - Supplies a pointer to the object.
  677. Return Value:
  678. None.
  679. --*/
  680. {
  681. ASSERT(Object->Type < AcpiObjectTypeCount);
  682. ASSERT((Object->ReferenceCount != 0) && (Object->ReferenceCount < 0x1000));
  683. Object->ReferenceCount -= 1;
  684. if (Object->ReferenceCount == 0) {
  685. AcpipDestroyNamespaceObject(Object);
  686. }
  687. return;
  688. }
  689. PACPI_OBJECT
  690. AcpipGetNamespaceObject (
  691. PSTR Name,
  692. PACPI_OBJECT CurrentScope
  693. )
  694. /*++
  695. Routine Description:
  696. This routine looks up an ACPI object in the namespace based on a location
  697. string.
  698. Arguments:
  699. Name - Supplies a pointer to a string containing the namespace path.
  700. CurrentScope - Supplies a pointer to the current namespace scope. If NULL
  701. is supplied, the global root namespace will be used.
  702. Return Value:
  703. Returns a pointer to the ACPI object on success.
  704. NULL if the object could not be found.
  705. --*/
  706. {
  707. return AcpipGetPartialNamespaceObject(Name, 0, CurrentScope);
  708. }
  709. PACPI_OBJECT *
  710. AcpipEnumerateChildObjects (
  711. PACPI_OBJECT ParentObject,
  712. ACPI_OBJECT_TYPE ObjectType,
  713. PULONG ObjectCount
  714. )
  715. /*++
  716. Routine Description:
  717. This routine allocates and initializes an array containing pointers to the
  718. children of the given namespace object, optionally filtering out only
  719. objects of a given type.
  720. Arguments:
  721. ParentObject - Supplies a pointer to the parent whose children should be
  722. enumerated.
  723. ObjectType - Supplies an object type. If a valid object type is supplied,
  724. then only objects of that type will be returned. Supply
  725. AcpiObjectTypeCount to return all objects. Note that if
  726. AcpiObjectDevice is requested, then AcpiObjectProcessor objects will
  727. also be returned.
  728. ObjectCount - Supplies a pointer where the number of elements in the return
  729. array will be returned.
  730. Return Value:
  731. Returns a pointer to an array of pointers to the child object. The caller
  732. must call the corresponding release enumeration list to free the memory
  733. allocated by this routine.
  734. NULL if there are no objects or there was an error.
  735. --*/
  736. {
  737. ULONG ChildCount;
  738. PLIST_ENTRY CurrentEntry;
  739. PACPI_OBJECT Object;
  740. ULONG ObjectIndex;
  741. PACPI_OBJECT *Objects;
  742. ULONG ProcessorObjectCount;
  743. PACPI_OBJECT *ProcessorObjects;
  744. Objects = NULL;
  745. ChildCount = 0;
  746. ProcessorObjects = NULL;
  747. //
  748. // If looking for devices in the system bus root, also find processors in
  749. // the _PR object and merge them in here.
  750. //
  751. if ((ObjectType == AcpiObjectDevice) &&
  752. (ParentObject == AcpiSystemBusRoot)) {
  753. ProcessorObjects = AcpipEnumerateChildObjects(AcpiProcessorRoot,
  754. AcpiObjectDevice,
  755. &ProcessorObjectCount);
  756. ChildCount += ProcessorObjectCount;
  757. }
  758. //
  759. // Loop through once to count the number of objects.
  760. //
  761. CurrentEntry = ParentObject->ChildListHead.Next;
  762. while (CurrentEntry != &(ParentObject->ChildListHead)) {
  763. Object = LIST_VALUE(CurrentEntry, ACPI_OBJECT, SiblingListEntry);
  764. if ((ObjectType == AcpiObjectTypeCount) ||
  765. (Object->Type == ObjectType) ||
  766. ((ObjectType == AcpiObjectDevice) &&
  767. (Object->Type == AcpiObjectProcessor))) {
  768. ChildCount += 1;
  769. }
  770. CurrentEntry = CurrentEntry->Next;
  771. }
  772. if (ChildCount == 0) {
  773. goto EnumerateChildObjectsEnd;
  774. }
  775. Objects = AcpipAllocateMemory(ChildCount * sizeof(PACPI_OBJECT));
  776. if (Objects == NULL) {
  777. ChildCount = 0;
  778. goto EnumerateChildObjectsEnd;
  779. }
  780. //
  781. // Enumerate through and for each elibile child, put it in the array and
  782. // increment its reference count.
  783. //
  784. ObjectIndex = 0;
  785. CurrentEntry = ParentObject->ChildListHead.Next;
  786. while (CurrentEntry != &(ParentObject->ChildListHead)) {
  787. Object = LIST_VALUE(CurrentEntry, ACPI_OBJECT, SiblingListEntry);
  788. CurrentEntry = CurrentEntry->Next;
  789. if ((ObjectType == AcpiObjectTypeCount) ||
  790. (Object->Type == ObjectType) ||
  791. ((ObjectType == AcpiObjectDevice) &&
  792. (Object->Type == AcpiObjectProcessor))) {
  793. Objects[ObjectIndex] = Object;
  794. AcpipObjectAddReference(Object);
  795. ObjectIndex += 1;
  796. }
  797. }
  798. //
  799. // Copy in those processor objects from the beginning if there are any.
  800. //
  801. if (ProcessorObjects != NULL) {
  802. RtlCopyMemory(&(Objects[ObjectIndex]),
  803. ProcessorObjects,
  804. ProcessorObjectCount * sizeof(PACPI_OBJECT));
  805. MmFreePagedPool(ProcessorObjects);
  806. ProcessorObjects = NULL;
  807. }
  808. EnumerateChildObjectsEnd:
  809. if (ProcessorObjects != NULL) {
  810. AcpipReleaseChildEnumerationArray(ProcessorObjects,
  811. ProcessorObjectCount);
  812. }
  813. *ObjectCount = ChildCount;
  814. return Objects;
  815. }
  816. VOID
  817. AcpipReleaseChildEnumerationArray (
  818. PACPI_OBJECT *Objects,
  819. ULONG ObjectCount
  820. )
  821. /*++
  822. Routine Description:
  823. This routine releases a list returned as a result of calling the enumerate
  824. child objects routine.
  825. Arguments:
  826. Objects - Supplies a pointer to the array of objects, as returned from
  827. the enumerate child objects routine.
  828. ObjectCount - Supplies the number of elements in the array, as returned
  829. from the enumerate child objects routine.
  830. Return Value:
  831. None.
  832. --*/
  833. {
  834. ULONG ChildIndex;
  835. for (ChildIndex = 0; ChildIndex < ObjectCount; ChildIndex += 1) {
  836. AcpipObjectReleaseReference(Objects[ChildIndex]);
  837. }
  838. AcpipFreeMemory(Objects);
  839. return;
  840. }
  841. VOID
  842. AcpipConvertEisaIdToString (
  843. ULONG EisaId,
  844. PSTR ResultIdString
  845. )
  846. /*++
  847. Routine Description:
  848. This routine converts an EISA encoded ID into a device ID string.
  849. Arguments:
  850. EisaId - Supplies the encoded EISA ID to get.
  851. ResultIdString - Supplies a pointer where the decoded result string will
  852. be returned. This buffer must be allocated by the caller, and must be
  853. at least 8 bytes long.
  854. Return Value:
  855. Returns a pointer to a string, allocated using the AML interpreter
  856. allocation routines. The caller is responsible for freeing this memory.
  857. --*/
  858. {
  859. UCHAR Manufacturer1;
  860. UCHAR Manufacturer2;
  861. UCHAR Manufacturer3;
  862. UCHAR ProductId1;
  863. UCHAR ProductId2;
  864. RtlZeroMemory(ResultIdString, EISA_ID_STRING_LENGTH);
  865. //
  866. // The EISA encoding is really goofy. It jams 3 characters of manufacturer
  867. // ID and 4 digits of product ID into 4 bytes. The manufacturer bits are
  868. // uppercase letters A - Z, where 0x40 is subtracted from each character
  869. // so it fits into 5 bits, then jammed into 3 bytes. The last two bytes
  870. // contain the product
  871. // code (byte 3 first, then byte 4). The encoding looks like this:
  872. //
  873. // Byte 0: 7 6 5 4 3 2 1 0
  874. // 1 1 1 1 1 2 2 - First character plus 2 MSB of second character.
  875. //
  876. // Byte 1: 7 6 5 4 3 2 1 0
  877. // 2 2 2 3 3 3 3 3 - 3 LSB of second character plus third character.
  878. //
  879. // Byte 2: Product ID byte 1.
  880. // Byte 3: Product ID byte 2.
  881. //
  882. // To decode the manufacturer ID, unstuff the 2 byte into 4, and add 0x40
  883. // to each one.
  884. //
  885. Manufacturer1 = (UCHAR)((EisaId >> 2) & 0x1F);
  886. //
  887. // Get the 3 LSB bits from byte 2, plus the two MSB from byte 1.
  888. //
  889. Manufacturer2 = (UCHAR)((EisaId >> (8 + 5)) & 0x7);
  890. Manufacturer2 |= (UCHAR)((EisaId << 3) & 0x18);
  891. //
  892. // Get character 3 from byte 2, and add 0x40 to every character.
  893. //
  894. Manufacturer3 = (UCHAR)((EisaId >> 8) & 0x1F);
  895. Manufacturer1 += 0x40;
  896. Manufacturer2 += 0x40;
  897. Manufacturer3 += 0x40;
  898. //
  899. // Get the product ID bytes.
  900. //
  901. ProductId1 = (UCHAR)(EisaId >> 16);
  902. ProductId2 = (UCHAR)(EisaId >> 24);
  903. //
  904. // Finally, construct the string.
  905. //
  906. RtlPrintToString(ResultIdString,
  907. EISA_ID_STRING_LENGTH,
  908. CharacterEncodingAscii,
  909. "%c%c%c%02X%02X",
  910. Manufacturer1,
  911. Manufacturer2,
  912. Manufacturer3,
  913. ProductId1,
  914. ProductId2);
  915. return;
  916. }
  917. KSTATUS
  918. AcpipPerformStoreOperation (
  919. PAML_EXECUTION_CONTEXT Context,
  920. PACPI_OBJECT Source,
  921. PACPI_OBJECT Destination
  922. )
  923. /*++
  924. Routine Description:
  925. This routine performs a store operation from one object into the value of
  926. another.
  927. Arguments:
  928. Context - Supplies a pointer to the current AML execution context.
  929. Source - Supplies a pointer to the source object for the store.
  930. Destination - Supplies a pointer to the object to store the value into.
  931. Return Value:
  932. Status code.
  933. --*/
  934. {
  935. BOOL NewObjectCreated;
  936. PACPI_OBJECT ResolvedDestination;
  937. ULONG Size;
  938. KSTATUS Status;
  939. NewObjectCreated = FALSE;
  940. //
  941. // Resolve to the correct destination.
  942. //
  943. ResolvedDestination = NULL;
  944. Status = AcpipResolveStoreDestination(Context,
  945. Destination,
  946. &ResolvedDestination);
  947. if (!KSUCCESS(Status)) {
  948. goto PerformStoreOperationEnd;
  949. }
  950. Destination = ResolvedDestination;
  951. //
  952. // The ACPI spec states that storing to constants is fatal, but also states
  953. // that it is a no-op and not an error. Go with the more lenient option. A
  954. // lot of operators use a store to Zero to indicate a no-op.
  955. //
  956. if (IS_ACPI_CONSTANT(Destination) != FALSE) {
  957. Status = STATUS_SUCCESS;
  958. goto PerformStoreOperationEnd;
  959. }
  960. //
  961. // Perform a conversion if necessary. Integers, Buffers, and Strings can
  962. // be stored into a Field/Buffer unit. Count strings as buffers.
  963. //
  964. if ((Destination->Type == AcpiObjectFieldUnit) ||
  965. (Destination->Type == AcpiObjectBufferField)) {
  966. if ((Source->Type != AcpiObjectInteger) &&
  967. (Source->Type != AcpiObjectBuffer)) {
  968. Source = AcpipConvertObjectType(Context, Source, AcpiObjectBuffer);
  969. if (Source == NULL) {
  970. Status = STATUS_CONVERSION_FAILED;
  971. goto PerformStoreOperationEnd;
  972. }
  973. NewObjectCreated = TRUE;
  974. }
  975. } else if ((Source->Type != Destination->Type) &&
  976. (Destination->Type != AcpiObjectDebug) &&
  977. (Destination->Type != AcpiObjectUninitialized)) {
  978. Source = AcpipConvertObjectType(Context, Source, Destination->Type);
  979. if (Source == NULL) {
  980. Status = STATUS_CONVERSION_FAILED;
  981. goto PerformStoreOperationEnd;
  982. }
  983. NewObjectCreated = TRUE;
  984. }
  985. //
  986. // Perform the store, which may involve freeing an old buffer and creating
  987. // a new one.
  988. //
  989. switch (Destination->Type) {
  990. case AcpiObjectUninitialized:
  991. //
  992. // If the object is uninitialized, then do a "replace contents"
  993. // operation.
  994. //
  995. Status = AcpipReplaceObjectContents(Context, Destination, Source);
  996. if (!KSUCCESS(Status)) {
  997. goto PerformStoreOperationEnd;
  998. }
  999. break;
  1000. case AcpiObjectInteger:
  1001. ASSERT(Source->Type == AcpiObjectInteger);
  1002. Destination->U.Integer.Value = Source->U.Integer.Value;
  1003. break;
  1004. case AcpiObjectString:
  1005. ASSERT(Source->Type == AcpiObjectString);
  1006. if (Destination->U.String.String != NULL) {
  1007. AcpipFreeMemory(Destination->U.String.String);
  1008. }
  1009. //
  1010. // If a new object was created, steal that buffer, otherwise create and
  1011. // copy a new buffer.
  1012. //
  1013. if (NewObjectCreated != FALSE) {
  1014. Destination->U.String.String = Source->U.String.String;
  1015. Source->U.String.String = NULL;
  1016. } else {
  1017. Size = RtlStringLength(Source->U.String.String);
  1018. Destination->U.String.String = AcpipAllocateMemory(Size + 1);
  1019. if (Destination->U.String.String == NULL) {
  1020. Status = STATUS_INSUFFICIENT_RESOURCES;
  1021. goto PerformStoreOperationEnd;
  1022. }
  1023. RtlCopyMemory(Destination->U.String.String,
  1024. Source->U.String.String,
  1025. Size + 1);
  1026. }
  1027. break;
  1028. case AcpiObjectBuffer:
  1029. ASSERT(Source->Type == AcpiObjectBuffer);
  1030. //
  1031. // If the old buffer is big enough, shrink it to the right size and
  1032. // just reuse it.
  1033. //
  1034. if (Destination->U.Buffer.Length >= Source->U.Buffer.Length) {
  1035. RtlCopyMemory(Destination->U.Buffer.Buffer,
  1036. Source->U.Buffer.Buffer,
  1037. Source->U.Buffer.Length);
  1038. } else {
  1039. //
  1040. // If a new object was created, steal that buffer, otherwise create
  1041. // and copy a new buffer.
  1042. //
  1043. if (NewObjectCreated != FALSE) {
  1044. Destination->U.Buffer.Buffer = Source->U.Buffer.Buffer;
  1045. Source->U.Buffer.Buffer = 0;
  1046. Source->U.Buffer.Length = 0;
  1047. } else {
  1048. Size = Source->U.Buffer.Length;
  1049. Destination->U.Buffer.Buffer = AcpipAllocateMemory(Size);
  1050. if (Destination->U.Buffer.Buffer == NULL) {
  1051. Status = STATUS_INSUFFICIENT_RESOURCES;
  1052. goto PerformStoreOperationEnd;
  1053. }
  1054. RtlCopyMemory(Destination->U.Buffer.Buffer,
  1055. Source->U.Buffer.Buffer,
  1056. Size + 1);
  1057. }
  1058. Destination->U.Buffer.Length = Source->U.Buffer.Length;
  1059. }
  1060. break;
  1061. case AcpiObjectFieldUnit:
  1062. Status = AcpipWriteToField(Context, Destination, Source);
  1063. if (!KSUCCESS(Status)) {
  1064. goto PerformStoreOperationEnd;
  1065. }
  1066. break;
  1067. case AcpiObjectBufferField:
  1068. Status = AcpipWriteToBufferField(Context, Destination, Source);
  1069. if (!KSUCCESS(Status)) {
  1070. goto PerformStoreOperationEnd;
  1071. }
  1072. break;
  1073. //
  1074. // Some object cannot be "stored" into.
  1075. //
  1076. case AcpiObjectPackage:
  1077. case AcpiObjectDevice:
  1078. case AcpiObjectEvent:
  1079. case AcpiObjectMethod:
  1080. case AcpiObjectMutex:
  1081. case AcpiObjectOperationRegion:
  1082. case AcpiObjectPowerResource:
  1083. case AcpiObjectProcessor:
  1084. case AcpiObjectThermalZone:
  1085. Status = STATUS_NOT_SUPPORTED;
  1086. goto PerformStoreOperationEnd;
  1087. //
  1088. // Stores to the debug object result in printing out the source.
  1089. //
  1090. case AcpiObjectDebug:
  1091. AcpipDebugOutputObject(Source);
  1092. break;
  1093. default:
  1094. ASSERT(FALSE);
  1095. Status = STATUS_NOT_SUPPORTED;
  1096. goto PerformStoreOperationEnd;
  1097. }
  1098. Status = STATUS_SUCCESS;
  1099. PerformStoreOperationEnd:
  1100. if (NewObjectCreated != FALSE) {
  1101. AcpipObjectReleaseReference(Source);
  1102. }
  1103. if (ResolvedDestination != NULL) {
  1104. AcpipObjectReleaseReference(ResolvedDestination);
  1105. }
  1106. return Status;
  1107. }
  1108. PACPI_OBJECT
  1109. AcpipCopyObject (
  1110. PACPI_OBJECT Object
  1111. )
  1112. /*++
  1113. Routine Description:
  1114. This routine creates an unnamed and unlinked copy of the given object.
  1115. Arguments:
  1116. Object - Supplies a pointer to the object whose contents should be copied.
  1117. Return Value:
  1118. Returns a pointer to the new copy on success.
  1119. NULL on failure.
  1120. --*/
  1121. {
  1122. PVOID Buffer;
  1123. ULONG BufferLength;
  1124. PACPI_OBJECT NewObject;
  1125. //
  1126. // Determine which part to copy.
  1127. //
  1128. switch (Object->Type) {
  1129. case AcpiObjectInteger:
  1130. Buffer = &(Object->U.Integer.Value);
  1131. BufferLength = sizeof(ULONGLONG);
  1132. break;
  1133. case AcpiObjectString:
  1134. Buffer = Object->U.String.String;
  1135. BufferLength = 0;
  1136. if (Buffer != NULL) {
  1137. BufferLength = RtlStringLength(Buffer) + 1;
  1138. }
  1139. break;
  1140. case AcpiObjectBuffer:
  1141. Buffer = Object->U.Buffer.Buffer;
  1142. BufferLength = Object->U.Buffer.Length;
  1143. break;
  1144. case AcpiObjectPackage:
  1145. Buffer = Object->U.Package.Array;
  1146. BufferLength = Object->U.Package.ElementCount * sizeof(PACPI_OBJECT);
  1147. break;
  1148. case AcpiObjectFieldUnit:
  1149. Buffer = &(Object->U.FieldUnit);
  1150. BufferLength = sizeof(ACPI_FIELD_UNIT_OBJECT);
  1151. break;
  1152. case AcpiObjectPowerResource:
  1153. Buffer = &(Object->U.PowerResource);
  1154. BufferLength = sizeof(ACPI_POWER_RESOURCE_OBJECT);
  1155. break;
  1156. case AcpiObjectProcessor:
  1157. Buffer = &(Object->U.Processor);
  1158. BufferLength = sizeof(ACPI_PROCESSOR_OBJECT);
  1159. break;
  1160. case AcpiObjectBufferField:
  1161. Buffer = &(Object->U.BufferField);
  1162. BufferLength = sizeof(ACPI_BUFFER_FIELD_OBJECT);
  1163. break;
  1164. case AcpiObjectUninitialized:
  1165. case AcpiObjectThermalZone:
  1166. case AcpiObjectDebug:
  1167. Buffer = NULL;
  1168. BufferLength = 0;
  1169. break;
  1170. case AcpiObjectAlias:
  1171. Buffer = &(Object->U.Alias);
  1172. BufferLength = sizeof(ACPI_ALIAS_OBJECT);
  1173. break;
  1174. case AcpiObjectDevice:
  1175. case AcpiObjectEvent:
  1176. case AcpiObjectMethod:
  1177. case AcpiObjectMutex:
  1178. case AcpiObjectOperationRegion:
  1179. default:
  1180. ASSERT(FALSE);
  1181. return NULL;
  1182. }
  1183. NewObject = AcpipCreateNamespaceObject(NULL,
  1184. Object->Type,
  1185. NULL,
  1186. Buffer,
  1187. BufferLength);
  1188. return NewObject;
  1189. }
  1190. KSTATUS
  1191. AcpipReplaceObjectContents (
  1192. PAML_EXECUTION_CONTEXT Context,
  1193. PACPI_OBJECT ObjectToReplace,
  1194. PACPI_OBJECT ObjectWithContents
  1195. )
  1196. /*++
  1197. Routine Description:
  1198. This routine replaces the inner contents of an object with a copy of those
  1199. from a different object.
  1200. Arguments:
  1201. Context - Supplies a pointer to the AML execution context.
  1202. ObjectToReplace - Supplies a pointer to an object whose contents should be
  1203. replaced.
  1204. ObjectWithContents - Supplies a pointer to the object that has the contents
  1205. to use for replacement.
  1206. Return Value:
  1207. STATUS_SUCCESS if the object to replace successfully became a copy of the
  1208. object with contents (on everything except its name, position in the
  1209. namespace, and actual pointer).
  1210. STATUS_INSUFFICIENT_RESOURCES if the space needed to replace the contents
  1211. could not be allocated. In this case, the object to be replaced will
  1212. remain unchanged.
  1213. Other error codes on other failures. On failure, the object to replace will
  1214. remain unchanged.
  1215. --*/
  1216. {
  1217. PACPI_OBJECT FieldReadResult;
  1218. PVOID NewBuffer;
  1219. ULONG NewBufferLength;
  1220. ULONG PackageIndex;
  1221. PACPI_OBJECT PackageObject;
  1222. KSTATUS Status;
  1223. FieldReadResult = NULL;
  1224. NewBuffer = NULL;
  1225. NewBufferLength = 0;
  1226. //
  1227. // Determine if a new buffer needs to be allocated, and its size.
  1228. //
  1229. switch (ObjectWithContents->Type) {
  1230. case AcpiObjectString:
  1231. NewBufferLength = RtlStringLength(ObjectWithContents->U.String.String) +
  1232. 1;
  1233. break;
  1234. case AcpiObjectBuffer:
  1235. NewBufferLength = ObjectWithContents->U.Buffer.Length;
  1236. break;
  1237. case AcpiObjectPackage:
  1238. NewBufferLength = ObjectWithContents->U.Package.ElementCount *
  1239. sizeof(PACPI_OBJECT);
  1240. break;
  1241. default:
  1242. break;
  1243. }
  1244. //
  1245. // Attempt to allocate the new buffer if needed.
  1246. //
  1247. if (NewBufferLength != 0) {
  1248. NewBuffer = AcpipAllocateMemory(NewBufferLength);
  1249. if (NewBuffer == NULL) {
  1250. return STATUS_INSUFFICIENT_RESOURCES;
  1251. }
  1252. }
  1253. //
  1254. // Now that all required resources are acquired, free the old stuff.
  1255. //
  1256. switch (ObjectToReplace->Type) {
  1257. case AcpiObjectString:
  1258. if (ObjectToReplace->U.String.String != NULL) {
  1259. AcpipFreeMemory(ObjectToReplace->U.String.String);
  1260. }
  1261. break;
  1262. case AcpiObjectBuffer:
  1263. if (ObjectToReplace->U.Buffer.Buffer != NULL) {
  1264. AcpipFreeMemory(ObjectToReplace->U.Buffer.Buffer);
  1265. }
  1266. break;
  1267. case AcpiObjectPackage:
  1268. if (ObjectToReplace->U.Package.Array != NULL) {
  1269. for (PackageIndex = 0;
  1270. PackageIndex < ObjectToReplace->U.Package.ElementCount;
  1271. PackageIndex += 1) {
  1272. PackageObject = ObjectToReplace->U.Package.Array[PackageIndex];
  1273. if (PackageObject != NULL) {
  1274. AcpipObjectReleaseReference(PackageObject);
  1275. }
  1276. }
  1277. AcpipFreeMemory(ObjectToReplace->U.Package.Array);
  1278. }
  1279. break;
  1280. case AcpiObjectFieldUnit:
  1281. if (ObjectToReplace->U.FieldUnit.BankRegister != NULL) {
  1282. AcpipObjectReleaseReference(
  1283. ObjectToReplace->U.FieldUnit.BankRegister);
  1284. ASSERT(ObjectToReplace->U.FieldUnit.BankValue != NULL);
  1285. AcpipObjectReleaseReference(ObjectToReplace->U.FieldUnit.BankValue);
  1286. }
  1287. if (ObjectToReplace->U.FieldUnit.IndexRegister != NULL) {
  1288. AcpipObjectReleaseReference(
  1289. ObjectToReplace->U.FieldUnit.IndexRegister);
  1290. ASSERT(ObjectToReplace->U.FieldUnit.DataRegister != NULL);
  1291. AcpipObjectReleaseReference(
  1292. ObjectToReplace->U.FieldUnit.DataRegister);
  1293. }
  1294. break;
  1295. case AcpiObjectEvent:
  1296. if (ObjectToReplace->U.Event.OsEvent != NULL) {
  1297. AcpipDestroyEvent(ObjectToReplace->U.Event.OsEvent);
  1298. ObjectToReplace->U.Event.OsEvent = NULL;
  1299. }
  1300. break;
  1301. case AcpiObjectMethod:
  1302. if (ObjectToReplace->U.Method.OsMutex != NULL) {
  1303. AcpipDestroyMutex(ObjectToReplace->U.Method.OsMutex);
  1304. ObjectToReplace->U.Method.OsMutex = NULL;
  1305. }
  1306. break;
  1307. case AcpiObjectMutex:
  1308. if (ObjectToReplace->U.Mutex.OsMutex != NULL) {
  1309. AcpipDestroyMutex(ObjectToReplace->U.Mutex.OsMutex);
  1310. ObjectToReplace->U.Mutex.OsMutex = NULL;
  1311. }
  1312. break;
  1313. case AcpiObjectBufferField:
  1314. if (ObjectToReplace->U.BufferField.DestinationObject != NULL) {
  1315. AcpipObjectReleaseReference(
  1316. ObjectToReplace->U.BufferField.DestinationObject);
  1317. }
  1318. break;
  1319. case AcpiObjectAlias:
  1320. if (ObjectToReplace->U.Alias.DestinationObject != NULL) {
  1321. AcpipObjectReleaseReference(
  1322. ObjectToReplace->U.Alias.DestinationObject);
  1323. }
  1324. break;
  1325. default:
  1326. break;
  1327. }
  1328. //
  1329. // Replace with the new stuff.
  1330. //
  1331. Status = STATUS_SUCCESS;
  1332. ObjectToReplace->Type = ObjectWithContents->Type;
  1333. switch (ObjectWithContents->Type) {
  1334. case AcpiObjectInteger:
  1335. ObjectToReplace->U.Integer.Value = ObjectWithContents->U.Integer.Value;
  1336. break;
  1337. case AcpiObjectString:
  1338. RtlCopyMemory(NewBuffer,
  1339. ObjectWithContents->U.String.String,
  1340. NewBufferLength);
  1341. ObjectToReplace->U.String.String = NewBuffer;
  1342. break;
  1343. case AcpiObjectBuffer:
  1344. RtlCopyMemory(NewBuffer,
  1345. ObjectWithContents->U.Buffer.Buffer,
  1346. NewBufferLength);
  1347. ObjectToReplace->U.Buffer.Buffer = NewBuffer;
  1348. ObjectToReplace->U.Buffer.Length = NewBufferLength;
  1349. break;
  1350. case AcpiObjectFieldUnit:
  1351. Status = AcpipReadFromField(Context,
  1352. ObjectWithContents,
  1353. &FieldReadResult);
  1354. if (!KSUCCESS(Status)) {
  1355. return Status;
  1356. }
  1357. //
  1358. // Call this routine again, replacing the object with the result of the
  1359. // read instead of the field itself. Set the type to be uninitialized
  1360. // so this routine doesn't try to re-free anything.
  1361. //
  1362. ObjectToReplace->Type = AcpiObjectUninitialized;
  1363. Status = AcpipReplaceObjectContents(Context,
  1364. ObjectToReplace,
  1365. FieldReadResult);
  1366. AcpipObjectReleaseReference(FieldReadResult);
  1367. break;
  1368. case AcpiObjectPackage:
  1369. RtlCopyMemory(NewBuffer,
  1370. ObjectWithContents->U.Package.Array,
  1371. NewBufferLength);
  1372. ObjectToReplace->U.Package.Array = NewBuffer;
  1373. ObjectToReplace->U.Package.ElementCount = NewBufferLength /
  1374. sizeof(PACPI_OBJECT);
  1375. //
  1376. // Increment the reference count on every object in the package.
  1377. //
  1378. for (PackageIndex = 0;
  1379. PackageIndex < ObjectToReplace->U.Package.ElementCount;
  1380. PackageIndex += 1) {
  1381. PackageObject = ObjectToReplace->U.Package.Array[PackageIndex];
  1382. if (PackageObject != NULL) {
  1383. AcpipObjectAddReference(PackageObject);
  1384. }
  1385. }
  1386. break;
  1387. case AcpiObjectPowerResource:
  1388. RtlCopyMemory(&(ObjectToReplace->U.PowerResource),
  1389. &(ObjectWithContents->U.PowerResource),
  1390. sizeof(ACPI_POWER_RESOURCE_OBJECT));
  1391. break;
  1392. case AcpiObjectProcessor:
  1393. RtlCopyMemory(&(ObjectToReplace->U.Processor),
  1394. &(ObjectWithContents->U.Processor),
  1395. sizeof(ACPI_PROCESSOR_OBJECT));
  1396. break;
  1397. case AcpiObjectBufferField:
  1398. Status = AcpipReadFromBufferField(Context,
  1399. ObjectWithContents,
  1400. &FieldReadResult);
  1401. if (!KSUCCESS(Status)) {
  1402. return Status;
  1403. }
  1404. //
  1405. // Call this routine again, replacing the object with the result of the
  1406. // read instead of the field itself. Set the type to be uninitialized
  1407. // so this routine doesn't try to re-free anything.
  1408. //
  1409. ObjectToReplace->Type = AcpiObjectUninitialized;
  1410. Status = AcpipReplaceObjectContents(Context,
  1411. ObjectToReplace,
  1412. FieldReadResult);
  1413. AcpipObjectReleaseReference(FieldReadResult);
  1414. break;
  1415. case AcpiObjectThermalZone:
  1416. case AcpiObjectDebug:
  1417. break;
  1418. case AcpiObjectAlias:
  1419. RtlCopyMemory(&(ObjectToReplace->U.Alias),
  1420. &(ObjectWithContents->U.Alias),
  1421. sizeof(ACPI_ALIAS_OBJECT));
  1422. if (ObjectToReplace->U.Alias.DestinationObject != NULL) {
  1423. AcpipObjectAddReference(
  1424. ObjectToReplace->U.Alias.DestinationObject);
  1425. }
  1426. break;
  1427. case AcpiObjectDevice:
  1428. case AcpiObjectEvent:
  1429. case AcpiObjectMethod:
  1430. case AcpiObjectMutex:
  1431. case AcpiObjectOperationRegion:
  1432. default:
  1433. ASSERT(FALSE);
  1434. Status = STATUS_NOT_SUPPORTED;
  1435. break;
  1436. }
  1437. return Status;
  1438. }
  1439. PACPI_OBJECT
  1440. AcpipGetPackageObject (
  1441. PACPI_OBJECT Package,
  1442. ULONG Index,
  1443. BOOL ConvertConstants
  1444. )
  1445. /*++
  1446. Routine Description:
  1447. This routine returns the object at a given index in a package.
  1448. Arguments:
  1449. Package - Supplies a pointer to the package to read from.
  1450. Index - Supplies the index of the element to get.
  1451. ConvertConstants - Supplies a boolean indicating whether or not constant
  1452. integers should be converted to non-constant integers before being
  1453. returned.
  1454. Return Value:
  1455. Returns a pointer to the element in the package at the given index.
  1456. NULL on error, either if too large of an index was specified, or there is
  1457. no value at that index.
  1458. --*/
  1459. {
  1460. PACPI_OBJECT *Array;
  1461. PVOID Buffer;
  1462. PACPI_OBJECT NewObject;
  1463. PACPI_OBJECT ResolvedName;
  1464. ASSERT(Package->Type == AcpiObjectPackage);
  1465. Array = (PACPI_OBJECT *)Package->U.Package.Array;
  1466. if ((Array == NULL) || (Index >= Package->U.Package.ElementCount)) {
  1467. return NULL;
  1468. }
  1469. if (Array[Index] == NULL) {
  1470. Array[Index] = AcpipCreateNamespaceObject(NULL,
  1471. AcpiObjectUninitialized,
  1472. NULL,
  1473. NULL,
  1474. 0);
  1475. //
  1476. // If the object is an unresolved name, attempt to resolve that name now.
  1477. //
  1478. } else if (Array[Index]->Type == AcpiObjectUnresolvedName) {
  1479. ResolvedName = AcpipGetNamespaceObject(
  1480. Array[Index]->U.UnresolvedName.Name,
  1481. Array[Index]->U.UnresolvedName.Scope);
  1482. //
  1483. // The name should really resolve. If it doesn't, this is a serious
  1484. // BIOS error.
  1485. //
  1486. ASSERT(ResolvedName != NULL);
  1487. //
  1488. // If the name resolves, replaced the unresolved reference with a
  1489. // resolved reference.
  1490. //
  1491. if (ResolvedName != NULL) {
  1492. AcpipSetPackageObject(Package, Index, ResolvedName);
  1493. }
  1494. return ResolvedName;
  1495. //
  1496. // If constant conversion is requested, convert Zero, One, and Ones into
  1497. // private integers and set it in the package.
  1498. //
  1499. } else if ((ConvertConstants != FALSE) &&
  1500. (Array[Index]->Type == AcpiObjectInteger)) {
  1501. if (IS_ACPI_CONSTANT(Array[Index]) != FALSE) {
  1502. Buffer = &(Array[Index]->U.Integer.Value),
  1503. NewObject = AcpipCreateNamespaceObject(NULL,
  1504. AcpiObjectInteger,
  1505. NULL,
  1506. Buffer,
  1507. sizeof(ULONGLONG));
  1508. if (NewObject == NULL) {
  1509. return NULL;
  1510. }
  1511. AcpipSetPackageObject(Package, Index, NewObject);
  1512. AcpipObjectReleaseReference(NewObject);
  1513. }
  1514. }
  1515. return Array[Index];
  1516. }
  1517. VOID
  1518. AcpipSetPackageObject (
  1519. PACPI_OBJECT Package,
  1520. ULONG Index,
  1521. PACPI_OBJECT Object
  1522. )
  1523. /*++
  1524. Routine Description:
  1525. This routine sets the object in a package at a given index.
  1526. Arguments:
  1527. Package - Supplies a pointer to the package to modify.
  1528. Index - Supplies the index of the element to set.
  1529. Object - Supplies the object to set at Package[Index]. This can be NULL.
  1530. Return Value:
  1531. None.
  1532. --*/
  1533. {
  1534. PACPI_OBJECT *Array;
  1535. ASSERT(Package->Type == AcpiObjectPackage);
  1536. Array = (PACPI_OBJECT *)Package->U.Package.Array;
  1537. if ((Array == NULL) || (Index >= Package->U.Package.ElementCount)) {
  1538. return;
  1539. }
  1540. //
  1541. // Decrement the reference count on the object that was there before.
  1542. //
  1543. if (Array[Index] != NULL) {
  1544. AcpipObjectReleaseReference(Array[Index]);
  1545. }
  1546. //
  1547. // Increment the reference count on the new object.
  1548. //
  1549. if (Object != NULL) {
  1550. AcpipObjectAddReference(Object);
  1551. }
  1552. Array[Index] = Object;
  1553. return;
  1554. }
  1555. //
  1556. // --------------------------------------------------------- Internal Functions
  1557. //
  1558. VOID
  1559. AcpipDestroyNamespaceObject (
  1560. PACPI_OBJECT Object
  1561. )
  1562. /*++
  1563. Routine Description:
  1564. This routine destroys an ACPI namespace object (and all of its child
  1565. object).
  1566. Arguments:
  1567. Object - Supplies a pointer to the object to destroy. It is expected that
  1568. this object is already properly unlinked from any namespace.
  1569. Return Value:
  1570. None.
  1571. --*/
  1572. {
  1573. PLIST_ENTRY ChildEntry;
  1574. PLIST_ENTRY DestructorEntry;
  1575. LIST_ENTRY DestructorStackHead;
  1576. ULONG PackageIndex;
  1577. PACPI_OBJECT PackageObject;
  1578. //
  1579. // If the object's sibling list entry is not null, then unlink it from the
  1580. // parent.
  1581. //
  1582. if (Object->SiblingListEntry.Next != NULL) {
  1583. LIST_REMOVE(&(Object->SiblingListEntry));
  1584. }
  1585. if (Object->DestructorListEntry.Next != NULL) {
  1586. LIST_REMOVE(&(Object->DestructorListEntry));
  1587. }
  1588. //
  1589. // Start by pushing the object on top of the stack.
  1590. //
  1591. INITIALIZE_LIST_HEAD(&DestructorStackHead);
  1592. INSERT_AFTER(&(Object->DestructorListEntry), &DestructorStackHead);
  1593. while (LIST_EMPTY(&DestructorStackHead) == FALSE) {
  1594. //
  1595. // Take a look at the value on top of the stack. If it has any children,
  1596. // remove the child from the child list, push it onto the destructor
  1597. // stack, and start over.
  1598. //
  1599. DestructorEntry = DestructorStackHead.Next;
  1600. Object = LIST_VALUE(DestructorEntry, ACPI_OBJECT, DestructorListEntry);
  1601. if (LIST_EMPTY(&(Object->ChildListHead)) == FALSE) {
  1602. ChildEntry = Object->ChildListHead.Next;
  1603. LIST_REMOVE(ChildEntry);
  1604. Object = LIST_VALUE(ChildEntry, ACPI_OBJECT, SiblingListEntry);
  1605. ASSERT(Object->DestructorListEntry.Next != NULL);
  1606. LIST_REMOVE(&(Object->DestructorListEntry));
  1607. INSERT_AFTER(&(Object->DestructorListEntry), &DestructorStackHead);
  1608. continue;
  1609. }
  1610. //
  1611. // The child list is empty, this is a leaf node. Pull it off the
  1612. // destructor stack and destroy it.
  1613. //
  1614. LIST_REMOVE(DestructorEntry);
  1615. switch (Object->Type) {
  1616. case AcpiObjectString:
  1617. if (Object->U.String.String != NULL) {
  1618. AcpipFreeMemory(Object->U.String.String);
  1619. }
  1620. break;
  1621. case AcpiObjectBuffer:
  1622. if (Object->U.Buffer.Buffer != NULL) {
  1623. AcpipFreeMemory(Object->U.Buffer.Buffer);
  1624. }
  1625. break;
  1626. case AcpiObjectPackage:
  1627. if (Object->U.Package.Array != NULL) {
  1628. for (PackageIndex = 0;
  1629. PackageIndex < Object->U.Package.ElementCount;
  1630. PackageIndex += 1) {
  1631. PackageObject = Object->U.Package.Array[PackageIndex];
  1632. if (PackageObject != NULL) {
  1633. AcpipObjectReleaseReference(PackageObject);
  1634. }
  1635. }
  1636. }
  1637. break;
  1638. case AcpiObjectFieldUnit:
  1639. if (Object->U.FieldUnit.BankRegister != NULL) {
  1640. AcpipObjectReleaseReference(Object->U.FieldUnit.BankRegister);
  1641. ASSERT(Object->U.FieldUnit.BankValue != NULL);
  1642. AcpipObjectReleaseReference(Object->U.FieldUnit.BankValue);
  1643. }
  1644. if (Object->U.FieldUnit.IndexRegister != NULL) {
  1645. AcpipObjectReleaseReference(Object->U.FieldUnit.IndexRegister);
  1646. ASSERT(Object->U.FieldUnit.DataRegister != NULL);
  1647. AcpipObjectReleaseReference(Object->U.FieldUnit.DataRegister);
  1648. }
  1649. if (Object->U.FieldUnit.OperationRegion != NULL) {
  1650. AcpipObjectReleaseReference(
  1651. Object->U.FieldUnit.OperationRegion);
  1652. }
  1653. break;
  1654. case AcpiObjectEvent:
  1655. if (Object->U.Event.OsEvent != NULL) {
  1656. AcpipDestroyEvent(Object->U.Event.OsEvent);
  1657. }
  1658. break;
  1659. case AcpiObjectMethod:
  1660. if (Object->U.Method.OsMutex != NULL) {
  1661. AcpipDestroyMutex(Object->U.Method.OsMutex);
  1662. Object->U.Method.OsMutex = NULL;
  1663. }
  1664. break;
  1665. case AcpiObjectMutex:
  1666. if (Object->U.Mutex.OsMutex != NULL) {
  1667. AcpipDestroyMutex(Object->U.Mutex.OsMutex);
  1668. }
  1669. break;
  1670. case AcpiObjectOperationRegion:
  1671. AcpipDestroyOperationRegion(Object);
  1672. break;
  1673. case AcpiObjectBufferField:
  1674. if (Object->U.BufferField.DestinationObject != NULL) {
  1675. AcpipObjectReleaseReference(
  1676. Object->U.BufferField.DestinationObject);
  1677. }
  1678. break;
  1679. case AcpiObjectInteger:
  1680. ASSERT(IS_ACPI_CONSTANT(Object) == FALSE);
  1681. break;
  1682. case AcpiObjectUninitialized:
  1683. case AcpiObjectDevice:
  1684. case AcpiObjectPowerResource:
  1685. case AcpiObjectProcessor:
  1686. case AcpiObjectThermalZone:
  1687. case AcpiObjectDebug:
  1688. break;
  1689. case AcpiObjectAlias:
  1690. if (Object->U.Alias.DestinationObject != NULL) {
  1691. AcpipObjectReleaseReference(Object->U.Alias.DestinationObject);
  1692. }
  1693. break;
  1694. case AcpiObjectUnresolvedName:
  1695. AcpipFreeMemory(Object->U.UnresolvedName.Name);
  1696. AcpipObjectReleaseReference(Object->U.UnresolvedName.Scope);
  1697. break;
  1698. default:
  1699. ASSERT(FALSE);
  1700. break;
  1701. }
  1702. Object->Type = AcpiObjectUninitialized;
  1703. AcpipFreeMemory(Object);
  1704. }
  1705. return;
  1706. }
  1707. PACPI_OBJECT
  1708. AcpipGetPartialNamespaceObject (
  1709. PSTR Name,
  1710. ULONG Length,
  1711. PACPI_OBJECT CurrentScope
  1712. )
  1713. /*++
  1714. Routine Description:
  1715. This routine looks up an ACPI object in the namespace based on a location
  1716. string.
  1717. Arguments:
  1718. Name - Supplies a pointer to a string containing the namespace path.
  1719. Length - Supplies the maximum number of bytes of the string to parse.
  1720. Supply 0 to parse the entire string.
  1721. CurrentScope - Supplies a pointer to the current namespace scope. If NULL
  1722. is supplied, the global root namespace will be used.
  1723. Return Value:
  1724. Returns a pointer to the ACPI object on success.
  1725. NULL if the object could not be found.
  1726. --*/
  1727. {
  1728. PACPI_OBJECT Child;
  1729. PLIST_ENTRY CurrentEntry;
  1730. ULONG DesiredName;
  1731. BOOL SearchUp;
  1732. SearchUp = TRUE;
  1733. //
  1734. // Zero means parse the whole string, so just set the length to a really
  1735. // big value.
  1736. //
  1737. if (Length == 0) {
  1738. Length = 0xFFFFFFFF;
  1739. }
  1740. if (CurrentScope == NULL) {
  1741. CurrentScope = AcpiNamespaceRoot;
  1742. }
  1743. if (Name[0] == ACPI_NAMESPACE_ROOT_CHARACTER) {
  1744. SearchUp = FALSE;
  1745. CurrentScope = AcpiNamespaceRoot;
  1746. Name += 1;
  1747. Length -= 1;
  1748. } else {
  1749. while ((Name[0] == ACPI_NAMESPACE_PARENT_CHARACTER) && (Length != 0)) {
  1750. SearchUp = FALSE;
  1751. CurrentScope = CurrentScope->Parent;
  1752. if (CurrentScope->Parent == NULL) {
  1753. return NULL;
  1754. }
  1755. Name += 1;
  1756. Length -= 1;
  1757. }
  1758. }
  1759. //
  1760. // Loop traversing into names until there are no more.
  1761. //
  1762. while ((Name[0] != '\0') && (Length != 0)) {
  1763. if ((Name[1] == '\0') || (Name[2] == '\0') || (Name[3] == '\0') ||
  1764. (Length < 4)) {
  1765. ASSERT(FALSE);
  1766. return NULL;
  1767. }
  1768. DesiredName = READ_UNALIGNED32(Name);
  1769. //
  1770. // Loop through all children of the current scope looking for the
  1771. // desired child.
  1772. //
  1773. CurrentEntry = CurrentScope->ChildListHead.Next;
  1774. Child = NULL;
  1775. while (CurrentEntry != &(CurrentScope->ChildListHead)) {
  1776. Child = LIST_VALUE(CurrentEntry, ACPI_OBJECT, SiblingListEntry);
  1777. //
  1778. // Stop if the name was found. Also, since a name was found, don't
  1779. // search up the tree anymore.
  1780. //
  1781. if (Child->Name == DesiredName) {
  1782. SearchUp = FALSE;
  1783. break;
  1784. }
  1785. CurrentEntry = CurrentEntry->Next;
  1786. }
  1787. //
  1788. // If the entry wasn't found, relative pathnames are in use, and no part
  1789. // of the name has been found so far, go up the tree towards the root
  1790. // as defined by the ACPI namespace search rules for relative names.
  1791. //
  1792. if (CurrentEntry == &(CurrentScope->ChildListHead)) {
  1793. if ((SearchUp == FALSE) || (CurrentScope == AcpiNamespaceRoot)) {
  1794. return NULL;
  1795. }
  1796. CurrentScope = CurrentScope->Parent;
  1797. ASSERT(CurrentScope != NULL);
  1798. continue;
  1799. }
  1800. CurrentScope = Child;
  1801. Name += ACPI_MAX_NAME_LENGTH;
  1802. Length -= ACPI_MAX_NAME_LENGTH;
  1803. }
  1804. return CurrentScope;
  1805. }
  1806. KSTATUS
  1807. AcpipPullOffLastName (
  1808. PSTR Name,
  1809. PULONG LastName,
  1810. PULONG LastNameOffset
  1811. )
  1812. /*++
  1813. Routine Description:
  1814. This routine pulls the innermost name off of the given name string. It also
  1815. validates that the last part is actually a name.
  1816. Arguments:
  1817. Name - Supplies a pointer to a string containing the namespace path.
  1818. LastName - Supplies a pointer where the last name in the path will be
  1819. returned.
  1820. LastNameOffset - Supplies a pointer where the offset, in bytes, of the last
  1821. name in the string will be returned.
  1822. Return Value:
  1823. STATUS_SUCCESS on success.
  1824. STATUS_INVALID_PARAMETER on failure.
  1825. --*/
  1826. {
  1827. UCHAR Character;
  1828. ULONG Length;
  1829. ULONG NameIndex;
  1830. Length = RtlStringLength(Name);
  1831. if (Length < ACPI_MAX_NAME_LENGTH) {
  1832. return STATUS_INVALID_PARAMETER;
  1833. }
  1834. for (NameIndex = 0; NameIndex < ACPI_MAX_NAME_LENGTH; NameIndex += 1) {
  1835. Character = Name[Length - 1 - NameIndex];
  1836. if ((Character == ACPI_NAMESPACE_ROOT_CHARACTER) ||
  1837. (Character == ACPI_NAMESPACE_PARENT_CHARACTER)) {
  1838. return STATUS_INVALID_PARAMETER;
  1839. }
  1840. }
  1841. RtlCopyMemory(LastName,
  1842. &(Name[Length - ACPI_MAX_NAME_LENGTH]),
  1843. ACPI_MAX_NAME_LENGTH);
  1844. *LastNameOffset = Length - ACPI_MAX_NAME_LENGTH;
  1845. return STATUS_SUCCESS;
  1846. }
  1847. VOID
  1848. AcpipDebugOutputObject (
  1849. PACPI_OBJECT Object
  1850. )
  1851. /*++
  1852. Routine Description:
  1853. This routine prints an ACPI object to the debugger.
  1854. Arguments:
  1855. Object - Supplies a pointer to the object to print.
  1856. Return Value:
  1857. None.
  1858. --*/
  1859. {
  1860. PUCHAR Buffer;
  1861. ULONG BufferLength;
  1862. ULONG ByteIndex;
  1863. PSTR Name;
  1864. ULONG PackageIndex;
  1865. PACPI_OBJECT PackageObject;
  1866. Name = (PSTR)&(Object->Name);
  1867. RtlDebugPrint("AML: ");
  1868. switch (Object->Type) {
  1869. case AcpiObjectInteger:
  1870. RtlDebugPrint("%I64x", Object->U.Integer.Value);
  1871. break;
  1872. case AcpiObjectString:
  1873. RtlDebugPrint("\"%s\"", Object->U.String.String);
  1874. break;
  1875. case AcpiObjectBuffer:
  1876. Buffer = Object->U.Buffer.Buffer;
  1877. BufferLength = Object->U.Buffer.Length;
  1878. RtlDebugPrint("{");
  1879. if ((Buffer != NULL) && (BufferLength != 0)) {
  1880. for (ByteIndex = 0; ByteIndex < BufferLength - 1; ByteIndex += 1) {
  1881. RtlDebugPrint("%02x ", Buffer[ByteIndex]);
  1882. }
  1883. RtlDebugPrint("%02x}", Buffer[BufferLength - 1]);
  1884. }
  1885. break;
  1886. case AcpiObjectPackage:
  1887. RtlDebugPrint("Package (%d) {", Object->U.Package.ElementCount);
  1888. if (Object->U.Package.Array != NULL) {
  1889. for (PackageIndex = 0;
  1890. PackageIndex < Object->U.Package.ElementCount;
  1891. PackageIndex += 1) {
  1892. PackageObject = Object->U.Package.Array[PackageIndex];
  1893. if (PackageObject != NULL) {
  1894. AcpipDebugOutputObject(PackageObject);
  1895. }
  1896. }
  1897. }
  1898. RtlDebugPrint("}");
  1899. break;
  1900. case AcpiObjectFieldUnit:
  1901. AcpipPrintFieldUnit(Object);
  1902. break;
  1903. case AcpiObjectDevice:
  1904. RtlDebugPrint("Device (%c%c%c%c)", Name[0], Name[1], Name[2], Name[3]);
  1905. break;
  1906. case AcpiObjectEvent:
  1907. RtlDebugPrint("Event (%c%c%c%c)",
  1908. Name[0],
  1909. Name[1],
  1910. Name[2],
  1911. Name[3]);
  1912. break;
  1913. case AcpiObjectMethod:
  1914. RtlDebugPrint("Method (%c%c%c%c)",
  1915. Name[0],
  1916. Name[1],
  1917. Name[2],
  1918. Name[3]);
  1919. break;
  1920. case AcpiObjectMutex:
  1921. RtlDebugPrint("Mutex (%c%c%c%c)",
  1922. Name[0],
  1923. Name[1],
  1924. Name[2],
  1925. Name[3]);
  1926. break;
  1927. case AcpiObjectOperationRegion:
  1928. AcpipPrintOperationRegion(Object);
  1929. break;
  1930. case AcpiObjectPowerResource:
  1931. RtlDebugPrint("PowerResource (%c%c%c%c, %d, %d)",
  1932. Name[0],
  1933. Name[1],
  1934. Name[2],
  1935. Name[3],
  1936. Object->U.PowerResource.SystemLevel,
  1937. Object->U.PowerResource.ResourceOrder);
  1938. break;
  1939. case AcpiObjectProcessor:
  1940. RtlDebugPrint("Processor (%c%c%c%c, %d, %d, %d)",
  1941. Name[0],
  1942. Name[1],
  1943. Name[2],
  1944. Name[3],
  1945. Object->U.Processor.ProcessorId,
  1946. Object->U.Processor.ProcessorBlockAddress,
  1947. Object->U.Processor.ProcessorBlockLength);
  1948. break;
  1949. case AcpiObjectThermalZone:
  1950. RtlDebugPrint("ThermalZone (%c%c%c%c)",
  1951. Name[0],
  1952. Name[1],
  1953. Name[2],
  1954. Name[3]);
  1955. break;
  1956. case AcpiObjectBufferField:
  1957. AcpipPrintBufferField(Object);
  1958. break;
  1959. case AcpiObjectDebug:
  1960. RtlDebugPrint("Debug object itself!");
  1961. break;
  1962. case AcpiObjectAlias:
  1963. RtlDebugPrint("Alias (%c%c%c%c) to (",
  1964. Name[0],
  1965. Name[1],
  1966. Name[2],
  1967. Name[3]);
  1968. AcpipDebugOutputObject(Object->U.Alias.DestinationObject);
  1969. RtlDebugPrint(")");
  1970. break;
  1971. default:
  1972. ASSERT(FALSE);
  1973. RtlDebugPrint("Unknown object of type %d\n", Object->Type);
  1974. }
  1975. RtlDebugPrint("\n");
  1976. return;
  1977. }