Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "mem.h"
2
 
3
#define KB		1024
4
#define MB		(1024*1024)
5
 
6
/*
7
 * Some machine instructions not handled by 8[al].
8
 */
9
#define	DELAY		BYTE $0xEB; BYTE $0x00	/* JMP .+2 */
10
#define FARJUMP(s, o)	BYTE $0xEA;		/* far jump to ptr32:16 */\
11
			LONG $o; WORD $s
12
 
13
#define NOP		BYTE $0x90
14
#define HLT		BYTE $0xF4
15
 
16
/*
17
 * Macro for calculating offset within the page directory base.
18
 * Note that this is assembler-specific hence the '<<2'.
19
 */
20
#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
21
 
22
/*
23
 * May enter here either from the 16-bit real-mode startup or
24
 * from other 32-bit protected mode code. For the latter case must
25
 * make sure the GDT is set as it would be by the 16-bit code:
26
 *	disable interrupts;
27
 *	load the GDT with the table in _gdt32p;
28
 *	load all the data segments
29
 *	load the code segment via a far jump.
30
 */
31
TEXT _start32p(SB), $0
32
/* if distance to _start32p32 changes, update the offset after 0xEB. */
33
//	jmp	.+32 (_start32p32).
34
	BYTE $0xEB; BYTE $(2+3*2*4+2+4)
35
	NOP; NOP
36
 
37
TEXT _gdt32p(SB), $0
38
	LONG	$0x0000; LONG $0
39
	LONG	$0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
40
	LONG	$0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
41
 
42
TEXT _gdtptr32p(SB), $0
43
	WORD	$(3*8)
44
	LONG	$_gdt32p-KZERO(SB)
45
 
46
_start32p32:
47
	CLI
48
 
49
	MOVL	AX, _multibootheader+(48-KZERO)(SB)
50
	MOVL	BX, _multibootheader+(52-KZERO)(SB)
51
 
52
	MOVL	$_gdtptr32p-KZERO(SB), AX
53
	MOVL	(AX), GDTR
54
 
55
	MOVL	$KDSEL, AX
56
	MOVW	AX, DS
57
	MOVW	AX, ES
58
	MOVW	AX, FS
59
	MOVW	AX, GS
60
	MOVW	AX, SS
61
 
62
	DELAY
63
	FARJUMP(KESEL, _start32pg-KZERO(SB))
64
 
65
/*
66
 * Make the basic page tables for processor 0. Eight pages are needed for
67
 * the basic set:
68
 * a page directory, 5 pages pf page tables for mapping the first 20MB of
69
 * physical memory, a single physical and virtual page for the Mach structure,
70
 * and a page to be used later for the GDT.
71
 *
72
 * The remaining PTEs will be allocated later when memory is sized.
73
 * Could clear BSS here too when clearing the space for the tables,
74
 * but that would violate the separation of church and state.
75
 * The first aligned page after end[] was used for passing BIOS parameters
76
 * by the real-mode startup, now it's BIOSTABLES.
77
 */
78
TEXT _start32pg(SB), $0			/* CHECK alignment (16) */
79
	DELAY
80
 
81
	MOVL	$end-KZERO(SB), DX	/* clear pages for the tables etc. */
82
	/* start must be page aligned, skip boot params page */
83
	ADDL	$(2*BY2PG-1), DX
84
	ANDL	$~(BY2PG-1), DX
85
 
86
	/*
87
	 * zero mach page & gdt in low memory
88
	 */
89
	MOVL	$(CPU0MACH-KZERO), DI
90
	XORL	AX, AX
91
	MOVL	$(2*BY2PG), CX		/* mach (phys & virt) & gdt */
92
	SHRL	$2, CX
93
	CLD
94
	REP;	STOSL			/* zero mach & gdt pages */
95
 
96
	/*
97
	 * zero pdb and pte for low memory
98
	 */
99
	MOVL	DX, DI			/* first page after end & boot params */
100
	XORL	AX, AX
101
	MOVL	$((1+LOWPTEPAGES)*BY2PG), CX /* pdb, n pte */
102
	SHRL	$2, CX
103
	CLD
104
	REP;	STOSL			/* zero pdb & pte pages */
105
 
106
	/*
107
	 * populate pdb for low memory (20MB)
108
	 */
109
	MOVL	DX, AX			/* bootstrap processor PDB (page 0) */
110
	MOVL	DX, DI			/* save it for later */
111
	MOVL	$(PTEWRITE|PTEVALID), BX/* page permissions */
112
 
113
	ADDL	$BY2PG, DX		/* -> PA of first page of page table (page 1)  */
114
	ADDL	$PDO(KZERO), AX		/* page directory offset for KZERO */
115
	MOVL	DX, (AX)		/* PTE's for KZERO */
116
	ORL	BX, (AX)
117
 
118
	/* should be LOWPTEPAGES-1 repetitions of this fragment */
119
	ADDL	$BY2PG, DX		/* -> PA of second page of page table (page 2)  */
