namespce.c 69 KB

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