Source code of Windows XP (NT5)
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.

1762 lines
43 KiB

  1. /*++ BUILD Version: 0004 // Increment this if a change has global effects
  2. */
  3. //++
  4. //
  5. // Module Name:
  6. //
  7. // kxia64.h
  8. //
  9. // Abstract:
  10. //
  11. // This module contains the nongenerated part of the IA64 assembler
  12. // header file. In general, it contains processor architecture constant
  13. // information, however some assembler macros are also included.
  14. //
  15. // Author:
  16. //
  17. // bjl 12-Jun-95 (based on David N. Cutler (davec) 23-Mar-1990)
  18. //
  19. // Revision History:
  20. //
  21. //--
  22. #define SHADOW_IRQL_IMPLEMENTATION 1
  23. //
  24. // N. B. Register aliases have been moved to ksia64.h (because we
  25. // use assembler aliases not #define's)
  26. //
  27. // Register constants
  28. // For setting non-rotating predicates (not used very much)
  29. #define PS0 0x0001
  30. #define PS1 0x0002
  31. #define PS2 0x0004
  32. #define PS3 0x0008
  33. #define PS4 0x0010
  34. #define PS5 0x0020
  35. #define PRP 0x0080
  36. #define PT0 0x0040
  37. #define PT1 0x0100
  38. #define PT2 0x0200
  39. #define PT3 0x0400
  40. #define PT4 0x0800
  41. #define PT5 0x1000
  42. #define PT6 0x2000
  43. #define PT7 0x4000
  44. #define PT8 0x8000
  45. // For setting nomination register
  46. #define NOM_BS0 0x0001
  47. #define NOM_BS1 0x0002
  48. #define NOM_BS2 0x0004
  49. #define NOM_BS3 0x0008
  50. #define NOM_BS4 0x0010
  51. #define NOM_BS5 0x0020
  52. #define NOM_BRP 0x0080
  53. #define NOM_BT0 0x0040
  54. #define NOM_BT1 0x0100
  55. #define NOM_BT2 0x0200
  56. #define NOM_BT3 0x0400
  57. #define NOM_BT4 0x0800
  58. #define NOM_BT5 0x1000
  59. #define NOM_BT6 0x2000
  60. #define NOM_BT7 0x4000
  61. #define NOM_BT8 0x8000
  62. //
  63. //
  64. // Define IA64 system registers.
  65. //
  66. // Define IA64 system register bit field offsets.
  67. //
  68. // Processor Status Register (PSR) Bit positions
  69. // User / System mask
  70. #define PSR_MBZ4 0
  71. #define PSR_BE 1
  72. #define PSR_UP 2
  73. #define PSR_AC 3
  74. #define PSR_MFL 4
  75. #define PSR_MFH 5
  76. // PSR bits 6-12 reserved (must be zero)
  77. #define PSR_MBZ0 6
  78. #define PSR_MBZ0_V 0x1ffi64
  79. // System only mask
  80. #define PSR_IC 13
  81. #define PSR_I 14
  82. #define PSR_PK 15
  83. #define PSR_MBZ1 16
  84. #define PSR_MBZ1_V 0x1i64
  85. #define PSR_DT 17
  86. #define PSR_DFL 18
  87. #define PSR_DFH 19
  88. #define PSR_SP 20
  89. #define PSR_PP 21
  90. #define PSR_DI 22
  91. #define PSR_SI 23
  92. #define PSR_DB 24
  93. #define PSR_LP 25
  94. #define PSR_TB 26
  95. #define PSR_RT 27
  96. // PSR bits 28-31 reserved (must be zero)
  97. #define PSR_MBZ2 28
  98. #define PSR_MBZ2_V 0xfi64
  99. // Neither mask
  100. #define PSR_CPL 32
  101. #define PSR_CPL_LEN 2
  102. #define PSR_IS 34
  103. #define PSR_MC 35
  104. #define PSR_IT 36
  105. #define PSR_ID 37
  106. #define PSR_DA 38
  107. #define PSR_DD 39
  108. #define PSR_SS 40
  109. #define PSR_RI 41
  110. #define PSR_RI_LEN 2
  111. #define PSR_ED 43
  112. #define PSR_BN 44
  113. // PSR bits 45-63 reserved (must be zero)
  114. #define PSR_MBZ3 45
  115. #define PSR_MBZ3_V 0xfffffi64
  116. //
  117. // Privilege levels
  118. //
  119. #define PL_KERNEL 0
  120. #define PL_USER 3
  121. //
  122. // Instruction set (IS) bits
  123. //
  124. #define IS_EM 0
  125. #define IS_IA 1
  126. // Floating Point Status Register (FPSR) Bit positions
  127. // Status Field 0 - Flags
  128. #define FPSR_VD 0
  129. #define FPSR_DD 1
  130. #define FPSR_ZD 2
  131. #define FPSR_OD 3
  132. #define FPSR_UD 4
  133. #define FPSR_ID 5
  134. // Status Field 0 - Controls
  135. #define FPSR_FTZ0 6
  136. #define FPSR_WRE0 7
  137. #define FPSR_PC0 8
  138. #define FPSR_RC0 10
  139. #define FPSR_TD0 12
  140. // Status Field 0 - Flags
  141. #define FPSR_V0 13
  142. #define FPSR_D0 14
  143. #define FPSR_Z0 15
  144. #define FPSR_O0 16
  145. #define FPSR_U0 17
  146. #define FPSR_I0 18
  147. // Status Field 1 - Controls
  148. #define FPSR_FTZ1 19
  149. #define FPSR_WRE1 20
  150. #define FPSR_PC1 21
  151. #define FPSR_RC1 23
  152. #define FPSR_TD1 25
  153. // Status Field 1 - Flags
  154. #define FPSR_V1 26
  155. #define FPSR_D1 27
  156. #define FPSR_Z1 28
  157. #define FPSR_O1 29
  158. #define FPSR_U1 30
  159. #define FPSR_I1 31
  160. // Status Field 2 - Controls
  161. #define FPSR_FTZ2 32
  162. #define FPSR_WRE2 33
  163. #define FPSR_PC2 34
  164. #define FPSR_RC2 36
  165. #define FPSR_TD2 38
  166. // Status Field 2 - Flags
  167. #define FPSR_V2 39
  168. #define FPSR_D2 40
  169. #define FPSR_Z2 41
  170. #define FPSR_O2 42
  171. #define FPSR_U2 43
  172. #define FPSR_I2 44
  173. // Status Field 3 - Controls
  174. #define FPSR_FTZ3 45
  175. #define FPSR_WRE3 46
  176. #define FPSR_PC3 47
  177. #define FPSR_RC3 49
  178. #define FPSR_TD3 51
  179. // Status Field 3 - Flags
  180. #define FPSR_V3 52
  181. #define FPSR_D3 53
  182. #define FPSR_Z3 54
  183. #define FPSR_O3 55
  184. #define FPSR_U3 56
  185. #define FPSR_I3 57
  186. // FPSR bits 58-63 Reserved -- Must be zero
  187. #define FPSR_MBZ0 58
  188. #define FPSR_MBZ0_V 0x3fi64
  189. //
  190. // For setting up FPSR on kernel entry
  191. //
  192. // all FP exceptions masked
  193. //
  194. // rounding to nearest, 64-bit precision, wide range enabled for FPSR.fs1
  195. //
  196. // rounding to nearest, 53-bit precision, wide range disabled for FPSR.fs0
  197. //
  198. #define FPSR_FOR_KERNEL 0x9804C0270033F
  199. //
  200. // Define hardware Task Priority Register (TPR)
  201. //
  202. // TPR bit positions
  203. // Bits 0 - 3 ignored
  204. #define TPR_MIC 4
  205. #define TPR_MIC_LEN 4
  206. // Bits 8 - 15 reserved
  207. // TPR.mmi is always 0 in NT
  208. #define TPR_MMI 16
  209. // Bits 17 - 63 ignored
  210. //
  211. // The current IRQL is maintained in the TPR.mic field. The
  212. // shift count is the number of bits to shift right to extract the
  213. // IRQL from the TPR. See the GET/SET_IRQL macros.
  214. //
  215. #define TPR_IRQL_SHIFT TPR_MIC
  216. //
  217. // To go from vector number <-> IRQL we just do a shift
  218. //
  219. #define VECTOR_IRQL_SHIFT TPR_IRQL_SHIFT
  220. //
  221. // Define hardware Interrupt Status Register (ISR)
  222. //
  223. // ISR bit positions
  224. #define ISR_CODE 0
  225. #define ISR_CODE_LEN 16
  226. #define ISR_CODE_MASK 0xFFFF
  227. #define ISR_IA_VECTOR 16
  228. #define ISR_IA_VECTOR_LEN 8
  229. // ISR bits 24-31 reserved
  230. #define ISR_MBZ0 24
  231. #define ISR_MBZ0_V 0xff
  232. #define ISR_X 32
  233. #define ISR_W 33
  234. #define ISR_R 34
  235. #define ISR_NA 35
  236. #define ISR_SP 36
  237. #define ISR_RS 37
  238. #define ISR_IR 38
  239. #define ISR_NI 39
  240. // ISR bit 40 reserved
  241. #define ISR_MBZ1 40
  242. #define ISR_EI 41
  243. #define ISR_ED 43
  244. // ISR bits 44-63 reserved
  245. #define ISR_MBZ2 44
  246. #define ISR_MBZ2_V 0xfffff
  247. //
  248. // ISR codes for General Exceptions: ISR{7:4}
  249. //
  250. #define ISR_ILLEGAL_OP 0 // Illegal operation fault
  251. #define ISR_PRIV_OP 1 // Privileged operation fault
  252. #define ISR_PRIV_REG 2 // Privileged register fault
  253. #define ISR_RESVD_REG 3 // Reserved register/field fault
  254. #define ISR_ILLEGAL_ISA 4 // Disabled instruction set transition fault
  255. #define ISR_ILLEGAL_HAZARD 8 // Illegal hazard fault
  256. //
  257. // ISR codes for Nat Consumption Faults: ISR{7:4}
  258. //
  259. #define ISR_NAT_REG 1 // Nat Register Consumption fault
  260. #define ISR_NAT_PAGE 2 // Nat Page Consumption fault
  261. //
  262. // For Traps ISR{3:0}
  263. //
  264. // FP trap
  265. #define ISR_FP_TRAP 0
  266. // Lower privilege transfer trap
  267. #define ISR_LP_TRAP 1
  268. // Taken branch trap
  269. #define ISR_TB_TRAP 2
  270. // Single step trap
  271. #define ISR_SS_TRAP 3
  272. // Unimplemented instruction address trap
  273. #define ISR_UI_TRAP 4
  274. //
  275. // Define hardware Default Control Register (DCR)
  276. //
  277. // DCR bit positions
  278. #define DCR_PP 0
  279. #define DCR_BE 1
  280. #define DCR_LC 2
  281. // DCR bits 3-7 reserved
  282. #define DCR_DM 8
  283. #define DCR_DP 9
  284. #define DCR_DK 10
  285. #define DCR_DX 11
  286. #define DCR_DR 12
  287. #define DCR_DA 13
  288. #define DCR_DD 14
  289. #define DCR_DEFER_ALL 0x7f00
  290. // DCR bits 16-63 reserved
  291. #define DCR_MBZ1 2
  292. #define DCR_MBZ1_V 0xffffffffffffi64
  293. // Define hardware RSE Configuration Register
  294. //
  295. // RS Configuration (RSC) bit field positions
  296. #define RSC_MODE 0
  297. #define RSC_PL 2
  298. #define RSC_BE 4
  299. // RSC bits 5-15 reserved
  300. #define RSC_MBZ0 5
  301. #define RSC_MBZ0_V 0x3ff
  302. #define RSC_LOADRS 16
  303. #define RSC_LOADRS_LEN 14
  304. // RSC bits 30-63 reserved
  305. #define RSC_MBZ1 30
  306. #define RSC_MBZ1_LEN 34
  307. #define RSC_MBZ1_V 0x3ffffffffi64
  308. // RSC modes
  309. // Lazy
  310. #define RSC_MODE_LY (0x0)
  311. // Store intensive
  312. #define RSC_MODE_SI (0x1)
  313. // Load intensive
  314. #define RSC_MODE_LI (0x2)
  315. // Eager
  316. #define RSC_MODE_EA (0x3)
  317. // RSC Endian bit values
  318. #define RSC_BE_LITTLE 0
  319. #define RSC_BE_BIG 1
  320. // RSC while in kernel: enabled, little endian, pl = 0, eager mode
  321. #define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
  322. // RSE disabled: disabled, pl = 0, little endian, eager mode
  323. #define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
  324. //
  325. // Define Interruption Function State (IFS) Register
  326. //
  327. // IFS bit field positions
  328. //
  329. #define IFS_IFM 0
  330. #define IFS_IFM_LEN 38
  331. #define IFS_MBZ0 38
  332. #define IFS_MBZ0_V 0x1ffffffi64
  333. #define IFS_V 63
  334. #define IFS_V_LEN 1
  335. //
  336. // IFS is valid when IFS_V = IFS_VALID
  337. //
  338. #define IFS_VALID 1
  339. //
  340. // define the width of each size field in PFS/IFS
  341. //
  342. #define PFS_PPL 62 // pfs.ppl bit location
  343. #define PFS_EC_SHIFT 52
  344. #define PFS_EC_SIZE 6
  345. #define PFS_EC_MASK 0x3F
  346. #define PFS_SIZE_SHIFT 7
  347. #define PFS_SIZE_MASK 0x7F
  348. #define NAT_BITS_PER_RNAT_REG 63
  349. #define RNAT_ALIGNMENT (NAT_BITS_PER_RNAT_REG << 3)
  350. //
  351. // Define Region Register (RR)
  352. //
  353. // RR bit field positions
  354. //
  355. #define RR_VE 0
  356. #define RR_MBZ0 1
  357. #define RR_PS 2
  358. #define RR_PS_LEN 6
  359. #define RR_RID 8
  360. #define RR_RID_LEN 24
  361. #define RR_MBZ1 32
  362. //
  363. // indirect mov index for loading RR
  364. //
  365. #define RR_INDEX 61
  366. #define RR_INDEX_LEN 3
  367. //
  368. // Define low order 8 bit's of RR. All RR's have same PS and VE
  369. //
  370. #define RR_PS_VE ( (PAGE_SHIFT<<RR_PS) | (1<<RR_VE) )
  371. //
  372. // Number of region registers used by NT
  373. //
  374. #define NT_RR_SIZE 4
  375. //
  376. // Total number of region registers
  377. //
  378. #define RR_SIZE 8
  379. //
  380. // Define Protection Key Register (PKR)
  381. //
  382. // PKR bit field positions
  383. //
  384. #define PKR_V 0
  385. #define PKR_WD 1
  386. #define PKR_RD 2
  387. #define PKR_XD 3
  388. #define PKR_MBZ0 4
  389. #define PKR_KEY 8
  390. #define PKR_KEY_LEN 24
  391. #define PKR_MBZ1 32
  392. //
  393. // Define low order 8 bit's of PKR. All valid PKR's have same V, WD, RD, XD
  394. //
  395. #define PKR_VALID (1<<PKR_V)
  396. //
  397. // Number of protection key registers
  398. //
  399. #define PKRNUM 16
  400. //
  401. // Define Interrupt TLB Insertion Register
  402. //
  403. // ITIR bit field positions
  404. //
  405. #define ITIR_RV0 0
  406. #define ITIR_PS 2
  407. #define ITIR_KEY 8
  408. #define ITIR_RV1 32
  409. //
  410. // The following definitions are obsolete but
  411. // there are codes in ke/ia64 reference them.
  412. //
  413. // Define Interruption Translation Register (IDTR/IITR)
  414. //
  415. // IDTR/IITR bit field positions
  416. //
  417. #define IDTR_MBZ0 0
  418. #define IDTR_PS 2
  419. #define IDTR_KEY 8
  420. #define IDTR_MBZ1 32
  421. #define IDTR_IGN0 48
  422. #define IDTR_PPN 56
  423. #define IDTR_MBZ2 63
  424. #define IITR_MBZ0 IDTR_MBZ0
  425. #define IITR_PS IDTR_PS
  426. #define IITR_KEY IDTR_KEY
  427. #define IITR_MBZ1 IDTR_MBZ1
  428. #define IITR_IGN0 IDTR_IGN0
  429. #define IITR_PPN IDTR_PPN
  430. #define IITR_MBZ2 IDTR_MBZ2
  431. //
  432. // ITIR bit field masks
  433. #define IITR_PPN_MASK 0x7FFF000000000000
  434. #define IITR_ATTRIBUTE_PPN_MASK 0x0003FFFFFFFFF000
  435. //
  436. // Define Translation Insertion Format (TR)
  437. //
  438. // TR bit field positions
  439. //
  440. #define TR_P 0
  441. #define TR_RV0 1
  442. #define TR_MA 2
  443. #define TR_A 5
  444. #define TR_D 6
  445. #define TR_PL 7
  446. #define TR_AR 9
  447. #define TR_PPN 13 // must be same as PAGE_SHIFT
  448. #define TR_RV1 50
  449. #define TR_ED 52
  450. #define TR_IGN0 53
  451. //
  452. // Macros for generating TR value
  453. //
  454. #define TR_VALUE(ed, ppn, ar, pl, d, a, ma, p) \
  455. ( ( ed << TR_ED ) | \
  456. ( ppn & IITR_ATTRIBUTE_PPN_MASK) | \
  457. ( ar << TR_AR ) | \
  458. ( pl << TR_PL ) | \
  459. ( d << TR_D ) | \
  460. ( a << TR_A ) | \
  461. ( ma << TR_MA ) | \
  462. ( p << TR_P ) \
  463. )
  464. #define ITIR_VALUE(key, ps) \
  465. ( ( ps << ITIR_PS ) | \
  466. ( key << ITIR_KEY ) \
  467. )
  468. //
  469. // Platform related virtual address constants
  470. //
  471. #define VIRTUAL_IO_BASE 0xe0000000f0000000
  472. #define VIRTUAL_PAL_BASE 0xe0000000f4000000
  473. //
  474. // Page size definitions
  475. //
  476. #define PS_4K 0xC // 0xC=12, 2^12=4K
  477. #define PS_8K 0xD // 0xD=13, 2^13=8K
  478. #define PS_16K 0xE // 0xE=14, 2^14=16K
  479. #define PS_64K 0x10 // 0x10=16, 2^16=64K
  480. #define PS_256K 0x12 // 0x12=18, 2^18=256K
  481. #define PS_1M 0x14 // 0x14=20, 2^20=1M
  482. #define PS_4M 0x16 // 0x16=22, 2^22=4M
  483. #define PS_16M 0x18 // 0x18=24, 2^24=16M
  484. #define PS_64M 0x1a // 0x1a=26, 2^26=64M
  485. #define PS_256M 0x1c // 0x1a=26, 2^26=64M
  486. //
  487. // Debug Registers definitions
  488. // For the break conditions (mask):
  489. //
  490. #define DR_MASK 0 // Mask
  491. #define DR_MASK_LEN 56 // Mask length
  492. #define DR_PLM0 56 // Enable privlege level 0
  493. #define DR_PLM1 57 // Enable privlege level 1
  494. #define DR_PLM2 58 // Enable privlege level 2
  495. #define DR_PLM3 59 // Enable privlege level 3 (user)
  496. #define DR_IG 60 // Ignore
  497. #define DR_RW 62 // Read/Write
  498. #define DR_RW_LEN 2 // R/W length
  499. #define DR_X 63 // Execute
  500. //
  501. // Macro to generate mask value from bit position
  502. // N.B. If this macro is used in a C expression and the result is a
  503. // 64-bit, the "value" argument shoud be cast as "unsigned long long" to
  504. // produce a 64-bit mask.
  505. //
  506. #define MASK_IA64(bp,value) (value << bp)
  507. //
  508. // Interrupt Vector Definitions
  509. //
  510. #define APC_VECTOR APC_LEVEL << VECTOR_IRQL_SHIFT
  511. #define DISPATCH_VECTOR DISPATCH_LEVEL << VECTOR_IRQL_SHIFT
  512. //
  513. // Define interruption vector offsets
  514. //
  515. #define OFFSET_VECTOR_BREAK 0x2800 // Break instruction vector
  516. #define OFFSET_VECTOR_EXT_INTERRUPT 0x2c00 // External interrupt vector
  517. #define OFFSET_VECTOR_EXC_GENERAL 0x4400 // General exception vector
  518. //
  519. //
  520. // Define IA64 page mask values.
  521. //
  522. #define PAGEMASK_4KB 0x0 // 4kb page
  523. #define PAGEMASK_16KB 0x3 // 16kb page
  524. #define PAGEMASK_64KB 0xf // 64kb page
  525. #define PAGEMASK_256KB 0x3f // 256kb page
  526. #define PAGEMASK_1MB 0xff // 1mb page
  527. #define PAGEMASK_4MB 0x3ff // 4mb page
  528. #define PAGEMASK_16MB 0xfff // 16mb page
  529. //
  530. // Define IA64 primary cache states.
  531. //
  532. #define PRIMARY_CACHE_INVALID 0x0 // primary cache invalid
  533. #define PRIMARY_CACHE_SHARED 0x1 // primary cache shared (clean or dirty)
  534. #define PRIMARY_CACHE_CLEAN_EXCLUSIVE 0x2 // primary cache clean exclusive
  535. #define PRIMARY_CACHE_DIRTY_EXCLUSIVE 0x3 // primary cache dirty exclusive
  536. //
  537. // Page table constants
  538. //
  539. #define PS_SHIFT 2
  540. #define PS_LEN 6
  541. #define PTE_VALID_MASK 1
  542. #define PTE_ACCESS_MASK 0x20
  543. #define PTE_NOCACHE 0x10
  544. #define PTE_LARGE_PAGE 54
  545. #define PTE_PFN_SHIFT 8
  546. #define PTE_PFN_LEN 24
  547. #define PTE_ATTR_SHIFT 1
  548. #define PTE_ATTR_LEN 5
  549. #define PTE_PS 55
  550. #define PTE_OFFSET_LEN 10
  551. #define PDE_OFFSET_LEN 10
  552. #define VFN_LEN 19
  553. #define VFN_LEN64 24
  554. #define TB_USER_MASK 0x180
  555. #define PTE_DIRTY_MASK 0x40
  556. #define PTE_WRITE_MASK 0x400
  557. #define PTE_EXECUTE_MASK 0x200
  558. #define PTE_CACHE_MASK 0x0
  559. #define PTE_EXC_DEFER 0x10000000000000
  560. #define VALID_KERNEL_PTE (PTE_VALID_MASK|PTE_ACCESS_MASK|PTE_WRITE_MASK|PTE_CACHE_MASK|PTE_DIRTY_MASK)
  561. #define VALID_KERNEL_EXECUTE_PTE (PTE_VALID_MASK|PTE_ACCESS_MASK|PTE_EXECUTE_MASK|PTE_WRITE_MASK|PTE_CACHE_MASK|PTE_DIRTY_MASK|PTE_EXC_DEFER)
  562. #define PTE_VALID 0
  563. #define PTE_ACCESS 5
  564. #define PTE_OWNER 7
  565. #define PTE_WRITE 10
  566. #define ATE_INDIRECT 62
  567. #define ATE_MASK 0xFFFFFFFFFFFFF9DE
  568. #define ATE_MASK0 0x621
  569. #define PAGE4K_SHIFT 12
  570. #define ALT4KB_BASE 0x6FC00000000
  571. #define ALT4KB_END 0x6FC00400000
  572. #define VRN_SHIFT 61
  573. #define KSEG3_VRN 4
  574. #define KSEG4_VRN 5
  575. #define MAX_PHYSICAL_SHIFT 44
  576. //
  577. // Translation register usage
  578. //
  579. //
  580. // In NTLDR
  581. //
  582. //
  583. // Boot loader CONFIGFLAG definitions.
  584. //
  585. #define DISABLE_TAR_FIX 0
  586. #define DISABLE_BTB_FIX 1
  587. #define DISABLE_DATA_BP_FIX 2
  588. #define DISABLE_DET_STALL_FIX 3
  589. #define ENABLE_FULL_DISPERSAL 4
  590. #define ENABLE_TB_BROADCAST 5
  591. #define DISABLE_CPL_FIX 6
  592. #define ENABLE_POWER_MANAGEMENT 7
  593. #define DISABLE_IA32BR_FIX 8
  594. #define DISABLE_L1_BYPASS 9
  595. #define DISABLE_VHPT_WALKER 10
  596. #define DISABLE_IA32RSB_FIX 11
  597. #define DISABLE_INTERRUPTION_LOG 13
  598. #define DISABLE_UNSAFE_FILL 14
  599. #define DISABLE_STORE_UPDATE 15
  600. #define BL_4M 0x00400000
  601. #define BL_16M 0x01000000
  602. #define BL_20M 0x01400000
  603. #define BL_24M 0x01800000
  604. #define BL_28M 0x01C00000
  605. #define BL_32M 0x02000000
  606. #define BL_36M 0x02400000
  607. #define BL_40M 0x02800000
  608. #define BL_48M 0x03000000
  609. #define BL_64M 0x04000000
  610. #define BL_80M 0x05000000
  611. #define TR_INFO_TABLE_SIZE 10
  612. #define BL_SAL_INDEX 0
  613. #define BL_KERNEL_INDEX 1
  614. #define BL_DRIVER0_INDEX 2 // freed during the phase 0 initialization
  615. #define BL_DRIVER1_INDEX 3 // freed during the phase 0 initialization
  616. #define BL_DECOMPRESS_INDEX 4 // freed before entering kernel
  617. #define BL_IO_PORT_INDEX 5 // freed before entering kernel
  618. #define BL_PAL_INDEX 6
  619. #define BL_LOADER_INDEX 7 // freed before entering kernel
  620. //
  621. // In NTOSKRNL
  622. //
  623. #define DTR_KIPCR_INDEX 0
  624. #define DTR_KERNEL_INDEX 1
  625. #define DTR_DRIVER0_INDEX 2 // freed during the phase 0 initialization
  626. #define DTR_DRIVER1_INDEX 3 // freed during the phase 0 initialization
  627. #define DTR_KTBASE_INDEX 2
  628. #define DTR_UTBASE_INDEX 3
  629. #define DTR_VIDEO_INDEX 3 // not used
  630. #define DTR_KIPCR2_INDEX 4 // freed in the phase 0 initialization
  631. #define DTR_STBASE_INDEX 4
  632. #define DTR_IO_PORT_INDEX 5
  633. #define DTR_KTBASE_INDEX_TMP 6 // freed during the phase 0 initialization
  634. #define DTR_UTBASE_INDEX_TMP 7 // freed during the phase 0 initialization
  635. #define DTR_HAL_INDEX 6
  636. #define DTR_PAL_INDEX 6
  637. #define ITR_EPC_INDEX 0
  638. #define ITR_KERNEL_INDEX 1
  639. #define ITR_DRIVER0_INDEX 2 // freed during the phase 0 initialization
  640. #define ITR_DRIVER1_INDEX 3 // freed during the phase 0 initialization
  641. #define ITR_HAL_INDEX 4
  642. #define ITR_PAL_INDEX 4
  643. //
  644. // TLB forward progress queue
  645. //
  646. #define NUMBER_OF_FWP_ENTRIES 8
  647. //
  648. // Define the kernel base address
  649. //
  650. #define KERNEL_BASE KADDRESS_BASE+0x80000000
  651. #define KERNEL_BASE2 KADDRESS_BASE+0x81000000
  652. //
  653. // Initial value of data TR's for kernel/user PCR
  654. // ed ign res ppn ar pl d a ma p
  655. // kernel: 0 000 0000 0x0 010 00 1 1 000 1
  656. // user: 0 000 0000 0x0 000 11 1 1 000 1
  657. //
  658. #define PDR_TR_INITIAL TR_VALUE(0, 0, 2, 0, 1, 1, 0, 1)
  659. #define KIPCR_TR_INITIAL TR_VALUE(0, 0, 2, 0, 1, 1, 0, 1)
  660. #define USPCR_TR_INITIAL TR_VALUE(0, 0, 0, 3, 1, 1, 0, 1)
  661. //
  662. // Initial value of PTA (64-bits)
  663. // base (region 0) res vf size res ve
  664. // 0x00000000000 0 0 00000 1 000000 0 1
  665. //
  666. #define PTA_INITIAL 0x001
  667. //
  668. // Initial value of DCR (64-bits)
  669. // res du dd da dr dx dk dp dm res lc be pp
  670. // 0x000000000000 1 1 1 1 1 1 1 1 00000 1 0 1
  671. //
  672. #define DCR_INITIAL 0x0000000000007f05
  673. //
  674. // Initial value of PSR low (32-bits)
  675. // res rt tb lp db si di pp sp dfh dfl dt rv pk i ic res mfh mfl ac up be res
  676. // 0000 1 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 0000 00 0 0 1 0 0 0
  677. //
  678. #define PSRL_INITIAL 0x086a2008
  679. //
  680. // Initial value of user PSR (64-bits)
  681. // Bits 63-32
  682. // res bn ed ri ss dd da id it mc is cpl
  683. // 0000 0000 0000 0000 000 1 0 00 0 0 0 0 1 0 0 11
  684. // Bits 31-0
  685. // res rt tb lp db si di pp sp dfh dfl dt rv pk i ic res mfh mfl ac up be res
  686. // 0000 1 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 0000 00 0 0 1 0 0 0
  687. //
  688. #define USER_PSR_INITIAL 0x00001013082a6008i64
  689. //
  690. // Initial value of user FPSR (64-bits)
  691. //
  692. // all FP exceptions masked
  693. //
  694. // rounding to nearest, 64-bit precisoin, wide range enabled for FPSR.fs1
  695. //
  696. // rounding to nearest, 53-bit precision, wide range disabled for FPSR.fs0
  697. //
  698. #define USER_FPSR_INITIAL 0x9804C0270033F
  699. //
  700. // Initial value of DCR (64-bits)
  701. // res dd da dr dx dk dp dm res lc be pp
  702. // 0x000000000000 1 1 1 1 1 1 1 00000 1 0 1
  703. //
  704. #define USER_DCR_INITIAL 0x0000000000007f05i64
  705. //
  706. // Initial value of user RSC (low 32-bits)
  707. // Mode: Lazy. Little endian. User PL.
  708. //
  709. #define USER_RSC_INITIAL ((RSC_MODE_LY<<RSC_MODE) \
  710. | (RSC_BE_LITTLE<<RSC_BE) \
  711. | (0x3<<RSC_PL))
  712. //
  713. //
  714. // IA64 Software conventions
  715. //
  716. // Bytes in stack scratch area
  717. #define STACK_SCRATCH_AREA 16
  718. //
  719. // Constants for trap
  720. //
  721. // Bits to shift for computing interrupt routine funtion pointer: fp = base + irql<<INT_ROUTINE_SHIFT
  722. #ifdef _WIN64
  723. #define INT_ROUTINES_SHIFT 3
  724. #else
  725. #define INT_ROUTINES_SHIFT 2
  726. #endif
  727. //
  728. //
  729. // Define disable and restore interrupt macros.
  730. // Note: Serialization is implicit for rsm
  731. //
  732. #define DISABLE_INTERRUPTS(reg) \
  733. mov reg = psr ;\
  734. rsm 1 << PSR_I
  735. //
  736. // Restore psr.i bit based on value of bit PSR_I in reg
  737. // Enable does not do serialization, so interrupts may not be enabeld for
  738. // a number of cycles after ssm.
  739. //
  740. #define RESTORE_INTERRUPTS(reg) \
  741. tbit##.##nz pt0,pt1 = reg, PSR_I;; ;\
  742. (pt0) ssm 1 << PSR_I ;\
  743. (pt1) rsm 1 << PSR_I
  744. //
  745. // The FAST versions can be used when it is not necessary to save/restore
  746. // the previous interrupt enable state.
  747. //
  748. #define FAST_DISABLE_INTERRUPTS \
  749. rsm 1 << PSR_I
  750. //
  751. // FAST ENABLE does not do serialization -- we don't care if interrupt
  752. // enable is not visible for few instructions.
  753. //
  754. #define FAST_ENABLE_INTERRUPTS \
  755. ssm 1 << PSR_I
  756. //
  757. //
  758. // Define TB and cache parameters.
  759. //
  760. #define PCR_ENTRY 0 // TB entry numbers (2) for the PCR
  761. #define PDR_ENTRY 2 // TB entry number (1) for the PDR
  762. #define LARGE_ENTRY 3 // TB entry number (1) for large entry
  763. #define DMA_ENTRY 4 // TB entry number (1) for DMA/InterruptSource
  764. #define TB_ENTRY_SIZE (3 * 4) // size of TB entry
  765. #define FIXED_BASE 0 // base index of fixed TB entries
  766. #define FIXED_ENTRIES (DMA_ENTRY + 1) // number of fixed TB entries
  767. //
  768. // Define cache parameters
  769. //
  770. #define DCACHE_SIZE 4 * 1024 // size of data cache in bytes
  771. #define ICACHE_SIZE 4 * 1024 // size of instruction cache in bytes
  772. #define MINIMUM_CACHE_SIZE 4 * 1024 // minimum size of cache
  773. #define MAXIMUM_CACHE_SIZE 128 * 1024 // maximum size fo cache
  774. //
  775. // RID and Sequence number limits.
  776. // Start with 1 because 0 means not initialized.
  777. // RID's are 24 bits.
  778. //
  779. #define KSEG3_RID 0x00000
  780. #define START_GLOBAL_RID 0x00001
  781. #define HAL_RID 0x00002
  782. #define START_SESSION_RID 0x00003
  783. #define START_PROCESS_RID 0x00004
  784. //
  785. // making the maximum RID to 18-bit, temp fix for Merced
  786. //
  787. #define MAXIMUM_RID 0x3FFFF
  788. //
  789. // Sequence numbers are 32 bits
  790. // Start with 1 because 0 means not initialized.
  791. //
  792. #define START_SEQUENCE 1
  793. #define MAXIMUM_SEQUENCE 0xFFFFFFFFFFFFFFFF
  794. //
  795. //
  796. // Define subtitle macro
  797. //
  798. #define SBTTL(x)
  799. //
  800. // Define procedure entry macros
  801. //
  802. #define PROLOGUE_BEGIN .##prologue;
  803. #define PROLOGUE_END .##body;
  804. #define ALTERNATE_ENTRY(Name) \
  805. .##global Name; \
  806. .##type Name, @function; \
  807. Name::
  808. #define CPUBLIC_LEAF_ENTRY(Name,i) \
  809. .##text; \
  810. .##proc Name##@##i; \
  811. Name##@##i::
  812. #define LEAF_ENTRY(Name) \
  813. .##text; \
  814. .##global Name; \
  815. .##proc Name; \
  816. Name::
  817. #define LEAF_SETUP(i,l,o,r) \
  818. .##regstk i,l,o,r; \
  819. alloc r31=ar##.##pfs,i,l,o,r
  820. #define CPUBLIC_NESTED_ENTRY(Name,i) \
  821. .##text; \
  822. .##proc Name##@##i; \
  823. .##unwentry; \
  824. Name##@##i::
  825. #define NESTED_ENTRY_EX(Name, Handler) \
  826. .##text; \
  827. .##global Name; \
  828. .##proc Name; \
  829. .##personality Handler; \
  830. Name::
  831. #define NESTED_ENTRY(Name) \
  832. .##text; \
  833. .##global Name; \
  834. .##proc Name; \
  835. Name::
  836. // Note: use of NESTED_SETUP requires number of locals (l) >= 2
  837. #define NESTED_SETUP(i,l,o,r) \
  838. .##regstk i,l,o,r; \
  839. .##prologue 0xC, loc0; \
  840. alloc savedpfs=ar##.##pfs,i,l,o,r ;\
  841. mov savedbrp=brp;
  842. //
  843. // Define procedure exit macros
  844. //
  845. #define LEAF_RETURN \
  846. br##.##ret##.##sptk##.##few##.##clr brp
  847. #define NESTED_RETURN \
  848. mov ar##.##pfs = savedpfs; \
  849. mov brp = savedbrp; \
  850. br##.##ret##.##sptk##.##few##.##clr brp
  851. #define LEAF_EXIT(Name) \
  852. .##endp Name;
  853. #define NESTED_EXIT(Name) \
  854. .##endp Name;
  855. //++
  856. // Routine:
  857. //
  858. // LDPTR(rD, rPtr)
  859. //
  860. // Routine Description:
  861. //
  862. // load pointer value.
  863. //
  864. // Agruments:
  865. //
  866. // rD: destination register
  867. // rPtr: register containing pointer
  868. //
  869. // Return Value:
  870. //
  871. // rD = load from address [rPtr]
  872. //
  873. // Notes:
  874. //
  875. // rPtr is unchanged
  876. //
  877. //--
  878. #ifdef _WIN64
  879. #define LDPTR(rD, rPtr) \
  880. ld8 rD = [rPtr]
  881. #else
  882. #define LDPTR(rD, rPtr) \
  883. ld4 rD = [rPtr] ;\
  884. ;; ;\
  885. sxt4 rD = rD
  886. #endif
  887. //++
  888. // Routine:
  889. //
  890. // LDPTRINC(rD, rPtr, imm)
  891. //
  892. // Routine Description:
  893. //
  894. // load pointer value and update base.
  895. //
  896. // Agruments:
  897. //
  898. // rD: destination register
  899. // rPtr: register containing pointer
  900. // imm: number to be incremented to base
  901. //
  902. // Return Value:
  903. //
  904. // rD = load from address [rPtr] and rPtr += imm
  905. //
  906. // Notes:
  907. //
  908. //--
  909. #ifdef _WIN64
  910. #define LDPTRINC(rD, rPtr, imm) \
  911. ld8 rD = [rPtr], imm
  912. #else
  913. #define LDPTRINC(rD, rPtr, imm) \
  914. ld4 rD = [rPtr], imm ;\
  915. ;; ;\
  916. sxt4 rD = rD
  917. #endif
  918. //++
  919. // Routine:
  920. //
  921. // PLDPTRINC(rP, rD, rPtr, imm)
  922. //
  923. // Routine Description:
  924. //
  925. // predicated load pointer value and update base.
  926. //
  927. // Agruments:
  928. //
  929. // rP: predicate register
  930. // rD: destination register
  931. // rPtr: register containing pointer
  932. // imm: number to be incremented to base
  933. //
  934. // Return Value:
  935. //
  936. // if (rP) rD = load from address [rPtr] and rPtr += imm
  937. //
  938. // Notes:
  939. //
  940. //--
  941. #ifdef _WIN64
  942. #define PLDPTRINC(rP, rD, rPtr, imm) \
  943. (rP) ld8 rD = [rPtr], imm
  944. #else
  945. #define PLDPTRINC(rP, rD, rPtr, imm) \
  946. (rP) ld4 rD = [rPtr], imm ;\
  947. ;; ;\
  948. (rP) sxt4 rD = rD
  949. #endif
  950. //++
  951. // Routine:
  952. //
  953. // PLDPTR(rP, rD, rPtr)
  954. //
  955. // Routine Description:
  956. //
  957. // predicated load pointer value.
  958. //
  959. // Agruments:
  960. //
  961. // rP: predicate register
  962. // rD: destination register
  963. // rPtr: register containing pointer
  964. //
  965. // Return Value:
  966. //
  967. // if (rP == 1) rD = load from address [rPtr], else NO-OP
  968. //
  969. // Notes:
  970. //
  971. // rPtr is unchanged
  972. //
  973. //--
  974. #ifdef _WIN64
  975. #define PLDPTR(rP, rD, rPtr) \
  976. (rP) ld8 rD = [rPtr]
  977. #else
  978. #define PLDPTR(rP, rD, rPtr) \
  979. (rP) ld4 rD = [rPtr] ;\
  980. ;; ;\
  981. (rP) sxt4 rD = rD
  982. #endif
  983. //++
  984. // Routine:
  985. //
  986. // STPTR(rPtr, rS)
  987. //
  988. // Routine Description:
  989. //
  990. // store pointer value.
  991. //
  992. // Agruments:
  993. //
  994. // rPtr: register containing pointer
  995. // rS : source pointer value
  996. //
  997. // Return Value:
  998. //
  999. // store [rPtr] = rS
  1000. //
  1001. // Notes:
  1002. //
  1003. // rPtr is unchanged
  1004. //
  1005. //--
  1006. #ifdef _WIN64
  1007. #define STPTR(rPtr, rS) \
  1008. st8 [rPtr] = rS
  1009. #else
  1010. #define STPTR(rPtr, rS) \
  1011. st4 [rPtr] = rS
  1012. #endif
  1013. //++
  1014. // Routine:
  1015. //
  1016. // PSTPTR(rP, rPtr, rS)
  1017. //
  1018. // Routine Description:
  1019. //
  1020. // predicated store pointer value.
  1021. //
  1022. // Agruments:
  1023. //
  1024. // rP: predicate register
  1025. // rPtr: register containing pointer
  1026. // rS : source pointer value
  1027. //
  1028. // Return Value:
  1029. //
  1030. // if (rP) store [rPtr] = rS
  1031. //
  1032. // Notes:
  1033. //
  1034. // rPtr is unchanged
  1035. //
  1036. //--
  1037. #ifdef _WIN64
  1038. #define PSTPTR(rP, rPtr, rS) \
  1039. (rP) st8 [rPtr] = rS
  1040. #else
  1041. #define PSTPTR(rP, rPtr, rS) \
  1042. (rP) st4 [rPtr] = rS
  1043. #endif
  1044. //++
  1045. // Routine:
  1046. //
  1047. // STPTRINC(rPtr, rS, imm)
  1048. //
  1049. // Routine Description:
  1050. //
  1051. // store pointer value.
  1052. //
  1053. // Agruments:
  1054. //
  1055. // rPtr: register containing pointer
  1056. // rS : source pointer value
  1057. // imm: number to be incremented to base
  1058. //
  1059. // Return Value:
  1060. //
  1061. // if (rP) store [rPtr] = rS, rPtr += imm
  1062. //
  1063. // Notes:
  1064. //
  1065. //--
  1066. #ifdef _WIN64
  1067. #define STPTRINC(rPtr, rS, imm) \
  1068. st8 [rPtr] = rS, imm
  1069. #else
  1070. #define STPTRINC(rPtr, rS, imm) \
  1071. st4 [rPtr] = rS, imm
  1072. #endif
  1073. //++
  1074. // Routine:
  1075. //
  1076. // ARGPTR(rPtr)
  1077. //
  1078. // Routine Description:
  1079. //
  1080. // sign extend the pointer argument for WIN32
  1081. //
  1082. // Agruments:
  1083. //
  1084. // rPtr: register containing pointer argument
  1085. //
  1086. // Return Value:
  1087. //
  1088. //
  1089. // Notes:
  1090. //
  1091. //
  1092. //
  1093. //--
  1094. #ifdef _WIN64
  1095. #define ARGPTR(rPtr)
  1096. #else
  1097. #define ARGPTR(rPtr) \
  1098. sxt4 rPtr = rPtr
  1099. #endif
  1100. //
  1101. // Assembler spinlock macros
  1102. //
  1103. //++
  1104. // Routine:
  1105. //
  1106. // ACQUIRE_SPINLOCK(rpLock, rOwn, Loop)
  1107. //
  1108. // Routine Description:
  1109. //
  1110. // Acquire a spinlock. Waits for lock to become free
  1111. // by spinning on the cached lock value.
  1112. //
  1113. // Agruments:
  1114. //
  1115. // rpLock: pointer to the spinlock (64-bit)
  1116. // rOwn: value to store in lock to indicate owner
  1117. // Depending on call location, it could be:
  1118. // - rpLock
  1119. // - pointer to process
  1120. // - pointer to thread
  1121. // - pointer to PRCB
  1122. // Loop: unique name for loop label
  1123. //
  1124. // Return Value:
  1125. //
  1126. // None
  1127. //
  1128. // Notes:
  1129. //
  1130. // Uses temporaries: predicates pt0, pt1, pt2, and GR t22.
  1131. //--
  1132. #define ACQUIRE_SPINLOCK(rpLock, rOwn, Loop) \
  1133. cmp##.##eq pt0, pt1 = zero, zero ;\
  1134. cmp##.##eq pt2 = zero, zero ;\
  1135. ;; ;\
  1136. Loop: ;\
  1137. .pred.rel "mutex",pt0,pt1 ;\
  1138. (pt0) xchg8 t22 = [rpLock], rOwn ;\
  1139. (pt1) ld8##.##nt1 t22 = [rpLock] ;\
  1140. ;; ;\
  1141. (pt0) cmp##.##ne pt2 = zero, t22 ;\
  1142. cmp##.##eq pt0, pt1 = zero, t22 ;\
  1143. (pt2) br##.##dpnt Loop
  1144. //++
  1145. // Routine:
  1146. //
  1147. // RELEASE_SPINLOCK(rpLock)
  1148. //
  1149. // Routine Description:
  1150. //
  1151. // Release a spinlock by setting lock to zero.
  1152. //
  1153. // Agruments:
  1154. //
  1155. // rpLock: pointer to the spinlock.
  1156. //
  1157. // Return Value:
  1158. //
  1159. // None
  1160. //
  1161. // Notes:
  1162. //
  1163. // Uses an ordered store to ensure previous memory accesses in
  1164. // critical section complete.
  1165. //--
  1166. #define RELEASE_SPINLOCK(rpLock) \
  1167. st8##.##rel [rpLock] = zero
  1168. //++
  1169. // Routine:
  1170. //
  1171. // PRELEASE_SPINLOCK(rpLock)
  1172. //
  1173. // Routine Description:
  1174. //
  1175. // Predicated release spinlock.
  1176. //
  1177. // Agruments:
  1178. //
  1179. // rpLock: pointer (swizzled) to the spinlock.
  1180. // spinlock itself is 32-bit.
  1181. //
  1182. // Return Value:
  1183. //
  1184. // None
  1185. //
  1186. // Notes:
  1187. //
  1188. // Uses an ordered store to ensure previous memory accesses in
  1189. // critical section complete.
  1190. //--
  1191. #define PRELEASE_SPINLOCK(px, rpLock) \
  1192. (px) st8##.##rel [rpLock] = zero
  1193. //
  1194. // Interrupt and IRQL macros
  1195. //
  1196. //++
  1197. // Routine:
  1198. //
  1199. // END_OF_INTERRUPT
  1200. //
  1201. // Routine Description:
  1202. //
  1203. // Hook to perform end-of-interrupt processing. Currently
  1204. // just writes to the EOI control register.
  1205. //
  1206. // Agruments:
  1207. //
  1208. // None
  1209. //
  1210. // Return Value:
  1211. //
  1212. // None
  1213. //
  1214. // Note:
  1215. //
  1216. // Writing EOI requires explicit data serialize. srlz must be preceded by
  1217. // stop bit.
  1218. //--
  1219. #define END_OF_INTERRUPT \
  1220. mov cr##.##eoi = zero ;\
  1221. ;; ;\
  1222. srlz##.##d /* Requires data srlz */
  1223. //++
  1224. // Routine:
  1225. //
  1226. // GET_IRQL(rOldIrql)
  1227. //
  1228. // Routine Description:
  1229. //
  1230. // Read the current IRQL by reading the TPR control register.
  1231. //
  1232. // Agruments:
  1233. //
  1234. // Register to contain the result.
  1235. //
  1236. // Return Value:
  1237. //
  1238. // rOldIrql: the current value of the IRQL.
  1239. //
  1240. //--
  1241. #ifndef SHADOW_IRQL_IMPLEMENTATION
  1242. #define GET_IRQL(rOldIrql) \
  1243. mov rOldIrql = cr##.##tpr ;;\
  1244. extr##.##u rOldIrql = rOldIrql, TPR_MIC, TPR_MIC_LEN
  1245. #else
  1246. #define GET_IRQL(rOldIrql) \
  1247. movl rOldIrql = KiPcr+PcCurrentIrql;; \
  1248. ld1 rOldIrql = [rOldIrql]
  1249. #endif
  1250. //++
  1251. // Routine:
  1252. //
  1253. // SET_IRQL(rNewIrql)
  1254. //
  1255. // Routine Description:
  1256. //
  1257. // Update the IRQL by writing the TPR control register.
  1258. // register t21 & t22 are used as a scratch
  1259. //
  1260. // Agruments:
  1261. //
  1262. // Register with the new IRQL value. Contains the unshifted
  1263. // IRQL value (0-15).
  1264. //
  1265. // Return Value:
  1266. //
  1267. // None.
  1268. //
  1269. // Notes:
  1270. //
  1271. // Writing TPR requires explicit data serialize. srlz must be preceded by
  1272. // stop bit.
  1273. //
  1274. //--
  1275. #ifndef SHADOW_IRQL_IMPLEMENTATION
  1276. #define SET_IRQL(rNewIrql) \
  1277. dep##.##z t22 = rNewIrql, TPR_MIC, TPR_MIC_LEN;; ;\
  1278. mov cr##.##tpr = t22;; ;\
  1279. srlz##.##d
  1280. #else
  1281. #define SET_IRQL(rNewIrql) \
  1282. dep##.##z t22 = rNewIrql, TPR_MIC, TPR_MIC_LEN;; ;\
  1283. movl t21 = KiPcr+PcCurrentIrql;; ;\
  1284. mov cr##.##tpr = t22 ;\
  1285. st1 [t21] = rNewIrql
  1286. #endif
  1287. //++
  1288. // Routine:
  1289. //
  1290. // PSET_IRQL(pr, rNewIrql)
  1291. //
  1292. // Routine Description:
  1293. //
  1294. // Update the IRQL by writing the TPR control register, predicated
  1295. // on pr
  1296. // register t21 & t22 are used as a scratch
  1297. //
  1298. // Agruments:
  1299. //
  1300. // pr: predicate -- set irql if pr true.
  1301. //
  1302. // rNewIrql: Register with the new IRQL value. Contains the unshifted
  1303. // IRQL value (0-15).
  1304. //
  1305. // Return Value:
  1306. //
  1307. // None.
  1308. //
  1309. // Notes:
  1310. //
  1311. // Relies on TPR.mi always 0.
  1312. // Writing TPR requires explicit data serialize. srlz must be preceded by
  1313. // stop bit.
  1314. //--
  1315. #ifndef SHADOW_IRQL_IMPLEMENTATION
  1316. #define PSET_IRQL(pr, rNewIrql) \
  1317. dep##.##z t22 = rNewIrql, TPR_MIC, TPR_MIC_LEN;; ;\
  1318. (pr) mov cr##.##tpr = t22;; ;\
  1319. (pr) srlz##.##d
  1320. #else
  1321. #define PSET_IRQL(pr, rNewIrql) \
  1322. mov t21 = rNewIrql ;\
  1323. dep##.##z t22 = rNewIrql, TPR_MIC, TPR_MIC_LEN;; ;\
  1324. (pr) mov cr##.##tpr = t22 ;\
  1325. (pr) movl t22 = KiPcr+PcCurrentIrql;; ;\
  1326. (pr) st1 [t22] = t21
  1327. #endif
  1328. //++
  1329. // Routine:
  1330. //
  1331. // SWAP_IRQL(rNewIrql)
  1332. //
  1333. // Routine Description:
  1334. //
  1335. // get the current IRQL value and set the IRQL to the new value
  1336. // register t21 and t22 are used as a scratch
  1337. //
  1338. // Agruments:
  1339. //
  1340. // Register with the new IRQL value. Contains the unshifted
  1341. // IRQL value (0-15).
  1342. //
  1343. // Return Value:
  1344. //
  1345. // v0 - current IRQL
  1346. //
  1347. //--
  1348. #define SWAP_IRQL(rNewIrql) \
  1349. movl t22 = KiPcr+PcCurrentIrql;; ;\
  1350. ld1 v0 = [t22] ;\
  1351. dep##.##z t21 = rNewIrql, TPR_MIC, TPR_MIC_LEN;; ;\
  1352. mov cr##.##tpr = t21 ;\
  1353. st1 [t22] = rNewIrql
  1354. //++
  1355. // Routine:
  1356. //
  1357. // GET_IRQL_FOR_VECTOR(pGet,rIrql,rVector)
  1358. //
  1359. // Routine Description:
  1360. //
  1361. // Hook to get the IRQL associated with an interrupt vector.
  1362. // Currently just returns bit {7:4} of the 8-bit vector number.
  1363. //
  1364. // Agruments:
  1365. //
  1366. // pGet: Predicate: if true then get, else skip.
  1367. // rIrql: Register to contain the associated IRQL.
  1368. // rVector: Register containing the vector number.
  1369. //
  1370. // Return Value:
  1371. //
  1372. // rIrql: The IRQL value. A 4-bit value in bits {3:0}. All
  1373. // other bits are zero.
  1374. //
  1375. //--
  1376. #define GET_IRQL_FOR_VECTOR(pGet,rIrql,rVector) \
  1377. (pGet) shr rIrql = rVector, VECTOR_IRQL_SHIFT
  1378. //++
  1379. // Routine:
  1380. //
  1381. // GET_VECTOR_FOR_IRQL(pGet,rVector,rIrql)
  1382. //
  1383. // Routine Description:
  1384. //
  1385. // Hook to get the interrupt vector associated with an IRQL.
  1386. // Currently just returns IRQL << 4.
  1387. //
  1388. // Agruments:
  1389. //
  1390. // pGet: Predicate: if true then get, else skip.
  1391. // rVector: Register containing the associated vector number.
  1392. // rIrql: Register to containing the IRQL.
  1393. //
  1394. // Return Value:
  1395. //
  1396. // rVector: The vector value. An 8-bit value in bits {7:0}. All
  1397. // other bits are zero.
  1398. //
  1399. //--
  1400. #define GET_VECTOR_FOR_IRQL(pGet, rVector, rIrql) \
  1401. (pGet) shl rVector = rIrql, VECTOR_IRQL_SHIFT
  1402. // Routine:
  1403. //
  1404. // REQUEST_APC_INT(pReq)
  1405. // REQUEST_DISPATCH_INT(pReq)
  1406. //
  1407. // Routine Description:
  1408. //
  1409. // Request a software interrupt. Used to request
  1410. // APC and DPC interrupts.
  1411. //
  1412. // Agruments:
  1413. //
  1414. // pReq: Predicate: if true then do request, else skip
  1415. //
  1416. // Return Value:
  1417. //
  1418. // None
  1419. //
  1420. // Notes:
  1421. //
  1422. // Uses temporary registers t20, t21
  1423. //--
  1424. #define REQUEST_APC_INT(pReq) \
  1425. mov t20 = 1 ;\
  1426. movl t21 = KiPcr+PcApcInterrupt ;\
  1427. ;; ;\
  1428. (pReq) st1 [t21] = t20
  1429. #define REQUEST_DISPATCH_INT(pReq) \
  1430. mov t20 = 1 ;\
  1431. movl t21 = KiPcr+PcDispatchInterrupt ;\
  1432. ;; ;\
  1433. (pReq) st1 [t21] = t20
  1434. #ifdef __assembler
  1435. //++
  1436. // Routine:
  1437. //
  1438. // LOWER_IRQL(rNewIrql)
  1439. //
  1440. // Routine Description:
  1441. //
  1442. // Check for pending s/w interrupts and lower Irql
  1443. //
  1444. // Agruments:
  1445. //
  1446. // rNewIrql: interrupt request level
  1447. //
  1448. // Return Value:
  1449. //
  1450. // None
  1451. //
  1452. // Notes:
  1453. //
  1454. // Pending s/w interrupts are dispatched if new IRQL is low enough,
  1455. // even though interrupts are disabled
  1456. //--
  1457. #define LOWER_IRQL(rNewIrql) \
  1458. cmp##.##gtu pt0, pt1 = DISPATCH_LEVEL, rNewIrql ;\
  1459. movl t22 = KiPcr+PcSoftwareInterruptPending;; ;\
  1460. ld2 t22 = [t22] ;\
  1461. mov out0 = rNewIrql;; ;\
  1462. (pt0) cmp##.##ne pt0, pt1 = r0, t22 ;\
  1463. PSET_IRQL(pt1, rNewIrql) ;\
  1464. (pt0) br##.##call##.##spnt brp = KiCheckForSoftwareInterrupt
  1465. //++
  1466. //
  1467. // Routine:
  1468. //
  1469. // LEAF_LOWER_IRQL_AND_RETURN(rNewIrql)
  1470. //
  1471. // Routine Description:
  1472. //
  1473. // Check for pending s/w interrupts and lower Irql
  1474. //
  1475. // If a software interupt is in fact pending and would
  1476. // logically fire if IRQL is lowered to the new level,
  1477. // branch to code that will promote to a nested function
  1478. // and handle the interrupt, otherwise, lower IRQL and
  1479. // return from this leaf function.
  1480. //
  1481. // Agruments:
  1482. //
  1483. // rNewIrql: interrupt request level
  1484. //
  1485. // Return Value:
  1486. //
  1487. // None
  1488. //
  1489. // Notes:
  1490. //
  1491. // Pending s/w interrupts are dispatched if new IRQL is low enough,
  1492. // even though interrupts are disabled
  1493. //--
  1494. #define LEAF_LOWER_IRQL_AND_RETURN(rNewIrql) \
  1495. cmp##.##gtu pt0 = DISPATCH_LEVEL, rNewIrql ;\
  1496. movl t21 = KiPcr+PcSoftwareInterruptPending;; ;\
  1497. (pt0) rsm 1 << PSR_I ;\
  1498. (pt0) ld2 t21 = [t21] ;\
  1499. mov t22 = rNewIrql;; ;\
  1500. (pt0) cmp##.##ltu##.##unc pt1 = rNewIrql, t21 ;\
  1501. (pt1) br##.##spnt KiLowerIrqlSoftwareInterruptPending ;\
  1502. SET_IRQL(rNewIrql) ;\
  1503. ssm 1 << PSR_I ;\
  1504. br##.##ret##.##spnt##.##few##.##clr brp
  1505. #endif // __assembler
  1506. //*******
  1507. //*
  1508. //* The following macros are used in C runtime asm code
  1509. //*
  1510. //* beginSection - a macro for declaring and beginning a section
  1511. //* .sdata is used to create short data section, if it does not exist
  1512. //*
  1513. //* endSection - a macro for ending a previously declared section
  1514. //*
  1515. //*******
  1516. #define beginSection(SectName) .##section .CRT$##SectName, "a", "progbits"
  1517. #define endSection(SectName)
  1518. #define PublicFunction(Name) .##global Name; .##type Name,@function
  1519. // XIA Begin C Initializer Sections
  1520. // XIC Microsoft Reserved
  1521. // XIU User
  1522. // XIZ End C Initializer Sections
  1523. //
  1524. // XCA Begin C++ Constructor Sections
  1525. // XCC Compiler (MS)
  1526. // XCL Library
  1527. // XCU User
  1528. // XCZ End C++ Constructor Sections
  1529. //
  1530. // XPA Begin C Pre-Terminator Sections
  1531. // XPU User
  1532. // XPX Microsoft Reserved
  1533. // XPZ End C Pre-Terminator Sections
  1534. //
  1535. // XTA Begin C Pre-Terminator Sections
  1536. // XTU User
  1537. // XTX Microsoft Reserved
  1538. // XTZ End C Pre-Terminator Sections
  1539. //