Subversion Repositories HelenOS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1805 decky 1
#
2
# Copyright (C) 2001-2004 Jakub Jermar
3
# Copyright (C) 2005-2006 Martin Decky
4
# All rights reserved.
5
#
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions
8
# are met:
9
#
10
# - Redistributions of source code must retain the above copyright
11
#   notice, this list of conditions and the following disclaimer.
12
# - Redistributions in binary form must reproduce the above copyright
13
#   notice, this list of conditions and the following disclaimer in the
14
#   documentation and/or other materials provided with the distribution.
15
# - The name of the author may not be used to endorse or promote products
16
#   derived from this software without specific prior written permission.
17
#
18
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
#
29
 
30
#include <arch/boot/boot.h>
31
#include <arch/boot/memmap.h>
32
#include <arch/mm/page.h>
33
#include <arch/pm.h>
34
 
35
.section __xen_guest
36
	.ascii  "GUEST_OS=HelenOS,"
37
	.ascii  "XEN_VER=xen-3.0,"
38
	.ascii  "HYPERCALL_PAGE=0x2,"
39
	.ascii  "LOADER=generic,"
40
	.ascii  "PT_MODE_WRITABLE"
41
	.byte   0
42
 
43
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
44
 
45
.section K_TEXT_START, "ax"
46
 
47
KTEXT=8
48
KDATA=16
49
 
50
.code32
51
.align 4
52
.global multiboot_image_start
53
multiboot_header:
54
	.long MULTIBOOT_HEADER_MAGIC
55
	.long MULTIBOOT_HEADER_FLAGS
56
	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)	# checksum
57
	.long multiboot_header
58
	.long unmapped_ktext_start
59
	.long 0
60
	.long 0
61
	.long multiboot_image_start
62
 
63
multiboot_image_start:
64
	movl $START_STACK, %esp			# initialize stack pointer
65
	lgdt KA2PA(bootstrap_gdtr)		# initialize Global Descriptor Table register
66
 
67
	movw $KDATA, %cx
68
	movw %cx, %es
69
	movw %cx, %fs
70
	movw %cx, %gs
71
	movw %cx, %ds					# kernel data + stack
72
	movw %cx, %ss
73
 
74
	jmpl $KTEXT, $multiboot_meeting_point
75
	multiboot_meeting_point:
76
 
77
	pushl %ebx							# save parameters from GRUB
78
	pushl %eax
79
 
80
#ifdef CONFIG_FB
81
	mov $vesa_init, %esi
82
	mov $VESA_INIT_SEGMENT << 4, %edi
83
	mov $e_vesa_init - vesa_init, %ecx
84
	cld
85
	rep movsb
86
 
87
	mov $VESA_INIT_SEGMENT << 4, %edi
88
	jmpl %edi
89
 
90
	vesa_meeting_point:
91
 
92
	mov %esi, KA2PA(vesa_ph_addr)
93
	mov %di, KA2PA(vesa_height)
94
	shr $16, %edi
95
	mov %di, KA2PA(vesa_width)
96
	mov %bx, KA2PA(vesa_scanline)
97
	shr $16, %ebx
98
	mov %bx, KA2PA(vesa_bpp)
99
#endif	
100
 
101
	call map_kernel							# map kernel and turn paging on
102
 
103
	popl %eax
104
	popl %ebx
105
	cmpl $MULTIBOOT_LOADER_MAGIC, %eax				# compare GRUB signature
106
	je valid_boot
107
 
108
		xorl %ecx, %ecx							# no memory size or map available
109
		movl %ecx, e801memorysize
110
		movl %ecx, e820counter
111
 
112
		jmp invalid_boot
113
 
114
	valid_boot:
115
 
116
		movl (%ebx), %eax						# ebx = physical address of struct multiboot_info
117
 
118
		bt $0, %eax								# mbi->flags[0] (mem_lower, mem_upper valid)
119
		jc mem_valid
120
 
121
			xorl %ecx, %ecx
122
			jmp mem_invalid
123
 
124
		mem_valid:
125
		movl 4(%ebx), %ecx						# mbi->mem_lower
126
		addl 8(%ebx), %ecx						# mbi->mem_upper
127
 
128
		mem_invalid:
129
		movl %ecx, e801memorysize
130
 
131
		bt $3, %eax								# mbi->flags[3] (mods_count, mods_addr valid)
132
		jc mods_valid
133
 
134
			xorl %ecx, %ecx
135
			movl %ecx, init
136
			jmp mods_end
137
 
138
		mods_valid:
139
 
140
		movl 20(%ebx), %ecx						# mbi->mods_count
141
		movl %ecx, init
142
 
143
		cmpl $0, %ecx
