Leaked source code of windows server 2003
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.

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