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.

862 lines
21 KiB

  1. ;/*++
  2. ;
  3. ;Module Name:
  4. ;
  5. ; ntapic.inc
  6. ;
  7. ;Abstract:
  8. ;
  9. ; This header file is intended to be included by any HAL
  10. ; that uses APICs.
  11. ;
  12. ;Author:
  13. ;
  14. ; Ron Mosgrove (Intel)
  15. ;
  16. ;Environment:
  17. ;
  18. ; Kernel mode only.
  19. ;
  20. ;Revision History:
  21. ;
  22. ; Separated out from pcmp_nt.inc -- 6-2-98 (jakeo)
  23. ;
  24. ;
  25. if 0 ; Begin C only code */
  26. #if !defined(_NTAPIC_INC_)
  27. #define _NTAPIC_INC_ 1
  28. //#define DEBUGGING 1
  29. #ifndef DBGMSG
  30. #ifdef DEBUGGING
  31. extern CHAR Cbuf[];
  32. #define DBGMSG(x) DbgPrint(x);
  33. #else
  34. #define DBGMSG(x)
  35. #endif
  36. #endif
  37. //
  38. // To allow the user to specify command line options to the HAL.
  39. //
  40. #define USER_SETABLE_OPTIONS
  41. // #define BUILD_FOR_OLD_IDW
  42. //
  43. // Default BusType
  44. //
  45. #ifndef MCA
  46. #define DEFAULT_PC_BUS Eisa
  47. #else
  48. #define DEFAULT_PC_BUS MicroChannel
  49. #endif
  50. //
  51. // Well known virtual address of local processor apic
  52. //
  53. #if defined(_WIN64)
  54. #define LOCALAPIC 0xfffffffffffe0000
  55. #else
  56. #define LOCALAPIC 0xfffe0000
  57. #endif
  58. #define pLocalApic ((ULONG volatile *) LOCALAPIC)
  59. #define LOCAL_APIC(x) (*((ULONG volatile *)&pLocalApic[(x)/sizeof(ULONG)]))
  60. //
  61. // Additional CpuFlags Bits used by NT in PC+MP Table
  62. //
  63. #define CPU_NT_STARTED 0x40 // CPU Has Been Started
  64. #define CPU_NT_RUNNING 0x80 // CPU is Runing NT
  65. #define MAX_PROCESSORS 32
  66. #define MAX_CLUSTERS 15
  67. #define MAX_IOAPICS 64
  68. //
  69. // This OS specific structure holds useful MP information. This information
  70. // is obtained from the PC+MP table and stored here for convenience.
  71. //
  72. typedef struct HalpMpInfo {
  73. ULONG ApicVersion; // 82489Dx or Not
  74. ULONG ProcessorCount; // Number of Enabled Processors
  75. ULONG NtProcessors; // Number of Running Processors
  76. ULONG BusCount; // Number of buses in system
  77. ULONG IOApicCount; // Number of Io Apics in system
  78. ULONG IntiCount; // Number of Io Apic interrupt input entries
  79. ULONG LintiCount; // Number of Local Apic interrupt input entries
  80. ULONG IMCRPresent; // Indicates if the IMCR is present
  81. ULONG LocalApicBase; // Base of local APIC
  82. PULONG IoApicBase[MAX_IOAPICS]; // The virtual addresses of the IoApics
  83. ULONG IoApicPhys[MAX_IOAPICS]; // The physical addresses of the IoApics
  84. #ifdef ACPI_HAL
  85. ULONG IoApicIntiBase[MAX_IOAPICS]; // The 'number' of the first INTI -- only used for ACPI
  86. #else
  87. PPCMPPROCESSOR ProcessorEntryPtr; // Ptr to 1st PC+MP processor entry
  88. PPCMPBUS BusEntryPtr; // Ptr to 1st PC+MP bus entry
  89. PPCMPIOAPIC IoApicEntryPtr; // Ptr to 1st PC+MP IoApic entry
  90. PPCMPINTI IntiEntryPtr; // Ptr to 1st PC+MP Inti entry
  91. PPCMPLINTI LintiEntryPtr; // Ptr to 1st PC+MP Linti entry
  92. PMPS_EXTENTRY ExtensionTable; // Ptr to 1st extension table entry
  93. PMPS_EXTENTRY EndOfExtensionTable;
  94. #endif
  95. } MP_INFO, *PMP_INFO;
  96. typedef struct {
  97. PUCHAR PcMpType;
  98. BOOLEAN PhysicalInstance;
  99. UCHAR Level;
  100. INTERFACE_TYPE NtType;
  101. PINSTALL_BUS_HANDLER NewInstance;
  102. BUS_DATA_TYPE NtConfig;
  103. ULONG BusExtensionSize;
  104. } PCMPBUSTRANS, *PPCMPBUSTRANS;
  105. #define CFG_MUST_BE 0x02
  106. #define CFG_ERROR 0x80
  107. #define CFG_HIGH 0x01
  108. #define CFG_LOW 0x00
  109. #define CFG_EDGE 0x00
  110. #define CFG_LEVEL 0x01
  111. #define CFG_MB_EDGE (CFG_MUST_BE | CFG_EDGE)
  112. #define CFG_MB_LEVEL (CFG_MUST_BE | CFG_LEVEL)
  113. #define CFG_ERR_EDGE (CFG_ERROR | CFG_EDGE)
  114. #define CFG_ERR_LEVEL (CFG_ERROR | CFG_LEVEL)
  115. #define CFG_ERR_MB_EDGE (CFG_ERROR | CFG_MUST_BE | CFG_EDGE)
  116. #define CFG_ERR_MB_LEVEL (CFG_ERROR | CFG_MUST_BE | CFG_LEVEL)
  117. #define CFG_TYPE(a) (a & 1)
  118. typedef union _INTERRUPT_DEST {
  119. union _Cluster {
  120. struct _Hw {
  121. UCHAR DestId:4;
  122. UCHAR ClusterId:4;
  123. } Hw;
  124. UCHAR AsUchar;
  125. } Cluster;
  126. UCHAR LogicalId;
  127. } INTERRUPT_DEST, *PINTERRUPT_DEST;
  128. #if defined(_X86_)
  129. //
  130. // The kernel leaves some space (64 byte) of the PCR for the HAL to use
  131. // as it needs. Currently this space is used for some efficiency in
  132. // some of the MP specific code and is highly implementation-dependent.
  133. //
  134. typedef struct _HALPCR {
  135. UCHAR PcrNumber; // Processor's number
  136. UCHAR ShortDpc; // Short circut dpc interrupt
  137. UCHAR DpcPending; // Dpc interrupt pending
  138. UCHAR Reserved; // force dword alignment
  139. //
  140. // The next three dwords are used to manipulate the APIC counter
  141. //
  142. ULONG ApicClockFreqHz; // Counter Freq in Hertz
  143. ULONG ApicClockFreqKhz; // Counter Freq in Khertz (rounded)
  144. ULONG ProfileCountDown; // Current Countdown Interval
  145. ULONGLONG TSCHz; // Time stamp counter hertz
  146. ULONG PerfCounterLow; // PerProcessor Counter
  147. ULONG PerfCounterHigh;
  148. } HALPCR, *PHALPCR;
  149. #elif defined(_AMD64_)
  150. typedef struct _HALPCR {
  151. ULONG64 PerfCounter;
  152. ULONG64 TSCHz; // time stamp counter frequency
  153. ULONG ProfileCountDown; // current profile countdown interval
  154. ULONG ApicClockFreqHz; // counter frequency
  155. ULONG StallScaleFactor;
  156. ULONG ApicId; // APIC Id assigned this processor
  157. } HALPCR, *PHALPCR;
  158. C_ASSERT(sizeof(HALPCR) <= RTL_FIELD_SIZE(KPCR,HalReserved));
  159. #else
  160. #error "Platform not supported"
  161. #endif
  162. //
  163. // The kernel leaves some space (64 byte) of the PCRB for the HAL to use
  164. // as it needs. Currently this space is used for some efficiency in
  165. // some of the MP specific code and is highly implementation-dependent.
  166. //
  167. typedef struct {
  168. UCHAR PCMPApicID;
  169. UCHAR na[3];
  170. } HALPRCB, *PHALPRCB;
  171. #if defined(_AMD64_)
  172. #define ZERO_VECTOR 0x00 // IRQL 0 placeholder
  173. #define APC_VECTOR 0x1f // IRQL 1 APC
  174. #define DPC_VECTOR 0x2f // IRQL 2 DPC
  175. #define APIC_SPURIOUS_VECTOR 0x3f // IRQL 3 Spurious handler
  176. #define APIC_REBOOT_VECTOR 0x50 // IRQL 5 Vector used to reboot
  177. #define APIC_GENERIC_VECTOR 0xC1 // IRQL 12 broadcast function call
  178. #define APIC_CLOCK_VECTOR 0xD1 // IRQL 13 APIC INTI0 - CLOCK2_LEVEL
  179. #define APIC_SYNCH_VECTOR 0xD1 // IRQL 13 IPI_LEVEL-1
  180. #define APIC_IPI_VECTOR 0xE1 // IRQL 14 APIC IPI
  181. #define APIC_FAULT_VECTOR 0xE3 // IRQL 14
  182. #define POWERFAIL_VECTOR 0xEF // IRQL 14 reserved. not used
  183. #define APIC_PROFILE_VECTOR 0xFD // IRQL 15
  184. #define APIC_PERF_VECTOR 0xFE // IRQL 15
  185. #define NMI_VECTOR 0xFF // IRQL 15
  186. //
  187. // The APIC hard-wires the four low-order bits of the spurious interrupt
  188. // vector to 1.
  189. //
  190. C_ASSERT((APIC_SPURIOUS_VECTOR & 0x0f) == 0x0f);
  191. #else
  192. //
  193. // interrupt vector definitions for C
  194. //
  195. #define ZERO_VECTOR 0x00 // IRQL 00 placeholder
  196. #define APIC_SPURIOUS_VECTOR 0x1f // IRQL Spurious handler
  197. #define APC_VECTOR 0x3D // IRQL 01 APC
  198. #define DPC_VECTOR 0x41 // IRQL 02 DPC
  199. #define APIC_REBOOT_VECTOR 0x50 // IRQL Vector used to reboot
  200. #define APIC_GENERIC_VECTOR 0xC1 // IRQL 27 broadcast function call
  201. #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28 APIC INTI0 - CLOCK2_LEVEL
  202. //
  203. // If MP, define APIC_SYNCH_LEVEL as SYNCH_LEVEL, otherwise define
  204. // to be the same as DPC_LEVEL.
  205. //
  206. #if (SYNCH_LEVEL != DISPATCH_LEVEL)
  207. #define APIC_SYNCH_VECTOR 0xC1 // IRQL 28 IPI_LEVEL-1
  208. #else
  209. #define APIC_SYNCH_VECTOR DPC_VECTOR // IRQL 02 if UNIPROCESSOR
  210. #endif
  211. #define APIC_IPI_VECTOR 0xE1 // IRQL 29 APIC IPI
  212. #define APIC_FAULT_VECTOR 0xE3 //
  213. #define POWERFAIL_VECTOR 0xEF // IRQL 30 reserved. not used
  214. #define APIC_PROFILE_VECTOR 0xFD // IRQL 31
  215. #define APIC_PERF_VECTOR 0xFE // IRQL 31
  216. #define NMI_VECTOR 0xFF // IRQL 31
  217. #endif
  218. //
  219. // 8259/ISP interrupt controller register addresses
  220. //
  221. #define PIC1_PORT0 0x20
  222. #define PIC1_PORT1 0x21
  223. #define PIC2_PORT0 0xA0
  224. #define PIC2_PORT1 0xA1
  225. #define PIC_SLAVE_IRQ 2
  226. #define RTC_IRQ 8
  227. #define PIC1_ELCR_PORT 0x04D0 // ISP edge/level control registers
  228. #define PIC2_ELCR_PORT 0x04D1
  229. #define PIC1_SPURIOUS_VECTOR 0x37
  230. //
  231. // Defines for HalpFeatureBits
  232. //
  233. extern ULONG HalpFeatureBits;
  234. //
  235. //
  236. //
  237. #if defined(_AMD64_) && defined(NT_UP)
  238. #define HalpAcquireHighLevelLock(lock) HalpDisableInterrupts()
  239. #define HalpReleaseHighLevelLock(lock,irql) HalpRestoreInterrupts(irql)
  240. #else
  241. ULONG FASTCALL HalpAcquireHighLevelLock(PKSPIN_LOCK);
  242. VOID FASTCALL HalpReleaseHighLevelLock(PKSPIN_LOCK, ULONG);
  243. #endif
  244. extern KSPIN_LOCK HalpAccountingLock;
  245. extern KAFFINITY HalpActiveProcessors;
  246. //
  247. // Prototypes
  248. //
  249. #define MAX_INTI (MAX_IOAPICS*32) // Max interrupt inputs from APICs
  250. #define MAX_SOURCE_IRQS MAX_INTI // Max different interrupts supported
  251. //
  252. // HalVectorToIDTEntry(vector) is defined in i386.h, because the kernel needs
  253. // it.
  254. #define MAX_NODES MAX_PROCESSORS
  255. #define HalpVectorToNode(vector) ((vector)>>8)
  256. #define HalpVector(node, idtentry) ((node)<<8|(idtentry))
  257. extern struct HalpMpInfo HalpMpInfoTable;
  258. extern UCHAR HalpMaxProcsPerCluster;
  259. extern BOOLEAN HalpELCRChecked;
  260. extern USHORT HalpGlobal8259Mask;
  261. extern USHORT HalpVectorToINTI[];
  262. extern UCHAR HalpInitLevel[4][4];
  263. extern UCHAR HalpDevPolarity[4][2];
  264. extern UCHAR HalpDevLevel[2][4];
  265. //
  266. // Initialized from MPS table
  267. //
  268. typedef struct _INTI_INFO {
  269. UCHAR Type:4;
  270. UCHAR Level:2;
  271. UCHAR Polarity:2;
  272. UCHAR Destinations;
  273. USHORT Entry;
  274. } INTI_INFO, *PINTI_INFO;
  275. extern INTI_INFO HalpIntiInfo[];
  276. extern USHORT HalpMaxApicInti[];
  277. extern PCMPBUSTRANS HalpTypeTranslation[];
  278. extern ULONG HalpIpiClock;
  279. #define BusIrq2Id(bus,no,irq) \
  280. ((bus << 16) | (no << 8) | irq)
  281. #define Id2BusIrq(id) \
  282. (id & 0xff)
  283. VOID
  284. HalpInitIntiInfo (
  285. VOID
  286. );
  287. ULONG
  288. HalpGetIoApicId(
  289. ULONG ApicNo
  290. );
  291. VOID
  292. HalpSet8259Mask(
  293. IN USHORT Mask
  294. );
  295. VOID
  296. HalpInitializeLocalUnit (
  297. VOID
  298. );
  299. VOID
  300. HalpInitializeIOUnits (
  301. VOID
  302. );
  303. VOID
  304. HalpRestoreIoApicRedirTable (
  305. VOID
  306. );
  307. VOID
  308. HalpEnableNMI (
  309. VOID
  310. );
  311. VOID
  312. HalpEnableLocalNmiSources(
  313. VOID
  314. );
  315. VOID
  316. HalpSet8259Mask(
  317. IN USHORT Mask
  318. );
  319. BOOLEAN
  320. HalpGetApicInterruptDesc (
  321. IN INTERFACE_TYPE BusType,
  322. IN ULONG BusNumber,
  323. IN ULONG BusInterruptLevel,
  324. OUT PUSHORT PcMpInti
  325. );
  326. VOID
  327. HalpCheckELCR (
  328. VOID
  329. );
  330. VOID
  331. HalpGenericCall (
  332. VOID (*Fnc)(ULONG_PTR),
  333. ULONG Context,
  334. KAFFINITY Processors
  335. );
  336. VOID
  337. HalpPollForBroadcast (
  338. VOID
  339. );
  340. ULONG
  341. FASTCALL
  342. HalpWaitForPending (
  343. IN ULONG Count,
  344. IN volatile ULONG *LuICR
  345. );
  346. //
  347. // Warning 4131 is "uses old-style declarator"
  348. //
  349. #pragma warning(disable:4131)
  350. //
  351. // Warning 4218 is "nonstandard extension used"
  352. //
  353. #pragma warning(disable:4218)
  354. HAL_INTERRUPT_SERVICE_PROTOTYPE(HalpPerfInterrupt);
  355. VOID
  356. HalpEnablePerfInterupt (
  357. ULONG_PTR Context
  358. );
  359. VOID
  360. HalpEnableNMI (
  361. VOID
  362. );
  363. NTSTATUS
  364. HalpSetSystemInformation (
  365. IN HAL_SET_INFORMATION_CLASS InformationClass,
  366. IN ULONG BufferSize,
  367. IN PVOID Buffer
  368. );
  369. ULONG
  370. HalpInti2BusInterruptLevel(
  371. ULONG Inti
  372. );
  373. VOID
  374. HalpUnMapIOApics(
  375. VOID
  376. );
  377. VOID
  378. HalpInitializeIOUnits (
  379. VOID
  380. );
  381. VOID
  382. HalpPostSleepMP(
  383. IN LONG NumberProcessors,
  384. IN volatile PLONG Number
  385. );
  386. VOID
  387. HalpSetRedirEntry (
  388. IN USHORT InterruptInput,
  389. IN ULONG Entry,
  390. IN ULONG Destination
  391. );
  392. VOID
  393. HalpGetRedirEntry (
  394. IN USHORT InterruptInput,
  395. IN PULONG Entry,
  396. IN PULONG Destination
  397. );
  398. /*++
  399. HalpStallWhileApicBusy (
  400. VOID
  401. )
  402. Routine Description:
  403. This routine waits until the local apic has completed sending
  404. an IPI.
  405. Parameters:
  406. None.
  407. Return Value:
  408. None.
  409. --*/
  410. #define HalpStallWhileApicBusy() \
  411. while ((LOCAL_APIC(LU_INT_CMD_LOW) & DELIVERY_PENDING) != 0) { }
  412. #if defined(_AMD64_)
  413. #define HalpGetHalPcr(pcr) ((PHALPCR)(pcr->HalReserved))
  414. #define HalpGetCurrentHalPcr() HalpGetHalPcr(KeGetPcr())
  415. #endif
  416. #endif // _NTAPIC_INC_
  417. /*
  418. endif
  419. ;
  420. ; Begin assembly part of the definitions
  421. ;
  422. ;
  423. ; Well known virtual address of local processor apic
  424. ;
  425. LOCALAPIC equ 0fffe0000h
  426. APIC equ ds:[LOCALAPIC]
  427. DEBUGGING equ 0
  428. if DEBUGGING
  429. IRQL_METRICS equ 0
  430. endif
  431. ;
  432. ; To allow the user to specify command line options to the HAL.
  433. ;
  434. USER_SETABLE_OPTIONS equ 1
  435. MAX_PROCESSORS equ 32
  436. MAX_NODES equ MAX_PROCESSORS
  437. MAX_IOAPICS equ 64
  438. ;
  439. ; This OS specific structure holds useful MP information. This information
  440. ; is obtained from the PC+MP table and stored here for convenience.
  441. ;
  442. HalpMpInfo struc
  443. ApicVersion dd 0 ; 82489Dx or Not
  444. ProcessorCount dd 0 ; Number of Enabled Processors
  445. NtProcessors dd 0 ; Number of Running Processors
  446. BusCount dd 0 ; Number of buses in system
  447. IOApicCount dd 0 ; Number of Io Apics in system
  448. IntiCount dd 0 ; Num of Io Apic interrupt inputs
  449. LintiCount dd 0 ; Num of Local Apic interrupt inputs
  450. IMCRPresent dd 0 ; Indicates if the IMCR is present
  451. LocalApicBase dd 0 ; Base of local apic
  452. IoApicBase dd MAX_IOAPICS dup (0) ; Virtual addresses of IoApics
  453. IoApicPhys dd MAX_IOAPICS dup (0) ; Physical addresses of IoApics
  454. ifdef ACPI_HAL
  455. IoApicIntiBase dd MAX_IOAPICS dup (0) ; ACPI only. First GSIV.
  456. else
  457. ProcessorEntryPtr dd 0 ; Ptr to 1st PC+MP processor entry
  458. BusEntryPtr dd 0 ; Ptr to 1st PC+MP bus entry
  459. IoApicEntryPtr dd 0 ; Ptr to 1st PC+MP IoApic entry
  460. IntiEntryPtr dd 0 ; Ptr to 1st PC+MP Inti entry
  461. LintiEntryPtr dd 0 ; Ptr to 1st PC+MP Linti entry
  462. ExtensionTable dd 0 ; Ptr to 1st extension table entry
  463. EndExtensionTable dd 0 ; Ptr to 1st extension table entry
  464. endif
  465. HalpMpInfo ends
  466. ;
  467. ; interrupt vector definitions for assembler
  468. ;
  469. ZERO_VECTOR equ 000h ; IRQL 00 placeholder
  470. APIC_SPURIOUS_VECTOR equ 01fh ; Vector used for spurious handler
  471. APC_VECTOR equ 03Dh ; IRQL 01 APC
  472. DPC_VECTOR equ 041h ; IRQL 02 DPC
  473. APIC_REBOOT_VECTOR equ 050h ; Vector used to reboot
  474. DEVICE_LEVEL1 equ 051h
  475. DEVICE_LEVEL2 equ 061h
  476. DEVICE_LEVEL3 equ 071h
  477. DEVICE_LEVEL4 equ 081h
  478. DEVICE_LEVEL5 equ 091h
  479. DEVICE_LEVEL6 equ 0A1h
  480. DEVICE_LEVEL7 equ 0B1h
  481. APIC_GENERIC_VECTOR equ 0C1h ; IRQL 27 broadcast function call
  482. APIC_CLOCK_VECTOR equ 0D1h ; IRQL 28 APIC INTI0 - CLOCK2_LEVEL
  483. if SYNCH_LEVEL-DISPATCH_LEVEL
  484. APIC_SYNCH_VECTOR equ 0C1h ; IRQL 28 IPI_LEVEL-1
  485. else
  486. APIC_SYNCH_VECTOR equ DPC_VECTOR
  487. endif
  488. APIC_IPI_VECTOR equ 0E1h ; IRQL 29 APIC IPI
  489. APIC_FAULT_VECTOR equ 0E3h ;
  490. POWERFAIL_VECTOR equ 0EFh ; IRQL 30 reserved
  491. APIC_PROFILE_VECTOR equ 0FDh ; IRQL 27
  492. APIC_PERF_VECTOR equ 0FEh ; IRQL 27
  493. NMI_VECTOR equ 0FFh ; IRQL 31
  494. HAL_PROFILE_LEVEL equ HIGH_LEVEL
  495. ;
  496. ; 8259/ISP interrupt controller register addresses
  497. ;
  498. PIC1_PORT0 equ 020H
  499. PIC1_PORT1 equ 021H
  500. PIC2_PORT0 equ 0A0H
  501. PIC2_PORT1 equ 0A1H
  502. PIC1_ELCR_PORT equ 04D0H ; ISP edge/level control registers
  503. PIC2_ELCR_PORT equ 04D1H
  504. ;
  505. ; Initialization control words for the PICs
  506. ;
  507. ICW1_ICW4_NEEDED equ 01H
  508. ICW1_CASCADE equ 00H
  509. ICW1_INTERVAL8 equ 00H
  510. ICW1_LEVEL_TRIG equ 08H
  511. ICW1_EDGE_TRIG equ 00H
  512. ICW1_ICW equ 10H
  513. ICW4_8086_MODE equ 001H
  514. ICW4_AUTO_EOI equ 002H
  515. ICW4_NORM_EOI equ 000H
  516. ICW4_NON_BUF_MODE equ 000H
  517. ICW4_SPEC_FULLY_NESTED equ 010H
  518. ICW4_NOT_SPEC_FULLY_NESTED equ 000H
  519. PIC_SLAVE_IRQ equ 2
  520. PIC1_BASE equ 30H
  521. PIC2_BASE equ 38H
  522. PIC_CLOCK_VECTOR equ 30H
  523. PIC_DMA_VECTOR equ 3DH
  524. PIC1_SPURIOUS_VECTOR equ 37H
  525. PIC2_SPURIOUS_VECTOR equ 3FH
  526. ;
  527. ; Operation control words for the PICs
  528. ;
  529. OCW2_NON_SPECIFIC_EOI equ 020H
  530. OCW2_SPECIFIC_EOI equ 060H
  531. OCW3_READ_ISR equ 0BH
  532. OCW3_READ_IRR equ 0AH
  533. OCW3_READ_POLLED equ 0CH
  534. ;
  535. ; A couple of definitions that shouldn't change on a Compatible
  536. ;
  537. TimerPicInti equ 0
  538. DmaPic2Inti equ 5
  539. SlavePicInti equ 2
  540. DmaPicInti equ 13 ; DMA input relative to 0
  541. cr equ 0ah
  542. lf equ 0dh
  543. ;
  544. ; The kernel leaves some space (64 byte) of the PCR for the HAL to use
  545. ; as it needs. Currently this space is used for some efficiency in
  546. ; some of the MP specific code and is highly implementation-dependent.
  547. ;
  548. PcrE struc
  549. PcrNumber db 0 ; Processor's number
  550. ShortDpc db 0 ; Short circut dpc interrupt
  551. DpcPending db 0 ; Dpc interrupt pending
  552. db 0 ; force dword alignment
  553. ;
  554. ; The next three dwords are used to manipulate the APIC counter
  555. ;
  556. ApicClockFreqHz dd 0 ; Counter Freq in Hertz
  557. ApicClockFreqKhz dd 0 ; Counter Freq in Khertz (rounded)
  558. ProfileCountDown dd 0 ; Current Countdown Interval
  559. TSCHz dq 0 ; Time stamp counter hertz
  560. PerfCounterLow dd 0 ; PerProcessor Counter
  561. PerfCounterHigh dd 0 ;
  562. ; ProfileCountLast dd 0
  563. OEMPcr db size OEMPcr dup(?)
  564. PcrE ends
  565. PrcbE struc
  566. PrcbPCMPApicID db 0 ; Processor's PCMP ApicID
  567. db 3 dup (0) ; force dword alignment
  568. PrcbE ends
  569. MsrTSC equ 10h
  570. ;++
  571. ;
  572. ; STALL_WHILE_APIC_BUSY
  573. ;
  574. ; Wait for the APIC DELIVERY_PENDING bit to be clear
  575. ;
  576. ;--
  577. STALL_WHILE_APIC_BUSY macro
  578. local a, b
  579. if 0
  580. push eax
  581. mov eax, 5000h
  582. a: test dword ptr APIC[LU_INT_CMD_LOW],DELIVERY_PENDING
  583. jz short b
  584. dec eax
  585. jnz short a
  586. int 3
  587. jmp short a
  588. b: pop eax
  589. else
  590. a: test dword ptr APIC[LU_INT_CMD_LOW],DELIVERY_PENDING
  591. jnz short a
  592. endif
  593. endm
  594. ;++
  595. ;
  596. ; APICFIX
  597. ;
  598. ; Macro Description:
  599. ;
  600. ; For internal testing use
  601. ;
  602. ; Arguments:
  603. ;
  604. ; None
  605. ;
  606. ;--
  607. APICFIX macro reg1
  608. ; inc dword ptr PCR[PcKernel] ; Count # of times patched
  609. endm
  610. ;++
  611. ;
  612. ; CHECKTPR
  613. ;
  614. ; Macro Description:
  615. ;
  616. ; For internal testing use
  617. ;
  618. ; Arguments:
  619. ;
  620. ; None
  621. ;
  622. ;--
  623. CHECKTPR macro reg1, reg2
  624. if DBG
  625. cmp reg1, reg2
  626. je short @f
  627. int 3
  628. @@:
  629. endif
  630. endm
  631. ;++
  632. ;
  633. ; IODELAY
  634. ;
  635. ; Macro Description:
  636. ;
  637. ; This macro delays the CPU just a little so the PIC has time to settle
  638. ; between IO port accesses. Current mechanism is to read an APIC local
  639. ; unit register (eax is saved). Note that PUSHF/POPF is worth 10 clocks.
  640. ;
  641. ; Arguments:
  642. ;
  643. ; None
  644. ;
  645. ;--
  646. IODELAY macro
  647. pushf
  648. popf
  649. jmp $+2
  650. endm
  651. ;++
  652. ;
  653. ; SET_8259_MASK
  654. ;
  655. ; Macro Description:
  656. ;
  657. ; This macro sets the 8259 PIC interrupt mask register with the mask
  658. ; passed from eax register. Bits 7:0 are the mask for the master PIC
  659. ; and bits 15:8 are the mask for the slave PIC.
  660. ;
  661. ; Arguments:
  662. ;
  663. ; (eax) = mask for setting 8259 PIC interrupt mask register
  664. ;
  665. ;--
  666. SET_8259_MASK macro
  667. out PIC1_PORT1, al ; set master 8259 mask
  668. shr eax, 8 ; shift slave 8259 mask to al
  669. out PIC2_PORT1, al ; set slave 8259 mask
  670. endm
  671. ;*/