xref: /plan9-contrib/sys/src/9/pcboot/l32v.s (revision 22402af72e824b13a03306b380e882c0b67c2e73)
1#include "/sys/src/boot/pc/x16.h"
2#include "mem.h"
3
4#define KB		1024
5#define MB		(1024*1024)
6
7#define WRMSR		BYTE $0x0F; BYTE $0x30	/* WRMSR, argument in AX/DX (lo/hi) */
8#define RDTSC 		BYTE $0x0F; BYTE $0x31	/* RDTSC, result in AX/DX (lo/hi) */
9#define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, result in AX/DX (lo/hi) */
10#define CPUID		BYTE $0x0F; BYTE $0xA2	/* CPUID, argument in AX */
11
12TEXT _start32v(SB),$0
13	CLI
14
15	MOVL	$edata(SB), DI
16	XORL	AX, AX
17	MOVL	$end(SB), CX
18	SUBL	DI, CX			/* end-edata bytes */
19	SHRL	$2, CX			/* end-edata doublewords */
20
21	CLD
22	REP; STOSL			/* clear BSS */
23
24	MOVL	CR3, AX
25	/* 1+LOWPTEPAGES zeroed pages at (AX): pdb, pte */
26	ADDL	$KZERO, AX		/* VA of PDB */
27	MOVL	AX, mach0pdb(SB)
28	ADDL	$((1+LOWPTEPAGES)*BY2PG), AX /* skip pdb & n pte */
29	MOVL	AX, memstart(SB)	/* start of available memory */
30
31	/* 2 zeroed pages at CPU0MACH: mach, gdt */
32	MOVL	$CPU0MACH, AX
33	MOVL	AX, mach0m(SB)		/* ... VA of Mach */
34	MOVL	AX, m(SB)		/* initialise global Mach pointer */
35	MOVL	$0, 0(AX)		/* initialise m->machno */
36	ADDL	$MACHSIZE, AX
37	MOVL	AX, SP			/* switch to new stack in Mach */
38	MOVL	$CPU0GDT, mach0gdt(SB)
39
40	MOVL	$0x240000, AX		/* try to set Id|Ac in EFLAGS */
41	PUSHL	AX
42	POPFL
43
44	PUSHFL				/* retrieve EFLAGS -> BX */
45	POPL	BX
46
47	MOVL	$0, AX			/* clear Id|Ac, EFLAGS initialised */
48	PUSHL	AX
49	POPFL
50
51	PUSHFL				/* retrieve EFLAGS -> AX */
52
53	XORL	BX, (SP)		/* togglable bits */
54	CALL	main(SB)
55
56/*
57 * Park a processor. Should never fall through a return from main to here,
58 * should only be called by application processors when shutting down.
59 */
60TEXT idle(SB), $0
61_idle:
62	STI
63	HLT
64	JMP	_idle
65
66TEXT hlt(SB), $0
67	STI
68	HLT
69	RET
70
71#ifdef UNUSED
72/*
73 */
74TEXT _warp9o(SB), $0
75	MOVL	entry+0(FP), CX
76	MOVL	multibootheader-KZERO(SB), BX	/* multiboot data pointer */
77	MOVL	$0x2badb002, AX			/* multiboot magic */
78
79	CLI
80	JMP*	CX
81
82	JMP	_idle
83
84/*
85 * Macro for calculating offset within the page directory base.
86 * Note that this is assembler-specific hence the '<<2'.
87 */
88#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
89
90/*
91 */
92TEXT _warp9(SB), $0
93	CLI
94	MOVL	entry+0(FP), BP
95
96	MOVL	CR3, CX				/* load address of PDB */
97	ADDL	$KZERO, CX
98	MOVL	PDO(KZERO)(CX), DX		/* double-map KZERO at 0 */
99	MOVL	DX, PDO(0)(CX)
100
101	MOVL	CR3, CX
102	MOVL	CX, CR3				/* load and flush the mmu */
103
104	MOVL	$_start32id<>-KZERO(SB), AX
105	JMP*	AX				/* jump to identity-map */
106
107TEXT _start32id<>(SB), $0
108	MOVL	CR0, DX				/* turn off paging */
109	ANDL	$~PG, DX
110
111	MOVL	$_stop32pg<>-KZERO(SB), AX
112	MOVL	DX, CR0
113	JMP*	AX				/* forward into the past */
114
115TEXT _stop32pg<>(SB), $0
116	MOVL	multibootheader-KZERO(SB), BX	/* multiboot data pointer */
117	MOVL	$0x2badb002, AX			/* multiboot magic */
118
119	JMP*	BP
120
121	JMP	_idle
122#endif
123
124/*
125 *  input a byte
126 */
127TEXT	inb(SB),$0
128
129	MOVL	p+0(FP),DX
130	XORL	AX,AX
131	INB
132	RET
133
134/*
135 * input a short from a port
136 */
137TEXT	ins(SB), $0
138
139	MOVL	p+0(FP), DX
140	XORL	AX, AX
141	OPSIZE; INL
142	RET
143
144/*
145 * input a long from a port
146 */
147TEXT	inl(SB), $0
148
149	MOVL	p+0(FP), DX
150	XORL	AX, AX
151	INL
152	RET
153
154/*
155 *  output a byte
156 */
157TEXT	outb(SB),$0
158
159	MOVL	p+0(FP),DX
160	MOVL	b+4(FP),AX
161	OUTB
162	RET
163
164/*
165 * output a short to a port
166 */
167TEXT	outs(SB), $0
168	MOVL	p+0(FP), DX
169	MOVL	s+4(FP), AX
170	OPSIZE; OUTL
171	RET
172
173/*
174 * output a long to a port
175 */
176TEXT	outl(SB), $0
177	MOVL	p+0(FP), DX
178	MOVL	s+4(FP), AX
179	OUTL
180	RET
181
182/*
183 *  input a string of bytes from a port
184 */
185TEXT	insb(SB),$0
186
187	MOVL	p+0(FP),DX
188	MOVL	a+4(FP),DI
189	MOVL	c+8(FP),CX
190	CLD; REP; INSB
191	RET
192
193/*
194 *  input a string of shorts from a port
195 */
196TEXT	inss(SB),$0
197	MOVL	p+0(FP),DX
198	MOVL	a+4(FP),DI
199	MOVL	c+8(FP),CX
200	CLD
201	REP; OPSIZE; INSL
202	RET
203
204/*
205 *  output a string of bytes to a port
206 */
207TEXT	outsb(SB),$0
208
209	MOVL	p+0(FP),DX
210	MOVL	a+4(FP),SI
211	MOVL	c+8(FP),CX
212	CLD; REP; OUTSB
213	RET
214
215/*
216 *  output a string of shorts to a port
217 */
218TEXT	outss(SB),$0
219	MOVL	p+0(FP),DX
220	MOVL	a+4(FP),SI
221	MOVL	c+8(FP),CX
222	CLD
223	REP; OPSIZE; OUTSL
224	RET
225
226/*
227 *  input a string of longs from a port
228 */
229TEXT	insl(SB),$0
230
231	MOVL	p+0(FP),DX
232	MOVL	a+4(FP),DI
233	MOVL	c+8(FP),CX
234	CLD; REP; INSL
235	RET
236
237/*
238 *  output a string of longs to a port
239 */
240TEXT	outsl(SB),$0
241
242	MOVL	p+0(FP),DX
243	MOVL	a+4(FP),SI
244	MOVL	c+8(FP),CX
245	CLD; REP; OUTSL
246	RET
247
248/*
249 *  routines to load/read various system registers
250 */
251GLOBL	idtptr(SB),$6
252TEXT	putidt(SB),$0		/* interrupt descriptor table */
253	MOVL	t+0(FP),AX
254	MOVL	AX,idtptr+2(SB)
255	MOVL	l+4(FP),AX
256	MOVW	AX,idtptr(SB)
257	MOVL	idtptr(SB),IDTR
258	RET
259
260TEXT lgdt(SB), $0			/* GDTR - global descriptor table */
261	MOVL	gdtptr+0(FP), AX
262	MOVL	(AX), GDTR
263	RET
264
265TEXT lidt(SB), $0			/* IDTR - interrupt descriptor table */
266	MOVL	idtptr+0(FP), AX
267	MOVL	(AX), IDTR
268	RET
269
270TEXT	putcr3(SB),$0		/* top level page table pointer */
271	MOVL	t+0(FP),AX
272	MOVL	AX,CR3
273	RET
274
275TEXT	getcr0(SB),$0		/* coprocessor bits */
276	MOVL	CR0,AX
277	RET
278
279TEXT	getcr2(SB),$0		/* fault address */
280	MOVL	CR2,AX
281	RET
282
283TEXT	getcr3(SB),$0		/* page directory base */
284	MOVL	CR3,AX
285	RET
286
287TEXT	getcr4(SB), $0		/* CR4 - extensions */
288	MOVL	CR4, AX
289	RET
290
291TEXT putcr4(SB), $0
292	MOVL	cr4+0(FP), AX
293	MOVL	AX, CR4
294	RET
295
296TEXT _cycles(SB), $0				/* time stamp counter */
297	RDTSC
298	MOVL	vlong+0(FP), CX			/* &vlong */
299	MOVL	AX, 0(CX)			/* lo */
300	MOVL	DX, 4(CX)			/* hi */
301	RET
302
303TEXT rdmsr(SB), $0				/* model-specific register */
304	MOVL	index+0(FP), CX
305	RDMSR
306	MOVL	vlong+4(FP), CX			/* &vlong */
307	MOVL	AX, 0(CX)			/* lo */
308	MOVL	DX, 4(CX)			/* hi */
309	RET
310
311TEXT wrmsr(SB), $0
312	MOVL	index+0(FP), CX
313	MOVL	lo+4(FP), AX
314	MOVL	hi+8(FP), DX
315	WRMSR
316	RET
317
318/*
319 * memory barriers
320 */
321TEXT mb386(SB), $0
322	POPL	AX				/* return PC */
323	PUSHFL
324	PUSHL	CS
325	PUSHL	AX
326	IRETL
327
328TEXT mb586(SB), $0
329	XORL	AX, AX
330	CPUID
331	RET
332
333TEXT sfence(SB), $0
334	BYTE $0x0f
335	BYTE $0xae
336	BYTE $0xf8
337	RET
338
339TEXT lfence(SB), $0
340	BYTE $0x0f
341	BYTE $0xae
342	BYTE $0xe8
343	RET
344
345TEXT mfence(SB), $0
346	BYTE $0x0f
347	BYTE $0xae
348	BYTE $0xf0
349	RET
350
351/*
352 *  special traps
353 */
354TEXT	intr0(SB),$0
355	PUSHL	$0
356	PUSHL	$0
357	JMP	intrcommon
358TEXT	intr1(SB),$0
359	PUSHL	$0
360	PUSHL	$1
361	JMP	intrcommon
362TEXT	intr2(SB),$0
363	PUSHL	$0
364	PUSHL	$2
365	JMP	intrcommon
366TEXT	intr3(SB),$0
367	PUSHL	$0
368	PUSHL	$3
369	JMP	intrcommon
370TEXT	intr4(SB),$0
371	PUSHL	$0
372	PUSHL	$4
373	JMP	intrcommon
374TEXT	intr5(SB),$0
375	PUSHL	$0
376	PUSHL	$5
377	JMP	intrcommon
378TEXT	intr6(SB),$0
379	PUSHL	$0
380	PUSHL	$6
381	JMP	intrcommon
382TEXT	intr7(SB),$0
383	PUSHL	$0
384	PUSHL	$7
385	JMP	intrcommon
386TEXT	intr8(SB),$0
387	PUSHL	$8
388	JMP	intrcommon
389TEXT	intr9(SB),$0
390	PUSHL	$0
391	PUSHL	$9
392	JMP	intrcommon
393TEXT	intr10(SB),$0
394	PUSHL	$10
395	JMP	intrcommon
396TEXT	intr11(SB),$0
397	PUSHL	$11
398	JMP	intrcommon
399TEXT	intr12(SB),$0
400	PUSHL	$12
401	JMP	intrcommon
402TEXT	intr13(SB),$0
403	PUSHL	$13
404	JMP	intrcommon
405TEXT	intr14(SB),$0
406	PUSHL	$14
407	JMP	intrcommon
408TEXT	intr15(SB),$0
409	PUSHL	$0
410	PUSHL	$15
411	JMP	intrcommon
412TEXT	intr16(SB),$0
413	PUSHL	$0
414	PUSHL	$16
415	JMP	intrcommon
416TEXT	intr24(SB),$0
417	PUSHL	$0
418	PUSHL	$24
419	JMP	intrcommon
420TEXT	intr25(SB),$0
421	PUSHL	$0
422	PUSHL	$25
423	JMP	intrcommon
424TEXT	intr26(SB),$0
425	PUSHL	$0
426	PUSHL	$26
427	JMP	intrcommon
428TEXT	intr27(SB),$0
429	PUSHL	$0
430	PUSHL	$27
431	JMP	intrcommon
432TEXT	intr28(SB),$0
433	PUSHL	$0
434	PUSHL	$28
435	JMP	intrcommon
436TEXT	intr29(SB),$0
437	PUSHL	$0
438	PUSHL	$29
439	JMP	intrcommon
440TEXT	intr30(SB),$0
441	PUSHL	$0
442	PUSHL	$30
443	JMP	intrcommon
444TEXT	intr31(SB),$0
445	PUSHL	$0
446	PUSHL	$31
447	JMP	intrcommon
448TEXT	intr32(SB),$0
449	PUSHL	$0
450	PUSHL	$32
451	JMP	intrcommon
452TEXT	intr33(SB),$0
453	PUSHL	$0
454	PUSHL	$33
455	JMP	intrcommon
456TEXT	intr34(SB),$0
457	PUSHL	$0
458	PUSHL	$34
459	JMP	intrcommon
460TEXT	intr35(SB),$0
461	PUSHL	$0
462	PUSHL	$35
463	JMP	intrcommon
464TEXT	intr36(SB),$0
465	PUSHL	$0
466	PUSHL	$36
467	JMP	intrcommon
468TEXT	intr37(SB),$0
469	PUSHL	$0
470	PUSHL	$37
471	JMP	intrcommon
472TEXT	intr38(SB),$0
473	PUSHL	$0
474	PUSHL	$38
475	JMP	intrcommon
476TEXT	intr39(SB),$0
477	PUSHL	$0
478	PUSHL	$39
479	JMP	intrcommon
480TEXT	intr64(SB),$0
481	PUSHL	$0
482	PUSHL	$64
483	JMP	intrcommon
484TEXT	intrbad(SB),$0
485	PUSHL	$0
486	PUSHL	$0x1ff
487	JMP	intrcommon
488
489intrcommon:
490	PUSHL	DS
491	PUSHL	ES
492	PUSHL	FS
493	PUSHL	GS
494	PUSHAL
495	MOVL	$(KDSEL),AX
496	MOVW	AX,DS
497	MOVW	AX,ES
498	LEAL	0(SP),AX
499	PUSHL	AX
500	CALL	trap(SB)
501	POPL	AX
502	POPAL
503	POPL	GS
504	POPL	FS
505	POPL	ES
506	POPL	DS
507	ADDL	$8,SP	/* error code and trap type */
508	IRETL
509
510
511/*
512 *  interrupt level is interrupts on or off.
513 *  kprof knows that spllo to spldone is splx routines.
514 */
515TEXT	spllo(SB),$0
516	PUSHFL
517	POPL	AX
518	STI
519	RET
520
521TEXT	splhi(SB),$0
522	PUSHFL
523	POPL	AX
524	CLI
525	RET
526
527TEXT	splx(SB),$0
528	MOVL	s+0(FP),AX
529	PUSHL	AX
530	POPFL
531	RET
532
533TEXT spldone(SB), $0
534	RET
535
536TEXT islo(SB), $0
537	PUSHFL
538	POPL	AX
539	ANDL	$0x200, AX			/* interrupt enable flag */
540	RET
541
542/*
543 * Miscellany
544 */
545TEXT bsr(SB), $0
546	BSRL	word+0(FP), AX			/* count leading zeros */
547	RET
548
549/*
550 *  basic timing loop to determine CPU frequency
551 */
552TEXT	aamloop(SB),$0
553
554	MOVL	c+0(FP),CX
555aaml1:
556	AAM
557	LOOP	aaml1
558	RET
559