* mikeOS 16 bit and amd64 baremetal
[mascara-docs.git] / amd64 / pure64-0.5.0 / src / init_ioapic.asm
blobce03e77d3c2e5e0e41924c2490c5c311c58fa1c0
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
5 ; INIT IO-APIC
6 ; =============================================================================
9 init_ioapic:
10 mov al, 0x70 ; IMCR access
11 out 0x22, al
12 mov al, 0x01 ; set bit 1 for SMP mode
13 out 0x23, al
15 xor eax, eax
16 mov rcx, 1 ; Register 1 - IOAPIC VERSION REGISTER
17 call ioapic_reg_read
18 shr eax, 16 ; Extract bytes 16-23 (Maximum Redirection Entry)
19 and eax, 0xFF ; Clear bits 16-31
20 add eax, 1
21 mov rcx, rax
22 xor rax, rax
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
25 shl rax, 56
26 bts rax, 16 ; Interrupt Mask Enabled
27 initentry: ; Initialize all entries 1:1
28 dec rcx
29 call ioapic_entry_write
30 cmp rcx, 0
31 jne initentry
33 ; Enable the Keyboard
34 mov rcx, 1 ; IRQ value
35 mov rax, 0x21 ; Interrupt value
36 call ioapic_entry_write
38 ; Enable the RTC
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
47 push rax
48 mov al, 0x0B ; Status Register B
49 out 0x70, al ; Select the address
50 pop rax
51 bts ax, 6 ; Set Periodic(6)
52 out 0x71, al ; Write the new settings
54 sti ; Enable interrupts
56 ; Acknowledge the RTC
57 mov al, 0x0C ; Status Register C
58 out 0x70, al ; Select the address
59 in al, 0x71 ; Read the current settings
61 ret
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
69 ioapic_reg_write:
70 push rsi
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
74 pop rsi
75 ret
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
84 ioapic_reg_read:
85 push rsi
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
89 pop rsi
90 ret
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
99 ioapic_entry_write:
100 push rax
101 push rcx
103 ; Calculate index for lower DWORD
104 shl rcx, 1 ; Quick multiply by 2
105 add rcx, 0x10 ; IO Redirection tables start at 0x10
107 ; Write lower DWORD
108 call ioapic_reg_write
110 ; Write higher DWORD
111 shr rax, 32
112 add rcx, 1
113 call ioapic_reg_write
115 pop rcx
116 pop rax
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
126 ioapic_entry_read:
127 push rbx
128 push rcx
130 ; Calculate index for lower DWORD
131 shl rcx, 1 ; Quick multiply by 2
132 add rcx, 0x10 ; IO Redirection tables start at 0x10
134 ; Read lower DWORD
135 call ioapic_reg_read
136 mov rbx, rax
138 ; Read higher DWORD
139 add rcx, 1
140 call ioapic_reg_read
142 ; Combine
143 shr rax, 32
144 or rbx, rax
145 xchg rbx, rax
147 pop rcx
148 pop rbx
150 ; -----------------------------------------------------------------------------
153 ; =============================================================================
154 ; EOF