1/*
2 * Copyright 2003-2010, Axel D��rfler, axeld@pinc-software.de.
3 * Copyright 2008, Fran��ois Revol, revol@free.fr. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include <KernelExport.h>
9#include <boot/platform.h>
10#include <boot/heap.h>
11#include <boot/stage2.h>
12#include <arch/cpu.h>
13
14#include <string.h>
15
16#include "console.h"
17#include "cpu.h"
18#include "mmu.h"
19#include "keyboard.h"
20#include "rom_calls.h"
21
22
23#define HEAP_SIZE 65536
24
25// GCC defined globals
26extern void (*__ctor_list)(void);
27extern void (*__ctor_end)(void);
28extern uint8 __bss_start;
29extern uint8 _end;
30
31extern "C" int main(stage2_args *args);
32extern "C" void _start(void);
33
34
35static uint32 sBootOptions;
36
37
38static void
39clear_bss(void)
40{
41	memset(&__bss_start, 0, &_end - &__bss_start);
42}
43
44
45static void
46call_ctors(void)
47{
48	void (**f)(void);
49
50	for (f = &__ctor_list; f < &__ctor_end; f++) {
51		(**f)();
52	}
53}
54
55
56extern "C" uint32
57platform_boot_options(void)
58{
59#if 0
60	if (!gKernelArgs.fb.enabled)
61		sBootOptions |= check_for_boot_keys();
62#endif
63	return sBootOptions;
64}
65
66
67extern "C" void
68platform_start_kernel(void)
69{
70	static struct kernel_args *args = &gKernelArgs;
71		// something goes wrong when we pass &gKernelArgs directly
72		// to the assembler inline below - might be a bug in GCC
73		// or I don't see something important...
74	addr_t stackTop
75		= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
76
77	preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
78		gKernelArgs.kernel_image.Pointer());
79
80	//smp_init_other_cpus();
81	//serial_cleanup();
82	mmu_init_for_kernel();
83	//smp_boot_other_cpus();
84
85#warning M68K: stop ints
86
87	dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
88
89	asm volatile (
90		"move.l	%0,%%sp;	"			// move stack out of way
91		: : "m" (stackTop));
92
93	asm volatile (
94		"or	#0x0700,%%sr; " : : );		// disable interrupts
95
96	asm volatile (
97		"move.l  #0x0,-(%%sp); "		// we're the BSP cpu (0)
98		"move.l 	%0,-(%%sp);	"		// kernel args
99		"move.l 	#0x0,-(%%sp);"		// dummy retval for call to main
100		"move.l 	%1,-(%%sp);	"		// this is the start address
101		"rts;		"					// jump.
102		: : "g" (args), "g" (image->elf_header.e_entry));
103
104	// Huston, we have a problem!
105
106	asm volatile (
107		"and	#0xf8ff,%%sr; " : : );		// reenable interrupts
108
109	panic("kernel returned!\n");
110
111}
112
113
114extern "C" void
115platform_exit(void)
116{
117	ColdReboot();
118	// Terminate
119	//TODO
120	while (true) {}
121}
122
123extern "C" void
124_start(void)
125{
126	stage2_args args;
127
128	//asm("cld");			// Ain't nothing but a GCC thang.
129	//asm("fninit");		// initialize floating point unit
130
131	clear_bss();
132	call_ctors();
133		// call C++ constructors before doing anything else
134
135	args.heap_size = HEAP_SIZE;
136	args.arguments = NULL;
137
138	//serial_init();
139	console_init();
140	dprintf("ramtop   = %p\n", NULL);
141	cpu_init();
142	mmu_init();
143
144	// wait a bit to give the user the opportunity to press a key
145	spin(750000);
146
147	// reading the keyboard doesn't seem to work in graphics mode (maybe a bochs problem)
148	sBootOptions = check_for_boot_keys();
149	//if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT)
150		//serial_enable();
151
152	//apm_init();
153	//smp_init();
154	main(&args);
155}
156