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