144
		je mods_end
145
 
146
		movl 24(%ebx), %esi						# mbi->mods_addr
147
		movl $init, %edi
148
 
149
		mods_loop:
150
 
151
			movl 0(%esi), %edx					# mods->mod_start
152
			addl $0x80000000, %edx
153
			movl %edx, 4(%edi)
154
 
155
			movl 4(%esi), %edx
156
			subl 0(%esi), %edx					# mods->mod_end - mods->mod_start
157
			movl %edx, 8(%edi)
158
 
159
			addl $16, %esi
160
			addl $8	, %edi
161
 
162
			loop mods_loop
163
 
164
		mods_end:
165
 
166
		bt $6, %eax								# mbi->flags[6] (mmap_length, mmap_addr valid)	
167
		jc mmap_valid
168
 
169
			xorl %edx, %edx
170
			jmp mmap_invalid
171
 
172
		mmap_valid:
173
		movl 44(%ebx), %ecx						# mbi->mmap_length
174
		movl 48(%ebx), %esi						# mbi->mmap_addr
175
		movl $e820table, %edi
176
		xorl %edx, %edx
177
 
178
		mmap_loop:
179
			cmpl $0, %ecx
180
			jle mmap_end
181
 
182
			movl 4(%esi), %eax					# mmap->base_addr_low
183
			movl %eax, (%edi)
184
 
185
			movl 8(%esi), %eax					# mmap->base_addr_high
186
			movl %eax, 4(%edi)
187
 
188
			movl 12(%esi), %eax					# mmap->length_low
189
			movl %eax, 8(%edi)
190
 
191
			movl 16(%esi), %eax					# mmap->length_high
192
			movl %eax, 12(%edi)
193
 
194
			movl 20(%esi), %eax					# mmap->type
195
			movl %eax, 16(%edi)
196
 
197
			movl (%esi), %eax					# mmap->size
198
			addl $0x4, %eax
199
			addl %eax, %esi
200
			subl %eax, %ecx
201
			addl $MEMMAP_E820_RECORD_SIZE, %edi
202
			incl %edx
203
			jmp mmap_loop
204
 
205
		mmap_end:
206
 
207
		mmap_invalid:
208
		movl %edx, e820counter
209
 
210
	invalid_boot:
211
 
212
#ifdef CONFIG_SMP
213
 
214
	# copy AP bootstrap routines below 1 MB
215
 
216
	movl $BOOT_OFFSET, %esi
217
	movl $AP_BOOT_OFFSET, %edi
218
	movl $_hardcoded_unmapped_size, %ecx
219
	cld
220
	rep movsb
221
 
222
#endif
223
 
224
	call main_bsp								# never returns
225
 
226
	cli
227
	hlt
228
 
229
.global map_kernel
230
map_kernel:
231
	#
232
	# Here we setup mapping for both the unmapped and mapped sections of the kernel.
233
	# For simplicity, we map the entire 4G space.
234
	#
235
	movl %cr4, %ecx
236
	orl $(1<<4), %ecx
237
	movl %ecx, %cr4							# turn PSE on
238
 
239
	movl $(page_directory+0), %esi
240
	movl $(page_directory+2048), %edi
241
	xorl %ecx, %ecx
242
	xorl %ebx, %ebx
243
0:
244
	movl $((1<<7)|(1<<0)), %eax
245
	orl %ebx, %eax
246
	movl %eax, (%esi,%ecx,4)					# mapping 0x00000000+%ecx*4M => 0x00000000+%ecx*4M
247
	movl %eax, (%edi,%ecx,4)					# mapping 0x80000000+%ecx*4M => 0x00000000+%ecx*4M
248
	addl $(4*1024*1024), %ebx
249
 
250
	incl %ecx
251
	cmpl $512, %ecx
252
	jl 0b
253
 
254
	movl %esi, %cr3
255
 
256
	# turn paging on
257
	movl %cr0, %ebx
258
	orl $(1<<31), %ebx
259
	movl %ebx, %cr0
260
	ret
261
 
262
#ifdef CONFIG_FB
263
vesa_init:
264
	jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
265
 
266
.code16
267
vesa_init_real:
268
 
269
	mov %cr0, %eax
270
	and $~1, %eax
271
	mov %eax, %cr0
272
 
273
	jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
274
 
275
vesa_init_real2:
276
 
277
	mov $VESA_INIT_SEGMENT, %bx
278
 
279
	mov %bx, %es
280
	mov %bx, %fs
281
	mov %bx, %gs
282
	mov %bx, %ds
283
	mov %bx, %ss
284
 
285
	movl %esp, %eax
286
	movl $0x0000fffc, %esp
287
	movl $0x0000fffc, %ebp
