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.

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