]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/l.s
9boot: add e820 scan to bootloader
[plan9front.git] / sys / src / boot / pc / l.s
1 #include "x16.h"
2 #include "mem.h"
3
4 #undef ORB
5
6 #define DATA32SEL SELECTOR(1, SELGDT, 0)
7 #define EXEC32SEL SELECTOR(2, SELGDT, 0)
8 #define DATA16SEL SELECTOR(3, SELGDT, 0)
9 #define EXEC16SEL SELECTOR(4, SELGDT, 0)
10
11 #define SEGSS BYTE $0x36
12 #define SEGES BYTE $0x26
13 #define FARRET BYTE $0xCB
14
15 TEXT origin(SB), $0
16         CLI
17         CLR(rCX)
18         MTSR(rCX, rSS)
19         OPSIZE; MOVL $origin(SB), SP
20         PUSHA
21         OPSIZE; ADSIZE; PUSHL SP
22         OPSIZE; ADSIZE; PUSHL CX
23         PUSHI(start(SB))
24
25 TEXT pmode32(SB), $0
26         CLI
27
28         /* disable nmi */
29         PUSHA
30         LWI(0x70, rDX)
31         INB
32         ANDB $0x7F, AL
33         OUTB
34         POPA
35
36         /* get return pc */
37         POPR(rDI)
38
39         /* make sure stack is at 0000: */
40         CLR(rCX)
41         MTSR(rCX, rSS)
42         OPSIZE; ANDL $0xFFFF, SP
43
44         /* convert 16-bit return pc to far pointer */
45         PUSHI(EXEC32SEL)
46         PUSHR(rDI)
47
48         /* load gdt */
49         SEGSS; LGDT(tgdtptr(SB))
50
51         /* enable protected mode */
52         MFCR(rCR0, rCX)
53         ORB $1, CL
54         MTCR(rCX, rCR0)
55
56         /* flush */
57         FARJUMP16(EXEC16SEL, pmode32flush(SB));
58 TEXT pmode32flush(SB), $0
59
60         /* load 32-bit protected mode data selector */
61         LWI(DATA32SEL, rCX)
62
63 _segret:
64         /* load all data segments */
65         MTSR(rCX, rDS)
66         MTSR(rCX, rES)
67         MTSR(rCX, rFS)
68         MTSR(rCX, rGS)
69         MTSR(rCX, rSS)
70         FARRET
71
72 TEXT rmode16(SB), $0
73         /* setup farret to rmode16x */
74         PUSHL $EXEC16SEL
75         PUSHL $rmode16x(SB)
76
77         /* load 16-bit protected mode data selector */
78         MOVL $DATA16SEL, CX
79         JMP _segret
80
81 TEXT rmode16x(SB), $0
82         /* disable protected mode */
83         MFCR(rCR0, rCX)
84         ANDB $0xfe, CL
85         MTCR(rCX, rCR0)
86
87         /* flush */
88         FARJUMP16(0, rmode16flush(SB));
89 TEXT rmode16flush(SB), $0
90
91         /*
92          * load 16-bit realmode data segment 0000: and
93          * return to 32 bit return pc interpreted
94          * as 16 bit far pointer.
95          */
96         CLR(rCX)
97         JMP _segret
98
99 TEXT tgdt(SB), $0 
100         /* null descriptor */
101         LONG $0
102         LONG $0
103
104         /* data segment descriptor for 4 gigabytes (PL 0) */
105         LONG $(0xFFFF)
106         LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
107
108         /* exec segment descriptor for 4 gigabytes (PL 0) */
109         LONG $(0xFFFF)
110         LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
111
112         /* data segment descriptor for (PL 0) 16-bit */
113         LONG $(0xFFFF)
114         LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
115
116         /* exec segment descriptor for (PL 0) 16-bit */
117         LONG $(0xFFFF)
118         LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
119
120 TEXT tgdtptr(SB), $0 
121          WORD $(5*8) 
122          LONG $tgdt(SB)
123
124 TEXT jump(SB), $0
125         MOVL 4(SP), AX
126         JMP *AX
127
128 TEXT halt(SB), $0
129 _halt:
130         JMP _halt
131
132 TEXT spllo(SB), $0
133         /* enable nmi */
134         PUSHA
135         LWI(0x70, rDX)
136         INB
137         ORB $0x80, AL
138         OUTB
139         POPA
140
141         STI
142         RET
143
144 TEXT getc(SB), $0
145         CALL rmode16(SB)
146         CALL16(spllo(SB))
147         MOVB $0x00, AH
148         BIOSCALL(0x16)
149 _getcret:
150         CALL16(pmode32(SB))
151         ANDL $0xFF, AX
152         RET
153
154 TEXT gotc(SB), $0
155         CALL rmode16(SB)
156         CALL16(spllo(SB))
157         MOVB $0x01, AH
158         BIOSCALL(0x16)
159         JNZ _getcret
160         CLR(rAX)
161         JMP _getcret
162         
163 TEXT putc(SB), $0
164         MOVL 4(SP),AX
165         CALL rmode16(SB)
166         CALL16(spllo(SB))
167         MOVB $0x0E, AH
168         BIOSCALL(0x10)
169 _pret32:
170         CALL16(pmode32(SB))
171         ANDL $0xFFFF, AX
172         RET
173
174 #ifdef PXE
175
176 TEXT pxeinit(SB), $0
177         CALL rmode16(SB)
178
179         /* get pxe env structure in ES:BX */
180         LWI(0x5650, rAX)
181         BIOSCALL(0x1A)
182         JC _pret32
183
184         /* !PXE or PXEENV+ signature */
185         SEGES; LXW(0, xBX, rAX)
186         CMPI((('!'<<0)|('P'<<8)), rAX)
187         JEQ _getentry
188         CMPI((('P'<<0)|('X'<<8)), rAX)
189         JNE _pret32
190
191         SEGES; LXW(0x2A, xBX, rAX)
192         SEGES; LXW(0x28, xBX, rBX)
193         MTSR(rAX, rES)
194
195 _getentry:
196         SEGES; LXW(0x12, xBX, rAX)
197         SW(rAX, pxepseg(SB))
198         SEGES; LXW(0x10, xBX, rAX)
199         SW(rAX, pxepoff(SB))
200         CLR(rAX)
201         JMP _pret32
202
203 TEXT pxecallret(SB), $0
204         ADDI(6, rSP)
205         JMP _pret32
206
207 TEXT pxecall(SB), $0
208         MOVL op+4(SP),AX
209         MOVL buf+8(SP),SI
210         CALL rmode16(SB)
211
212         CLR(rCX)
213         PUSHR(rCX)
214         PUSHR(rSI)
215
216         /* opcode */
217         PUSHR(rAX)
218
219         /* farcall */
220         PUSHR(rCX)
221         PUSHI(pxecallret(SB))
222
223         LW(pxepseg(SB), rAX)
224         PUSHR(rAX)
225         LW(pxepoff(SB), rAX)
226         PUSHR(rAX)
227
228         CALL16(spllo(SB))
229
230         CLR(rAX)
231         CLR(rBX)
232         CLR(rCX)
233         CLR(rDX)
234         CLR(rDI)
235         CLR(rSI)
236         FARRET
237
238 TEXT pxepseg(SB), $0
239         WORD $0
240 TEXT pxepoff(SB), $0
241         WORD $0
242
243 #else /* PXE */
244
245 /*
246  * in:
247  *      DL drive
248  *      AX:BX lba32,
249  *      0000:SI buffer
250  */
251 TEXT readsect16(SB), $0
252         PUSHA
253         CLR(rCX)
254
255         PUSHR(rCX)              /* qword lba */
256         PUSHR(rCX)
257         PUSHR(rBX)
258         PUSHR(rAX)
259
260         PUSHR(rCX)              /* dword buffer */
261         PUSHR(rSI)
262
263         INC(rCX)
264         PUSHR(rCX)              /* word # of sectors */
265
266         PUSHI(0x0010)           /* byte reserved, byte packet size */
267
268         MW(rSP, rSI)
269         LWI(0x4200, rAX)
270         BIOSCALL(0x13)
271         JCC _readok
272         ADDI(0x10, rSP)
273         POPA
274         CLR(rAX)
275         DEC(rAX)
276         RET
277 _readok:
278         ADDI(0x10, rSP)
279         POPA
280         CLR(rAX)
281         RET
282
283 TEXT readsect(SB), $0
284         MOVL 4(SP), DX
285         MOVW 8(SP), AX
286         MOVW 10(SP), BX
287         MOVL 12(SP), SI 
288         CALL rmode16(SB)
289         CALL16(spllo(SB))
290         CALL16(readsect16(SB))
291         CALL16(pmode32(SB))
292         ANDL $0xFFFF, AX
293         RET
294
295 #endif
296
297 #ifdef ISO
298
299 TEXT bootname(SB), $0
300         BYTE $'3'; BYTE $'8'; BYTE $'6'; BYTE $'/';
301         BYTE $'9'; BYTE $'b'; BYTE $'o'; BYTE $'o';
302         BYTE $'t'; BYTE $'i'; BYTE $'s'; BYTE $'o';
303         BYTE $0
304
305 #endif
306
307 TEXT crnl(SB), $0
308         BYTE $'\r'; BYTE $'\n'; BYTE $0
309
310 TEXT hex(SB), $0
311         BYTE $'0'; BYTE $'1'; BYTE $'2'; BYTE $'3';
312         BYTE $'4'; BYTE $'5'; BYTE $'6'; BYTE $'7';
313         BYTE $'8'; BYTE $'9'; BYTE $'a'; BYTE $'b';
314         BYTE $'c'; BYTE $'d'; BYTE $'e'; BYTE $'f'