120
	ADDL	$4, AX			/* page dir. offset for KZERO+4MB */
121
	MOVL	DX, (AX)		/* PTE's for KZERO */
122
	ORL	BX, (AX)
123
 
124
	ADDL	$BY2PG, DX		/* -> PA of third page of page table (page 3)  */
125
	ADDL	$4, AX			/* page dir. offset for KZERO+8MB */
126
	MOVL	DX, (AX)		/* PTE's for KZERO */
127
	ORL	BX, (AX)
128
 
129
	ADDL	$BY2PG, DX		/* -> PA of fourth page of page table (page 4)  */
130
	ADDL	$4, AX			/* page dir. offset for KZERO+12MB */
131
	MOVL	DX, (AX)		/* PTE's for KZERO */
132
	ORL	BX, (AX)
133
 
134
	ADDL	$BY2PG, DX		/* -> PA of fifth page of page table (page 5)  */
135
	ADDL	$4, AX			/* page dir. offset for KZERO+16MB */
136
	MOVL	DX, (AX)		/* PTE's for KZERO */
137
	ORL	BX, (AX)
138
 
139
	/*
140
	 * populate page tables for low memory
141
	 */
142
	MOVL	DI, AX
143
	ADDL	$BY2PG, AX		/* PA of first page of page table */
144
	MOVL	$(MemMin/BY2PG), CX
145
_setpte:
146
	MOVL	BX, (AX)
147
	ADDL	$(1<<PGSHIFT), BX
148
	ADDL	$4, AX
149
	LOOP	_setpte
150
 
151
	/*
152
	 * map the Mach page
153
	 */
154
	MOVL	DI, AX
155
	ADDL	$BY2PG, AX		/* PA of first page of page table */
156
	MOVL	$(CPU0MACH-KZERO), DX	/* -> PA of Mach structure */
157
	MOVL	$CPU0MACH, BX		/* VA of Mach structure */
158
	SHRL	$10, BX			/* create offset into PTEs */
159
	ANDL	$(0x3FF<<2), BX
160
 
161
	ADDL	BX, AX			/* PTE offset for Mach structure */
162
	MOVL	DX, (AX)		/* create PTE for Mach */
163
	MOVL	$(PTEWRITE|PTEVALID), BX/* page permissions */
164
	ORL	BX, (AX)
165
 
166
/*
167
 * Now ready to use the new map. Initialise CR0 (assume the BIOS gets
168
 * it mostly correct for this processor type w.r.t. caches and FPU).
169
 * It is necessary on some processors to follow mode switching
170
 * with a JMP instruction to clear the prefetch queues.
171
 * The instruction to switch modes and the following jump instruction
172
 * should be identity-mapped; to this end double map KZERO at
173
 * virtual 0 and undo the mapping once virtual nirvana has been attained.
174
 * If paging is already on, don't load CR3 before setting CR0, in which
175
 * case most of this is a NOP and the 2nd load of CR3 actually does
176
 * the business.
177
 */
178
	MOVL	DI, CX			/* load address of PDB */
179
	/* double-map first 20 MB, since we are running at 7 or 9 MB */
180
	/* should be LOWPTEPAGES repetitions */
181
	MOVL	PDO(KZERO)(CX), DX	/* double-map KZERO at 0 */
182
	MOVL	DX, PDO(0)(CX)
183
	MOVL	PDO(KZERO+4*MB)(CX), DX
184
	MOVL	DX, PDO(4*MB)(CX)
185
	MOVL	PDO(KZERO+8*MB)(CX), DX
186
	MOVL	DX, PDO(8*MB)(CX)
187
	MOVL	PDO(KZERO+12*MB)(CX), DX
188
	MOVL	DX, PDO(12*MB)(CX)
189
	MOVL	PDO(KZERO+16*MB)(CX), DX
190
	MOVL	DX, PDO(16*MB)(CX)
191
 
192
	MOVL	CR0, DX
193
	MOVL	DX, AX
194
	ANDL	$PG, AX			/* check paging not already on */
195
	JNE	_nocr3load
196
	MOVL	CX, CR3			/* paging off, safe to load cr3 */
197
_nocr3load:
198
	ORL	$(PG|0x10000), DX	/* PG|WP */
199
	ANDL	$~0x6000000A, DX	/* ~(CD|NW|TS|MP) */
200
 
201
	MOVL	$_startpg(SB), AX
202
	TESTL	$KZERO, AX		/* want to run protected or virtual? */
203
	JEQ	_to32v			/* protected */
204
	MOVL	DX, CR0			/* turn on paging */
205
	JMP*	AX			/* headfirst into the new world */
206
 
207
TEXT _startpg(SB), $0
208
//	MOVL	$0, PDO(0)(CX)		/* undo double-map of KZERO at 0 */
209
	MOVL	CX, CR3			/* load and flush the mmu */
210
_to32v:
211
	MOVL	$_start32v(SB), AX
212
	JMP*	AX			/* into the dorkness */