Subversion Repositories HelenOS

Rev

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

Rev Author Line No. Line
4341 svoboda 1
#
2071 jermar 2
# Copyright (c) 2005 Ondrej Palkovsky
3
# Copyright (c) 2006 Martin Decky
2703 jermar 4
# Copyright (c) 2008 Jakub Jermar
164 palkovsky 5
# All rights reserved.
6
#
7
# Redistribution and use in source and binary forms, with or without
8
# modification, are permitted provided that the following conditions
9
# are met:
10
#
11
# - Redistributions of source code must retain the above copyright
12
#   notice, this list of conditions and the following disclaimer.
13
# - Redistributions in binary form must reproduce the above copyright
14
#   notice, this list of conditions and the following disclaimer in the
15
#   documentation and/or other materials provided with the distribution.
16
# - The name of the author may not be used to endorse or promote products
17
#   derived from this software without specific prior written permission.
18
#
19
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#
30
 
695 decky 31
#include <arch/boot/boot.h>
32
#include <arch/boot/memmap.h>
194 palkovsky 33
#include <arch/mm/page.h>	
188 palkovsky 34
#include <arch/mm/ptl.h>
194 palkovsky 35
#include <arch/pm.h>
251 palkovsky 36
#include <arch/cpu.h>
275 palkovsky 37
#include <arch/cpuid.h>
164 palkovsky 38
 
694 decky 39
#define START_STACK	(BOOT_OFFSET - BOOT_STACK_SIZE)
4346 svoboda 40
 
406 jermar 41
.section K_TEXT_START, "ax"
695 decky 42
 
680 decky 43
.code32
44
.align 4
695 decky 45
.global multiboot_image_start
680 decky 46
multiboot_header:
47
	.long MULTIBOOT_HEADER_MAGIC
48
	.long MULTIBOOT_HEADER_FLAGS
4346 svoboda 49
	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
694 decky 50
	.long multiboot_header
51
	.long unmapped_ktext_start
680 decky 52
	.long 0
53
	.long 0
694 decky 54
	.long multiboot_image_start
188 palkovsky 55
 
680 decky 56
multiboot_image_start:
2784 jermar 57
	cld
4346 svoboda 58
	movl $START_STACK, %esp             # initialize stack pointer
59
	lgdtl bootstrap_gdtr                # initialize Global Descriptor Table register
60
 
685 decky 61
	movw $gdtselector(KDATA_DES), %cx
62
	movw %cx, %es
4346 svoboda 63
	movw %cx, %ds                       # kernel data + stack
685 decky 64
	movw %cx, %ss
4346 svoboda 65
 
66
	#
807 palkovsky 67
	# Simics seems to remove hidden part of GS on entering user mode
4346 svoboda 68
	# when _visible_ part of GS does not point to user-mode segment.
69
	#
70
 
807 palkovsky 71
	movw $gdtselector(UDATA_DES), %cx
72
	movw %cx, %fs
73
	movw %cx, %gs
685 decky 74
 
695 decky 75
	jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point
685 decky 76
	multiboot_meeting_point:
77
 
4346 svoboda 78
	movl %eax, grub_eax                 # save parameters from GRUB
695 decky 79
	movl %ebx, grub_ebx
80
 
4346 svoboda 81
	#
2219 decky 82
	# Protected 32-bit. We want to reuse the code-seg descriptor,
4346 svoboda 83
	# the Default operand size must not be 1 when entering long mode.
84
	#
2219 decky 85
 
4346 svoboda 86
	movl $(INTEL_CPUID_EXTENDED), %eax
87
	cpuid
88
	cmp $(INTEL_CPUID_EXTENDED), %eax
2692 decky 89
	ja extended_cpuid_supported
4346 svoboda 90
 
2692 decky 91
		movl $extended_cpuid_msg, %esi
92
		jmp error_halt
93
 
94
	extended_cpuid_supported:
95
 
96
	movl $(AMD_CPUID_EXTENDED), %eax
2219 decky 97
	cpuid
2692 decky 98
	bt $(AMD_EXT_LONG_MODE), %edx
4346 svoboda 99
	jc long_mode_supported
100
 
2219 decky 101
		movl $long_mode_msg, %esi
102
		jmp error_halt
4346 svoboda 103
 
