]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/l.s
9boot: disable nmi, reload idt, load segments twice, check sequence number of pxe...
[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         /* reload idt */
83         SEGSS; LIDT(tidtptr(SB))
84
85         /* disable protected mode */
86         MFCR(rCR0, rCX)
87         ANDB $0xfe, CL
88         MTCR(rCX, rCR0)
89
90         /* flush */
91         FARJUMP16(0, rmode16flush(SB));
92 TEXT rmode16flush(SB), $0
93
94         /*
95          * load 16-bit realmode data segment 0000: and
96          * return to 32 bit return pc interpreted
97          * as 16 bit far pointer.
98          */
99         CLR(rCX)
100         JMP _segret
101
102 TEXT tgdt(SB), $0 
103         /* null descriptor */
104         LONG $0
105         LONG $0
106
107         /* data segment descriptor for 4 gigabytes (PL 0) */
108         LONG $(0xFFFF)
109         LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
110
111         /* exec segment descriptor for 4 gigabytes (PL 0) */
112         LONG $(0xFFFF)
113         LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
114
115         /* data segment descriptor for (PL 0) 16-bit */
116         LONG $(0xFFFF)
117         LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
118
119         /* exec segment descriptor for (PL 0) 16-bit */
120         LONG $(0xFFFF)
121         LONG $((0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
122
123 TEXT tgdtptr(SB), $0 
124          WORD $(5*8) 
125          LONG $tgdt(SB)
126
127 TEXT tidtptr(SB), $0
128         WORD $0x3ff
129         LONG $0
130
131 TEXT jump(SB), $0
132         MOVL 4(SP), AX
133         JMP *AX
134
135 TEXT halt(SB), $0
136 _halt:
137         JMP _halt
138
139 TEXT spllo(SB), $0
140         /* enable nmi */
141         PUSHA
142         LWI(0x70, rDX)
143         INB
144         ORB $0x80, AL
145         OUTB
146         POPA
147
148         STI
149         RET
150
151 TEXT getc(SB), $0
152         CALL rmode16(SB)
153         CALL16(spllo(SB))
154         MOVB $0x00, AH
155         BIOSCALL(0x16)
156 _getcret:
157         CALL16(pmode32(SB))
158         ANDL $0xFF, AX
159         RET
160
161 TEXT gotc(SB), $0
162         CALL rmode16(SB)
163         CALL16(spllo(SB))
164         MOVB $0x01, AH
165         BIOSCALL(0x16)
166         JNZ _getcret
167         CLR(rAX)
168         JMP _getcret
169         
170 TEXT putc(SB), $0
171         MOVL 4(SP),AX
172         CALL rmode16(SB)
173         CALL16(spllo(SB))
174         MOVB $0x0E, AH
175         BIOSCALL(0x10)
176 _pret32:
177         CALL16(pmode32(SB))
178         ANDL $0xFFFF, AX
179         RET
180
181 #ifdef PXE
182
183 TEXT pxecallret(SB), $0
184         ADDI(6, rSP)
185         JMP _pret32
186
187 TEXT pxecall(SB), $0
188         MOVL op+4(SP),AX
189         MOVL buf+8(SP),SI
190         CALL rmode16(SB)
191
192         CLR(rCX)
193         PUSHR(rCX)
194         PUSHR(rSI)
195
196         /* opcode */
197         PUSHR(rAX)
198
199         /* farcall */
200         PUSHR(rCX)
201         PUSHI(pxecallret(SB))
202
203         /* get pxe env structure in ES:BX */
204         LWI(0x5650, rAX)
205         BIOSCALL(0x1A)
206         JC _farret
207
208         /* !PXE or PXEENV+ signature */
209         SEGES; LXW(0, xBX, rAX)
210         CMPI((('!'<<0)|('P'<<8)), rAX)
211         JEQ _getentry
212         CMPI((('P'<<0)|('X'<<8)), rAX)
213         JNE _farret
214
215         SEGES; LXW(0x2A, xBX, rAX)
216         SEGES; LXW(0x28, xBX, rBX)
217         MTSR(rAX, rES)
218
219 _getentry:
220         SEGES; LXW(0x12, xBX, rAX)
221         PUSHR(rAX)
222         SEGES; LXW(0x10, xBX, rAX)
223         PUSHR(rAX)
224
225         CALL16(spllo(SB))
226
227         CLR(rAX)
228         CLR(rBX)
229         CLR(rCX)
230         CLR(rDX)
231         CLR(rDI)
232         CLR(rSI)
233 _farret:
234         FARRET
235
236 #else /* PXE */
237
238 /*
239  * in:
240  *      DL drive
241  *      AX:BX lba32,
242  *      0000:SI buffer
243  */
244 TEXT readsect16(SB), $0
245         PUSHA
246         CLR(rCX)
247
248         PUSHR(rCX)              /* qword lba */
249         PUSHR(rCX)
250         PUSHR(rBX)
251         PUSHR(rAX)
252
253         PUSHR(rCX)              /* dword buffer */
254         PUSHR(rSI)
255
256         INC(rCX)
257         PUSHR(rCX)              /* word # of sectors */
258
259         PUSHI(0x0010)           /* byte reserved, byte packet size */
260
261         MW(rSP, rSI)
262         LWI(0x4200, rAX)
263         BIOSCALL(0x13)
264         JCC _readok
265         ADDI(0x10, rSP)
266         POPA
267         CLR(rAX)
268         DEC(rAX)
269         RET
270 _readok:
271         ADDI(0x10, rSP)
272         POPA
273         CLR(rAX)
274         RET
275
276 TEXT readsect(SB), $0
277         MOVL 4(SP), DX
278         MOVW 8(SP), AX
279         MOVW 10(SP), BX
280         MOVL 12(SP), SI 
281         CALL rmode16(SB)
282         CALL16(spllo(SB))
283         CALL16(readsect16(SB))
284         CALL16(pmode32(SB))
285         ANDL $0xFFFF, AX
286         RET
287
288 #endif
289
290 #ifdef ISO
291
292 TEXT bootname(SB), $0
293         BYTE $'3'; BYTE $'8'; BYTE $'6'; BYTE $'/';
294         BYTE $'9'; BYTE $'b'; BYTE $'o'; BYTE $'o';
295         BYTE $'t'; BYTE $'i'; BYTE $'s'; BYTE $'o';
296         BYTE $0
297
298 #endif
299
300 TEXT crnl(SB), $0
301         BYTE $'\r'; BYTE $'\n'; BYTE $0
302
303 TEXT hex(SB), $0
304         BYTE $'0'; BYTE $'1'; BYTE $'2'; BYTE $'3';
305         BYTE $'4'; BYTE $'5'; BYTE $'6'; BYTE $'7';
306         BYTE $'8'; BYTE $'9'; BYTE $'a'; BYTE $'b';
307         BYTE $'c'; BYTE $'d'; BYTE $'e'; BYTE $'f'