CpuPm.asl 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /*-----------------------------------------------------------------------------
  2. Intel Silvermont Processor Power Management BIOS Reference Code
  3. Copyright (c) 2006 - 2014, Intel Corporation
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. Filename: CPUPM.ASL
  6. Revision: Refer to Readme
  7. Date: Refer to Readme
  8. -------------------------------------------------------------------------------
  9. This Processor Power Management BIOS Source Code is furnished under license
  10. and may only be used or copied in accordance with the terms of the license.
  11. The information in this document is furnished for informational use only, is
  12. subject to change without notice, and should not be construed as a commitment
  13. by Intel Corporation. Intel Corporation assumes no responsibility or liability
  14. for any errors or inaccuracies that may appear in this document or any
  15. software that may be provided in association with this document.
  16. Except as permitted by such license, no part of this document may be
  17. reproduced, stored in a retrieval system, or transmitted in any form or by
  18. any means without the express written consent of Intel Corporation.
  19. WARNING: You are authorized and licensed to install and use this BIOS code
  20. ONLY on an IST PC. This utility may damage any system that does not
  21. meet these requirements.
  22. An IST PC is a computer which
  23. (1) Is capable of seamlessly and automatically transitioning among
  24. multiple performance states (potentially operating at different
  25. efficiency ratings) based upon power source changes, END user
  26. preference, processor performance demand, and thermal conditions; and
  27. (2) Includes an Intel Pentium II processors, Intel Pentium III
  28. processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
  29. Processor-M, Intel Pentium M Processor, or any other future Intel
  30. processors that incorporates the capability to transition between
  31. different performance states by altering some, or any combination of,
  32. the following processor attributes: core voltage, core frequency, bus
  33. frequency, number of processor cores available, or any other attribute
  34. that changes the efficiency (instructions/unit time-power) at which the
  35. processor operates.
  36. -------------------------------------------------------------------------------
  37. NOTES:
  38. (1) <TODO> - Except for the SSDT package, the objects in this ASL code
  39. may be moved to the DSDT. It is kept separate in this reference package
  40. for ease of distribution only.
  41. ------------------------------------------------------------------------------*/
  42. DefinitionBlock (
  43. "CPUPM.aml",
  44. "SSDT",
  45. 0x01,
  46. "PmRef",
  47. "CpuPm",
  48. 0x3000
  49. )
  50. {
  51. External(\_PR.CPU0, DeviceObj)
  52. External(\_PR.CPU1, DeviceObj)
  53. External(\_PR.CPU2, DeviceObj)
  54. External(\_PR.CPU3, DeviceObj)
  55. External(SMIF)
  56. Scope(\)
  57. {
  58. // Package of pointers to SSDT's
  59. //
  60. // First column is SSDT name, used for debug only.
  61. // (First column must be EXACTLY eight characters.)
  62. // Second column is physical address.
  63. // Third column is table length.
  64. //
  65. // IF modifying this file, see warnings listed in ppminit.asm.
  66. //
  67. Name(SSDT,Package()
  68. {
  69. "CPU0IST ", 0x80000000, 0x80000000,
  70. "APIST ", 0x80000000, 0x80000000,
  71. "CPU0CST ", 0x80000000, 0x80000000,
  72. "APCST ", 0x80000000, 0x80000000
  73. })
  74. //
  75. // Note: See PpmBiosInit in PPMINIT.ASM for a definition of
  76. // the PpmFlags mirrored in CFGD.
  77. //
  78. Name(CFGD, 0x80000000)
  79. Name(\PDC0,0x80000000) // CPU0 _PDC Flags.
  80. Name(\PDC1,0x80000000) // CPU1 _PDC Flags.
  81. Name(\PDC2,0x80000000) // CPU2 _PDC Flags.
  82. Name(\PDC3,0x80000000) // CPU3 _PDC Flags.
  83. Name(\SDTL,0x00) // Loaded SSDT Flags.
  84. }
  85. Scope(\_PR.CPU0)
  86. {
  87. //
  88. // Define handles for opregions (used by load.)
  89. //
  90. Name(HI0,0) // Handle to CPU0IST
  91. Name(HC0,0) // Handle to CPU0CST
  92. Method(_PDC,1)
  93. {
  94. //
  95. // Check and extract the _PDC information.
  96. //
  97. Store(CPDC(Arg0), Local0)
  98. //
  99. // Save the capability information and load tables as needed.
  100. //
  101. GCAP(Local0)
  102. //
  103. // Return status.
  104. //
  105. //Return (Local0)
  106. }
  107. Method(_OSC, 4)
  108. {
  109. //
  110. // Check and extract the _OSC information.
  111. //
  112. Store(COSC(Arg0, Arg1, Arg2, Arg3), Local0)
  113. //
  114. // Save the capability information and load tables as needed.
  115. //
  116. GCAP(Local0)
  117. //
  118. // Return status.
  119. //
  120. Return (Local0)
  121. }
  122. //
  123. // Implement a generic Method to check _PDC information which may be called
  124. // by any of the processor scopes. (The use of _PDC is deprecated in ACPI 3.
  125. // in favor of _OSC. However, for backwards compatibility, _PDC may be
  126. // implemented using _OSC as follows:)
  127. //
  128. Method(CPDC,1)
  129. {
  130. CreateDwordField (Arg0, 0, REVS)
  131. CreateDwordField (Arg0, 4, SIZE)
  132. //
  133. // Local0 = Number of bytes for Arg0
  134. //
  135. Store (SizeOf (Arg0), Local0)
  136. //
  137. // Local1 = Number of Capabilities bytes in Arg0
  138. //
  139. Store (Subtract (Local0, 8), Local1)
  140. //
  141. // TEMP = Temporary field holding Capability DWORDs
  142. //
  143. CreateField (Arg0, 64, Multiply (Local1, 8), TEMP)
  144. //
  145. // Create the Status (STAT) buffer with the first DWORD = 0
  146. // This is required as per ACPI 3.0 Spec which says the
  147. // first DWORD is used to return errors defined by _OSC.
  148. //
  149. Name (STS0, Buffer () {0x00, 0x00, 0x00, 0x00})
  150. //
  151. // Concatenate the _PDC capabilities bytes to the STS0 Buffer
  152. // and store them in a local variable for calling OSC
  153. //
  154. Concatenate (STS0, TEMP, Local2)
  155. Return(COSC (ToUUID("4077A616-290C-47BE-9EBD-D87058713953"), REVS, SIZE, Local2))
  156. }
  157. //
  158. // Implement a generic Method to check _OSC information which may be called
  159. // by any of the processor scopes.
  160. //
  161. Method(COSC, 4)
  162. {
  163. //
  164. // Point to Status DWORD in the Arg3 buffer (STATUS)
  165. //
  166. CreateDWordField(Arg3, 0, STS0)
  167. //
  168. // Point to Caps DWORDs of the Arg3 buffer (CAPABILITIES)
  169. //
  170. CreateDwordField(Arg3, 4, CAP0)
  171. //
  172. // _OSC needs to validate the UUID and Revision.
  173. //
  174. // IF Unrecognized UUID
  175. // Return Unrecognized UUID _OSC Failure
  176. // IF Unsupported Revision
  177. // Return Unsupported Revision _OSC Failure
  178. //
  179. // STS0[0] = Reserved
  180. // STS0[1] = _OSC Failure
  181. // STS0[2] = Unrecognized UUID
  182. // STS0[3] = Unsupported Revision
  183. // STS0[4] = Capabilities masked
  184. //
  185. // Note: The comparison method used is necessary due to
  186. // limitations of certain OSes which cannot perform direct
  187. // buffer comparisons.
  188. //
  189. // Create a set of "Input" UUID fields.
  190. //
  191. CreateDwordField(Arg0, 0x0, IID0)
  192. CreateDwordField(Arg0, 0x4, IID1)
  193. CreateDwordField(Arg0, 0x8, IID2)
  194. CreateDwordField(Arg0, 0xC, IID3)
  195. //
  196. // Create a set of "Expected" UUID fields.
  197. //
  198. Name(UID0, ToUUID("4077A616-290C-47BE-9EBD-D87058713953"))
  199. CreateDwordField(UID0, 0x0, EID0)
  200. CreateDwordField(UID0, 0x4, EID1)
  201. CreateDwordField(UID0, 0x8, EID2)
  202. CreateDwordField(UID0, 0xC, EID3)
  203. //
  204. // Verify the input UUID matches the expected UUID.
  205. //
  206. If(LNot(LAnd(LAnd(LEqual(IID0, EID0),LEqual(IID1, EID1)),LAnd(LEqual(IID2, EID2),LEqual(IID3, EID3)))))
  207. {
  208. //
  209. // Return Unrecognized UUID _OSC Failure
  210. //
  211. Store (0x6, STS0)
  212. Return (Arg3)
  213. }
  214. If(LNot(LEqual(Arg1,1)))
  215. {
  216. //
  217. // Return Unsupported Revision _OSC Failure
  218. //
  219. Store (0xA, STS0)
  220. Return (Arg3)
  221. }
  222. Return (Arg3)
  223. }
  224. //
  225. // Get the capability information and load appropriate tables as needed.
  226. //
  227. Method(GCAP, 1)
  228. {
  229. // Point to Status DWORD in the Arg0 buffer (STATUS)
  230. CreateDWordField(Arg0, 0, STS0)
  231. // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
  232. CreateDwordField(Arg0, 4, CAP0)
  233. //
  234. // If the UUID was unrecognized or the _OSC revision was unsupported,
  235. // return without updating capabilities.
  236. //
  237. If(LOr(LEqual(STS0,0x6),LEqual(STS0,0xA)))
  238. {
  239. Return()
  240. }
  241. //
  242. // Check if this is a query (BIT0 of Status = 1).
  243. // If so, mask off the bits we support and return.
  244. //
  245. if (And(STS0, 1))
  246. {
  247. And(CAP0, 0xBFF, CAP0)
  248. Return()
  249. }
  250. //
  251. // Store result of PDC. (We clear out the MSB, which was just
  252. // used as a placeholder for the compiler; and then "OR" the
  253. // value in case we get multiple calls, each of which only
  254. // reports partial support.)
  255. //
  256. Or(And(PDC0, 0x7FFFFFFF), CAP0, PDC0)
  257. //
  258. // Check IF the IST SSDTs should be loaded.
  259. //
  260. // CFGD[0] = GV3 Capable/Enabled
  261. //
  262. If(And(CFGD,0x01))
  263. {
  264. //
  265. // Load the IST SSDTs if:
  266. // (1) CMP capable and enabled.
  267. // (2) Driver supports P-States in MP configurations
  268. // (3) Driver supports direct HW P-State control
  269. // (4) SSDT is not already loaded
  270. //
  271. // CFGD[24] = Two or more cores enabled
  272. // PDCx[3] = OS supports C1 and P-states in MP systems
  273. // PDCx[0] = OS supports direct access of the perf MSR
  274. // SDTL[0] = CPU0 IST SSDT Loaded
  275. //
  276. If(LAnd(LAnd(And(CFGD,0x01000000),LEqual(And(PDC0, 0x0009), 0x0009)),LNot(And(SDTL,0x01))))
  277. {
  278. //
  279. // Flag the IST SSDT as loaded for CPU0
  280. //
  281. Or(SDTL, 0x01, SDTL)
  282. OperationRegion(IST0,SystemMemory,DeRefOf(Index(SSDT,1)),DeRefOf(Index(SSDT,2)))
  283. Load(IST0, HI0) // Dynamically load the CPU0IST SSDT
  284. }
  285. }
  286. //
  287. // Check IF the CST SSDTs should be loaded.
  288. //
  289. // CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
  290. //
  291. If(And(CFGD,0x82))
  292. {
  293. //
  294. // Load the CST SSDTs if:
  295. // (1) CMP capable/enabled
  296. // (2) Driver supports multi-processor configurations
  297. // (3) CPU0 CST ISDT is not already loaded
  298. //
  299. // CFGD[24] = Two or more cores enabled
  300. // PDCx[3] = OS supports C1 and P-states in MP systems
  301. // PDCx[4] = OS supports ind. C2/C3 in MP systems
  302. // SDTL[1] = CPU0 CST SSDT Loaded
  303. //
  304. If(LAnd(LAnd(And(CFGD,0x01000000),And(PDC0,0x0018)),LNot(And(SDTL,0x02))))
  305. {
  306. //
  307. // Flag the CST SSDT as loaded for CPU0
  308. //
  309. Or(SDTL, 0x02, SDTL)
  310. OperationRegion(CST0,SystemMemory,DeRefOf(Index(SSDT,7)),DeRefOf(Index(SSDT,8)))
  311. Load(CST0, HC0) // Dynamically load the CPU0CST SSDT
  312. }
  313. }
  314. Return ()
  315. }
  316. }
  317. Scope(\_PR.CPU1)
  318. {
  319. //
  320. // Define handles for opregions (used by load.)
  321. //
  322. Name(HI1,0) // Handle to APIST
  323. Name(HC1,0) // Handle to APCST
  324. Method(_PDC,1)
  325. {
  326. //
  327. // Refer to \_PR.CPU0._PDC for description.
  328. //
  329. Store(\_PR.CPU0.CPDC(Arg0), Local0)
  330. GCAP(Local0)
  331. //Return (Local0)
  332. }
  333. Method(_OSC, 4)
  334. {
  335. //
  336. // Refer to \_PR.CPU0._OSC for description.
  337. //
  338. Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
  339. GCAP(Local0)
  340. Return (Local0)
  341. }
  342. //
  343. // Get the capability information and load appropriate tables as needed.
  344. //
  345. Method(GCAP, 1)
  346. {
  347. //
  348. // Point to Status DWORD in the Arg0 buffer (STATUS)
  349. //
  350. CreateDWordField(Arg0, 0, STS1)
  351. //
  352. // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
  353. //
  354. CreateDwordField(Arg0, 4, CAP1)
  355. //
  356. // If the UUID was unrecognized or the _OSC revision was unsupported,
  357. // return without updating capabilities.
  358. //
  359. If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
  360. {
  361. Return()
  362. }
  363. //
  364. // Check if this is a query (BIT0 of Status = 1).
  365. // If so, mask off the bits we support and return.
  366. //
  367. if (And(STS1, 1))
  368. {
  369. And(CAP1, 0xBFF, CAP1)
  370. Return()
  371. }
  372. //
  373. // Store result of PDC. (We clear out the MSB, which was just
  374. // used as a placeholder for the compiler; and then "OR" the
  375. // value in case we get multiple calls, each of which only
  376. // reports partial support.)
  377. //
  378. Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
  379. //
  380. // Attempt to dynamically load the IST SSDTs if:
  381. // (1) Driver supports P-States in MP configurations
  382. // (2) Driver supports direct HW P-State control
  383. //
  384. // PDCx[3] = OS supports C1 and P-states in MP systems
  385. // PDCx[0] = OS supports direct access of the perf MSR
  386. //
  387. If(LEqual(And(PDC0, 0x0009), 0x0009))
  388. {
  389. APPT()
  390. }
  391. //
  392. // Load the CST SSDTs if:
  393. // (1) Driver supports multi-processor configurations
  394. //
  395. // PDCx[3] = OS supports C1 and P-states in MP systems
  396. // PDCx[4] = OS supports ind. C2/C3 in MP systems
  397. //
  398. If(And(PDC0,0x0018))
  399. {
  400. APCT()
  401. }
  402. Return()
  403. }
  404. //
  405. // Dynamically load the CST SSDTs if:
  406. // (1) C-States are enabled
  407. // (2) SSDT is not already loaded
  408. //
  409. // CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
  410. // SDTL[5] = AP CST SSDT Loaded
  411. //
  412. Method(APCT,0)
  413. {
  414. If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
  415. {
  416. //
  417. // Flag the CST SSDT as loaded for the AP's
  418. //
  419. Or(SDTL, 0x20, SDTL)
  420. //
  421. // Dynamically load the APCST SSDT
  422. //
  423. OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(Index(SSDT,11)))
  424. Load(CST1, HC1)
  425. }
  426. }
  427. //
  428. // Dynamically load the IST SSDTs if:
  429. // (1) If GV3 capable and enabled
  430. // (2) SSDT is not already loaded
  431. //
  432. // CFGD[0] = GV3 Capable/Enabled
  433. // SDTL[4] = AP IST SSDT Loaded
  434. //
  435. Method(APPT,0)
  436. {
  437. If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
  438. {
  439. //
  440. // Flag the IST SSDT as loaded for CPU0
  441. //
  442. Or(SDTL, 0x10, SDTL)
  443. OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(Index(SSDT,5)))
  444. Load(IST1, HI1) // Dynamically load the CPU1IST SSDT
  445. }
  446. }
  447. } // End CPU1
  448. Scope(\_PR.CPU2)
  449. {
  450. //
  451. // Define handles for opregions (used by load.)
  452. //
  453. Name(HI1,0) // Handle to APIST
  454. Name(HC1,0) // Handle to APCST
  455. Method(_PDC,1)
  456. {
  457. //
  458. // Refer to \_PR.CPU0._PDC for description.
  459. //
  460. Store(\_PR.CPU0.CPDC(Arg0), Local0)
  461. GCAP(Local0)
  462. //Return (Local0)
  463. }
  464. Method(_OSC, 4)
  465. {
  466. //
  467. // Refer to \_PR.CPU0._OSC for description.
  468. //
  469. Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
  470. GCAP(Local0)
  471. Return (Local0)
  472. }
  473. //
  474. // Get the capability information and load appropriate tables as needed.
  475. //
  476. Method(GCAP, 1)
  477. {
  478. //
  479. // Point to Status DWORD in the Arg0 buffer (STATUS)
  480. //
  481. CreateDWordField(Arg0, 0, STS1)
  482. //
  483. // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
  484. //
  485. CreateDwordField(Arg0, 4, CAP1)
  486. //
  487. // If the UUID was unrecognized or the _OSC revision was unsupported,
  488. // return without updating capabilities.
  489. //
  490. If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
  491. {
  492. Return()
  493. }
  494. //
  495. // Check if this is a query (BIT0 of Status = 1).
  496. // If so, mask off the bits we support and return.
  497. //
  498. if (And(STS1, 1))
  499. {
  500. And(CAP1, 0xBFF, CAP1)
  501. Return()
  502. }
  503. //
  504. // Store result of PDC. (We clear out the MSB, which was just
  505. // used as a placeholder for the compiler; and then "OR" the
  506. // value in case we get multiple calls, each of which only
  507. // reports partial support.)
  508. //
  509. Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
  510. //
  511. // Attempt to dynamically load the IST SSDTs if:
  512. // (1) Driver supports P-States in MP configurations
  513. // (2) Driver supports direct HW P-State control
  514. //
  515. // PDCx[3] = OS supports C1 and P-states in MP systems
  516. // PDCx[0] = OS supports direct access of the perf MSR
  517. //
  518. If(LEqual(And(PDC0, 0x0009), 0x0009))
  519. {
  520. APPT()
  521. }
  522. //
  523. // Load the CST SSDTs if:
  524. // (1) Driver supports multi-processor configurations
  525. //
  526. // PDCx[3] = OS supports C1 and P-states in MP systems
  527. // PDCx[4] = OS supports ind. C2/C3 in MP systems
  528. //
  529. If(And(PDC0,0x0018))
  530. {
  531. APCT()
  532. }
  533. Return()
  534. }
  535. //
  536. // Dynamically load the CST SSDTs if:
  537. // (1) C-States are enabled
  538. // (2) SSDT is not already loaded
  539. //
  540. // CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
  541. // SDTL[5] = AP CST SSDT Loaded
  542. //
  543. Method(APCT,0)
  544. {
  545. If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
  546. {
  547. //
  548. // Flag the CST SSDT as loaded for the AP's
  549. //
  550. Or(SDTL, 0x20, SDTL)
  551. //
  552. // Dynamically load the APCST SSDT
  553. //
  554. OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(Index(SSDT,11)))
  555. Load(CST1, HC1)
  556. }
  557. }
  558. //
  559. // Dynamically load the IST SSDTs if:
  560. // (1) If GV3 capable and enabled
  561. // (2) SSDT is not already loaded
  562. //
  563. // CFGD[0] = GV3 Capable/Enabled
  564. // SDTL[4] = AP IST SSDT Loaded
  565. //
  566. Method(APPT,0)
  567. {
  568. If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
  569. {
  570. //
  571. // Flag the IST SSDT as loaded for CPU0
  572. //
  573. Or(SDTL, 0x10, SDTL)
  574. OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(Index(SSDT,5)))
  575. Load(IST1, HI1) // Dynamically load the CPU1IST SSDT
  576. }
  577. }
  578. } // End CPU1
  579. Scope(\_PR.CPU3)
  580. {
  581. //
  582. // Define handles for opregions (used by load.)
  583. //
  584. Name(HI1,0) // Handle to APIST
  585. Name(HC1,0) // Handle to APCST
  586. Method(_PDC,1)
  587. {
  588. //
  589. // Refer to \_PR.CPU0._PDC for description.
  590. //
  591. Store(\_PR.CPU0.CPDC(Arg0), Local0)
  592. GCAP(Local0)
  593. //Return (Local0)
  594. }
  595. Method(_OSC, 4)
  596. {
  597. //
  598. // Refer to \_PR.CPU0._OSC for description.
  599. //
  600. Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
  601. GCAP(Local0)
  602. Return (Local0)
  603. }
  604. //
  605. // Get the capability information and load appropriate tables as needed.
  606. //
  607. Method(GCAP, 1)
  608. {
  609. //
  610. // Point to Status DWORD in the Arg0 buffer (STATUS)
  611. //
  612. CreateDWordField(Arg0, 0, STS1)
  613. //
  614. // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
  615. //
  616. CreateDwordField(Arg0, 4, CAP1)
  617. //
  618. // If the UUID was unrecognized or the _OSC revision was unsupported,
  619. // return without updating capabilities.
  620. //
  621. If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
  622. {
  623. Return()
  624. }
  625. //
  626. // Check if this is a query (BIT0 of Status = 1).
  627. // If so, mask off the bits we support and return.
  628. //
  629. if (And(STS1, 1))
  630. {
  631. And(CAP1, 0xBFF, CAP1)
  632. Return()
  633. }
  634. //
  635. // Store result of PDC. (We clear out the MSB, which was just
  636. // used as a placeholder for the compiler; and then "OR" the
  637. // value in case we get multiple calls, each of which only
  638. // reports partial support.)
  639. //
  640. Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
  641. //
  642. // Attempt to dynamically load the IST SSDTs if:
  643. // (1) Driver supports P-States in MP configurations
  644. // (2) Driver supports direct HW P-State control
  645. //
  646. // PDCx[3] = OS supports C1 and P-states in MP systems
  647. // PDCx[0] = OS supports direct access of the perf MSR
  648. //
  649. If(LEqual(And(PDC0, 0x0009), 0x0009))
  650. {
  651. APPT()
  652. }
  653. //
  654. // Load the CST SSDTs if:
  655. // (1) Driver supports multi-processor configurations
  656. //
  657. // PDCx[3] = OS supports C1 and P-states in MP systems
  658. // PDCx[4] = OS supports ind. C2/C3 in MP systems
  659. //
  660. If(And(PDC0,0x0018))
  661. {
  662. APCT()
  663. }
  664. Return()
  665. }
  666. //
  667. // Dynamically load the CST SSDTs if:
  668. // (1) C-States are enabled
  669. // (2) SSDT is not already loaded
  670. //
  671. // CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
  672. // SDTL[5] = AP CST SSDT Loaded
  673. //
  674. Method(APCT,0)
  675. {
  676. If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
  677. {
  678. //
  679. // Flag the CST SSDT as loaded for the AP's
  680. //
  681. Or(SDTL, 0x20, SDTL)
  682. //
  683. // Dynamically load the APCST SSDT
  684. //
  685. OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(Index(SSDT,11)))
  686. Load(CST1, HC1)
  687. }
  688. }
  689. //
  690. // Dynamically load the IST SSDTs if:
  691. // (1) If GV3 capable and enabled
  692. // (2) SSDT is not already loaded
  693. //
  694. // CFGD[0] = GV3 Capable/Enabled
  695. // SDTL[4] = AP IST SSDT Loaded
  696. //
  697. Method(APPT,0)
  698. {
  699. If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
  700. {
  701. //
  702. // Flag the IST SSDT as loaded for CPU0
  703. //
  704. Or(SDTL, 0x10, SDTL)
  705. OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(Index(SSDT,5)))
  706. Load(IST1, HI1) // Dynamically load the CPU1IST SSDT
  707. }
  708. }
  709. } // End CPU3
  710. } // End of Definition Block