2219 decky 104
	long_mode_supported:
105
 
2692 decky 106
	bt $(AMD_EXT_NOEXECUTE), %edx
107
	jc noexecute_supported
108
 
109
		movl $noexecute_msg, %esi
110
		jmp error_halt
111
 
112
	noexecute_supported:
113
 
114
	movl $(INTEL_CPUID_STANDARD), %eax
115
	cpuid
116
	bt $(INTEL_FXSAVE), %edx
4346 svoboda 117
	jc fx_supported
2692 decky 118
 
119
		movl $fx_msg, %esi
120
		jmp error_halt
121
 
122
	fx_supported:
123
 
124
	bt $(INTEL_SSE2), %edx
4346 svoboda 125
	jc sse2_supported
2692 decky 126
 
127
		movl $sse2_msg, %esi
128
		jmp error_halt
129
 
130
	sse2_supported:
1289 vana 131
 
4346 svoboda 132
#include "vesa_prot.inc"
133
 
134
	#
2692 decky 135
	# Enable 64-bit page translation entries - CR4.PAE = 1.
4346 svoboda 136
	# Paging is not enabled until after long mode is enabled.
137
	#
694 decky 138
 
188 palkovsky 139
	movl %cr4, %eax
140
	btsl $5, %eax
141
	movl %eax, %cr4
694 decky 142
 
4346 svoboda 143
	# set up paging tables
144
 
188 palkovsky 145
	leal ptl_0, %eax
146
	movl %eax, %cr3
275 palkovsky 147
 
4346 svoboda 148
	# enable long mode
178 palkovsky 149
 
4346 svoboda 150
	movl $EFER_MSR_NUM, %ecx            # EFER MSR number
151
	rdmsr                               # read EFER
152
	btsl $AMD_LME_FLAG, %eax            # set LME = 1
153
	wrmsr                               # write EFER
694 decky 154
 
4346 svoboda 155
	# enable paging to activate long mode (set CR0.PG = 1)
694 decky 156
 
188 palkovsky 157
	movl %cr0, %eax
158
	btsl $31, %eax
159
	movl %eax, %cr0
160
 
4346 svoboda 161
	# at this point we are in compatibility mode
694 decky 162
 
206 palkovsky 163
	jmpl $gdtselector(KTEXT_DES), $start64
164 palkovsky 164
 
188 palkovsky 165
.code64
166
start64:
275 palkovsky 167
	movq $(PA2KA(START_STACK)), %rsp
4346 svoboda 168
 
169
	# call arch_pre_main(grub_eax, grub_ebx)
4345 svoboda 170
	xorq %rdi, %rdi
171
	movl grub_eax, %edi
172
	xorq %rsi, %rsi
173
	movl grub_ebx, %esi
174
	call arch_pre_main
695 decky 175
 
4346 svoboda 176
	call main_bsp
1641 decky 177
 
4346 svoboda 178
	# not reached
1289 vana 179
 
4346 svoboda 180
	cli
181
	hlt0:
182
		hlt
183
		jmp hlt0
1289 vana 184
 
2219 decky 185
# Print string from %esi to EGA display (in red) and halt
186
error_halt:
4346 svoboda 187
	movl $0xb8000, %edi       # base of EGA text mode memory
2219 decky 188
	xorl %eax, %eax
189
 
4346 svoboda 190
	movw $0x3d4, %dx          # read bits 8 - 15 of the cursor address
2219 decky 191
	movb $0xe, %al
192
	outb %al, %dx
193
 
194
	movw $0x3d5, %dx
195
	inb %dx, %al
196
	shl $8, %ax
197
 
4346 svoboda 198
	movw $0x3d4, %dx          # read bits 0 - 7 of the cursor address
2219 decky 199
	movb $0xf, %al
200
	outb %al, %dx
201
 
202
	movw $0x3d5, %dx
203
	inb %dx, %al
204
 
205
	cmp $1920, %ax
206
	jbe cursor_ok
4346 svoboda 207
 
208
		movw $1920, %ax       # sanity check for the cursor on the last line
209
 
2219 decky 210
	cursor_ok:
211
 
212
	movw %ax, %bx
213
	shl $1, %eax
214
	addl %eax, %edi
215
 
4346 svoboda 216
	movw $0x0c00, %ax         # black background, light red foreground
