* mikeOS 16 bit and amd64 baremetal
[mascara-docs.git] / amd64 / pure64-0.5.0 / src / init_isa.asm
blobc7da318c122ca4766fdda642688f5a2d8f34689b
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 ISA
6 ; =============================================================================
9 isa_setup:
10 mov edi, 0x00004000 ; Clear out memory for the E820 map
11 xor eax, eax
12 mov ecx, 2048
13 rep stosd
15 ; Get the BIOS E820 Memory Map
16 ; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
17 ; inputs: es:di -> destination buffer for 24 byte entries
18 ; outputs: bp = entry count, trashes all registers except esi
19 do_e820:
20 mov edi, 0x00004000 ; location that memory map will be stored to
21 xor ebx, ebx ; ebx must be 0 to start
22 xor bp, bp ; keep an entry count in bp
23 mov edx, 0x0534D4150 ; Place "SMAP" into edx
24 mov eax, 0xe820
25 mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
26 mov ecx, 24 ; ask for 24 bytes
27 int 0x15
28 jc nomemmap ; carry set on first call means "unsupported function"
29 mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
30 cmp eax, edx ; on success, eax must have been reset to "SMAP"
31 jne nomemmap
32 test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
33 je nomemmap
34 jmp jmpin
35 e820lp:
36 mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
37 mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
38 mov ecx, 24 ; ask for 24 bytes again
39 int 0x15
40 jc memmapend ; carry set means "end of list already reached"
41 mov edx, 0x0534D4150 ; repair potentially trashed register
42 jmpin:
43 jcxz skipent ; skip any 0 length entries
44 cmp cl, 20 ; got a 24 byte ACPI 3.X response?
45 jbe notext
46 test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
47 je skipent
48 notext:
49 mov ecx, [es:di + 8] ; get lower dword of memory region length
50 test ecx, ecx ; is the qword == 0?
51 jne goodent
52 mov ecx, [es:di + 12] ; get upper dword of memory region length
53 jecxz skipent ; if length qword is 0, skip entry
54 goodent:
55 inc bp ; got a good entry: ++count, move to next storage spot
56 add di, 32
57 skipent:
58 test ebx, ebx ; if ebx resets to 0, list is complete
59 jne e820lp
60 nomemmap:
61 mov byte [cfg_e820], 0 ; No memory map function
62 memmapend:
63 xor eax, eax ; Create a blank record for termination (32 bytes)
64 mov ecx, 8
65 rep stosd
67 ; Enable the A20 gate
68 set_A20:
69 in al, 0x64
70 test al, 0x02
71 jnz set_A20
72 mov al, 0xD1
73 out 0x64, al
74 check_A20:
75 in al, 0x64
76 test al, 0x02
77 jnz check_A20
78 mov al, 0xDF
79 out 0x60, al
81 ; Set up RTC
82 ; Port 0x70 is RTC Address, and 0x71 is RTC Data
83 ; http://www.nondot.org/sabre/os/files/MiscHW/RealtimeClockFAQ.txt
84 rtc_poll:
85 mov al, 0x0A ; Status Register A
86 out 0x70, al ; Select the address
87 in al, 0x71 ; Read the data
88 test al, 0x80 ; Is there an update in process?
89 jne rtc_poll ; If so then keep polling
90 mov al, 0x0A ; Status Register A
91 out 0x70, al ; Select the address
92 mov al, 00100110b ; UIP (0), RTC@32.768KHz (010), Rate@1024Hz (0110)
93 out 0x71, al ; Write the data
95 ; VBE init
96 cmp byte [cfg_vesa], 1 ; Check if VESA should be enabled
97 jne VBEdone ; If not then skip VESA init
99 mov edi, VBEModeInfoBlock ; VBE data will be stored at this address
100 mov ax, 0x4F01 ; GET SuperVGA MODE INFORMATION - http://www.ctyme.com/intr/rb-0274.htm
101 ; CX queries the mode, it should be in the form 0x41XX as bit 14 is set for LFB and bit 8 is set for VESA mode
102 ; 0x4112 is 640x480x24bit 0x4129 is 640x480x32bit
103 ; 0x4115 is 800x600x24bit 0x412E is 800x600x32bit
104 ; 0x4118 is 1024x768x24bit 0x4138 is 1024x768x32bit
105 ; 0x411B is 1280x1024x24bit 0x413D is 1280x1024x32bit
106 mov cx, 0x4112 ; Put your desired mode here
107 mov bx, cx ; Mode is saved to BX for the set command later
108 int 0x10
110 cmp ax, 0x004F ; Return value in AX should equal 0x004F if supported and sucessful
111 jne VBEfail
112 cmp byte[VBEModeInfoBlock.BitsPerPixel], 24 ; Make sure this matches the number of bits for the mode!
113 jne VBEfail ; If set bit mode was unsucessful then bail out
115 mov ax, 0x4F02 ; SET SuperVGA VIDEO MODE - http://www.ctyme.com/intr/rb-0275.htm
116 int 0x10
117 cmp ax, 0x004F ; Return value in AX should equal 0x004F if supported and sucessful
118 jne VBEfail
120 jmp VBEdone
122 VBEfail:
123 mov byte [cfg_vesa], 0 ; Clear the VESA config as it was not sucessful
125 VBEdone:
127 ; Remap PIC IRQ's
128 mov al, 00010001b ; begin PIC 1 initialization
129 out 0x20, al
130 mov al, 00010001b ; begin PIC 2 initialization
131 out 0xA0, al
132 mov al, 0x20 ; IRQ 0-7: interrupts 20h-27h
133 out 0x21, al
134 mov al, 0x28 ; IRQ 8-15: interrupts 28h-2Fh
135 out 0xA1, al
136 mov al, 4
137 out 0x21, al
138 mov al, 2
139 out 0xA1, al
140 mov al, 1
141 out 0x21, al
142 out 0xA1, al
144 ; Mask all PIC interrupts
145 mov al, 0xFF
146 out 0x21, al
147 out 0xA1, al
152 ; =============================================================================
153 ; EOF