288
	pushl %eax
289
 
290
#define VESA_INFO_SIZE 1024
291
 
292
#define VESA_MODE_LIST_PTR_OFFSET 14
293
#define VESA_MODE_WIDTH_OFFSET 18
294
#define VESA_MODE_HEIGHT_OFFSET 20
295
#define VESA_MODE_BPP_OFFSET 25
296
#define VESA_MODE_SCANLINE_OFFSET 16
297
#define VESA_MODE_PHADDR_OFFSET 40
298
 
299
#define VESA_END_OF_MODES 0xffff
300
 
301
#define VESA_OK 0x4f
302
 
303
#define VESA_GET_INFO 0x4f00
304
#define VESA_GET_MODE_INFO 0x4f01
305
#define VESA_SET_MODE 0x4f02
306
 
307
#define CONFIG_VESA_BPP_a 255
308
 
309
#if CONFIG_VESA_BPP == 24
310
#undef CONFIG_VESA_BPP_a
311
#define CONFIG_VESA_BPP_a 32
312
#endif
313
 
314
	mov $VESA_GET_INFO, %ax
315
	mov $e_vesa_init - vesa_init, %di
316
	push %di
317
	int $0x10
318
 
319
	pop %di
320
	cmp $VESA_OK, %al
321
	jnz 0f
322
 
323
	mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
324
	mov %si, %gs
325
	mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
326
 
327
	add $VESA_INFO_SIZE, %di
328
 
329
1:# Try next mode
330
	mov %gs:(%si), %cx
331
	cmp $VESA_END_OF_MODES, %cx
332
	jz 0f
333
 
334
	inc %si
335
	inc %si
336
	push %cx
337
	push %di
338
	push %si
339
	mov $VESA_GET_MODE_INFO, %ax
340
	int $0x10
341
 
342
	pop %si
343
	pop %di
344
	pop %cx
345
	cmp $VESA_OK, %al
346
	jnz 0f
347
 
348
	mov $CONFIG_VESA_WIDTH, %ax
349
	cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
350
	jnz 1b
351
 
352
	mov $CONFIG_VESA_HEIGHT,%ax
353
	cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
354
	jnz 1b
355
 
356
	mov $CONFIG_VESA_BPP, %al
357
	cmp VESA_MODE_BPP_OFFSET(%di), %al
358
	jz 2f
359
 
360
	mov $CONFIG_VESA_BPP_a, %al
361
	cmp VESA_MODE_BPP_OFFSET(%di), %al
362
	jnz 1b
363
 
364
2:
365
 
366
	mov %cx, %bx
367
	or $0xc000, %bx
368
	push %di
369
	mov $VESA_SET_MODE, %ax
370
	int $0x10
371
 
372
	pop %di
373
	cmp $VESA_OK, %al
374
	jnz 0f
375
 
376
	mov VESA_MODE_PHADDR_OFFSET(%di), %esi
377
	mov VESA_MODE_WIDTH_OFFSET(%di), %ax
378
	shl $16, %eax
379
	mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
380
	mov VESA_MODE_BPP_OFFSET(%di), %bl
381
	xor %bh, %bh
382
	shl $16, %ebx
383
	mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
384
	mov %eax, %edi
385
 
386
8:	
387
 
388
	mov %cr0, %eax
389
	or $1, %eax
390
	mov %eax, %cr0
391
 
392
	jmp 9f
393
9:
394
 
395
	ljmpl $KTEXT, $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
396
 
397
0:# No prefered mode found
398
	mov $0x111, %cx
399
	push %di
400
	push %cx
401
	mov $VESA_GET_MODE_INFO, %ax
402
	int $0x10
403
 
404
	pop %cx
405
	pop %di
406
	cmp $VESA_OK, %al
407
	jnz 1f
408
	jz 2b						# Force relative jump
409
 
410
1:
411
	mov $0x0003, %ax
412
	int $0x10
413
	mov $0xffffffff, %edi		# EGA text mode used, because of problems with VESA
414
	xor %ax, %ax
415
	jz 8b						# Force relative jump
416
 
417
 
418
.code32
419
vesa_init_protect:
420
	popl %esp
421
 
422
	movw $KDATA, %cx
423
	movw %cx, %es
424
	movw %cx, %fs
425
	movw %cx, %gs
426
	movw %cx, %ds					# kernel data + stack
427
	movw %cx, %ss
428
 
429
	jmpl $KTEXT, $vesa_meeting_point
430
 
431
.align 4
432
e_vesa_init:
433
#endif	
434
 
435
.section K_DATA_START, "aw", @progbits
436
 
437
.align 4096
438
page_directory:
439
	.space 4096, 0