2219 decky 217
 
218
	ploop:
219
		lodsb
220
		cmp $0, %al
221
		je ploop_end
222
		stosw
4346 svoboda 223
		inc %bx
2219 decky 224
		jmp ploop
225
	ploop_end:
226
 
4346 svoboda 227
	movw $0x3d4, %dx          # write bits 8 - 15 of the cursor address
2219 decky 228
	movb $0xe, %al
229
	outb %al, %dx
230
 
231
	movw $0x3d5, %dx
232
	movb %bh, %al
233
	outb %al, %dx
234
 
4346 svoboda 235
	movw $0x3d4, %dx          # write bits 0 - 7 of the cursor address
2219 decky 236
	movb $0xf, %al
237
	outb %al, %dx
238
 
239
	movw $0x3d5, %dx
240
	movb %bl, %al
241
	outb %al, %dx
4346 svoboda 242
 
2219 decky 243
	cli
4346 svoboda 244
	hlt1:
245
		hlt
246
		jmp hlt1
2703 jermar 247
 
4346 svoboda 248
#include "vesa_real.inc"
249
 
2703 jermar 250
.section K_INI_PTLS, "aw", @progbits
251
 
252
#
253
# Macro for generating initial page table contents.
4346 svoboda 254
# @param cnt Number of entries to generat. Must be multiple of 8.
255
# @param g   Number of GB that will be added to the mapping.
2703 jermar 256
#
257
.macro ptl2gen cnt g 
258
.if \cnt
259
	ptl2gen "\cnt - 8" \g 
260
	.quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
261
	.quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
262
	.quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
263
	.quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
264
	.quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
265
	.quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
266
	.quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
267
	.quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
268
.endif
269
.endm
270
 
271
# Page table for pages in the first gigabyte.
164 palkovsky 272
.align 4096
2703 jermar 273
.global ptl_2_0g
274
ptl_2_0g:	
275
	ptl2gen 512 0
206 palkovsky 276
 
2703 jermar 277
# Page table for pages in the second gigabyte.
188 palkovsky 278
.align 4096
2703 jermar 279
.global ptl_2_1g
280
ptl_2_1g:
281
	ptl2gen 512 1
282
 
283
# Page table for pages in the third gigabyte.
284
.align 4096
285
.global ptl_2_2g
286
ptl_2_2g:
287
	ptl2gen 512 2
288
 
289
# Page table for pages in the fourth gigabyte.
290
.align 4096
291
.global ptl_2_3g
292
ptl_2_3g:
293
	ptl2gen 512 3
294
 
295
.align 4096
188 palkovsky 296
.global ptl_1
297
ptl_1:
2703 jermar 298
	# Identity mapping for [0; 4G)
299
	.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
300
	.quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) 
301
	.quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT)
302
	.quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT)
303
	.fill 506, 8, 0
304
	# Mapping of [0; 1G) at -2G
305
	.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
306
	.fill 1, 8, 0
4346 svoboda 307
 
188 palkovsky 308
.align 4096
309
.global ptl_0
310
ptl_0:
311
	.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
1063 palkovsky 312
	.fill 255,8,0
188 palkovsky 313
	.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
1063 palkovsky 314
	.fill 254,8,0
315
	.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
178 palkovsky 316
 
2703 jermar 317
.section K_DATA_START, "aw", @progbits
318
 
695 decky 319
.global bootstrap_gdtr
320
bootstrap_gdtr:
685 decky 321
	.word gdtselector(GDT_ITEMS)
322
	.long KA2PA(gdt)
695 decky 323
 
324
grub_eax:
325
	.long 0
326
 
327
grub_ebx:
328
	.long 0
2219 decky 329
 
2692 decky 330
extended_cpuid_msg:
331
	.asciz "Extended CPUID not supported. System halted."
2219 decky 332
long_mode_msg:
2302 decky 333
	.asciz "64 bit long mode not supported. System halted."
2692 decky 334
noexecute_msg:
335
	.asciz "No-execute pages not supported. System halted."
336
fx_msg:
337
	.asciz "FXSAVE/FXRESTORE instructions not supported. System halted."
338
sse2_msg:
339
	.asciz "SSE2 instructions not supported. System halted."