1/*
2 * Copyright 2008-2010, François Revol, revol@free.fr. All rights reserved.
3 * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de.
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 "toscalls.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	// Terminate if running under ARAnyM
118	int32 nfShutdownId = nat_feat_getid("NF_SHUTDOWN");
119	if (nfShutdownId)
120		nat_feat_call(nfShutdownId, 0);
121
122	// This crashes...
123	// TODO: Puntaes() instead ?
124	Pterm0();
125}
126
127
128extern "C" void
129_start(void)
130{
131	stage2_args args;
132	Bconout(DEV_CON, 'H');
133
134	//asm("cld");			// Ain't nothing but a GCC thang.
135	//asm("fninit");		// initialize floating point unit
136
137	clear_bss();
138	Bconout(DEV_CON, 'A');
139	call_ctors();
140		// call C++ constructors before doing anything else
141	Bconout(DEV_CON, 'I');
142
143	args.heap_size = HEAP_SIZE;
144	args.arguments = NULL;
145
146	// so we can dprintf
147	init_nat_features();
148
149	//serial_init();
150	Bconout(DEV_CON, 'K');
151	console_init();
152	Bconout(DEV_CON, 'U');
153	Bconout(DEV_CON, '\n');
154	dprintf("membot   = %p\n", (void*)*TOSVAR_membot);
155	dprintf("memtop   = %p\n", (void*)*TOSVAR_memtop);
156	dprintf("v_bas_ad = %p\n", *TOSVAR_v_bas_ad);
157	dprintf("phystop  = %p\n", (void*)*TOSVARphystop);
158	dprintf("ramtop   = %p\n", (void*)*TOSVARramtop);
159	cpu_init();
160	mmu_init();
161
162	// wait a bit to give the user the opportunity to press a key
163	spin(750000);
164
165	// reading the keyboard doesn't seem to work in graphics mode (maybe a bochs problem)
166	sBootOptions = check_for_boot_keys();
167	//if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT)
168		//serial_enable();
169
170	//apm_init();
171	//smp_init();
172	main(&args);
173}
174