Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1046 lines
35 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1993 Digital Equipment Corporation
  3. Module Name:
  4. gammaio.s
  5. Abstract:
  6. This contains assembler code routines for the Gamma system.
  7. The module contains the functions to turn quasi virtual
  8. addresses into an Alpha superpage virtual address
  9. and then read or write based on the request.
  10. (We are using EV4 64-bit superpage mode.)
  11. Author:
  12. Joe Notarangelo 25-Oct-1993
  13. Environment:
  14. Executes in kernel mode.
  15. Revision History:
  16. --*/
  17. #include "gamma.h"
  18. #include "halalpha.h"
  19. // Superpage VA
  20. //
  21. // This value is used to define the base physical address from which
  22. // QVA's are defined.
  23. //
  24. // This value is specified as a negative number so that the value will
  25. // be sign extended when loaded into a register. If defined positive, the
  26. // assembler will prevent sign extension.
  27. //
  28. #define GAMMA_IO_SVA -0x3800 // negative of 0xc800
  29. .set noreorder
  30. LEAF_ENTRY(WRITE_T2_REGISTER)
  31. ALTERNATE_ENTRY(WRITE_CPU_REGISTER)
  32. ALTERNATE_ENTRY(WRITE_MEM_REGISTER)
  33. /*++
  34. Routine Description:
  35. Writes a T2 or a CPU CSR.
  36. Arguments:
  37. a0 QVA of register to be written.
  38. a1 Longword to be written.
  39. Return Value:
  40. None.
  41. --*/
  42. and a0, QVA_SELECTORS, t1 // get qva selector bits
  43. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set in selectors
  44. bne t1, 2f // if ne, iff failed
  45. zap a0, 0xf0, a0 // clear <63:32>
  46. bic a0, QVA_ENABLE, a0 // clear QVA fields so shift is correct
  47. sll a0, IO_BIT_SHIFT, t0
  48. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  49. sll t4, 28, t4 // 0xffff fc80 0000 0000
  50. or t0, t4, t0 // superpage mode
  51. stq a1, (t0) // write the quadword
  52. mb // order the write
  53. mb
  54. ret zero, (ra)
  55. 2:
  56. BREAK_DEBUG_STOP // Bad Qva
  57. ret zero, (ra)
  58. .end WRITE_T2_REGISTER
  59. LEAF_ENTRY(READ_T2_REGISTER)
  60. ALTERNATE_ENTRY(READ_CPU_REGISTER)
  61. ALTERNATE_ENTRY(READ_MEM_REGISTER)
  62. /*++
  63. Routine Description:
  64. Read a T2 or CPU CSR.
  65. Arguments:
  66. a0 QVA of register to be read.
  67. Return Value:
  68. The quadword read from the register.
  69. --*/
  70. and a0, QVA_SELECTORS, t1 // get qva selector bits
  71. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set in selectors
  72. bne t1, 2f // if ne, iff failed
  73. zap a0, 0xf0, a0 // clear <63:32>
  74. bic a0, QVA_ENABLE, a0 // clear QVA fields so shift is correct
  75. sll a0, IO_BIT_SHIFT, t0
  76. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  77. sll t4, 28, t4 // 0xffff fc80 0000 0000
  78. or t0, t4, t0 // superpage mode
  79. //
  80. // Save Address of Config space access for the machine check handler:
  81. // (This isn't a config space access, but the exception handling is identical)
  82. //
  83. lda t1, HalpConfigIoAccess
  84. lda t4, CPUCsrRead // machine check return address
  85. stl t4, 0(t1)
  86. mb // commit the store before reading
  87. DISABLE_INTERRUPTS // don't allow ints before Mcheck
  88. CPUCsrRead:
  89. ldq v0, (t0) // read the register
  90. mb // synchronize
  91. mb //
  92. stl zero, 0(t1) // Restore HalpConfigIoAccess
  93. ENABLE_INTERRUPTS // Interrupts OK after Mcheck
  94. ret zero, (ra)
  95. 2:
  96. BREAK_DEBUG_STOP // Bad Qva
  97. ret zero, (ra)
  98. .end READ_T2_REGISTER
  99. //
  100. // Values and structures used to access configuration space.
  101. //
  102. //
  103. // Define the QVA for the Configuration Cycle Type register within the
  104. // IOC.
  105. //
  106. // PASS 1 SABLE SUPPORT
  107. #define T2_HAE0_2_QVA (0xbc700008)
  108. #define T2_HAE02_CYCLETYPE_SHIFT 30
  109. #define T2_HAE02_CYCLETYPE_MASK 0xc0000000
  110. // PASS 2 SABLE SUPPORT
  111. #define T2_HAE03_CYCLETYPE_SHIFT 30
  112. #define T2_HAE03_CYCLETYPE_MASK 0xc0000000
  113. #define T2_HAE0_3_QVA (0xbc700012)
  114. #define T2_CONFIG_ADDR_QVA (0xbc800000)
  115. //
  116. // T4 Support:
  117. //
  118. #define T4_HAE0_3_QVA (0xbc780012)
  119. #define T4_CONFIG_ADDR_QVA (0xbcc00000)
  120. //
  121. // Define the configuration routines stack frame.
  122. //
  123. .struct 0
  124. CfgRa: .space 8 // return address
  125. CfgA0: .space 8 // saved ConfigurationAddress
  126. CfgA1: .space 8 // saved ConfigurationData
  127. CfgA2: .space 8 // padding for 16 byte alignment
  128. CfgFrameLength:
  129. //++
  130. //
  131. // ULONG
  132. // READ_CONFIG_UCHAR(
  133. // ULONG ConfigurationAddress,
  134. // ULONG ConfigurationCycleType
  135. // )
  136. //
  137. // Routine Description:
  138. //
  139. // Read an unsigned byte from PCI configuration space.
  140. //
  141. // Arguments:
  142. //
  143. // ConfigurationAddress(a0) - Supplies the QVA of configuration to be read.
  144. //
  145. // ConfigurationCycleType(a1) - Supplies the type of the configuration cycle.
  146. //
  147. // Return Value:
  148. //
  149. // (v0) Returns the value of configuration space at the specified location.
  150. //
  151. // N.B. - This routine follows a protocol for reading from PCI configuration
  152. // space that allows the HAL or firmware to fixup and continue
  153. // execution if no device exists at the configuration target address.
  154. // The protocol requires 2 rules:
  155. // (1) The configuration space load must use a destination register
  156. // of v0
  157. // (2) The instruction immediately following the configuration space
  158. // load must use v0 as an operand (it must consume the value
  159. // returned by the load)
  160. //
  161. //--
  162. NESTED_ENTRY( READ_CONFIG_UCHAR, CfgFrameLength, zero )
  163. lda sp, -CfgFrameLength(sp) // allocate stack frame
  164. stq ra, CfgRa(sp) // save return address
  165. PROLOGUE_END // end prologue
  166. //
  167. // Depending on whether it's a pass 1 or pass 2 T2 the configuration
  168. // cycle type is in different registers
  169. //
  170. ldl t0, T2VersionNumber // load version number
  171. beq t0, 1f // if 0 then pass 1 T2
  172. //
  173. // PASS 2 T2 or XIO access:
  174. // Cycle type are the only bits in HAE0_3 register
  175. //
  176. stq a0, CfgA0(sp) // save config space address
  177. //
  178. // Determine whether access is to T2 or T4 space:
  179. // Isolate the Base address bits: bit 22 indicates T4 space access
  180. //
  181. ldil t0, T4_CONFIG_ADDR_QVA // check for QVA in T4 space
  182. and t0, a0, t1 // isolate QVA base address
  183. ldil a0, T2_HAE0_3_QVA // address of T2 space HAE0_3
  184. xor t0, t1, t0 // T4 address space ? (bit 22 set)
  185. ldil t1, T4_HAE0_3_QVA // load address of T4 HAE register
  186. cmoveq t0, t1, a0 // if in T4 space, update a0
  187. sll a1, T2_HAE03_CYCLETYPE_SHIFT, a1 // put cycle type in position
  188. bsr ra, WRITE_T2_REGISTER // write updated HAE
  189. br zero, 2f // go do actual read
  190. //
  191. // PASS 1 T2
  192. // Merge the configuration cycle type into the HAE0_2 register within
  193. // the T2.
  194. //
  195. 1:
  196. stq a0, CfgA0(sp) // save config space address
  197. stq a1, CfgA1(sp) // save config cycle type
  198. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  199. bsr ra, READ_T2_REGISTER // read current value
  200. ldq a1, CfgA1(sp) // restore config cycle type
  201. ldil t0, T2_HAE02_CYCLETYPE_MASK // get cycle type field mask
  202. bic v0, t0, t0 // clear config cycle type field
  203. sll a1, T2_HAE02_CYCLETYPE_SHIFT, a1// put cycle type in position
  204. bis a1, t0, a1 // merge config cycle type
  205. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  206. bsr ra, WRITE_T2_REGISTER // write updated HAE
  207. //
  208. // Perform the read from configuration space after restoring the
  209. // configuration space address.
  210. //
  211. 2:
  212. ldq a0, CfgA0(sp) // restore config space address
  213. and a0, QVA_SELECTORS, t1 // get qva selector bits
  214. and a0, 0x3, t3 // capture byte lane
  215. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set
  216. bne t1, 3f // if ne, iff failed
  217. zap a0, 0xf0, a0 // clear <63:32>
  218. bic a0, QVA_ENABLE, a0 // clear QVA fields
  219. sll a0, IO_BIT_SHIFT, t0 //
  220. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  221. sll t4, 28, t4 // 0xffff fc80 0000 0000
  222. bis t0, t4, t0 // superpage mode
  223. bis t0, IO_BYTE_LEN, t0 // or in the byte enables
  224. //
  225. // Save Address of Config space address for the machine check handler:
  226. //
  227. lda t1, HalpConfigIoAccess
  228. lda t4, CfgUcharRead // machine check return address
  229. stl t4, 0(t1)
  230. mb // commit the store before reading
  231. DISABLE_INTERRUPTS // don't allow ints before Mcheck
  232. CfgUcharRead:
  233. ldl v0, (t0) // read the longword
  234. extbl v0, t3, v0 // return byte from requested lane
  235. // also, consume loaded value
  236. // to cause a pipeline stall
  237. mb // Gamma requires MBs or the
  238. mb // machine check may happen
  239. // much later
  240. stl zero, 0(t1) // Restore HalpConfigIoAccess
  241. ENABLE_INTERRUPTS // Interrupts OK after Mcheck
  242. 3: //
  243. ldq ra, CfgRa(sp) // restore return address
  244. lda sp, CfgFrameLength(sp) // deallocate stack frame
  245. ret zero, (ra) // return
  246. .end READ_CONFIG_UCHAR
  247. //++
  248. //
  249. // VOID
  250. // WRITE_CONFIG_UCHAR(
  251. // ULONG ConfigurationAddress,
  252. // UCHAR ConfigurationData,
  253. // ULONG ConfigurationCycleType
  254. // )
  255. //
  256. // Routine Description:
  257. //
  258. // Read an unsigned byte from PCI configuration space.
  259. //
  260. // Arguments:
  261. //
  262. // ConfigurationAddress(a0) - Supplies the QVA to write.
  263. //
  264. // ConfigurationData(a1) - Supplies the data to be written.
  265. //
  266. // ConfigurationCycleType(a2) - Supplies the type of the configuration cycle.
  267. //
  268. // Return Value:
  269. //
  270. // None.
  271. //
  272. // N.B. - The configuration address must exist within the address space
  273. // allocated to an existing PCI device. Otherwise, the access
  274. // below will initiate an unrecoverable machine check.
  275. //
  276. //--
  277. NESTED_ENTRY( WRITE_CONFIG_UCHAR, CfgFrameLength, zero )
  278. lda sp, -CfgFrameLength(sp) // allocate stack frame
  279. stq ra, CfgRa(sp) // save return address
  280. PROLOGUE_END // end prologue
  281. //
  282. // Depending on whether it's a pass 1 or pass 2 T2 the configuration
  283. // cycle type is in different registers
  284. //
  285. ldl t0, T2VersionNumber // load version number
  286. beq t0, 1f // if 0 then pass 1 T2
  287. //
  288. // PASS 2 T2 or XIO access:
  289. // Merge the configuration cycle type into the HAE0_3 register within
  290. // the T2.
  291. //
  292. stq a0, CfgA0(sp) // save config space address
  293. stq a1, CfgA1(sp) // save config data
  294. //
  295. // Determine whether access is to T2 or T4 space:
  296. // Isolate the Base address bits: bit 22 indicates T4 space access
  297. //
  298. ldil t0, T4_CONFIG_ADDR_QVA // check for QVA in T4 space
  299. and t0, a0, t1 // isolate QVA base address
  300. ldil a0, T2_HAE0_3_QVA // address of HAE0_3
  301. xor t0, t1, t0 // T4 address space ? (bit 22 set)
  302. ldil t1, T4_HAE0_3_QVA // load address of T4 HAE register
  303. cmoveq t0, t1, a0 // if in T4 space, update a0
  304. sll a2, T2_HAE03_CYCLETYPE_SHIFT, a1 // put cycle type into position
  305. bsr ra, WRITE_T2_REGISTER // write updated HAE
  306. br zero, 2f
  307. //
  308. // Merge the configuration cycle type into the HAE0_3 register within
  309. // the T2.
  310. //
  311. 1:
  312. stq a0, CfgA0(sp) // save config space address
  313. stq a1, CfgA1(sp) // save config data
  314. stq a2, CfgA2(sp) // save config cycle type
  315. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  316. bsr ra, READ_T2_REGISTER // read current value
  317. ldq a1, CfgA2(sp) // restore config cycle type
  318. ldil t0, T2_HAE02_CYCLETYPE_MASK // get cycle type field mask
  319. bic v0, t0, t0 // clear config cycle type field
  320. sll a1, T2_HAE02_CYCLETYPE_SHIFT, a1 // put cycle type into position
  321. bis a1, t0, a1 // merge config cycle type
  322. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  323. bsr ra, WRITE_T2_REGISTER // write updated HAE
  324. //
  325. // Perform the read from configuration space after restoring the
  326. // configuration space address and data.
  327. //
  328. 2:
  329. ldq a0, CfgA0(sp) // restore config space address
  330. ldq a1, CfgA1(sp) // restore config data
  331. and a0, QVA_SELECTORS, t1 // get qva selector bits
  332. and a0, 0x3, t3 // capture byte lane
  333. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE
  334. bne t1, 3f // if ne, iff failed
  335. zap a0, 0xf0, a0 // clear <63:32>
  336. bic a0, QVA_ENABLE, a0 // clear QVA fields
  337. sll a0, IO_BIT_SHIFT, t0 //
  338. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  339. sll t4, 28, t4 // 0xffff fc80 0000 0000
  340. bis t0, t4, t0 // superpage mode
  341. bis t0, IO_BYTE_LEN, t0 // or in the byte length indicator
  342. insbl a1, t3, t4 // put byte in the appropriate lane
  343. stl t4, (t0) // write the configuration byte
  344. mb // synchronize
  345. mb // synchronize
  346. 3:
  347. ldq ra, CfgRa(sp) // restore return address
  348. lda sp, CfgFrameLength(sp) // deallocate stack frame
  349. ret zero, (ra) // return
  350. .end WRITE_CONFIG_UCHAR
  351. //++
  352. //
  353. // ULONG
  354. // READ_CONFIG_USHORT(
  355. // ULONG ConfigurationAddress,
  356. // ULONG ConfigurationCycleType
  357. // )
  358. //
  359. // Routine Description:
  360. //
  361. // Read a longword from PCI configuration space.
  362. //
  363. // Arguments:
  364. //
  365. // ConfigurationAddress(a0) - Supplies the QVA of quadword to be read.
  366. //
  367. // ConfigurationCycleType(a1) - Supplies the type of the configuration cycle.
  368. //
  369. // Return Value:
  370. //
  371. // (v0) Returns the value of configuration space at the specified location.
  372. //
  373. // N.B. - This routine follows a protocol for reading from PCI configuration
  374. // space that allows the HAL or firmware to fixup and continue
  375. // execution if no device exists at the configuration target address.
  376. // The protocol requires 2 rules:
  377. // (1) The configuration space load must use a destination register
  378. // of v0
  379. // (2) The instruction immediately following the configuration space
  380. // load must use v0 as an operand (it must consume the value
  381. // returned by the load)
  382. //--
  383. NESTED_ENTRY( READ_CONFIG_USHORT, CfgFrameLength, zero )
  384. lda sp, -CfgFrameLength(sp) // allocate stack frame
  385. stq ra, CfgRa(sp) // save return address
  386. PROLOGUE_END // end prologue
  387. //
  388. // Depending on whether it's a pass 1 or pass 2 T2 the configuration
  389. // cycle type is in different registers
  390. //
  391. ldl t0, T2VersionNumber // load version number
  392. beq t0, 1f // if 0 then pass 1 T2
  393. //
  394. // PASS 2 T2 or XIO access:
  395. // Merge the configuration cycle type into the HAE0_2 register within
  396. // the T2.
  397. //
  398. stq a0, CfgA0(sp) // save config space address
  399. //
  400. // Determine whether access is to T2 or T4 space:
  401. // Isolate the Base address bits: bit 22 indicates T4 space access
  402. //
  403. ldil t0, T4_CONFIG_ADDR_QVA // check for QVA in T4 space
  404. and t0, a0, t1 // isolate QVA base address
  405. ldil a0, T2_HAE0_3_QVA // address of HAE0_3
  406. xor t0, t1, t0 // T4 address space ? (bit 22 set)
  407. ldil t1, T4_HAE0_3_QVA // load address of T4 HAE register
  408. cmoveq t0, t1, a0 // if in T4 space, update a0
  409. sll a1, T2_HAE03_CYCLETYPE_SHIFT, a1 // put cycle type into position
  410. bsr ra, WRITE_T2_REGISTER // write updated HAE
  411. br zero, 2f // go do actual io
  412. //
  413. // Pass 1 T2
  414. // Merge the configuration cycle type into the HAE0_2 register within
  415. // the T2.
  416. //
  417. 1:
  418. stq a0, CfgA0(sp) // save config space address
  419. stq a1, CfgA1(sp) // save config cycle type
  420. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  421. bsr ra, READ_T2_REGISTER // read current value
  422. ldq a1, CfgA1(sp) // restore configuration cycle type
  423. ldil t0, T2_HAE02_CYCLETYPE_MASK // get cycle type field mask
  424. bic v0, t0, t0 // clear config cycle type field
  425. sll a1, T2_HAE02_CYCLETYPE_SHIFT, a1 // put cycle type into position
  426. bis a1, t0, a1 // merge config cycle type
  427. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  428. bsr ra, WRITE_T2_REGISTER // write updated HAE
  429. //
  430. // Perform the read from configuration space after restoring the
  431. // configuration space address.
  432. //
  433. 2:
  434. ldq a0, CfgA0(sp) // restore config space address
  435. and a0, QVA_SELECTORS, t1 // get qva selector bits
  436. and a0, 0x3, t3 // capture word offset
  437. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set
  438. bne t1, 3f // if ne, iff failed
  439. zap a0, 0xf0, a0 // clear <63:32>
  440. bic a0, QVA_ENABLE, a0 // clear QVA fields
  441. sll a0, IO_BIT_SHIFT, t0 //
  442. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  443. sll t4, 28, t4 // 0xffff fc80 0000 0000
  444. bis t0, t4, t0 // superpage mode
  445. bis t0, IO_WORD_LEN, t0 // or in the byte enables
  446. //
  447. // Save Address of Config space address for the machine check handler:
  448. //
  449. lda t1, HalpConfigIoAccess
  450. lda t4, CfgShortRead // machine check return address
  451. stl t4, 0(t1)
  452. mb // commit the store before reading
  453. DISABLE_INTERRUPTS // don't allow ints before Mcheck
  454. CfgShortRead:
  455. ldl v0, (t0) // read the longword
  456. extwl v0, t3, v0 // return word from requested lanes
  457. // also, consume loaded value
  458. // to cause a pipeline stall
  459. mb // Gamma requires MBs or the
  460. mb // machine check may happen
  461. // much later
  462. stl zero, 0(t1) // restore HalpConfigIoAccess
  463. ENABLE_INTERRUPTS // Interrupts OK after Mcheck
  464. 3:
  465. ldq ra, CfgRa(sp) // restore return address
  466. lda sp, CfgFrameLength(sp) // deallocate stack frame
  467. ret zero, (ra) // return
  468. .end READ_CONFIG_USHORT
  469. //++
  470. //
  471. // VOID
  472. // WRITE_CONFIG_USHORT(
  473. // ULONG ConfigurationAddress,
  474. // USHORT ConfigurationData,
  475. // ULONG ConfigurationCycleType
  476. // )
  477. //
  478. // Routine Description:
  479. //
  480. // Read a longword from PCI configuration space.
  481. //
  482. // Arguments:
  483. //
  484. // ConfigurationAddress(a0) - Supplies the QVA to write.
  485. //
  486. // ConfigurationData(a1) - Supplies the data to be written.
  487. //
  488. // ConfigurationCycleType(a2) - Supplies the type of the configuration cycle.
  489. //
  490. // Return Value:
  491. //
  492. // (v0) Returns the value of configuration space at the specified location.
  493. //
  494. // N.B. - The configuration address must exist within the address space
  495. // allocated to an existing PCI device. Otherwise, the access
  496. // below will initiate an unrecoverable machine check.
  497. //
  498. //--
  499. NESTED_ENTRY( WRITE_CONFIG_USHORT, CfgFrameLength, zero )
  500. lda sp, -CfgFrameLength(sp) // allocate stack frame
  501. stq ra, CfgRa(sp) // save return address
  502. PROLOGUE_END // end prologue
  503. //
  504. // Depending on whether it's a pass 1 or pass 2 T2 the configuration
  505. // cycle type is in different registers
  506. //
  507. ldl t0, T2VersionNumber // load version number
  508. beq t0, 1f // if 0 then pass 1 T2
  509. //
  510. // PASS 2 T2 or XIO access:
  511. // Merge the configuration cycle type into the HAE0_2 register within
  512. // the T2.
  513. //
  514. stq a0, CfgA0(sp) // save config space address
  515. stq a1, CfgA1(sp) // save config data
  516. //
  517. // Determine whether access is to T2 or T4 space:
  518. // Isolate the Base address bits: bit 22 indicates T4 space access
  519. //
  520. ldil t0, T4_CONFIG_ADDR_QVA // check for QVA in T4 space
  521. and t0, a0, t1 // isolate QVA base address
  522. ldil a0, T2_HAE0_3_QVA // address of HAE0_3
  523. xor t0, t1, t0 // T4 address space ? (bit 22 set)
  524. ldil t1, T4_HAE0_3_QVA // load address of T4 HAE register
  525. cmoveq t0, t1, a0 // if in T4 space, update a0
  526. sll a2, T2_HAE03_CYCLETYPE_SHIFT, a1 // put cycle type into position
  527. bsr ra, WRITE_T2_REGISTER // write updated HAE
  528. br zero, 2f // go do actual transfer
  529. //
  530. // Pass 1 T2
  531. // Merge the configuration cycle type into the HAE0_2 register within
  532. // the T2.
  533. //
  534. 1:
  535. stq a0, CfgA0(sp) // save config space address
  536. stq a1, CfgA1(sp) // save config data
  537. stq a2, CfgA2(sp) // save config cycle type
  538. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  539. bsr ra, READ_T2_REGISTER // read current value
  540. ldq a1, CfgA2(sp) // restore configuration cycle type
  541. ldil t0, T2_HAE02_CYCLETYPE_MASK // get cycle type field mask
  542. bic v0, t0, t0 // clear config cycle type field
  543. sll a1, T2_HAE02_CYCLETYPE_SHIFT, a1 // put cycle type into position
  544. bis a1, t0, a1 // merge config cycle type
  545. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  546. bsr ra, WRITE_T2_REGISTER // write updated HAE
  547. //
  548. // Perform the read from configuration space after restoring the
  549. // configuration space address and data.
  550. //
  551. 2:
  552. ldq a0, CfgA0(sp) // restore config space address
  553. ldq a1, CfgA1(sp) // restore config data
  554. and a0, QVA_SELECTORS, t1 // get qva selector bits
  555. and a0, 0x3, t3 // capture word offset
  556. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set
  557. bne t1, 3f // if ne, iff failed
  558. zap a0, 0xf0, a0 // clear <63:32>
  559. bic a0, QVA_ENABLE, a0 // clear QVA fields
  560. sll a0, IO_BIT_SHIFT, t0 //
  561. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  562. sll t4, 28, t4 // 0xffff fc80 0000 0000
  563. bis t0, t4, t0 // superpage mode
  564. bis t0, IO_WORD_LEN, t0 // or in the byte enables
  565. inswl a1, t3, t4 // put data to appropriate lane
  566. stl t4, (t0) // read the longword
  567. mb // synchronize
  568. mb // synchronize
  569. 3:
  570. ldq ra, CfgRa(sp) // restore return address
  571. lda sp, CfgFrameLength(sp) // deallocate stack frame
  572. ret zero, (ra) // return
  573. .end WRITE_CONFIG_USHORT
  574. //++
  575. //
  576. // ULONG
  577. // READ_CONFIG_ULONG(
  578. // ULONG ConfigurationAddress,
  579. // ULONG ConfigurationCycleType
  580. // )
  581. //
  582. // Routine Description:
  583. //
  584. // Read a longword from PCI configuration space.
  585. //
  586. // Arguments:
  587. //
  588. // ConfigurationAddress(a0) - Supplies the QVA of quadword to be read.
  589. //
  590. // ConfigurationCycleType(a1) - Supplies the type of the configuration cycle.
  591. //
  592. // Return Value:
  593. //
  594. // (v0) Returns the value of configuration space at the specified location.
  595. //
  596. // N.B. - This routine follows a protocol for reading from PCI configuration
  597. // space that allows the HAL or firmware to fixup and continue
  598. // execution if no device exists at the configuration target address.
  599. // The protocol requires 2 rules:
  600. // (1) The configuration space load must use a destination register
  601. // of v0
  602. // (2) The instruction immediately following the configuration space
  603. // load must use v0 as an operand (it must consume the value
  604. // returned by the load)
  605. //--
  606. NESTED_ENTRY( READ_CONFIG_ULONG, CfgFrameLength, zero )
  607. lda sp, -CfgFrameLength(sp) // allocate stack frame
  608. stq ra, CfgRa(sp) // save return address
  609. PROLOGUE_END // end prologue
  610. //
  611. // Depending on whether it's a pass 1 or pass 2 T2 the configuration
  612. // cycle type is in different registers
  613. //
  614. ldl t0, T2VersionNumber // load version number
  615. beq t0, 1f // if 0 then pass 1 T2
  616. //
  617. // PASS 2 T2 or XIO access:
  618. // Cycle type are the only bits in HAE0_3 register
  619. //
  620. stq a0, CfgA0(sp) // save config space address
  621. //
  622. // Determine whether access is to T2 or T4 space:
  623. // Isolate the Base address bits: bit 22 indicates T4 space access
  624. //
  625. ldil t0, T4_CONFIG_ADDR_QVA // check for QVA in T4 space
  626. and t0, a0, t1 // isolate QVA base address
  627. ldil a0, T2_HAE0_3_QVA // address of HAE0_3
  628. xor t0, t1, t0 // T4 address space ? (bit 22 set)
  629. ldil t1, T4_HAE0_3_QVA // load address of T4 HAE register
  630. cmoveq t0, t1, a0 // if in T4 space, update a0
  631. sll a1, T2_HAE03_CYCLETYPE_SHIFT, a1 // put cycle type in position
  632. bsr ra, WRITE_T2_REGISTER // write updated HAE
  633. br zero, 2f // go do actual read
  634. //
  635. // PASS 1 T2
  636. // Merge the configuration cycle type into the HAE0_2 register within
  637. // the T2.
  638. //
  639. 1:
  640. stq a0, CfgA0(sp) // save config space address
  641. stq a1, CfgA1(sp) // save config cycle type
  642. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  643. bsr ra, READ_T2_REGISTER // read current value
  644. ldq a1, CfgA1(sp) // restore config cycle type
  645. ldil t0, T2_HAE02_CYCLETYPE_MASK // get cycle type field mask
  646. bic v0, t0, t0 // clear config cycle type field
  647. sll a1, T2_HAE02_CYCLETYPE_SHIFT, a1// put cycle type in position
  648. bis a1, t0, a1 // merge config cycle type
  649. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  650. bsr ra, WRITE_T2_REGISTER // write updated HAE
  651. //
  652. // Perform the read from configuration space after restoring the
  653. // configuration space address.
  654. //
  655. 2:
  656. ldq a0, CfgA0(sp) // restore config space address
  657. and a0, QVA_SELECTORS, t1 // get qva selector bits
  658. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set
  659. bne t1, 3f // if ne, iff failed
  660. zap a0, 0xf0, a0 // clear <63:32>
  661. bic a0, QVA_ENABLE,a0 // clear QVA fields
  662. sll a0, IO_BIT_SHIFT, t0 //
  663. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  664. sll t4, 28, t4 // 0xffff fc80 0000 0000
  665. or t0, t4, t0 // superpage mode
  666. or t0, IO_LONG_LEN, t0 // or in the byte enables
  667. //
  668. // Save Address of Config space address for the machine check handler:
  669. //
  670. lda t1, HalpConfigIoAccess
  671. lda t4, CfgUlongRead // machine check return address
  672. stl t4, 0(t1)
  673. mb // commit the store before reading
  674. DISABLE_INTERRUPTS // don't take interrupt before MCHK
  675. CfgUlongRead:
  676. ldl v0, (t0) // read the longword
  677. bis v0, zero, t4 // consume loaded value to cause
  678. // a pipeline stall
  679. mb // Gamma requires MBs or the
  680. mb // machine check may happen
  681. // much later
  682. stl zero, 0(t1) // restore HalpConfigIoAccess
  683. ENABLE_INTERRUPTS // Mcheck has occurred: allow ints
  684. 3:
  685. ldq ra, CfgRa(sp) // restore return address
  686. lda sp, CfgFrameLength(sp) // deallocate stack frame
  687. ret zero, (ra) // return
  688. .end READ_CONFIG_ULONG
  689. //++
  690. //
  691. // VOID
  692. // WRITE_CONFIG_ULONG(
  693. // ULONG ConfigurationAddress,
  694. // ULONG ConfigurationData,
  695. // ULONG ConfigurationCycleType
  696. // )
  697. //
  698. // Routine Description:
  699. //
  700. // Read a longword from PCI configuration space.
  701. //
  702. // Arguments:
  703. //
  704. // ConfigurationAddress(a0) - Supplies the QVA to write.
  705. //
  706. // ConfigurationData(a1) - Supplies the data to be written.
  707. //
  708. // ConfigurationCycleType(a2) - Supplies the type of the configuration cycle.
  709. //
  710. // Return Value:
  711. //
  712. // (v0) Returns the value of configuration space at the specified location.
  713. //
  714. // N.B. - The configuration address must exist within the address space
  715. // allocated to an existing PCI device. Otherwise, the access
  716. // below will initiate an unrecoverable machine check.
  717. //
  718. //--
  719. NESTED_ENTRY( WRITE_CONFIG_ULONG, CfgFrameLength, zero )
  720. lda sp, -CfgFrameLength(sp) // allocate stack frame
  721. stq ra, CfgRa(sp) // save return address
  722. PROLOGUE_END // end prologue
  723. //
  724. // Depending on whether it's a pass 1 or pass 2 T2 the configuration
  725. // cycle type is in different registers
  726. //
  727. ldl t0, T2VersionNumber // load version number
  728. beq t0, 1f // if 0 then pass 1 T2
  729. //
  730. // PASS 2 T2 or XIO access:
  731. // Merge the configuration cycle type into the HAE0_2 register within
  732. // the T2.
  733. //
  734. stq a0, CfgA0(sp) // save config space address
  735. stq a1, CfgA1(sp) // save config data
  736. //
  737. // Determine whether access is to T2 or T4 space:
  738. // Isolate the Base address bits: bit 22 indicates T4 space access
  739. //
  740. ldil t0, T4_CONFIG_ADDR_QVA // check for QVA in T4 space
  741. and t0, a0, t1 // isolate QVA base address
  742. ldil a0, T2_HAE0_3_QVA // address of HAE0_3
  743. xor t0, t1, t0 // T4 address space ? (bit 22 set)
  744. ldil t1, T4_HAE0_3_QVA // load address of T4 HAE register
  745. cmoveq t0, t1, a0 // if in T4 space, update a0
  746. sll a2, T2_HAE03_CYCLETYPE_SHIFT, a1 // put cycle type into position
  747. bsr ra, WRITE_T2_REGISTER // write updated HAE
  748. br zero, 2f // go do actual transfer
  749. //
  750. // Pass 1 T2
  751. // Merge the configuration cycle type into the HAE0_2 register within
  752. // the T2.
  753. //
  754. 1:
  755. stq a0, CfgA0(sp) // save config space address
  756. stq a1, CfgA1(sp) // save config data
  757. stq a2, CfgA2(sp) // save config cycle type
  758. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  759. bsr ra, READ_T2_REGISTER // read current value
  760. ldq a1, CfgA2(sp) // restore configuration cycle type
  761. ldil t0, T2_HAE02_CYCLETYPE_MASK // get cycle type field mask
  762. bic v0, t0, t0 // clear config cycle type field
  763. sll a1, T2_HAE02_CYCLETYPE_SHIFT, a1 // put cycle type into position
  764. bis a1, t0, a1 // merge config cycle type
  765. ldil a0, T2_HAE0_2_QVA // address of HAE0_2
  766. bsr ra, WRITE_T2_REGISTER // write updated HAE
  767. //
  768. // Perform the read from configuration space after restoring the
  769. // configuration space address and data.
  770. //
  771. 2:
  772. ldq a0, CfgA0(sp) // restore config space address
  773. ldq a1, CfgA1(sp) // restore config data
  774. and a0, QVA_SELECTORS, t1 // get qva selector bits
  775. xor t1, QVA_ENABLE, t1 // ok iff QVA_ENABLE set
  776. bne t1, 3f // if ne, iff failed
  777. zap a0, 0xf0, a0 // clear <63:32>
  778. bic a0, QVA_ENABLE, a0 // clear QVA fields
  779. sll a0, IO_BIT_SHIFT, t0 //
  780. ldiq t4, GAMMA_IO_SVA // 0xffff ffff ffff c800
  781. sll t4, 28, t4 // 0xffff fc80 0000 0000
  782. bis t0, t4, t0 // superpage mode
  783. bis t0, IO_LONG_LEN, t0 // or in the byte enables
  784. stl a1, (t0) // write the longword
  785. mb // synchronize
  786. mb // synchronize
  787. 3: //
  788. ldq ra, CfgRa(sp) // restore return address
  789. lda sp, CfgFrameLength(sp) // deallocate stack frame
  790. ret zero, (ra) // return
  791. .end WRITE_CONFIG_ULONG