1
0

resdesc.c 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061
  1. /*++
  2. Copyright (c) 2015 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. resdesc.c
  9. Abstract:
  10. This module implements support functions for handling ACPI resource
  11. descriptors.
  12. Author:
  13. Evan Green 4-Aug-2015
  14. Environment:
  15. Kernel
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/driver.h>
  21. #include <minoca/intrface/acpi.h>
  22. #include "acpip.h"
  23. #include "namespce.h"
  24. #include "resdesc.h"
  25. //
  26. // --------------------------------------------------------------------- Macros
  27. //
  28. #define ASSERT_SPB_UART_CONTROL_LINES_EQUIVALENT() \
  29. ASSERT((ACPI_SPB_UART_CONTROL_DTD == RESOURCE_SPB_UART_CONTROL_DTD) && \
  30. (ACPI_SPB_UART_CONTROL_RI == RESOURCE_SPB_UART_CONTROL_RI) && \
  31. (ACPI_SPB_UART_CONTROL_DSR == RESOURCE_SPB_UART_CONTROL_DSR) && \
  32. (ACPI_SPB_UART_CONTROL_DTR == RESOURCE_SPB_UART_CONTROL_DTR) && \
  33. (ACPI_SPB_UART_CONTROL_CTS == RESOURCE_SPB_UART_CONTROL_CTS) && \
  34. (ACPI_SPB_UART_CONTROL_RTS == RESOURCE_SPB_UART_CONTROL_RTS))
  35. //
  36. // ---------------------------------------------------------------- Definitions
  37. //
  38. //
  39. // ------------------------------------------------------ Data Type Definitions
  40. //
  41. //
  42. // ----------------------------------------------- Internal Function Prototypes
  43. //
  44. KSTATUS
  45. AcpipConvertFromGenericAddressDescriptor (
  46. PVOID GenericAddressBuffer,
  47. ULONG BufferLength,
  48. ULONG TypeSize,
  49. BOOL Extended,
  50. PRESOURCE_REQUIREMENT_LIST RequirementList
  51. );
  52. KSTATUS
  53. AcpipParseSmallDmaDescriptor (
  54. PVOID Buffer,
  55. ULONG BufferLength,
  56. PRESOURCE_REQUIREMENT_LIST RequirementList
  57. );
  58. KSTATUS
  59. AcpipParseSmallFixedDmaDescriptor (
  60. PVOID Buffer,
  61. ULONG BufferLength,
  62. PRESOURCE_REQUIREMENT_LIST RequirementList
  63. );
  64. KSTATUS
  65. AcpipParseSmallIrqDescriptor (
  66. PVOID Buffer,
  67. ULONG BufferLength,
  68. PRESOURCE_REQUIREMENT_LIST RequirementList
  69. );
  70. KSTATUS
  71. AcpipParseLargeIrqDescriptor (
  72. PVOID Buffer,
  73. ULONG BufferLength,
  74. PRESOURCE_REQUIREMENT_LIST RequirementList
  75. );
  76. KSTATUS
  77. AcpipParseGpioDescriptor (
  78. PACPI_OBJECT NamespaceStart,
  79. PVOID Buffer,
  80. ULONG BufferLength,
  81. PRESOURCE_REQUIREMENT_LIST RequirementList
  82. );
  83. KSTATUS
  84. AcpipParseSpbDescriptor (
  85. PACPI_OBJECT NamespaceStart,
  86. PVOID Buffer,
  87. ULONG BufferLength,
  88. PRESOURCE_REQUIREMENT_LIST RequirementList
  89. );
  90. KSTATUS
  91. AcpipParseSpbI2cDescriptor (
  92. USHORT TypeSpecificFlags,
  93. UCHAR TypeSpecificRevisionId,
  94. USHORT TypeDataLength,
  95. PUCHAR Buffer,
  96. PRESOURCE_REQUIREMENT Requirement,
  97. PRESOURCE_SPB_I2C Descriptor
  98. );
  99. KSTATUS
  100. AcpipParseSpbSpiDescriptor (
  101. USHORT TypeSpecificFlags,
  102. UCHAR TypeSpecificRevisionId,
  103. USHORT TypeDataLength,
  104. PUCHAR Buffer,
  105. PRESOURCE_REQUIREMENT Requirement,
  106. PRESOURCE_SPB_SPI Descriptor
  107. );
  108. KSTATUS
  109. AcpipParseSpbUartDescriptor (
  110. USHORT TypeSpecificFlags,
  111. UCHAR TypeSpecificRevisionId,
  112. USHORT TypeDataLength,
  113. PUCHAR Buffer,
  114. PRESOURCE_SPB_UART Descriptor
  115. );
  116. KSTATUS
  117. AcpipParseLargeVendorDescriptor (
  118. PVOID Buffer,
  119. ULONG BufferLength,
  120. PRESOURCE_REQUIREMENT_LIST RequirementList
  121. );
  122. //
  123. // -------------------------------------------------------------------- Globals
  124. //
  125. //
  126. // ------------------------------------------------------------------ Functions
  127. //
  128. KSTATUS
  129. AcpipParseGenericAddress (
  130. PACPI_OBJECT ResourceBuffer,
  131. PGENERIC_ADDRESS GenericAddress
  132. )
  133. /*++
  134. Routine Description:
  135. This routine reads a single generic address from the given resource buffer.
  136. Arguments:
  137. ResourceBuffer - Supplies a pointer to the ACPI resource buffer to parse.
  138. GenericAddress - Supplies a pointer where the extracted generic address
  139. will be returned.
  140. Return Value:
  141. Status code.
  142. --*/
  143. {
  144. PUCHAR Buffer;
  145. UCHAR Byte;
  146. USHORT DescriptorLength;
  147. ULONGLONG RemainingSize;
  148. KSTATUS Status;
  149. if ((ResourceBuffer == NULL) ||
  150. (ResourceBuffer->Type != AcpiObjectBuffer)) {
  151. Status = STATUS_INVALID_PARAMETER;
  152. goto ReadGenericAddressEnd;
  153. }
  154. Buffer = ResourceBuffer->U.Buffer.Buffer;
  155. RemainingSize = ResourceBuffer->U.Buffer.Length;
  156. Byte = *Buffer;
  157. RemainingSize -= 1;
  158. Buffer += 1;
  159. if ((Byte & RESOURCE_DESCRIPTOR_LARGE) == 0) {
  160. Status = STATUS_MALFORMED_DATA_STREAM;
  161. goto ReadGenericAddressEnd;
  162. }
  163. if (RemainingSize < 2) {
  164. Status = STATUS_MALFORMED_DATA_STREAM;
  165. goto ReadGenericAddressEnd;
  166. }
  167. DescriptorLength = *((PUSHORT)Buffer);
  168. Buffer += 2;
  169. RemainingSize -= 2;
  170. switch (Byte & LARGE_RESOURCE_TYPE_MASK) {
  171. case LARGE_RESOURCE_TYPE_GENERIC_REGISTER:
  172. if (DescriptorLength < sizeof(GENERIC_ADDRESS)) {
  173. Status = STATUS_MALFORMED_DATA_STREAM;
  174. goto ReadGenericAddressEnd;
  175. }
  176. RtlCopyMemory(GenericAddress, Buffer, sizeof(GENERIC_ADDRESS));
  177. break;
  178. default:
  179. Status = STATUS_MALFORMED_DATA_STREAM;
  180. goto ReadGenericAddressEnd;
  181. }
  182. Status = STATUS_SUCCESS;
  183. ReadGenericAddressEnd:
  184. return Status;
  185. }
  186. KSTATUS
  187. AcpipConvertFromAcpiResourceBuffer (
  188. PACPI_OBJECT Device,
  189. PACPI_OBJECT ResourceBuffer,
  190. PRESOURCE_CONFIGURATION_LIST *ConfigurationListResult
  191. )
  192. /*++
  193. Routine Description:
  194. This routine converts an ACPI resource buffer into an OS configuration list.
  195. Arguments:
  196. Device - Supplies a pointer to the namespace object of the device this
  197. buffer is coming from. This is used for relative namespace traversal
  198. for certain types of resource descriptors (like GPIO).
  199. ResourceBuffer - Supplies a pointer to the ACPI resource list buffer to
  200. parse.
  201. ConfigurationListResult - Supplies a pointer where a newly allocated
  202. resource configuration list will be returned. It is the callers
  203. responsibility to manage this memory once it is returned.
  204. Return Value:
  205. Status code.
  206. --*/
  207. {
  208. ULONGLONG Alignment;
  209. PUCHAR Buffer;
  210. UCHAR Byte;
  211. UCHAR Checksum;
  212. PRESOURCE_CONFIGURATION_LIST ConfigurationList;
  213. PRESOURCE_REQUIREMENT_LIST CurrentConfiguration;
  214. USHORT DescriptorLength;
  215. ULONGLONG Length;
  216. ULONGLONG Maximum;
  217. ULONGLONG Minimum;
  218. ULONGLONG RemainingSize;
  219. RESOURCE_REQUIREMENT Requirement;
  220. RESOURCE_TYPE ResourceType;
  221. KSTATUS Status;
  222. PUCHAR TemplateStart;
  223. BOOL Writeable;
  224. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  225. ConfigurationList = NULL;
  226. CurrentConfiguration = NULL;
  227. if ((ResourceBuffer == NULL) ||
  228. (ResourceBuffer->Type != AcpiObjectBuffer)) {
  229. Status = STATUS_INVALID_PARAMETER;
  230. goto ConvertFromAcpiResourceBufferEnd;
  231. }
  232. //
  233. // Create an initial configuration list and configuration.
  234. //
  235. ConfigurationList = IoCreateResourceConfigurationList(NULL);
  236. if (ConfigurationList == NULL) {
  237. Status = STATUS_INVALID_PARAMETER;
  238. goto ConvertFromAcpiResourceBufferEnd;
  239. }
  240. CurrentConfiguration = IoCreateResourceRequirementList();
  241. if (CurrentConfiguration == NULL) {
  242. Status = STATUS_INVALID_PARAMETER;
  243. goto ConvertFromAcpiResourceBufferEnd;
  244. }
  245. //
  246. // Loop parsing the buffer.
  247. //
  248. Buffer = ResourceBuffer->U.Buffer.Buffer;
  249. RemainingSize = ResourceBuffer->U.Buffer.Length;
  250. TemplateStart = Buffer;
  251. while (RemainingSize != 0) {
  252. //
  253. // Investigate small resource types.
  254. //
  255. Byte = *Buffer;
  256. RemainingSize -= 1;
  257. Buffer += 1;
  258. if ((Byte & RESOURCE_DESCRIPTOR_LARGE) == 0) {
  259. DescriptorLength = Byte & RESOURCE_DESCRIPTOR_LENGTH_MASK;
  260. if (RemainingSize < DescriptorLength) {
  261. Status = STATUS_MALFORMED_DATA_STREAM;
  262. goto ConvertFromAcpiResourceBufferEnd;
  263. }
  264. switch (Byte & SMALL_RESOURCE_TYPE_MASK) {
  265. case SMALL_RESOURCE_TYPE_IRQ:
  266. Status = AcpipParseSmallIrqDescriptor(Buffer,
  267. DescriptorLength,
  268. CurrentConfiguration);
  269. if (!KSUCCESS(Status)) {
  270. goto ConvertFromAcpiResourceBufferEnd;
  271. }
  272. break;
  273. case SMALL_RESOURCE_TYPE_DMA:
  274. Status = AcpipParseSmallDmaDescriptor(Buffer,
  275. DescriptorLength,
  276. CurrentConfiguration);
  277. if (!KSUCCESS(Status)) {
  278. goto ConvertFromAcpiResourceBufferEnd;
  279. }
  280. break;
  281. case SMALL_RESOURCE_TYPE_START_DEPENDENT_FUNCTIONS:
  282. if (DescriptorLength == 1) {
  283. RtlDebugPrint("Start Dependent Function: %x\n", *Buffer);
  284. } else {
  285. RtlDebugPrint("Start Dependent Function\n");
  286. }
  287. ASSERT(FALSE);
  288. break;
  289. case SMALL_RESOURCE_TYPE_END_DEPENDENT_FUNCTIONS:
  290. RtlDebugPrint("End Dependent Function\n");
  291. ASSERT(FALSE);
  292. break;
  293. case SMALL_RESOURCE_TYPE_IO_PORT:
  294. if (DescriptorLength < 7) {
  295. Status = STATUS_MALFORMED_DATA_STREAM;
  296. goto ConvertFromAcpiResourceBufferEnd;
  297. }
  298. Requirement.Type = ResourceTypeIoPort;
  299. Requirement.Minimum = *((PUSHORT)(Buffer + 1));
  300. Requirement.Maximum = *((PUSHORT)(Buffer + 3)) + 1;
  301. Requirement.Alignment = *((PUCHAR)(Buffer + 5));
  302. Requirement.Length = *((PUCHAR)(Buffer + 6));
  303. if (Requirement.Maximum <
  304. Requirement.Minimum + Requirement.Length) {
  305. Requirement.Maximum = Requirement.Minimum +
  306. Requirement.Length;
  307. }
  308. Requirement.Characteristics = 0;
  309. Requirement.Flags = 0;
  310. Status = IoCreateAndAddResourceRequirement(&Requirement,
  311. CurrentConfiguration,
  312. NULL);
  313. if (!KSUCCESS(Status)) {
  314. goto ConvertFromAcpiResourceBufferEnd;
  315. }
  316. break;
  317. case SMALL_RESOURCE_TYPE_FIXED_LOCATION_IO_PORT:
  318. if (DescriptorLength < 3) {
  319. Status = STATUS_MALFORMED_DATA_STREAM;
  320. goto ConvertFromAcpiResourceBufferEnd;
  321. }
  322. Requirement.Type = ResourceTypeIoPort;
  323. Requirement.Minimum = *((PUSHORT)Buffer);
  324. Requirement.Length = *(Buffer + 2);
  325. Requirement.Maximum = Requirement.Minimum + Requirement.Length;
  326. Requirement.Alignment = 1;
  327. Requirement.Characteristics = 0;
  328. Requirement.Flags = 0;
  329. Status = IoCreateAndAddResourceRequirement(&Requirement,
  330. CurrentConfiguration,
  331. NULL);
  332. if (!KSUCCESS(Status)) {
  333. goto ConvertFromAcpiResourceBufferEnd;
  334. }
  335. break;
  336. case SMALL_RESOURCE_TYPE_FIXED_DMA:
  337. Status = AcpipParseSmallFixedDmaDescriptor(
  338. Buffer,
  339. DescriptorLength,
  340. CurrentConfiguration);
  341. if (!KSUCCESS(Status)) {
  342. goto ConvertFromAcpiResourceBufferEnd;
  343. }
  344. break;
  345. case SMALL_RESOURCE_TYPE_VENDOR_DEFINED:
  346. RtlDebugPrint("Vendor Defined, Length %d\n", DescriptorLength);
  347. ASSERT(FALSE);
  348. break;
  349. case SMALL_RESOURCE_TYPE_END_TAG:
  350. if (DescriptorLength < 1) {
  351. Status = STATUS_MALFORMED_DATA_STREAM;
  352. goto ConvertFromAcpiResourceBufferEnd;
  353. }
  354. //
  355. // Checksum the template, but only if the checksum field is
  356. // non-zero.
  357. //
  358. if (*Buffer != 0) {
  359. Length = (UINTN)Buffer + 1 - (UINTN)TemplateStart;
  360. Checksum = AcpipChecksumData(TemplateStart, (ULONG)Length);
  361. if (Checksum != 0) {
  362. RtlDebugPrint("ACPI: Resource template checksum "
  363. "failed. Start of template %x, Length "
  364. "%I64x, Checksum %x, Expected 0.\n",
  365. TemplateStart,
  366. Length,
  367. Checksum);
  368. Status = STATUS_MALFORMED_DATA_STREAM;
  369. goto ConvertFromAcpiResourceBufferEnd;
  370. }
  371. }
  372. //
  373. // Add the current configuration to the configuration list.
  374. //
  375. Status = IoAddResourceConfiguration(CurrentConfiguration,
  376. NULL,
  377. ConfigurationList);
  378. if (!KSUCCESS(Status)) {
  379. goto ConvertFromAcpiResourceBufferEnd;
  380. }
  381. CurrentConfiguration = NULL;
  382. //
  383. // If the buffer is not done, create a new configuration.
  384. //
  385. if (RemainingSize > DescriptorLength) {
  386. CurrentConfiguration = IoCreateResourceRequirementList();
  387. if (CurrentConfiguration == NULL) {
  388. Status = STATUS_INSUFFICIENT_RESOURCES;
  389. goto ConvertFromAcpiResourceBufferEnd;
  390. }
  391. }
  392. break;
  393. default:
  394. RtlDebugPrint("ACPI: Error, found invalid resource descriptor "
  395. "type 0x%02x.\n",
  396. Byte & SMALL_RESOURCE_TYPE_MASK);
  397. Status = STATUS_MALFORMED_DATA_STREAM;
  398. goto ConvertFromAcpiResourceBufferEnd;
  399. }
  400. //
  401. // Parse a large descriptor.
  402. //
  403. } else {
  404. if (RemainingSize < 2) {
  405. Status = STATUS_MALFORMED_DATA_STREAM;
  406. goto ConvertFromAcpiResourceBufferEnd;
  407. }
  408. DescriptorLength = *((PUSHORT)Buffer);
  409. Buffer += 2;
  410. RemainingSize -= 2;
  411. switch (Byte & LARGE_RESOURCE_TYPE_MASK) {
  412. case LARGE_RESOURCE_TYPE_MEMORY24:
  413. if (DescriptorLength < 9) {
  414. Status = STATUS_MALFORMED_DATA_STREAM;
  415. goto ConvertFromAcpiResourceBufferEnd;
  416. }
  417. Writeable = FALSE;
  418. if ((*Buffer & ACPI_MEMORY_DESCRIPTOR_WRITEABLE) != 0) {
  419. Writeable = TRUE;
  420. }
  421. Minimum = *((PUSHORT)(Buffer + 1));
  422. Minimum = Minimum << 8;
  423. Maximum = *((PUSHORT)(Buffer + 3));
  424. Maximum = Maximum << 8;
  425. Alignment = *((PUSHORT)(Buffer + 5));
  426. Length = *((PUSHORT)(Buffer + 7));
  427. Length = Length << 8;
  428. RtlDebugPrint("Memory24: Min 0x%I64x, Max 0x%I64x, Alignment "
  429. "0x%I64x, Length 0x%I64x, Writeable: %d\n",
  430. Minimum,
  431. Maximum,
  432. Alignment,
  433. Length,
  434. Writeable);
  435. ASSERT(FALSE);
  436. break;
  437. case LARGE_RESOURCE_TYPE_GENERIC_REGISTER:
  438. if (DescriptorLength < 12) {
  439. Status = STATUS_MALFORMED_DATA_STREAM;
  440. goto ConvertFromAcpiResourceBufferEnd;
  441. }
  442. //
  443. // Get the resource type.
  444. //
  445. switch (*Buffer) {
  446. case AddressSpaceMemory:
  447. ResourceType = ResourceTypePhysicalAddressSpace;
  448. break;
  449. case AddressSpaceIo:
  450. ResourceType = ResourceTypeIoPort;
  451. break;
  452. case AddressSpacePciConfig:
  453. case AddressSpaceEmbeddedController:
  454. case AddressSpaceSmBus:
  455. case AddressSpaceFixedHardware:
  456. default:
  457. ResourceType = ResourceTypeVendorSpecific;
  458. break;
  459. }
  460. //
  461. // Get the access size.
  462. //
  463. if (*(Buffer + 4) == 0) {
  464. Alignment = 1;
  465. } else {
  466. Alignment = 1ULL << (*(Buffer + 4) - 1);
  467. }
  468. Length = (*(Buffer + 2) + *(Buffer + 3)) / BITS_PER_BYTE;
  469. if (Length < Alignment) {
  470. Length = Alignment;
  471. }
  472. Minimum = *((PULONGLONG)Buffer + 4);
  473. Maximum = Minimum + Length;
  474. RtlDebugPrint("Generic Register type %d, Minimum 0x%I64x, "
  475. "Length 0x%I64x, Alignment 0x%I64x.\n",
  476. ResourceType,
  477. Minimum,
  478. Length,
  479. Alignment);
  480. ASSERT(FALSE);
  481. break;
  482. case LARGE_RESOURCE_TYPE_VENDOR_DEFINED:
  483. Status = AcpipParseLargeVendorDescriptor(Buffer,
  484. DescriptorLength,
  485. CurrentConfiguration);
  486. if (!KSUCCESS(Status)) {
  487. goto ConvertFromAcpiResourceBufferEnd;
  488. }
  489. break;
  490. case LARGE_RESOURCE_TYPE_MEMORY32:
  491. if (DescriptorLength < 17) {
  492. Status = STATUS_MALFORMED_DATA_STREAM;
  493. goto ConvertFromAcpiResourceBufferEnd;
  494. }
  495. Writeable = FALSE;
  496. if ((*Buffer & ACPI_MEMORY_DESCRIPTOR_WRITEABLE) != 0) {
  497. Writeable = TRUE;
  498. }
  499. Requirement.Type = ResourceTypePhysicalAddressSpace;
  500. Requirement.Minimum = *((PULONG)(Buffer + 1));
  501. Requirement.Maximum = *((PULONG)(Buffer + 5)) + 1;
  502. Requirement.Alignment = *((PULONG)(Buffer + 9));
  503. Requirement.Length = *((PULONG)(Buffer + 13));
  504. if (Requirement.Maximum <
  505. Requirement.Minimum + Requirement.Length) {
  506. Requirement.Maximum = Requirement.Minimum +
  507. Requirement.Length;
  508. }
  509. Requirement.Characteristics = 0;
  510. Requirement.Flags = 0;
  511. Status = IoCreateAndAddResourceRequirement(&Requirement,
  512. CurrentConfiguration,
  513. NULL);
  514. if (!KSUCCESS(Status)) {
  515. goto ConvertFromAcpiResourceBufferEnd;
  516. }
  517. break;
  518. case LARGE_RESOURCE_TYPE_FIXED_MEMORY32:
  519. if (DescriptorLength < 9){
  520. Status = STATUS_MALFORMED_DATA_STREAM;
  521. goto ConvertFromAcpiResourceBufferEnd;
  522. }
  523. Writeable = FALSE;
  524. if ((*Buffer & ACPI_MEMORY_DESCRIPTOR_WRITEABLE) != 0) {
  525. Writeable = TRUE;
  526. }
  527. Requirement.Type = ResourceTypePhysicalAddressSpace;
  528. Requirement.Minimum = *((PULONG)(Buffer + 1));
  529. Requirement.Length = *((PULONG)(Buffer + 5));
  530. Requirement.Maximum = Requirement.Minimum + Requirement.Length;
  531. Requirement.Alignment = 1;
  532. Requirement.Characteristics = 0;
  533. Requirement.Flags = 0;
  534. Status = IoCreateAndAddResourceRequirement(&Requirement,
  535. CurrentConfiguration,
  536. NULL);
  537. if (!KSUCCESS(Status)) {
  538. goto ConvertFromAcpiResourceBufferEnd;
  539. }
  540. break;
  541. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE32:
  542. Status = AcpipConvertFromGenericAddressDescriptor(
  543. Buffer,
  544. DescriptorLength,
  545. sizeof(ULONG),
  546. FALSE,
  547. CurrentConfiguration);
  548. if (!KSUCCESS(Status)) {
  549. goto ConvertFromAcpiResourceBufferEnd;
  550. }
  551. break;
  552. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE16:
  553. Status = AcpipConvertFromGenericAddressDescriptor(
  554. Buffer,
  555. DescriptorLength,
  556. sizeof(USHORT),
  557. FALSE,
  558. CurrentConfiguration);
  559. if (!KSUCCESS(Status)) {
  560. goto ConvertFromAcpiResourceBufferEnd;
  561. }
  562. break;
  563. case LARGE_RESOURCE_TYPE_IRQ:
  564. Status = AcpipParseLargeIrqDescriptor(Buffer,
  565. DescriptorLength,
  566. CurrentConfiguration);
  567. if (!KSUCCESS(Status)) {
  568. goto ConvertFromAcpiResourceBufferEnd;
  569. }
  570. break;
  571. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE64:
  572. Status = AcpipConvertFromGenericAddressDescriptor(
  573. Buffer,
  574. DescriptorLength,
  575. sizeof(ULONGLONG),
  576. FALSE,
  577. CurrentConfiguration);
  578. if (!KSUCCESS(Status)) {
  579. goto ConvertFromAcpiResourceBufferEnd;
  580. }
  581. break;
  582. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE_EXTENDED:
  583. Status = AcpipConvertFromGenericAddressDescriptor(
  584. Buffer,
  585. DescriptorLength,
  586. sizeof(ULONGLONG),
  587. TRUE,
  588. CurrentConfiguration);
  589. if (!KSUCCESS(Status)) {
  590. goto ConvertFromAcpiResourceBufferEnd;
  591. }
  592. break;
  593. case LARGE_RESOURCE_TYPE_GPIO:
  594. Status = AcpipParseGpioDescriptor(Device,
  595. Buffer,
  596. DescriptorLength,
  597. CurrentConfiguration);
  598. if (!KSUCCESS(Status)) {
  599. goto ConvertFromAcpiResourceBufferEnd;
  600. }
  601. break;
  602. case LARGE_RESOURCE_TYPE_SPB:
  603. Status = AcpipParseSpbDescriptor(Device,
  604. Buffer,
  605. DescriptorLength,
  606. CurrentConfiguration);
  607. if (!KSUCCESS(Status)) {
  608. goto ConvertFromAcpiResourceBufferEnd;
  609. }
  610. break;
  611. default:
  612. RtlDebugPrint("ACPI: Error, found invalid resource descriptor "
  613. "type 0x%02x.\n",
  614. Byte & LARGE_RESOURCE_TYPE_MASK);
  615. Status = STATUS_MALFORMED_DATA_STREAM;
  616. goto ConvertFromAcpiResourceBufferEnd;
  617. }
  618. }
  619. //
  620. // Advance the buffer beyond this descriptor.
  621. //
  622. Buffer += DescriptorLength;
  623. RemainingSize -= DescriptorLength;
  624. }
  625. Status = STATUS_SUCCESS;
  626. ConvertFromAcpiResourceBufferEnd:
  627. if (CurrentConfiguration != NULL) {
  628. IoDestroyResourceRequirementList(CurrentConfiguration);
  629. }
  630. if (!KSUCCESS(Status)) {
  631. if (ConfigurationList != NULL) {
  632. IoDestroyResourceConfigurationList(ConfigurationList);
  633. ConfigurationList = NULL;
  634. }
  635. }
  636. *ConfigurationListResult = ConfigurationList;
  637. return Status;
  638. }
  639. KSTATUS
  640. AcpipConvertFromRequirementListToAllocationList (
  641. PRESOURCE_CONFIGURATION_LIST ConfigurationList,
  642. PRESOURCE_ALLOCATION_LIST *AllocationList
  643. )
  644. /*++
  645. Routine Description:
  646. This routine converts a resource requirement list into a resource allocation
  647. list. For every requirement, it will create an allocation from the
  648. requirement's minimum and length.
  649. Arguments:
  650. ConfigurationList - Supplies a pointer to the resource configuration list to
  651. convert. This routine assumes there is only one configuration on the
  652. list.
  653. AllocationList - Supplies a pointer where a pointer to a new resource
  654. allocation list will be returned on success. The caller is responsible
  655. for freeing this memory once it is returned.
  656. Return Value:
  657. Status code.
  658. --*/
  659. {
  660. RESOURCE_ALLOCATION Allocation;
  661. PRESOURCE_ALLOCATION_LIST NewAllocationList;
  662. PRESOURCE_REQUIREMENT Requirement;
  663. PRESOURCE_REQUIREMENT_LIST RequirementList;
  664. KSTATUS Status;
  665. //
  666. // Create a new allocation list.
  667. //
  668. NewAllocationList = IoCreateResourceAllocationList();
  669. if (NewAllocationList == NULL) {
  670. Status = STATUS_INSUFFICIENT_RESOURCES;
  671. goto ConvertFromRequirementListToAllocationListEnd;
  672. }
  673. //
  674. // Get the first configuration.
  675. //
  676. RequirementList = IoGetNextResourceConfiguration(ConfigurationList, NULL);
  677. if (RequirementList == NULL) {
  678. Status = STATUS_UNSUCCESSFUL;
  679. goto ConvertFromRequirementListToAllocationListEnd;
  680. }
  681. //
  682. // Loop through every requirement in the list, and construct a resource
  683. // allocation based off the requirement's minimum and length.
  684. //
  685. RtlZeroMemory(&Allocation, sizeof(RESOURCE_ALLOCATION));
  686. Requirement = IoGetNextResourceRequirement(RequirementList, NULL);
  687. while (Requirement != NULL) {
  688. Allocation.Type = Requirement->Type;
  689. Allocation.Allocation = Requirement->Minimum;
  690. Allocation.Length = Requirement->Length;
  691. Allocation.Characteristics = Requirement->Characteristics;
  692. Allocation.Flags = Requirement->Flags;
  693. Allocation.Data = Requirement->Data;
  694. Allocation.DataSize = Requirement->DataSize;
  695. Allocation.Provider = Requirement->Provider;
  696. ASSERT(Requirement->Minimum + Requirement->Length <=
  697. Requirement->Maximum);
  698. Status = IoCreateAndAddResourceAllocation(&Allocation,
  699. NewAllocationList);
  700. if (!KSUCCESS(Status)) {
  701. goto ConvertFromRequirementListToAllocationListEnd;
  702. }
  703. Requirement = IoGetNextResourceRequirement(RequirementList,
  704. Requirement);
  705. }
  706. Status = STATUS_SUCCESS;
  707. ConvertFromRequirementListToAllocationListEnd:
  708. if (!KSUCCESS(Status)) {
  709. if (NewAllocationList != NULL) {
  710. IoDestroyResourceAllocationList(NewAllocationList);
  711. NewAllocationList = NULL;
  712. }
  713. }
  714. *AllocationList = NewAllocationList;
  715. return Status;
  716. }
  717. KSTATUS
  718. AcpipConvertToAcpiResourceBuffer (
  719. PRESOURCE_ALLOCATION_LIST AllocationList,
  720. PACPI_OBJECT ResourceBuffer
  721. )
  722. /*++
  723. Routine Description:
  724. This routine converts an ACPI resource buffer into an OS configuration list.
  725. Arguments:
  726. AllocationList - Supplies a pointer to a resource allocation list to convert
  727. to a resource buffer.
  728. ResourceBuffer - Supplies a pointer to a resource buffer to tweak to fit
  729. the allocation list. The resource buffer comes from executing the _CRS
  730. method.
  731. Return Value:
  732. Status code.
  733. --*/
  734. {
  735. ULONGLONG Alignment;
  736. PRESOURCE_ALLOCATION Allocation;
  737. PUCHAR Buffer;
  738. UCHAR Byte;
  739. USHORT DescriptorLength;
  740. UCHAR Flags;
  741. ULONGLONG Length;
  742. ULONGLONG Maximum;
  743. ULONGLONG Minimum;
  744. ULONGLONG RemainingSize;
  745. RESOURCE_TYPE ResourceType;
  746. KSTATUS Status;
  747. BOOL StayOnCurrentAllocation;
  748. BOOL Writeable;
  749. if ((ResourceBuffer == NULL) ||
  750. (ResourceBuffer->Type != AcpiObjectBuffer)) {
  751. Status = STATUS_INVALID_PARAMETER;
  752. goto ConvertToAcpiResourceBufferEnd;
  753. }
  754. //
  755. // Loop parsing the buffer.
  756. //
  757. Buffer = ResourceBuffer->U.Buffer.Buffer;
  758. RemainingSize = ResourceBuffer->U.Buffer.Length;
  759. Allocation = NULL;
  760. StayOnCurrentAllocation = FALSE;
  761. while (RemainingSize != 0) {
  762. //
  763. // Get the next resource allocation.
  764. //
  765. if (StayOnCurrentAllocation == FALSE) {
  766. Allocation = IoGetNextResourceAllocation(AllocationList,
  767. Allocation);
  768. }
  769. StayOnCurrentAllocation = FALSE;
  770. //
  771. // Investigate small resource types.
  772. //
  773. Byte = *Buffer;
  774. RemainingSize -= 1;
  775. Buffer += 1;
  776. if ((Byte & RESOURCE_DESCRIPTOR_LARGE) == 0) {
  777. DescriptorLength = Byte & RESOURCE_DESCRIPTOR_LENGTH_MASK;
  778. if (RemainingSize < DescriptorLength) {
  779. Status = STATUS_MALFORMED_DATA_STREAM;
  780. goto ConvertToAcpiResourceBufferEnd;
  781. }
  782. switch (Byte & SMALL_RESOURCE_TYPE_MASK) {
  783. case SMALL_RESOURCE_TYPE_IRQ:
  784. ASSERT(DescriptorLength >= 2);
  785. if (Allocation->Type != ResourceTypeInterruptLine) {
  786. Status = STATUS_UNEXPECTED_TYPE;
  787. goto ConvertToAcpiResourceBufferEnd;
  788. }
  789. //
  790. // If multiple interrupt lines are selected, implement that
  791. // support.
  792. //
  793. ASSERT(Allocation->Length == 1);
  794. ASSERT(Allocation->Allocation <= 15);
  795. //
  796. // Set the interrupt line.
  797. //
  798. *((PUSHORT)Buffer) = 1 << Allocation->Allocation;
  799. break;
  800. case SMALL_RESOURCE_TYPE_DMA:
  801. ASSERT(DescriptorLength >= 2);
  802. *((PUCHAR)Buffer) = 1 << Allocation->Allocation;
  803. Flags = 0;
  804. if ((Allocation->Characteristics & DMA_TYPE_EISA_A) != 0) {
  805. Flags |= ACPI_SMALL_DMA_SPEED_EISA_A;
  806. } else if ((Allocation->Characteristics &
  807. DMA_TYPE_EISA_B) != 0) {
  808. Flags |= ACPI_SMALL_DMA_SPEED_EISA_B;
  809. } else if ((Allocation->Characteristics &
  810. DMA_TYPE_EISA_F) != 0) {
  811. Flags |= ACPI_SMALL_DMA_SPEED_EISA_F;
  812. }
  813. if ((Allocation->Characteristics & DMA_BUS_MASTER) != 0) {
  814. Flags |= ACPI_SMALL_DMA_BUS_MASTER;
  815. }
  816. if ((Allocation->Characteristics & DMA_TRANSFER_SIZE_8) != 0) {
  817. if ((Allocation->Characteristics &
  818. DMA_TRANSFER_SIZE_16) != 0) {
  819. Flags |= ACPI_SMALL_DMA_SIZE_8_AND_16_BIT;
  820. } else {
  821. Flags |= ACPI_SMALL_DMA_SIZE_8_BIT;
  822. }
  823. } else if ((Allocation->Characteristics &
  824. DMA_TRANSFER_SIZE_16) != 0) {
  825. Flags |= ACPI_SMALL_DMA_SIZE_16_BIT;
  826. }
  827. *((PUCHAR)Buffer + 1) = Flags;
  828. break;
  829. case SMALL_RESOURCE_TYPE_START_DEPENDENT_FUNCTIONS:
  830. if (DescriptorLength == 1) {
  831. RtlDebugPrint("Start Dependent Function: %x\n", *Buffer);
  832. } else {
  833. RtlDebugPrint("Start Dependent Function\n");
  834. }
  835. ASSERT(FALSE);
  836. break;
  837. case SMALL_RESOURCE_TYPE_END_DEPENDENT_FUNCTIONS:
  838. RtlDebugPrint("End Dependent Function\n");
  839. ASSERT(FALSE);
  840. break;
  841. case SMALL_RESOURCE_TYPE_IO_PORT:
  842. ASSERT(DescriptorLength >= 7);
  843. if (Allocation->Type != ResourceTypeIoPort) {
  844. Length = *((PUCHAR)(Buffer + 6));
  845. if (Length == 0) {
  846. StayOnCurrentAllocation = TRUE;
  847. break;
  848. }
  849. Status = STATUS_UNEXPECTED_TYPE;
  850. goto ConvertToAcpiResourceBufferEnd;
  851. }
  852. //
  853. // Set the I/O port base.
  854. //
  855. ASSERT(Allocation->Length >= *((PUCHAR)(Buffer + 6)));
  856. ASSERT(Allocation->Allocation <= *((PUSHORT)(Buffer + 3)) + 1);
  857. ASSERT(Allocation->Allocation <= 0xFFFF);
  858. *((PUSHORT)(Buffer + 1)) = (USHORT)Allocation->Allocation;
  859. break;
  860. case SMALL_RESOURCE_TYPE_FIXED_LOCATION_IO_PORT:
  861. ASSERT(DescriptorLength >= 3);
  862. if (Allocation->Type != ResourceTypeIoPort) {
  863. Length = *(Buffer + 2);
  864. if (Length == 0) {
  865. StayOnCurrentAllocation = TRUE;
  866. break;
  867. }
  868. Status = STATUS_UNEXPECTED_TYPE;
  869. goto ConvertToAcpiResourceBufferEnd;
  870. }
  871. ASSERT(Allocation->Allocation == *((PUSHORT)Buffer));
  872. ASSERT(Allocation->Length == *(Buffer + 2));
  873. break;
  874. case SMALL_RESOURCE_TYPE_VENDOR_DEFINED:
  875. RtlDebugPrint("Vendor Defined, Length %d\n", DescriptorLength);
  876. ASSERT(FALSE);
  877. break;
  878. case SMALL_RESOURCE_TYPE_END_TAG:
  879. ASSERT(DescriptorLength >= 1);
  880. //
  881. // Set the checksum field to zero.
  882. //
  883. *Buffer = 0;
  884. break;
  885. case LARGE_RESOURCE_TYPE_GPIO:
  886. RtlDebugPrint("ACPI: GPIO not implemented.\n");
  887. *Buffer = 0;
  888. break;
  889. default:
  890. RtlDebugPrint("ACPI: Error, found invalid resource descriptor "
  891. "type 0x%02x.\n",
  892. Byte & SMALL_RESOURCE_TYPE_MASK);
  893. Status = STATUS_MALFORMED_DATA_STREAM;
  894. goto ConvertToAcpiResourceBufferEnd;
  895. }
  896. //
  897. // Parse a large descriptor.
  898. //
  899. } else {
  900. ASSERT(RemainingSize >= 2);
  901. DescriptorLength = *((PUSHORT)Buffer);
  902. Buffer += 2;
  903. RemainingSize -= 2;
  904. switch (Byte & LARGE_RESOURCE_TYPE_MASK) {
  905. case LARGE_RESOURCE_TYPE_MEMORY24:
  906. ASSERT(DescriptorLength >= 9);
  907. Writeable = FALSE;
  908. if ((*Buffer & ACPI_MEMORY_DESCRIPTOR_WRITEABLE) != 0) {
  909. Writeable = TRUE;
  910. }
  911. Minimum = *((PUSHORT)(Buffer + 1));
  912. Minimum = Minimum << 8;
  913. Maximum = *((PUSHORT)(Buffer + 3));
  914. Maximum = Maximum << 8;
  915. Alignment = *((PUSHORT)(Buffer + 5));
  916. Length = *((PUSHORT)(Buffer + 7));
  917. Length = Length << 8;
  918. RtlDebugPrint("Memory24: Min 0x%I64x, Max 0x%I64x, Alignment "
  919. "0x%I64x, Length 0x%I64x, Writeable: %d\n",
  920. Minimum,
  921. Maximum,
  922. Alignment,
  923. Length,
  924. Writeable);
  925. ASSERT(FALSE);
  926. break;
  927. case LARGE_RESOURCE_TYPE_GENERIC_REGISTER:
  928. ASSERT(DescriptorLength >= 12);
  929. //
  930. // Get the resource type.
  931. //
  932. switch (*Buffer) {
  933. case AddressSpaceMemory:
  934. ResourceType = ResourceTypePhysicalAddressSpace;
  935. break;
  936. case AddressSpaceIo:
  937. ResourceType = ResourceTypeIoPort;
  938. break;
  939. case AddressSpacePciConfig:
  940. case AddressSpaceEmbeddedController:
  941. case AddressSpaceSmBus:
  942. case AddressSpaceFixedHardware:
  943. default:
  944. ResourceType = ResourceTypeVendorSpecific;
  945. break;
  946. }
  947. //
  948. // Get the access size.
  949. //
  950. if (*(Buffer + 4) == 0) {
  951. Alignment = 1;
  952. } else {
  953. Alignment = 1ULL << (*(Buffer + 4) - 1);
  954. }
  955. Length = (*(Buffer + 2) + *(Buffer + 3)) / BITS_PER_BYTE;
  956. if (Length < Alignment) {
  957. Length = Alignment;
  958. }
  959. Minimum = *((PULONGLONG)Buffer + 4);
  960. Maximum = Minimum + Length;
  961. RtlDebugPrint("Generic Register type %d, Minimum 0x%I64x, "
  962. "Length 0x%I64x, Alignment 0x%I64x.\n",
  963. ResourceType,
  964. Minimum,
  965. Length,
  966. Alignment);
  967. ASSERT(FALSE);
  968. break;
  969. case LARGE_RESOURCE_TYPE_VENDOR_DEFINED:
  970. RtlDebugPrint("Vendor Defined, Length %x\n", DescriptorLength);
  971. ASSERT(FALSE);
  972. break;
  973. case LARGE_RESOURCE_TYPE_MEMORY32:
  974. ASSERT(DescriptorLength >= 17);
  975. Writeable = FALSE;
  976. if ((*Buffer & ACPI_MEMORY_DESCRIPTOR_WRITEABLE) != 0) {
  977. Writeable = TRUE;
  978. }
  979. Minimum = *((PULONG)(Buffer + 1));
  980. Maximum = *((PULONG)(Buffer + 5));
  981. Alignment = *((PULONG)(Buffer + 9));
  982. Length = *((PULONG)(Buffer + 13));
  983. RtlDebugPrint("Memory32: Min 0x%I64x, Max 0x%I64x, Alignment "
  984. "0x%I64x, Length 0x%I64x, Writeable %d\n",
  985. Minimum,
  986. Maximum,
  987. Alignment,
  988. Length,
  989. Writeable);
  990. ASSERT(FALSE);
  991. break;
  992. case LARGE_RESOURCE_TYPE_FIXED_MEMORY32:
  993. ASSERT(DescriptorLength >= 9);
  994. Writeable = FALSE;
  995. if ((*Buffer & ACPI_MEMORY_DESCRIPTOR_WRITEABLE) != 0) {
  996. Writeable = TRUE;
  997. }
  998. Minimum = *((PULONG)(Buffer + 1));
  999. Alignment = 1;
  1000. Length = *((PULONG)(Buffer + 5));
  1001. Maximum = Minimum + Length;
  1002. RtlDebugPrint("Memory32Fixed: Min 0x%I64x, Max 0x%I64x, "
  1003. "Alignment 0x%I64x, Length 0x%I64x, Writeable "
  1004. "%d\n",
  1005. Minimum,
  1006. Maximum,
  1007. Alignment,
  1008. Length,
  1009. Writeable);
  1010. ASSERT(FALSE);
  1011. break;
  1012. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE32:
  1013. ASSERT(DescriptorLength >= (3 + (5 * sizeof(ULONG))));
  1014. ASSERT(FALSE);
  1015. break;
  1016. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE16:
  1017. ASSERT(DescriptorLength >= (3 + (5 * sizeof(USHORT))));
  1018. ASSERT(FALSE);
  1019. break;
  1020. case LARGE_RESOURCE_TYPE_IRQ:
  1021. ASSERT(DescriptorLength <= 2 + sizeof(ULONG));
  1022. if (Allocation->Type != ResourceTypeInterruptLine) {
  1023. Status = STATUS_UNEXPECTED_TYPE;
  1024. goto ConvertToAcpiResourceBufferEnd;
  1025. }
  1026. //
  1027. // If multiple interrupt lines are selected, implement that
  1028. // support.
  1029. //
  1030. ASSERT(Allocation->Length == 1);
  1031. //
  1032. // Set the interrupt line.
  1033. //
  1034. *((PULONG)(Buffer + 2)) = (ULONG)Allocation->Allocation;
  1035. break;
  1036. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE64:
  1037. ASSERT(DescriptorLength >= (3 + (5 * sizeof(ULONGLONG))));
  1038. ASSERT(FALSE);
  1039. break;
  1040. case LARGE_RESOURCE_TYPE_ADDRESS_SPACE_EXTENDED:
  1041. ASSERT(DescriptorLength >= (3 + (6 * sizeof(ULONGLONG))));
  1042. ASSERT(FALSE);
  1043. break;
  1044. default:
  1045. RtlDebugPrint("ACPI: Error, found invalid resource descriptor "
  1046. "type 0x%02x.\n",
  1047. Byte & LARGE_RESOURCE_TYPE_MASK);
  1048. Status = STATUS_MALFORMED_DATA_STREAM;
  1049. goto ConvertToAcpiResourceBufferEnd;
  1050. }
  1051. }
  1052. //
  1053. // Advance the buffer beyond this descriptor.
  1054. //
  1055. Buffer += DescriptorLength;
  1056. RemainingSize -= DescriptorLength;
  1057. }
  1058. Status = STATUS_SUCCESS;
  1059. ConvertToAcpiResourceBufferEnd:
  1060. return Status;
  1061. }
  1062. //
  1063. // --------------------------------------------------------- Internal Functions
  1064. //
  1065. KSTATUS
  1066. AcpipConvertFromGenericAddressDescriptor (
  1067. PVOID GenericAddressBuffer,
  1068. ULONG BufferLength,
  1069. ULONG TypeSize,
  1070. BOOL Extended,
  1071. PRESOURCE_REQUIREMENT_LIST RequirementList
  1072. )
  1073. /*++
  1074. Routine Description:
  1075. This routine converts an ACPI Generic Address descriptor into an OS
  1076. resource requirement.
  1077. Arguments:
  1078. GenericAddressBuffer - Supplies a pointer to the generic address buffer,
  1079. immediately after the 2 length bits.
  1080. BufferLength - Supplies the length of the buffer, in bytes.
  1081. TypeSize - Supplies the type of the generic address descriptor, in bytes.
  1082. This is the size of each address-related field in the structure.
  1083. Extended - Supplies a boolean indicating if this is an extended resource
  1084. descriptor (which as the type specific attributes field) or not.
  1085. RequirementList - Supplies a pointer to a resource requirement list where
  1086. a new resource requirement will be added on success.
  1087. Return Value:
  1088. Status code.
  1089. --*/
  1090. {
  1091. ULONGLONG Alignment;
  1092. ULONGLONG Attributes;
  1093. PUCHAR Buffer;
  1094. ULONG FieldsNeeded;
  1095. UCHAR Flags;
  1096. ULONGLONG Length;
  1097. ULONGLONG Maximum;
  1098. BOOL MaximumFixed;
  1099. ULONGLONG Minimum;
  1100. BOOL MinimumFixed;
  1101. RESOURCE_REQUIREMENT Requirement;
  1102. RESOURCE_TYPE ResourceType;
  1103. KSTATUS Status;
  1104. ULONGLONG TranslationOffset;
  1105. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1106. FieldsNeeded = 5;
  1107. if (Extended != FALSE) {
  1108. FieldsNeeded = 6;
  1109. }
  1110. if (BufferLength < (3 + (FieldsNeeded * TypeSize))) {
  1111. Status = STATUS_BUFFER_TOO_SMALL;
  1112. goto ConvertFromGenericAddressDescriptorEnd;
  1113. }
  1114. Buffer = (PUCHAR)GenericAddressBuffer;
  1115. //
  1116. // Determine the resource type.
  1117. //
  1118. ResourceType = ResourceTypeVendorSpecific;
  1119. switch (*Buffer) {
  1120. case GENERIC_ADDRESS_TYPE_MEMORY:
  1121. ResourceType = ResourceTypePhysicalAddressSpace;
  1122. break;
  1123. case GENERIC_ADDRESS_TYPE_IO:
  1124. ResourceType = ResourceTypeIoPort;
  1125. break;
  1126. case GENERIC_ADDRESS_TYPE_BUS_NUMBER:
  1127. ResourceType = ResourceTypeBusNumber;
  1128. break;
  1129. default:
  1130. break;
  1131. }
  1132. //
  1133. // Determine the flag values.
  1134. //
  1135. Flags = *(Buffer + 1);
  1136. MinimumFixed = FALSE;
  1137. if ((Flags & GENERIC_ADDRESS_MINIMUM_FIXED) != 0) {
  1138. MinimumFixed = TRUE;
  1139. }
  1140. MaximumFixed = FALSE;
  1141. if ((Flags & GENERIC_ADDRESS_MAXIMUM_FIXED) != 0) {
  1142. MaximumFixed = TRUE;
  1143. }
  1144. //
  1145. // Get the alignment variable. This is billed in the descriptor as a
  1146. // "Granularity" field, where bits set to 1 are decoded by the bus. Simply
  1147. // add 1 to get back up to a power of 2 alignment.
  1148. //
  1149. Alignment = 0;
  1150. RtlCopyMemory(&Alignment, Buffer + 3, TypeSize);
  1151. Alignment += 1;
  1152. Buffer += 3 + TypeSize;
  1153. //
  1154. // Get the minimum and maximum.
  1155. //
  1156. Minimum = 0;
  1157. RtlCopyMemory(&Minimum, Buffer, TypeSize);
  1158. Buffer += TypeSize;
  1159. Maximum = 0;
  1160. RtlCopyMemory(&Maximum, Buffer, TypeSize);
  1161. Buffer += TypeSize;
  1162. //
  1163. // Get the translation offset and length.
  1164. //
  1165. TranslationOffset = 0;
  1166. RtlCopyMemory(&TranslationOffset, Buffer, TypeSize);
  1167. Buffer += TypeSize;
  1168. Length = 0;
  1169. RtlCopyMemory(&Length, Buffer, TypeSize);
  1170. Buffer += TypeSize;
  1171. //
  1172. // Restrict the minimum or maximum depending on the flags.
  1173. //
  1174. if (MinimumFixed != FALSE) {
  1175. Maximum = Minimum + Length - 1;
  1176. } else if (MaximumFixed != FALSE) {
  1177. Minimum = Maximum + 1 - Length;
  1178. }
  1179. //
  1180. // Get the attributes for extended descriptors.
  1181. //
  1182. Attributes = 0;
  1183. if (Extended != FALSE) {
  1184. RtlCopyMemory(&Attributes, Buffer, TypeSize);
  1185. Buffer += TypeSize;
  1186. }
  1187. Requirement.Type = ResourceType;
  1188. Requirement.Minimum = Minimum;
  1189. Requirement.Length = Length;
  1190. Requirement.Maximum = Maximum + 1;
  1191. Requirement.Alignment = Alignment;
  1192. Requirement.Characteristics = Attributes;
  1193. Requirement.Flags = RESOURCE_FLAG_NOT_SHAREABLE;
  1194. Status = IoCreateAndAddResourceRequirement(&Requirement,
  1195. RequirementList,
  1196. NULL);
  1197. if (!KSUCCESS(Status)) {
  1198. goto ConvertFromGenericAddressDescriptorEnd;
  1199. }
  1200. ConvertFromGenericAddressDescriptorEnd:
  1201. return Status;
  1202. }
  1203. KSTATUS
  1204. AcpipParseSmallDmaDescriptor (
  1205. PVOID Buffer,
  1206. ULONG BufferLength,
  1207. PRESOURCE_REQUIREMENT_LIST RequirementList
  1208. )
  1209. /*++
  1210. Routine Description:
  1211. This routine converts an ACPI small DMA descriptor into a resource
  1212. requirement, and puts that requirement on the given requirement list.
  1213. Arguments:
  1214. Buffer - Supplies a pointer to the DMA descriptor buffer, pointing after the
  1215. byte identifying the descriptor as a short DMA descriptor.
  1216. BufferLength - Supplies the length of the descriptor buffer.
  1217. RequirementList - Supplies a pointer to the resource requirement list to
  1218. put the descriptor on.
  1219. Return Value:
  1220. Status code.
  1221. --*/
  1222. {
  1223. UCHAR Flags;
  1224. UCHAR Mask;
  1225. PRESOURCE_REQUIREMENT NewRequirement;
  1226. RESOURCE_REQUIREMENT Requirement;
  1227. KSTATUS Status;
  1228. NewRequirement = NULL;
  1229. if (BufferLength < 2) {
  1230. Status = STATUS_MALFORMED_DATA_STREAM;
  1231. goto ParseSmallDmaDescriptorEnd;
  1232. }
  1233. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1234. Requirement.Type = ResourceTypeDmaChannel;
  1235. Mask = *((PUCHAR)Buffer);
  1236. Flags = *((PUCHAR)Buffer + 1);
  1237. //
  1238. // Skip over zero bits.
  1239. //
  1240. while ((Mask != 0) && ((Mask & 0x1) == 0)) {
  1241. Requirement.Minimum += 1;
  1242. Mask = Mask >> 1;
  1243. }
  1244. //
  1245. // Collect one bits.
  1246. //
  1247. Requirement.Maximum = Requirement.Minimum;
  1248. while ((Mask & 0x1) != 0) {
  1249. Requirement.Maximum += 1;
  1250. Mask = Mask >> 1;
  1251. }
  1252. if (Mask != 0) {
  1253. Status = STATUS_MALFORMED_DATA_STREAM;
  1254. goto ParseSmallDmaDescriptorEnd;
  1255. }
  1256. Requirement.Length = 1;
  1257. Requirement.Flags = RESOURCE_FLAG_NOT_SHAREABLE;
  1258. //
  1259. // Parse the flags.
  1260. //
  1261. switch (Flags & ACPI_SMALL_DMA_SPEED_MASK) {
  1262. case ACPI_SMALL_DMA_SPEED_ISA:
  1263. Requirement.Characteristics |= DMA_TYPE_ISA;
  1264. break;
  1265. case ACPI_SMALL_DMA_SPEED_EISA_A:
  1266. Requirement.Characteristics |= DMA_TYPE_EISA_A;
  1267. break;
  1268. case ACPI_SMALL_DMA_SPEED_EISA_B:
  1269. Requirement.Characteristics |= DMA_TYPE_EISA_B;
  1270. break;
  1271. case ACPI_SMALL_DMA_SPEED_EISA_F:
  1272. default:
  1273. Requirement.Characteristics |= DMA_TYPE_EISA_F;
  1274. break;
  1275. }
  1276. switch (Flags & ACPI_SMALL_DMA_SIZE_MASK) {
  1277. case ACPI_SMALL_DMA_SIZE_8_BIT:
  1278. Requirement.Characteristics |= DMA_TRANSFER_SIZE_8;
  1279. break;
  1280. case ACPI_SMALL_DMA_SIZE_8_AND_16_BIT:
  1281. Requirement.Characteristics |= DMA_TRANSFER_SIZE_8 |
  1282. DMA_TRANSFER_SIZE_16;
  1283. break;
  1284. case ACPI_SMALL_DMA_SIZE_16_BIT:
  1285. default:
  1286. Requirement.Characteristics |= DMA_TRANSFER_SIZE_16;
  1287. break;
  1288. }
  1289. if ((Flags & ACPI_SMALL_DMA_BUS_MASTER) != 0) {
  1290. Requirement.Characteristics |= DMA_BUS_MASTER;
  1291. }
  1292. //
  1293. // Register the requirement.
  1294. //
  1295. Status = IoCreateAndAddResourceRequirement(&Requirement,
  1296. RequirementList,
  1297. &NewRequirement);
  1298. if (!KSUCCESS(Status)) {
  1299. goto ParseSmallDmaDescriptorEnd;
  1300. }
  1301. Status = STATUS_SUCCESS;
  1302. ParseSmallDmaDescriptorEnd:
  1303. if (!KSUCCESS(Status)) {
  1304. if (NewRequirement != NULL) {
  1305. IoRemoveResourceRequirement(NewRequirement);
  1306. }
  1307. }
  1308. return Status;
  1309. }
  1310. KSTATUS
  1311. AcpipParseSmallFixedDmaDescriptor (
  1312. PVOID Buffer,
  1313. ULONG BufferLength,
  1314. PRESOURCE_REQUIREMENT_LIST RequirementList
  1315. )
  1316. /*++
  1317. Routine Description:
  1318. This routine converts an ACPI small fixed DMA descriptor into a resource
  1319. requirement, and puts that requirement on the given requirement list.
  1320. Arguments:
  1321. Buffer - Supplies a pointer to the DMA descriptor buffer, pointing after the
  1322. byte identifying the descriptor as a short fixed DMA descriptor.
  1323. BufferLength - Supplies the length of the descriptor buffer.
  1324. RequirementList - Supplies a pointer to the resource requirement list to
  1325. put the descriptor on.
  1326. Return Value:
  1327. Status code.
  1328. --*/
  1329. {
  1330. RESOURCE_DMA_DATA DmaData;
  1331. PRESOURCE_REQUIREMENT NewRequirement;
  1332. RESOURCE_REQUIREMENT Requirement;
  1333. KSTATUS Status;
  1334. UCHAR Width;
  1335. NewRequirement = NULL;
  1336. if (BufferLength < 5) {
  1337. Status = STATUS_MALFORMED_DATA_STREAM;
  1338. goto ParseSmallFixedDmaDescriptorEnd;
  1339. }
  1340. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1341. RtlZeroMemory(&DmaData, sizeof(RESOURCE_DMA_DATA));
  1342. DmaData.Version = RESOURCE_DMA_DATA_VERSION;
  1343. Requirement.Type = ResourceTypeDmaChannel;
  1344. DmaData.Request = READ_UNALIGNED16(Buffer);
  1345. Buffer += 2;
  1346. Requirement.Minimum = READ_UNALIGNED16(Buffer);
  1347. Buffer += 1;
  1348. Requirement.Maximum = Requirement.Minimum + 1;
  1349. Requirement.Length = 1;;
  1350. Width = *((PUCHAR)Buffer);
  1351. Buffer += 1;
  1352. switch (Width) {
  1353. case ACPI_SMALL_FIXED_DMA_8BIT:
  1354. Requirement.Characteristics |= DMA_TRANSFER_SIZE_8;
  1355. DmaData.Width = 8;
  1356. break;
  1357. case ACPI_SMALL_FIXED_DMA_16BIT:
  1358. Requirement.Characteristics |= DMA_TRANSFER_SIZE_16;
  1359. DmaData.Width = 16;
  1360. break;
  1361. case ACPI_SMALL_FIXED_DMA_32BIT:
  1362. Requirement.Characteristics |= DMA_TRANSFER_SIZE_32;
  1363. DmaData.Width = 32;
  1364. break;
  1365. case ACPI_SMALL_FIXED_DMA_64BIT:
  1366. Requirement.Characteristics |= DMA_TRANSFER_SIZE_64;
  1367. DmaData.Width = 64;
  1368. break;
  1369. case ACPI_SMALL_FIXED_DMA_128BIT:
  1370. Requirement.Characteristics |= DMA_TRANSFER_SIZE_128;
  1371. DmaData.Width = 128;
  1372. break;
  1373. case ACPI_SMALL_FIXED_DMA_256BIT:
  1374. Requirement.Characteristics |= DMA_TRANSFER_SIZE_256;
  1375. DmaData.Width = 256;
  1376. break;
  1377. default:
  1378. Status = STATUS_MALFORMED_DATA_STREAM;
  1379. goto ParseSmallFixedDmaDescriptorEnd;
  1380. }
  1381. Requirement.Flags = RESOURCE_FLAG_NOT_SHAREABLE;
  1382. Requirement.Data = &DmaData;
  1383. Requirement.DataSize = sizeof(RESOURCE_DMA_DATA);
  1384. //
  1385. // Register the requirement.
  1386. //
  1387. Status = IoCreateAndAddResourceRequirement(&Requirement,
  1388. RequirementList,
  1389. &NewRequirement);
  1390. if (!KSUCCESS(Status)) {
  1391. goto ParseSmallFixedDmaDescriptorEnd;
  1392. }
  1393. Status = STATUS_SUCCESS;
  1394. ParseSmallFixedDmaDescriptorEnd:
  1395. if (!KSUCCESS(Status)) {
  1396. if (NewRequirement != NULL) {
  1397. IoRemoveResourceRequirement(NewRequirement);
  1398. }
  1399. }
  1400. return Status;
  1401. }
  1402. KSTATUS
  1403. AcpipParseSmallIrqDescriptor (
  1404. PVOID Buffer,
  1405. ULONG BufferLength,
  1406. PRESOURCE_REQUIREMENT_LIST RequirementList
  1407. )
  1408. /*++
  1409. Routine Description:
  1410. This routine converts an ACPI small IRQ descriptor into a resource
  1411. requirement, and puts that requirement on the given requirement list.
  1412. Arguments:
  1413. Buffer - Supplies a pointer to the IRQ descriptor buffer, pointing after the
  1414. byte identifying the descriptor as a short IRQ descriptor.
  1415. BufferLength - Supplies the length of the descriptor buffer.
  1416. RequirementList - Supplies a pointer to the resource requirement list to
  1417. put the descriptor on.
  1418. Return Value:
  1419. Status code.
  1420. --*/
  1421. {
  1422. PUCHAR BufferPointer;
  1423. UCHAR InterruptOptions;
  1424. PRESOURCE_REQUIREMENT NewRequirement;
  1425. USHORT PicInterrupts;
  1426. RESOURCE_REQUIREMENT Requirement;
  1427. KSTATUS Status;
  1428. NewRequirement = NULL;
  1429. if (BufferLength < 2) {
  1430. Status = STATUS_MALFORMED_DATA_STREAM;
  1431. goto ParseSmallIrqDescriptorEnd;
  1432. }
  1433. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1434. Requirement.Type = ResourceTypeInterruptLine;
  1435. BufferPointer = Buffer;
  1436. PicInterrupts = *((PUSHORT)BufferPointer);
  1437. InterruptOptions = 0;
  1438. if (BufferLength >= 3) {
  1439. InterruptOptions = *(BufferPointer + 2);
  1440. }
  1441. //
  1442. // Set the flags and characteristics.
  1443. //
  1444. if ((InterruptOptions & ACPI_SMALL_IRQ_FLAG_SHAREABLE) == 0) {
  1445. Requirement.Flags |= RESOURCE_FLAG_NOT_SHAREABLE;
  1446. }
  1447. if ((InterruptOptions & ACPI_SMALL_IRQ_FLAG_EDGE_TRIGGERED) != 0) {
  1448. Requirement.Characteristics |= INTERRUPT_LINE_EDGE_TRIGGERED;
  1449. }
  1450. if ((InterruptOptions & ACPI_SMALL_IRQ_FLAG_ACTIVE_LOW) != 0) {
  1451. Requirement.Characteristics |= INTERRUPT_LINE_ACTIVE_LOW;
  1452. } else {
  1453. Requirement.Characteristics |= INTERRUPT_LINE_ACTIVE_HIGH;
  1454. }
  1455. //
  1456. // Loop getting runs of set bits.
  1457. //
  1458. Requirement.Length = 1;
  1459. Requirement.Minimum = 0;
  1460. while (PicInterrupts != 0) {
  1461. //
  1462. // Skip over zero bits.
  1463. //
  1464. while ((PicInterrupts != 0) && ((PicInterrupts & 0x1) == 0)) {
  1465. Requirement.Minimum += 1;
  1466. PicInterrupts = PicInterrupts >> 1;
  1467. }
  1468. //
  1469. // Collect one bits.
  1470. //
  1471. Requirement.Maximum = Requirement.Minimum;
  1472. while ((PicInterrupts & 0x1) != 0) {
  1473. Requirement.Maximum += 1;
  1474. PicInterrupts = PicInterrupts >> 1;
  1475. }
  1476. //
  1477. // Bail out if there's nothing there.
  1478. //
  1479. if (Requirement.Minimum == Requirement.Maximum) {
  1480. break;
  1481. }
  1482. //
  1483. // Register the requirement or the alternative.
  1484. //
  1485. if (NewRequirement == NULL) {
  1486. Status = IoCreateAndAddResourceRequirement(&Requirement,
  1487. RequirementList,
  1488. &NewRequirement);
  1489. } else {
  1490. Status = IoCreateAndAddResourceRequirementAlternative(
  1491. &Requirement,
  1492. NewRequirement);
  1493. }
  1494. if (!KSUCCESS(Status)) {
  1495. goto ParseSmallIrqDescriptorEnd;
  1496. }
  1497. Requirement.Minimum = Requirement.Maximum;
  1498. }
  1499. Status = STATUS_SUCCESS;
  1500. ParseSmallIrqDescriptorEnd:
  1501. if (!KSUCCESS(Status)) {
  1502. if (NewRequirement != NULL) {
  1503. IoRemoveResourceRequirement(NewRequirement);
  1504. }
  1505. }
  1506. return Status;
  1507. }
  1508. KSTATUS
  1509. AcpipParseLargeIrqDescriptor (
  1510. PVOID Buffer,
  1511. ULONG BufferLength,
  1512. PRESOURCE_REQUIREMENT_LIST RequirementList
  1513. )
  1514. /*++
  1515. Routine Description:
  1516. This routine converts an ACPI large IRQ descriptor into a resource
  1517. requirement, and puts that requirement on the given requirement list.
  1518. Arguments:
  1519. Buffer - Supplies a pointer to the IRQ descriptor buffer, pointing after the
  1520. length bytes.
  1521. BufferLength - Supplies the length of the descriptor buffer.
  1522. RequirementList - Supplies a pointer to the resource requirement list to
  1523. put the descriptor on.
  1524. Return Value:
  1525. Status code.
  1526. --*/
  1527. {
  1528. PUCHAR BufferPointer;
  1529. PRESOURCE_REQUIREMENT CreatedRequirement;
  1530. UCHAR InterruptCount;
  1531. UCHAR InterruptOptions;
  1532. PULONG LongPointer;
  1533. RESOURCE_REQUIREMENT Requirement;
  1534. KSTATUS Status;
  1535. BufferPointer = (PUCHAR)Buffer;
  1536. CreatedRequirement = NULL;
  1537. if (BufferLength < 2) {
  1538. Status = STATUS_MALFORMED_DATA_STREAM;
  1539. goto ParseLargeIrqDescriptorEnd;
  1540. }
  1541. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1542. Requirement.Type = ResourceTypeInterruptLine;
  1543. Requirement.Length = 1;
  1544. InterruptOptions = *BufferPointer;
  1545. InterruptCount = *(BufferPointer + 1);
  1546. if (BufferLength < 2 + (sizeof(ULONG) * InterruptCount)) {
  1547. Status = STATUS_MALFORMED_DATA_STREAM;
  1548. goto ParseLargeIrqDescriptorEnd;
  1549. }
  1550. //
  1551. // Parse the options.
  1552. //
  1553. if ((InterruptOptions & ACPI_LARGE_IRQ_FLAG_SHAREABLE) == 0) {
  1554. Requirement.Flags |= RESOURCE_FLAG_NOT_SHAREABLE;
  1555. }
  1556. if ((InterruptOptions & ACPI_LARGE_IRQ_FLAG_EDGE_TRIGGERED) != 0) {
  1557. Requirement.Characteristics |= INTERRUPT_LINE_EDGE_TRIGGERED;
  1558. }
  1559. if ((InterruptOptions & ACPI_LARGE_IRQ_FLAG_ACTIVE_LOW) != 0) {
  1560. Requirement.Characteristics |= INTERRUPT_LINE_ACTIVE_LOW;
  1561. } else {
  1562. Requirement.Characteristics |= INTERRUPT_LINE_ACTIVE_HIGH;
  1563. }
  1564. BufferPointer += 2;
  1565. BufferLength -= 2;
  1566. LongPointer = (PULONG)BufferPointer;
  1567. while (InterruptCount != 0) {
  1568. //
  1569. // Create an interrupt line descriptor. Attempt to pack as many
  1570. // sequential GSIs into the descriptor as there are.
  1571. //
  1572. Requirement.Minimum = *LongPointer;
  1573. Requirement.Maximum = Requirement.Minimum + 1;
  1574. LongPointer += 1;
  1575. InterruptCount -= 1;
  1576. while ((InterruptCount != 0) &&
  1577. (*LongPointer == Requirement.Maximum)) {
  1578. LongPointer += 1;
  1579. InterruptCount -= 1;
  1580. Requirement.Maximum += 1;
  1581. }
  1582. //
  1583. // Create the main descriptor if it has not been created yet. If it has,
  1584. // create an alternative.
  1585. //
  1586. if (CreatedRequirement == NULL) {
  1587. Status = IoCreateAndAddResourceRequirement(&Requirement,
  1588. RequirementList,
  1589. &CreatedRequirement);
  1590. } else {
  1591. Status = IoCreateAndAddResourceRequirementAlternative(
  1592. &Requirement,
  1593. CreatedRequirement);
  1594. }
  1595. if (!KSUCCESS(Status)) {
  1596. goto ParseLargeIrqDescriptorEnd;
  1597. }
  1598. }
  1599. Status = STATUS_SUCCESS;
  1600. ParseLargeIrqDescriptorEnd:
  1601. return Status;
  1602. }
  1603. KSTATUS
  1604. AcpipParseGpioDescriptor (
  1605. PACPI_OBJECT NamespaceStart,
  1606. PVOID Buffer,
  1607. ULONG BufferLength,
  1608. PRESOURCE_REQUIREMENT_LIST RequirementList
  1609. )
  1610. /*++
  1611. Routine Description:
  1612. This routine converts an ACPI GPIO resource descriptor into a resource
  1613. requirement, and puts that requirement on the given requirement list.
  1614. Arguments:
  1615. NamespaceStart - Supplies a pointer to the starting point for namespace
  1616. traversals.
  1617. Buffer - Supplies a pointer to the GPIO descriptor buffer, pointing after
  1618. the length bytes.
  1619. BufferLength - Supplies the length of the descriptor buffer.
  1620. RequirementList - Supplies a pointer to the resource requirement list to
  1621. put the descriptor on.
  1622. Return Value:
  1623. Status code.
  1624. --*/
  1625. {
  1626. PUCHAR BufferPointer;
  1627. UCHAR ConnectionType;
  1628. PRESOURCE_REQUIREMENT CreatedRequirement;
  1629. USHORT DebounceTimeout;
  1630. PRESOURCE_GPIO_DATA GpioData;
  1631. UINTN GpioDataSize;
  1632. INTERRUPT_CONTROLLER_INFORMATION InterruptController;
  1633. RESOURCE_REQUIREMENT InterruptRequirement;
  1634. USHORT IoFlags;
  1635. USHORT OutputDrive;
  1636. UCHAR PinConfiguration;
  1637. USHORT PinCount;
  1638. PUSHORT PinPointer;
  1639. USHORT PinTableOffset;
  1640. PACPI_OBJECT Provider;
  1641. RESOURCE_REQUIREMENT Requirement;
  1642. USHORT ResourceSourceNameOffset;
  1643. PSTR SourceName;
  1644. KSTATUS Status;
  1645. PVOID VendorData;
  1646. USHORT VendorDataLength;
  1647. USHORT VendorDataOffset;
  1648. BufferPointer = (PUCHAR)Buffer;
  1649. CreatedRequirement = NULL;
  1650. GpioData = NULL;
  1651. if (BufferLength < 0x14) {
  1652. Status = STATUS_MALFORMED_DATA_STREAM;
  1653. goto ParseGpioDescriptorEnd;
  1654. }
  1655. //
  1656. // Check the revision.
  1657. //
  1658. if (*BufferPointer < 1) {
  1659. Status = STATUS_MALFORMED_DATA_STREAM;
  1660. goto ParseGpioDescriptorEnd;
  1661. }
  1662. ConnectionType = *(BufferPointer + 1);
  1663. IoFlags = READ_UNALIGNED16(BufferPointer + 4);
  1664. PinConfiguration = *(BufferPointer + 6);
  1665. OutputDrive = READ_UNALIGNED16(BufferPointer + 7);
  1666. DebounceTimeout = READ_UNALIGNED16(BufferPointer + 9);
  1667. PinTableOffset = READ_UNALIGNED16(BufferPointer + 11);
  1668. ResourceSourceNameOffset = READ_UNALIGNED16(BufferPointer + 14);
  1669. VendorDataOffset = READ_UNALIGNED16(BufferPointer + 15);
  1670. VendorDataLength = READ_UNALIGNED16(BufferPointer + 16);
  1671. VendorData = BufferPointer + VendorDataOffset - 3;
  1672. PinPointer = (PUSHORT)(BufferPointer + PinTableOffset - 3);
  1673. SourceName = (PSTR)(BufferPointer + ResourceSourceNameOffset - 3);
  1674. PinCount = (ResourceSourceNameOffset - PinTableOffset) / 2;
  1675. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1676. RtlZeroMemory(&InterruptRequirement, sizeof(RESOURCE_REQUIREMENT));
  1677. GpioDataSize = sizeof(RESOURCE_GPIO_DATA) + VendorDataLength;
  1678. GpioData = MmAllocatePagedPool(GpioDataSize, ACPI_RESOURCE_ALLOCATION_TAG);
  1679. if (GpioData == NULL) {
  1680. Status = STATUS_INSUFFICIENT_RESOURCES;
  1681. goto ParseGpioDescriptorEnd;
  1682. }
  1683. RtlZeroMemory(GpioData, GpioDataSize);
  1684. GpioData->Version = RESOURCE_GPIO_DATA_VERSION;
  1685. //
  1686. // Set the secondary flag on the interrupt requirement since this is a GPIO
  1687. // line interrupt, not a primary interrupt controller interrupt. This flag
  1688. // indicates that the interrupt vector to run-level correlation may not
  1689. // be there.
  1690. //
  1691. InterruptRequirement.Type = ResourceTypeInterruptLine;
  1692. InterruptRequirement.Characteristics = INTERRUPT_LINE_SECONDARY;
  1693. Requirement.Type = ResourceTypeGpio;
  1694. //
  1695. // Parse the options.
  1696. //
  1697. if ((IoFlags & ACPI_GPIO_SHARED) == 0) {
  1698. Requirement.Flags |= RESOURCE_FLAG_NOT_SHAREABLE;
  1699. }
  1700. switch (ConnectionType) {
  1701. case ACPI_GPIO_CONNECTION_INTERRUPT:
  1702. GpioData->Flags |= RESOURCE_GPIO_INTERRUPT;
  1703. if ((IoFlags & ACPI_GPIO_WAKE) != 0) {
  1704. GpioData->Flags |= RESOURCE_GPIO_WAKE;
  1705. InterruptRequirement.Characteristics |= INTERRUPT_LINE_WAKE;
  1706. }
  1707. switch (IoFlags & ACPI_GPIO_POLARITY_MASK) {
  1708. case ACPI_GPIO_POLARITY_ACTIVE_HIGH:
  1709. GpioData->Flags |= RESOURCE_GPIO_ACTIVE_HIGH;
  1710. InterruptRequirement.Characteristics |= INTERRUPT_LINE_ACTIVE_HIGH;
  1711. break;
  1712. case ACPI_GPIO_POLARITY_ACTIVE_LOW:
  1713. GpioData->Flags |= RESOURCE_GPIO_ACTIVE_LOW;
  1714. InterruptRequirement.Characteristics |= INTERRUPT_LINE_ACTIVE_LOW;
  1715. break;
  1716. case ACPI_GPIO_POLARITY_ACTIVE_BOTH:
  1717. GpioData->Flags |= RESOURCE_GPIO_ACTIVE_HIGH |
  1718. RESOURCE_GPIO_ACTIVE_LOW;
  1719. InterruptRequirement.Characteristics |= INTERRUPT_LINE_ACTIVE_HIGH |
  1720. INTERRUPT_LINE_ACTIVE_LOW;
  1721. break;
  1722. default:
  1723. ASSERT(FALSE);
  1724. break;
  1725. }
  1726. if ((IoFlags & ACPI_GPIO_EDGE_TRIGGERED) != 0) {
  1727. GpioData->Flags |= RESOURCE_GPIO_EDGE_TRIGGERED;
  1728. InterruptRequirement.Characteristics |=
  1729. INTERRUPT_LINE_EDGE_TRIGGERED;
  1730. }
  1731. break;
  1732. case ACPI_GPIO_CONNECTION_IO:
  1733. switch (IoFlags & ACPI_GPIO_IO_RESTRICTION_MASK) {
  1734. case ACPI_GPIO_IO_RESTRICTION_IO:
  1735. case ACPI_GPIO_IO_RESTRICTION_IO_PRESERVE:
  1736. GpioData->Flags |= RESOURCE_GPIO_INPUT | RESOURCE_GPIO_OUTPUT;
  1737. break;
  1738. case ACPI_GPIO_IO_RESTRICTION_INPUT:
  1739. GpioData->Flags |= RESOURCE_GPIO_INPUT;
  1740. break;
  1741. case ACPI_GPIO_IO_RESTRICTION_OUTPUT:
  1742. GpioData->Flags |= RESOURCE_GPIO_OUTPUT;
  1743. break;
  1744. default:
  1745. ASSERT(FALSE);
  1746. break;
  1747. }
  1748. break;
  1749. default:
  1750. ASSERT(FALSE);
  1751. Status = STATUS_MALFORMED_DATA_STREAM;
  1752. goto ParseGpioDescriptorEnd;
  1753. }
  1754. switch (PinConfiguration) {
  1755. case ACPI_GPIO_PIN_PULL_DEFAULT:
  1756. break;
  1757. case ACPI_GPIO_PIN_PULL_UP:
  1758. GpioData->Flags |= RESOURCE_GPIO_PULL_UP;
  1759. break;
  1760. case ACPI_GPIO_PIN_PULL_DOWN:
  1761. GpioData->Flags |= RESOURCE_GPIO_PULL_DOWN;
  1762. break;
  1763. case ACPI_GPIO_PIN_PULL_NONE:
  1764. GpioData->Flags |= RESOURCE_GPIO_PULL_NONE;
  1765. break;
  1766. }
  1767. if (OutputDrive == ACPI_GPIO_OUTPUT_DRIVE_DEFAULT) {
  1768. GpioData->OutputDriveStrength = RESOURCE_GPIO_DEFAULT_DRIVE_STRENGTH;
  1769. } else {
  1770. GpioData->OutputDriveStrength = OutputDrive * 10;
  1771. }
  1772. if (DebounceTimeout == ACPI_GPIO_DEBOUNCE_TIMEOUT_DEFAULT) {
  1773. GpioData->DebounceTimeout = RESOURCE_GPIO_DEFAULT_DEBOUNCE_TIMEOUT;
  1774. } else {
  1775. GpioData->DebounceTimeout = DebounceTimeout * 10;
  1776. }
  1777. RtlCopyMemory(GpioData + 1, VendorData, VendorDataLength);
  1778. GpioData->VendorDataOffset = sizeof(RESOURCE_GPIO_DATA);
  1779. GpioData->VendorDataSize = VendorDataLength;
  1780. Requirement.Data = GpioData;
  1781. Requirement.DataSize = GpioDataSize;
  1782. //
  1783. // Find the device providing the GPIO resource.
  1784. //
  1785. Provider = AcpipGetNamespaceObject(SourceName, NamespaceStart);
  1786. if (Provider == NULL) {
  1787. RtlDebugPrint("ACPI: Failed to find GPIO device '%s'\n", SourceName);
  1788. Status = STATUS_INVALID_CONFIGURATION;
  1789. goto ParseGpioDescriptorEnd;
  1790. }
  1791. if (Provider->Type != AcpiObjectDevice) {
  1792. ASSERT(FALSE);
  1793. Status = STATUS_INVALID_CONFIGURATION;
  1794. goto ParseGpioDescriptorEnd;
  1795. }
  1796. //
  1797. // If the GPIO device is not yet started, then fail for now and try again
  1798. // when it's ready.
  1799. //
  1800. if (Provider->U.Device.IsDeviceStarted == FALSE) {
  1801. Status = AcpipCreateDeviceDependency(NamespaceStart->U.Device.OsDevice,
  1802. Provider);
  1803. if (Status != STATUS_TOO_LATE) {
  1804. if (KSUCCESS(Status)) {
  1805. Status = STATUS_NOT_READY;
  1806. }
  1807. goto ParseGpioDescriptorEnd;
  1808. }
  1809. }
  1810. Requirement.Provider = Provider->U.Device.OsDevice;
  1811. ASSERT(Requirement.Provider != NULL);
  1812. //
  1813. // Now add resources for each streak of pins defined in the table.
  1814. //
  1815. while (PinCount != 0) {
  1816. //
  1817. // Create a GPIO descriptor. Attempt to pack as many sequential lines
  1818. // into the descriptor as there are.
  1819. //
  1820. Requirement.Minimum = READ_UNALIGNED16(PinPointer);
  1821. Requirement.Maximum = Requirement.Minimum + 1;
  1822. PinPointer += 1;
  1823. PinCount -= 1;
  1824. while ((PinCount != 0) &&
  1825. (READ_UNALIGNED16(PinPointer) == Requirement.Maximum)) {
  1826. PinPointer += 1;
  1827. PinCount -= 1;
  1828. Requirement.Maximum += 1;
  1829. }
  1830. Requirement.Length = Requirement.Maximum - Requirement.Minimum;
  1831. Status = IoCreateAndAddResourceRequirement(&Requirement,
  1832. RequirementList,
  1833. &CreatedRequirement);
  1834. if (!KSUCCESS(Status)) {
  1835. goto ParseGpioDescriptorEnd;
  1836. }
  1837. //
  1838. // Add a standard interrupt line requirement too if this is an
  1839. // interrupt. This way devices do not have to become GPIO-aware to
  1840. // have interrupts serviced via GPIO.
  1841. //
  1842. if ((GpioData->Flags & RESOURCE_GPIO_INTERRUPT) != 0) {
  1843. InterruptRequirement.Length = Requirement.Length;
  1844. InterruptRequirement.Flags = Requirement.Flags;
  1845. InterruptRequirement.Data = Requirement.Data;
  1846. InterruptRequirement.DataSize = Requirement.DataSize;
  1847. //
  1848. // Translate from the provider device back to an interrupt
  1849. // controller, and then to a GSI to determine which interrupt
  1850. // line to connect to. This line will end up being a dynamically
  1851. // allocated GSI. Using the device pointer as the interrupt
  1852. // controller ID is an agreed-upon convention with the GPIO library
  1853. // driver.
  1854. //
  1855. Status = HlGetInterruptControllerInformation(
  1856. (UINTN)(Requirement.Provider),
  1857. &InterruptController);
  1858. if (!KSUCCESS(Status)) {
  1859. RtlDebugPrint("ACPI: Missing interrupt controller\n");
  1860. Status = STATUS_NOT_READY;
  1861. goto ParseGpioDescriptorEnd;
  1862. }
  1863. InterruptRequirement.Minimum = InterruptController.StartingGsi +
  1864. Requirement.Minimum;
  1865. InterruptRequirement.Maximum = InterruptController.StartingGsi +
  1866. Requirement.Maximum;
  1867. Status = IoCreateAndAddResourceRequirement(&InterruptRequirement,
  1868. RequirementList,
  1869. NULL);
  1870. if (!KSUCCESS(Status)) {
  1871. goto ParseGpioDescriptorEnd;
  1872. }
  1873. }
  1874. }
  1875. Status = STATUS_SUCCESS;
  1876. ParseGpioDescriptorEnd:
  1877. if (GpioData != NULL) {
  1878. MmFreePagedPool(GpioData);
  1879. }
  1880. return Status;
  1881. }
  1882. KSTATUS
  1883. AcpipParseSpbDescriptor (
  1884. PACPI_OBJECT NamespaceStart,
  1885. PVOID Buffer,
  1886. ULONG BufferLength,
  1887. PRESOURCE_REQUIREMENT_LIST RequirementList
  1888. )
  1889. /*++
  1890. Routine Description:
  1891. This routine converts an ACPI Simple Peripheral Bus resource descriptor
  1892. into a resource requirement, and puts that requirement on the given
  1893. requirement list.
  1894. Arguments:
  1895. NamespaceStart - Supplies a pointer to the starting point for namespace
  1896. traversals.
  1897. Buffer - Supplies a pointer to the SPB descriptor buffer, pointing after
  1898. the length bytes.
  1899. BufferLength - Supplies the length of the descriptor buffer.
  1900. RequirementList - Supplies a pointer to the resource requirement list to
  1901. put the descriptor on.
  1902. Return Value:
  1903. Status code.
  1904. --*/
  1905. {
  1906. PUCHAR BufferPointer;
  1907. UCHAR BusType;
  1908. UCHAR GeneralFlags;
  1909. RESOURCE_SPB_I2C I2cDescriptor;
  1910. PACPI_OBJECT Provider;
  1911. RESOURCE_REQUIREMENT Requirement;
  1912. PSTR SourceName;
  1913. PVOID SpbData;
  1914. PRESOURCE_SPB_DATA SpbDataSource;
  1915. UINTN SpbDataSourceSize;
  1916. RESOURCE_SPB_SPI SpiDescriptor;
  1917. KSTATUS Status;
  1918. USHORT TypeDataLength;
  1919. USHORT TypeSpecificFlags;
  1920. UCHAR TypeSpecificRevisionId;
  1921. RESOURCE_SPB_UART UartDescriptor;
  1922. PVOID VendorData;
  1923. ULONG VendorDataLength;
  1924. BufferPointer = Buffer;
  1925. SpbData = NULL;
  1926. if (BufferLength < 0x0F) {
  1927. Status = STATUS_MALFORMED_DATA_STREAM;
  1928. goto ParseSpbDescriptorEnd;
  1929. }
  1930. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  1931. //
  1932. // Check the revision.
  1933. //
  1934. if (*BufferPointer < 1) {
  1935. Status = STATUS_MALFORMED_DATA_STREAM;
  1936. goto ParseSpbDescriptorEnd;
  1937. }
  1938. BusType = *(BufferPointer + 2);
  1939. GeneralFlags = *(BufferPointer + 3);
  1940. TypeSpecificFlags = READ_UNALIGNED16(BufferPointer + 4);
  1941. TypeSpecificRevisionId = *(BufferPointer + 6);
  1942. TypeDataLength = READ_UNALIGNED16(BufferPointer + 7);
  1943. SourceName = (PSTR)(BufferPointer + 9 + TypeDataLength);
  1944. if (BufferLength < 9 + TypeDataLength) {
  1945. Status = STATUS_MALFORMED_DATA_STREAM;
  1946. goto ParseSpbDescriptorEnd;
  1947. }
  1948. switch (BusType) {
  1949. case ACPI_SPB_BUS_I2C:
  1950. VendorData = BufferPointer + 9 + ACPI_SPB_I2C_TYPE_DATA_LENGTH;
  1951. VendorDataLength = TypeDataLength - ACPI_SPB_I2C_TYPE_DATA_LENGTH;
  1952. Status = AcpipParseSpbI2cDescriptor(TypeSpecificFlags,
  1953. TypeSpecificRevisionId,
  1954. TypeDataLength,
  1955. Buffer + 9,
  1956. &Requirement,
  1957. &I2cDescriptor);
  1958. SpbDataSource = &(I2cDescriptor.Header);
  1959. SpbDataSourceSize = sizeof(RESOURCE_SPB_I2C);
  1960. break;
  1961. case ACPI_SPB_BUS_SPI:
  1962. VendorData = BufferPointer + 9 + ACPI_SPB_SPI_TYPE_DATA_LENGTH;
  1963. VendorDataLength = TypeDataLength - ACPI_SPB_SPI_TYPE_DATA_LENGTH;
  1964. Status = AcpipParseSpbSpiDescriptor(TypeSpecificFlags,
  1965. TypeSpecificRevisionId,
  1966. TypeDataLength,
  1967. Buffer + 9,
  1968. &Requirement,
  1969. &SpiDescriptor);
  1970. SpbDataSource = &(SpiDescriptor.Header);
  1971. SpbDataSourceSize = sizeof(RESOURCE_SPB_SPI);
  1972. break;
  1973. case ACPI_SPB_BUS_UART:
  1974. VendorData = BufferPointer + 9 + ACPI_SPB_UART_TYPE_DATA_LENGTH;
  1975. VendorDataLength = TypeDataLength - ACPI_SPB_UART_TYPE_DATA_LENGTH;
  1976. Status = AcpipParseSpbUartDescriptor(TypeSpecificFlags,
  1977. TypeSpecificRevisionId,
  1978. TypeDataLength,
  1979. Buffer + 9,
  1980. &UartDescriptor);
  1981. SpbDataSource = &(UartDescriptor.Header);
  1982. SpbDataSourceSize = sizeof(RESOURCE_SPB_UART);
  1983. break;
  1984. default:
  1985. ASSERT(FALSE);
  1986. Status = STATUS_MALFORMED_DATA_STREAM;
  1987. break;
  1988. }
  1989. if (!KSUCCESS(Status)) {
  1990. goto ParseSpbDescriptorEnd;
  1991. }
  1992. //
  1993. // Parse the general flags, which are not specific to any bus type.
  1994. //
  1995. if ((GeneralFlags & ACPI_SPB_FLAG_SLAVE) != 0) {
  1996. SpbDataSource->Flags |= RESOURCE_SPB_DATA_SLAVE;
  1997. }
  1998. SpbDataSource->VendorDataOffset = SpbDataSourceSize;
  1999. SpbDataSource->VendorDataSize = VendorDataLength;
  2000. //
  2001. // Find the device providing the resource.
  2002. //
  2003. Provider = AcpipGetNamespaceObject(SourceName, NamespaceStart);
  2004. if (Provider == NULL) {
  2005. RtlDebugPrint("ACPI: Failed to find SPB device '%s'\n", SourceName);
  2006. Status = STATUS_INVALID_CONFIGURATION;
  2007. goto ParseSpbDescriptorEnd;
  2008. }
  2009. if (Provider->Type != AcpiObjectDevice) {
  2010. ASSERT(FALSE);
  2011. Status = STATUS_INVALID_CONFIGURATION;
  2012. goto ParseSpbDescriptorEnd;
  2013. }
  2014. //
  2015. // If the SPB device is not yet started, then fail for now and try again
  2016. // when it's ready.
  2017. //
  2018. if (Provider->U.Device.IsDeviceStarted == FALSE) {
  2019. Status = AcpipCreateDeviceDependency(NamespaceStart->U.Device.OsDevice,
  2020. Provider);
  2021. if (Status != STATUS_TOO_LATE) {
  2022. if (KSUCCESS(Status)) {
  2023. Status = STATUS_NOT_READY;
  2024. }
  2025. goto ParseSpbDescriptorEnd;
  2026. }
  2027. }
  2028. Requirement.Type = ResourceTypeSimpleBus;
  2029. Requirement.Provider = Provider->U.Device.OsDevice;
  2030. ASSERT(Requirement.Provider != NULL);
  2031. SpbData = MmAllocatePagedPool(SpbDataSourceSize + VendorDataLength,
  2032. ACPI_RESOURCE_ALLOCATION_TAG);
  2033. if (SpbData == NULL) {
  2034. Status = STATUS_INSUFFICIENT_RESOURCES;
  2035. goto ParseSpbDescriptorEnd;
  2036. }
  2037. RtlCopyMemory(SpbData, SpbDataSource, SpbDataSourceSize);
  2038. if (VendorDataLength != 0) {
  2039. RtlCopyMemory(SpbData + SpbDataSourceSize,
  2040. VendorData,
  2041. VendorDataLength);
  2042. }
  2043. Requirement.Data = SpbData;
  2044. Requirement.DataSize = SpbDataSourceSize + VendorDataLength;
  2045. Status = IoCreateAndAddResourceRequirement(&Requirement,
  2046. RequirementList,
  2047. NULL);
  2048. if (!KSUCCESS(Status)) {
  2049. goto ParseSpbDescriptorEnd;
  2050. }
  2051. Status = STATUS_SUCCESS;
  2052. ParseSpbDescriptorEnd:
  2053. if (SpbData != NULL) {
  2054. MmFreePagedPool(SpbData);
  2055. }
  2056. return Status;
  2057. }
  2058. KSTATUS
  2059. AcpipParseSpbI2cDescriptor (
  2060. USHORT TypeSpecificFlags,
  2061. UCHAR TypeSpecificRevisionId,
  2062. USHORT TypeDataLength,
  2063. PUCHAR Buffer,
  2064. PRESOURCE_REQUIREMENT Requirement,
  2065. PRESOURCE_SPB_I2C Descriptor
  2066. )
  2067. /*++
  2068. Routine Description:
  2069. This routine parses the bus type specific contents of an I2C resource
  2070. descriptor.
  2071. Arguments:
  2072. TypeSpecificFlags - Supplies the type specific flags.
  2073. TypeSpecificRevisionId - Supplies the type specific revision identifier.
  2074. TypeDataLength - Supplies the type data length.
  2075. Buffer - Supplies a pointer to the descriptor buffer, pointing to the type
  2076. specific data.
  2077. Requirement - Supplies a pointer to the resource requirement.
  2078. Descriptor - Supplies a pointer where the descriptor will be returned on
  2079. success.
  2080. Return Value:
  2081. Status code.
  2082. --*/
  2083. {
  2084. //
  2085. // Check the revision.
  2086. //
  2087. if ((TypeSpecificRevisionId < 1) ||
  2088. (TypeDataLength < ACPI_SPB_I2C_TYPE_DATA_LENGTH)) {
  2089. return STATUS_MALFORMED_DATA_STREAM;
  2090. }
  2091. RtlZeroMemory(Descriptor, sizeof(RESOURCE_SPB_I2C));
  2092. Descriptor->Header.Version = RESOURCE_SPB_DATA_VERSION;
  2093. Descriptor->Header.Size = sizeof(RESOURCE_SPB_I2C);
  2094. Descriptor->Header.BusType = ResourceSpbBusI2c;
  2095. Descriptor->Speed = READ_UNALIGNED32(Buffer);
  2096. Descriptor->SlaveAddress = READ_UNALIGNED16(Buffer + 4);
  2097. if ((TypeSpecificFlags & ACPI_SPB_I2C_10_BIT_ADDRESSING) != 0) {
  2098. Descriptor->Flags |= RESOURCE_SPB_I2C_10_BIT_ADDRESSING;
  2099. }
  2100. Requirement->Minimum = Descriptor->SlaveAddress;
  2101. Requirement->Maximum = Requirement->Minimum + 1;
  2102. Requirement->Length = 1;
  2103. return STATUS_SUCCESS;
  2104. }
  2105. KSTATUS
  2106. AcpipParseSpbSpiDescriptor (
  2107. USHORT TypeSpecificFlags,
  2108. UCHAR TypeSpecificRevisionId,
  2109. USHORT TypeDataLength,
  2110. PUCHAR Buffer,
  2111. PRESOURCE_REQUIREMENT Requirement,
  2112. PRESOURCE_SPB_SPI Descriptor
  2113. )
  2114. /*++
  2115. Routine Description:
  2116. This routine parses the bus type specific contents of an SPI resource
  2117. descriptor.
  2118. Arguments:
  2119. TypeSpecificFlags - Supplies the type specific flags.
  2120. TypeSpecificRevisionId - Supplies the type specific revision identifier.
  2121. TypeDataLength - Supplies the type data length.
  2122. Buffer - Supplies a pointer to the descriptor buffer, pointing to the type
  2123. specific data.
  2124. Requirement - Supplies a pointer to the resource requirement.
  2125. Descriptor - Supplies a pointer where the descriptor will be returned on
  2126. success.
  2127. Return Value:
  2128. Status code.
  2129. --*/
  2130. {
  2131. UCHAR Phase;
  2132. UCHAR Polarity;
  2133. //
  2134. // Check the revision.
  2135. //
  2136. if ((TypeSpecificRevisionId < 1) ||
  2137. (TypeDataLength < ACPI_SPB_SPI_TYPE_DATA_LENGTH)) {
  2138. return STATUS_MALFORMED_DATA_STREAM;
  2139. }
  2140. RtlZeroMemory(Descriptor, sizeof(RESOURCE_SPB_SPI));
  2141. Descriptor->Header.Version = RESOURCE_SPB_DATA_VERSION;
  2142. Descriptor->Header.Size = sizeof(RESOURCE_SPB_SPI);
  2143. Descriptor->Header.BusType = ResourceSpbBusSpi;
  2144. Descriptor->Speed = READ_UNALIGNED32(Buffer);
  2145. Descriptor->WordSize = *(Buffer + 4);
  2146. Phase = *(Buffer + 5);
  2147. Polarity = *(Buffer + 6);
  2148. Descriptor->DeviceSelect = READ_UNALIGNED16(Buffer + 7);
  2149. if (Phase == ACPI_SPB_SPI_PHASE_SECOND) {
  2150. Descriptor->Flags |= RESOURCE_SPB_SPI_SECOND_PHASE;
  2151. }
  2152. if (Polarity == ACPI_SPB_SPI_POLARITY_START_HIGH) {
  2153. Descriptor->Flags |= RESOURCE_SPB_SPI_START_HIGH;
  2154. }
  2155. if ((TypeSpecificFlags & ACPI_SPB_SPI_3_WIRES) != 0) {
  2156. Descriptor->Flags |= RESOURCE_SPB_SPI_3_WIRES;
  2157. }
  2158. if ((TypeSpecificFlags & ACPI_SPB_SPI_DEVICE_SELECT_ACTIVE_HIGH) != 0) {
  2159. Descriptor->Flags |= RESOURCE_SPB_SPI_DEVICE_SELECT_ACTIVE_HIGH;
  2160. }
  2161. if (Descriptor->DeviceSelect != 0) {
  2162. Requirement->Minimum =
  2163. RtlCountTrailingZeros32(Descriptor->DeviceSelect);
  2164. Requirement->Maximum = Requirement->Minimum + 1;
  2165. Requirement->Length = 1;
  2166. }
  2167. return STATUS_SUCCESS;
  2168. }
  2169. KSTATUS
  2170. AcpipParseSpbUartDescriptor (
  2171. USHORT TypeSpecificFlags,
  2172. UCHAR TypeSpecificRevisionId,
  2173. USHORT TypeDataLength,
  2174. PUCHAR Buffer,
  2175. PRESOURCE_SPB_UART Descriptor
  2176. )
  2177. /*++
  2178. Routine Description:
  2179. This routine parses the bus type specific contents of a UART resource
  2180. descriptor.
  2181. Arguments:
  2182. TypeSpecificFlags - Supplies the type specific flags.
  2183. TypeSpecificRevisionId - Supplies the type specific revision identifier.
  2184. TypeDataLength - Supplies the type data length.
  2185. Buffer - Supplies a pointer to the descriptor buffer, pointing to the type
  2186. specific data.
  2187. Descriptor - Supplies a pointer where the descriptor will be returned on
  2188. success.
  2189. Return Value:
  2190. Status code.
  2191. --*/
  2192. {
  2193. UCHAR Parity;
  2194. //
  2195. // Check the revision.
  2196. //
  2197. if ((TypeSpecificRevisionId < 1) ||
  2198. (TypeDataLength < ACPI_SPB_UART_TYPE_DATA_LENGTH)) {
  2199. return STATUS_MALFORMED_DATA_STREAM;
  2200. }
  2201. RtlZeroMemory(Descriptor, sizeof(RESOURCE_SPB_UART));
  2202. Descriptor->Header.Version = RESOURCE_SPB_DATA_VERSION;
  2203. Descriptor->Header.Size = sizeof(RESOURCE_SPB_UART);
  2204. Descriptor->Header.BusType = ResourceSpbBusUart;
  2205. Descriptor->BaudRate = READ_UNALIGNED32(Buffer);
  2206. Descriptor->RxFifoSize = READ_UNALIGNED16(Buffer + 4);
  2207. Descriptor->TxFifoSize = READ_UNALIGNED16(Buffer + 6);
  2208. Parity = *(Buffer + 8);
  2209. //
  2210. // The ACPI control line definitions happen to match up to the OS
  2211. // definitions.
  2212. //
  2213. ASSERT_SPB_UART_CONTROL_LINES_EQUIVALENT();
  2214. Descriptor->ControlLines = *(Buffer + 9);
  2215. switch (Parity) {
  2216. case ACPI_SPB_UART_PARITY_NONE:
  2217. break;
  2218. case ACPI_SPB_UART_PARITY_EVEN:
  2219. Descriptor->Flags |= RESOURCE_SPB_UART_PARITY_EVEN;
  2220. break;
  2221. case ACPI_SPB_UART_PARITY_ODD:
  2222. Descriptor->Flags |= RESOURCE_SPB_UART_PARITY_ODD;
  2223. break;
  2224. case ACPI_SPB_UART_PARITY_MARK:
  2225. Descriptor->Flags |= RESOURCE_SPB_UART_PARITY_MARK;
  2226. break;
  2227. case ACPI_SPB_UART_PARITY_SPACE:
  2228. Descriptor->Flags |= RESOURCE_SPB_UART_PARITY_SPACE;
  2229. break;
  2230. default:
  2231. ASSERT(FALSE);
  2232. break;
  2233. }
  2234. if ((TypeSpecificFlags & ACPI_SPB_UART_BIG_ENDIAN) != 0) {
  2235. Descriptor->Flags |= RESOURCE_SPB_UART_BIG_ENDIAN;
  2236. }
  2237. switch (TypeSpecificFlags & ACPI_SPB_UART_FLOW_CONTROL_MASK) {
  2238. case ACPI_SPB_UART_FLOW_CONTROL_NONE:
  2239. break;
  2240. case ACPI_SPB_UART_FLOW_CONTROL_HARDWARE:
  2241. Descriptor->Flags |= RESOURCE_SPB_UART_FLOW_CONTROL_HARDWARE;
  2242. break;
  2243. case ACPI_SPB_UART_FLOW_CONTROL_SOFTWARE:
  2244. Descriptor->Flags |= RESOURCE_SPB_UART_FLOW_CONTROL_SOFTWARE;
  2245. break;
  2246. default:
  2247. ASSERT(FALSE);
  2248. break;
  2249. }
  2250. switch (TypeSpecificFlags & ACPI_SPB_UART_STOP_BITS_MASK) {
  2251. case ACPI_SPB_UART_STOP_BITS_NONE:
  2252. Descriptor->Flags |= RESOURCE_SPB_UART_STOP_BITS_NONE;
  2253. break;
  2254. case ACPI_SPB_UART_STOP_BITS_1:
  2255. Descriptor->Flags |= RESOURCE_SPB_UART_STOP_BITS_1;
  2256. break;
  2257. case ACPI_SPB_UART_STOP_BITS_1_5:
  2258. Descriptor->Flags |= RESOURCE_SPB_UART_STOP_BITS_1_5;
  2259. break;
  2260. case ACPI_SPB_UART_STOP_BITS_2:
  2261. Descriptor->Flags |= RESOURCE_SPB_UART_STOP_BITS_2;
  2262. break;
  2263. default:
  2264. ASSERT(FALSE);
  2265. break;
  2266. }
  2267. //
  2268. // The data bits values just go 5-9 in increasing order, so just use that
  2269. // value directly (with an offset of 5 of course).
  2270. //
  2271. Descriptor->DataBits = ((TypeSpecificFlags &
  2272. ACPI_SPB_UART_DATA_BITS_MASK) >>
  2273. ACPI_SPB_UART_DATA_BITS_SHIFT) + 5;
  2274. return STATUS_SUCCESS;
  2275. }
  2276. KSTATUS
  2277. AcpipParseLargeVendorDescriptor (
  2278. PVOID Buffer,
  2279. ULONG BufferLength,
  2280. PRESOURCE_REQUIREMENT_LIST RequirementList
  2281. )
  2282. /*++
  2283. Routine Description:
  2284. This routine converts an ACPI large vendor-defined descriptor into a
  2285. resource requirement, and puts that requirement on the given requirement
  2286. list.
  2287. Arguments:
  2288. Buffer - Supplies a pointer to the IRQ descriptor buffer, pointing after the
  2289. length bytes.
  2290. BufferLength - Supplies the length of the descriptor buffer.
  2291. RequirementList - Supplies a pointer to the resource requirement list to
  2292. put the descriptor on.
  2293. Return Value:
  2294. Status code.
  2295. --*/
  2296. {
  2297. PRESOURCE_REQUIREMENT CreatedRequirement;
  2298. RESOURCE_REQUIREMENT Requirement;
  2299. KSTATUS Status;
  2300. CreatedRequirement = NULL;
  2301. RtlZeroMemory(&Requirement, sizeof(RESOURCE_REQUIREMENT));
  2302. Requirement.Type = ResourceTypeVendorSpecific;
  2303. Requirement.Data = Buffer;
  2304. Requirement.DataSize = BufferLength;
  2305. Status = IoCreateAndAddResourceRequirement(&Requirement,
  2306. RequirementList,
  2307. &CreatedRequirement);
  2308. return Status;
  2309. }