1 ; =============================================================================
2 ; Pure64 -- a 64-bit OS loader written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2012 Return Infinity -- see LICENSE.TXT
6 ; =============================================================================
10 mov al, 0x70 ; IMCR access
12 mov al, 0x01 ; set bit 1 for SMP mode
16 mov rcx
, 1 ; Register 1 - IOAPIC VERSION REGISTER
18 shr eax, 16 ; Extract bytes 16-23 (Maximum Redirection Entry)
19 and eax, 0xFF ; Clear bits 16-31
23 mov eax, dword [rsi
+0x20] ; Grab the BSP APIC ID; stored in bits 31:24
24 shr rax
, 24 ; AL now holds the BSP CPU's APIC ID
26 bts rax
, 16 ; Interrupt Mask Enabled
27 initentry: ; Initialize all entries 1:1
29 call ioapic_entry_write
34 mov rcx
, 1 ; IRQ value
35 mov rax
, 0x21 ; Interrupt value
36 call ioapic_entry_write
39 mov rcx
, 8 ; IRQ value
40 mov rax
, 0x28 ; Interrupt value
41 call ioapic_entry_write
43 ; Set the periodic flag in the RTC
44 mov al, 0x0B ; Status Register B
45 out 0x70, al ; Select the address
46 in al, 0x71 ; Read the current settings
48 mov al, 0x0B ; Status Register B
49 out 0x70, al ; Select the address
51 bts ax, 6 ; Set Periodic(6)
52 out 0x71, al ; Write the new settings
54 sti ; Enable interrupts
57 mov al, 0x0C ; Status Register C
58 out 0x70, al ; Select the address
59 in al, 0x71 ; Read the current settings
64 ; -----------------------------------------------------------------------------
65 ; ioapic_reg_write -- Write to an I/O APIC register
66 ; IN: EAX = Value to write
67 ; ECX = Index of register
68 ; OUT: Nothing. All registers preserved
71 mov rsi
, [os_IOAPICAddress
]
72 mov dword [rsi
], ecx ; Write index to register selector
73 mov dword [rsi
+ 0x10], eax ; Write data to window register
76 ; -----------------------------------------------------------------------------
79 ; -----------------------------------------------------------------------------
80 ; ioapic_reg_read -- Read from an I/O APIC register
81 ; IN: ECX = Index of register
82 ; OUT: EAX = Value of register
83 ; All other registers preserved
86 mov rsi
, [os_IOAPICAddress
]
87 mov dword [rsi
], ecx ; Write index to register selector
88 mov eax, dword [rsi
+ 0x10] ; Read data from window register
91 ; -----------------------------------------------------------------------------
94 ; -----------------------------------------------------------------------------
95 ; ioapic_entry_write -- Write to an I/O APIC entry in the redirection table
96 ; IN: RAX = Data to write to entry
97 ; ECX = Index of the entry
98 ; OUT: Nothing. All registers preserved
103 ; Calculate index for lower DWORD
104 shl rcx
, 1 ; Quick multiply by 2
105 add rcx
, 0x10 ; IO Redirection tables start at 0x10
108 call ioapic_reg_write
113 call ioapic_reg_write
118 ; -----------------------------------------------------------------------------
121 ; -----------------------------------------------------------------------------
122 ; ioapic_entry_read -- Read an I/O APIC entry from the redirection table
123 ; IN: ECX = Index of the entry
124 ; OUT: RAX = Data that was read
125 ; All other registers preserved
130 ; Calculate index for lower DWORD
131 shl rcx
, 1 ; Quick multiply by 2
132 add rcx
, 0x10 ; IO Redirection tables start at 0x10
150 ; -----------------------------------------------------------------------------
153 ; =============================================================================