]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/l.s
merge
[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 TEXT usleep(SB), $0
175         MOVL t+4(SP), AX
176         PUSHL AX
177         CALL rmode16(SB)
178         CALL16(spllo(SB))
179         POPR(rDX)
180         POPR(rCX)
181         MOVB $0x86, AH
182         BIOSCALL(0x15)
183         JMP _pret32
184
185 #ifdef PXE
186
187 TEXT pxeinit(SB), $0
188         CALL rmode16(SB)
189
190         /* get pxe env structure in ES:BX */
191         LWI(0x5650, rAX)
192         BIOSCALL(0x1A)
193         JC _pret32
194
195         /* !PXE or PXEENV+ signature */
196         SEGES; LXW(0, xBX, rAX)
197         CMPI((('!'<<0)|('P'<<8)), rAX)
198         JEQ _getentry
199         CMPI((('P'<<0)|('X'<<8)), rAX)
200         JNE _pret32
201
202         SEGES; LXW(0x2A, xBX, rAX)
203         SEGES; LXW(0x28, xBX, rBX)
204         MTSR(rAX, rES)
205
206 _getentry:
207         SEGES; LXW(0x12, xBX, rAX)
208         SW(rAX, pxepseg(SB))
209         SEGES; LXW(0x10, xBX, rAX)
210         SW(rAX, pxepoff(SB))
211         CLR(rAX)
212         JMP _pret32
213
214 TEXT pxecallret(SB), $0
215         ADDI(6, rSP)
216         JMP _pret32
217
218 TEXT pxecall(SB), $0
219         MOVL op+4(SP),AX
220         MOVL buf+8(SP),SI
221         CALL rmode16(SB)
222
223         CLR(rCX)
224         PUSHR(rCX)
225         PUSHR(rSI)
226
227         /* opcode */
228         PUSHR(rAX)
229
230         /* farcall */
231         PUSHR(rCX)
232         PUSHI(pxecallret(SB))
233
234         LW(pxepseg(SB), rAX)
235         PUSHR(rAX)
236         LW(pxepoff(SB), rAX)
237         PUSHR(rAX)
238
239         CALL16(spllo(SB))
240
241         CLR(rAX)
242         CLR(rBX)
243         CLR(rCX)
244         CLR(rDX)
245         CLR(rDI)
246         CLR(rSI)
247         FARRET
248
249 TEXT pxepseg(SB), $0
250         WORD $0
251 TEXT pxepoff(SB), $0
252         WORD $0
253
254 #else /* PXE */
255
256 /*
257  * in:
258  *      DL drive
259  *      AX:BX lba32,
260  *      0000:SI buffer
261  */
262 TEXT readsect16(SB), $0
263         PUSHA
264         CLR(rCX)
265
266         PUSHR(rCX)              /* qword lba */
267         PUSHR(rCX)
268         PUSHR(rBX)
269         PUSHR(rAX)
270
271         PUSHR(rCX)              /* dword buffer */
272         PUSHR(rSI)
273
274         INC(rCX)
275         PUSHR(rCX)              /* word # of sectors */
276
277         PUSHI(0x0010)           /* byte reserved, byte packet size */
278
279         MW(rSP, rSI)
280         LWI(0x4200, rAX)
281         BIOSCALL(0x13)
282         JCC _readok
283         ADDI(0x10, rSP)
284         POPA
285         CLR(rAX)
286         DEC(rAX)
287         RET
288 _readok:
289         ADDI(0x10, rSP)
290         POPA
291         CLR(rAX)
292         RET
293
294 TEXT readsect(SB), $0
295         MOVL 4(SP), DX
296         MOVW 8(SP), AX
297         MOVW 10(SP), BX
298         MOVL 12(SP), SI 
299         CALL rmode16(SB)
300         CALL16(spllo(SB))
301         CALL16(readsect16(SB))
302         CALL16(pmode32(SB))
303         ANDL $0xFFFF, AX
304         RET
305
306 #endif
307
308 #ifdef ISO
309
310 TEXT bootname(SB), $0
311         BYTE $'3'; BYTE $'8'; BYTE $'6'; BYTE $'/';
312         BYTE $'9'; BYTE $'b'; BYTE $'o'; BYTE $'o';
313         BYTE $'t'; BYTE $'i'; BYTE $'s'; BYTE $'o';
314         BYTE $0
315
316 #endif
317
318 TEXT crnl(SB), $0
319         BYTE $'\r'; BYTE $'\n'; BYTE $0
320
321 TEXT hex(SB), $0
322         BYTE $'0'; BYTE $'1'; BYTE $'2'; BYTE $'3';
323         BYTE $'4'; BYTE $'5'; BYTE $'6'; BYTE $'7';
324         BYTE $'8'; BYTE $'9'; BYTE $'a'; BYTE $'b';
325         BYTE $'c'; BYTE $'d'; BYTE $'e'; BYTE $'f'