xref: /haiku/src/system/boot/platform/next_m68k/start.cpp (revision 10bba152b3d5d0f55621871ab7660aab0877cdfc)
1ec5a7997SFrançois Revol /*
2ec5a7997SFrançois Revol  * Copyright 2008-2020, François Revol, revol@free.fr. All rights reserved.
3ec5a7997SFrançois Revol  * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de.
4ec5a7997SFrançois Revol  * Distributed under the terms of the MIT License.
5ec5a7997SFrançois Revol  */
6ec5a7997SFrançois Revol 
7ec5a7997SFrançois Revol 
8ec5a7997SFrançois Revol #include <KernelExport.h>
9ec5a7997SFrançois Revol #include <boot/platform.h>
10ec5a7997SFrançois Revol #include <boot/heap.h>
11ec5a7997SFrançois Revol #include <boot/stage2.h>
12ec5a7997SFrançois Revol #include <arch/cpu.h>
13ec5a7997SFrançois Revol 
14ec5a7997SFrançois Revol #include <string.h>
15ec5a7997SFrançois Revol 
16ec5a7997SFrançois Revol #include "console.h"
17ec5a7997SFrançois Revol #include "cpu.h"
18ec5a7997SFrançois Revol #include "mmu.h"
19ec5a7997SFrançois Revol #include "keyboard.h"
20ec5a7997SFrançois Revol #include "nextrom.h"
21ec5a7997SFrançois Revol 
22ec5a7997SFrançois Revol 
23ec5a7997SFrançois Revol // GCC defined globals
24ec5a7997SFrançois Revol extern void (*__ctor_list)(void);
25ec5a7997SFrançois Revol extern void (*__ctor_end)(void);
26ec5a7997SFrançois Revol extern uint8 __bss_start;
27ec5a7997SFrançois Revol extern uint8 _end;
28ec5a7997SFrançois Revol 
29ec5a7997SFrançois Revol extern "C" int main(stage2_args *args);
30ec5a7997SFrançois Revol extern "C" void _start(void);
31ec5a7997SFrançois Revol 
32ec5a7997SFrançois Revol // the boot rom monitor entry point
33ec5a7997SFrançois Revol struct mon_global *mg = NULL;
34ec5a7997SFrançois Revol 
35ec5a7997SFrançois Revol static uint32 sBootOptions;
36ec5a7997SFrançois Revol 
37ec5a7997SFrançois Revol 
38ec5a7997SFrançois Revol static void
clear_bss(void)39ec5a7997SFrançois Revol clear_bss(void)
40ec5a7997SFrançois Revol {
41ec5a7997SFrançois Revol 	memset(&__bss_start, 0, &_end - &__bss_start);
42ec5a7997SFrançois Revol }
43ec5a7997SFrançois Revol 
44ec5a7997SFrançois Revol 
45ec5a7997SFrançois Revol static void
call_ctors(void)46ec5a7997SFrançois Revol call_ctors(void)
47ec5a7997SFrançois Revol {
48ec5a7997SFrançois Revol 	void (**f)(void);
49ec5a7997SFrançois Revol 
50ec5a7997SFrançois Revol 	for (f = &__ctor_list; f < &__ctor_end; f++) {
51ec5a7997SFrançois Revol 		(**f)();
52ec5a7997SFrançois Revol 	}
53ec5a7997SFrançois Revol }
54ec5a7997SFrançois Revol 
55ec5a7997SFrançois Revol 
56ec5a7997SFrançois Revol extern "C" uint32
platform_boot_options(void)57ec5a7997SFrançois Revol platform_boot_options(void)
58ec5a7997SFrançois Revol {
59ec5a7997SFrançois Revol #if 0
60ec5a7997SFrançois Revol 	if (!gKernelArgs.fb.enabled)
61ec5a7997SFrançois Revol 		sBootOptions |= check_for_boot_keys();
62ec5a7997SFrançois Revol #endif
63ec5a7997SFrançois Revol 	return sBootOptions;
64ec5a7997SFrançois Revol }
65ec5a7997SFrançois Revol 
66ec5a7997SFrançois Revol 
67ec5a7997SFrançois Revol extern "C" void
platform_start_kernel(void)68ec5a7997SFrançois Revol platform_start_kernel(void)
69ec5a7997SFrançois Revol {
70ec5a7997SFrançois Revol #if 0
71ec5a7997SFrançois Revol 	static struct kernel_args *args = &gKernelArgs;
72ec5a7997SFrançois Revol 		// something goes wrong when we pass &gKernelArgs directly
73ec5a7997SFrançois Revol 		// to the assembler inline below - might be a bug in GCC
74ec5a7997SFrançois Revol 		// or I don't see something important...
75ec5a7997SFrançois Revol 	addr_t stackTop
76ec5a7997SFrançois Revol 		= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
77ec5a7997SFrançois Revol 
78ec5a7997SFrançois Revol 	preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
79ec5a7997SFrançois Revol 		gKernelArgs.kernel_image.Pointer());
80ec5a7997SFrançois Revol 
81ec5a7997SFrançois Revol 	//smp_init_other_cpus();
82ec5a7997SFrançois Revol 	//serial_cleanup();
83ec5a7997SFrançois Revol 	mmu_init_for_kernel();
84ec5a7997SFrançois Revol 	//smp_boot_other_cpus();
85ec5a7997SFrançois Revol 
86ec5a7997SFrançois Revol #warning M68K: stop ints
87ec5a7997SFrançois Revol 
88ec5a7997SFrançois Revol 	dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
89ec5a7997SFrançois Revol 
90ec5a7997SFrançois Revol 	asm volatile (
91ec5a7997SFrançois Revol 		"move.l	%0,%%sp;	"			// move stack out of way
92ec5a7997SFrançois Revol 		: : "m" (stackTop));
93ec5a7997SFrançois Revol 
94ec5a7997SFrançois Revol 	asm volatile (
95ec5a7997SFrançois Revol 		"or	#0x0700,%%sr; " : : );		// disable interrupts
96ec5a7997SFrançois Revol 
97ec5a7997SFrançois Revol 	asm volatile (
98ec5a7997SFrançois Revol 		"move.l  #0x0,-(%%sp); "		// we're the BSP cpu (0)
99ec5a7997SFrançois Revol 		"move.l 	%0,-(%%sp);	"		// kernel args
100ec5a7997SFrançois Revol 		"move.l 	#0x0,-(%%sp);"		// dummy retval for call to main
101ec5a7997SFrançois Revol 		"move.l 	%1,-(%%sp);	"		// this is the start address
102ec5a7997SFrançois Revol 		"rts;		"					// jump.
103ec5a7997SFrançois Revol 		: : "g" (args), "g" (image->elf_header.e_entry));
104ec5a7997SFrançois Revol 
105ec5a7997SFrançois Revol 	// Huston, we have a problem!
106ec5a7997SFrançois Revol 
107ec5a7997SFrançois Revol 	asm volatile (
108ec5a7997SFrançois Revol 		"and	#0xf8ff,%%sr; " : : );		// reenable interrupts
109ec5a7997SFrançois Revol 
110ec5a7997SFrançois Revol 	panic("kernel returned!\n");
111ec5a7997SFrançois Revol #endif
112ec5a7997SFrançois Revol 
113ec5a7997SFrançois Revol }
114ec5a7997SFrançois Revol 
115ec5a7997SFrançois Revol 
116ec5a7997SFrançois Revol extern "C" void
platform_exit(void)117ec5a7997SFrançois Revol platform_exit(void)
118ec5a7997SFrançois Revol {
119ec5a7997SFrançois Revol 	// TODO
120ec5a7997SFrançois Revol 	while (true);
121ec5a7997SFrançois Revol }
122ec5a7997SFrançois Revol 
dump_mg(struct mon_global * mg)123ec5a7997SFrançois Revol inline void dump_mg(struct mon_global *mg)
124ec5a7997SFrançois Revol {
125ab173783SFrançois Revol 	int i;
126ec5a7997SFrançois Revol 	dprintf("mg@ %p\n", (void*)mg);
127ec5a7997SFrançois Revol 
128ec5a7997SFrançois Revol 	dprintf("mg_flags\t%x\n", (unsigned char)mg->mg_flags);
129ec5a7997SFrançois Revol 	dprintf("mg_sid\t%x\n", mg->mg_sid);
130ec5a7997SFrançois Revol 	dprintf("mg_pagesize\t%x\n", mg->mg_pagesize);
131ec5a7997SFrançois Revol 	dprintf("mg_mon_stack\t%x\n", mg->mg_mon_stack);
132ec5a7997SFrançois Revol 	dprintf("mg_vbr\t%x\n", mg->mg_vbr);
133ec5a7997SFrançois Revol 	dprintf("mg_console_i\t%x\n", mg->mg_console_i);
134ec5a7997SFrançois Revol 	dprintf("mg_console_o\t%x\n", mg->mg_console_o);
135ab173783SFrançois Revol 
136ab173783SFrançois Revol 	for (i = 0; i < N_SIMM; i++) {
137ab173783SFrançois Revol 		dprintf("mg_region[%d] = {%08lx, %08lx}\n", i,
138ab173783SFrançois Revol 				mg->mg_region[i].first_phys_addr,
139ab173783SFrançois Revol 				mg->mg_region[i].last_phys_addr);
140ec5a7997SFrançois Revol 	}
141ec5a7997SFrançois Revol 
142ab173783SFrançois Revol 	dprintf("mg_boot_dev\t%s\n", mg->mg_boot_dev);
143ab173783SFrançois Revol 	dprintf("mg_boot_arg\t%s\n", mg->mg_boot_arg);
144ab173783SFrançois Revol 	dprintf("mg_boot_info\t%s\n", mg->mg_boot_info);
145ab173783SFrançois Revol 	dprintf("mg_boot_file\t%s\n", mg->mg_boot_file);
146ab173783SFrançois Revol 	dprintf("mg_boot_dev\t%s\n", mg->mg_boot_dev);
147ab173783SFrançois Revol 	dprintf("mg_boot_how\t%d\n", mg->mg_boot_how);
148ab173783SFrançois Revol 
149ab173783SFrançois Revol 	dprintf("mg_sddp\t%p\n", mg->mg_sddp);
150ab173783SFrançois Revol 	dprintf("mg_dgp\t%p\n", mg->mg_dgp);
151ab173783SFrançois Revol 		// "dlV3" (disk label signature ?) SCSI boot gives "@dlV3"
152ab173783SFrançois Revol 	dprintf("mg_fdgp\t%p\n", mg->mg_fdgp);	// "A" ?? SCSI: "to become ready"
153ab173783SFrançois Revol 	dprintf("mg_s5cp\t%p\n", mg->mg_s5cp);
154ab173783SFrançois Revol 	dprintf("mg_odc\t%p\n", mg->mg_odc);
155ab173783SFrançois Revol 	dprintf("mg_odd\t%p\n", mg->mg_odd);
156ab173783SFrançois Revol 
157ab173783SFrançois Revol #if 0
158ab173783SFrançois Revol 	for (int i = 0; i < sizeof(struct mon_global); i++) {
159ab173783SFrançois Revol 		uint8 *p = ((uint8 *)mg)+i;
160ab173783SFrançois Revol 		if (i % 32 == 0)
161ab173783SFrançois Revol 			dprintf("%04x", i);
162ab173783SFrançois Revol 		if (i % 4 == 0)
163ab173783SFrançois Revol 			dprintf(" ");
164ab173783SFrançois Revol 		if (i % 8 == 0)
165ab173783SFrançois Revol 			dprintf(" ");
166ab173783SFrançois Revol 		dprintf("%02x", *p);
167ab173783SFrançois Revol 		if (i % 32 == 31 || i == sizeof(struct mon_global) - 1)
168ab173783SFrançois Revol 			dprintf("\n");
169ab173783SFrançois Revol 	}
170ab173783SFrançois Revol 	//while(true);
171ab173783SFrançois Revol #endif
172ab173783SFrançois Revol 
173ab173783SFrançois Revol 
174ab173783SFrançois Revol 	dprintf("mg_si\t%p\n", mg->mg_si);
175ab173783SFrançois Revol 	/* XXX:the pointer seems completely random, sadly.
176ab173783SFrançois Revol 	 * Possibly the kernel is supposed to set it?
177ab173783SFrançois Revol 	 */
178ab173783SFrançois Revol #if 0
179ab173783SFrançois Revol 	for (int i = 0; i < sizeof(struct sio); i++) {
180ab173783SFrançois Revol 		uint8 *p = ((uint8 *)mg->mg_si)+i;
181ab173783SFrançois Revol 		if (i % 32 == 0)
182ab173783SFrançois Revol 			dprintf("%04x", i);
183ab173783SFrançois Revol 		if (i % 4 == 0)
184ab173783SFrançois Revol 			dprintf(" ");
185ab173783SFrançois Revol 		if (i % 8 == 0)
186ab173783SFrançois Revol 			dprintf(" ");
187ab173783SFrançois Revol 		dprintf("%02x", *p);
188ab173783SFrançois Revol 		if (i % 32 == 31 || i == sizeof(struct sio) - 1)
189ab173783SFrançois Revol 			dprintf("\n");
190ab173783SFrançois Revol 	}
191ab173783SFrançois Revol 	for (i = 0; i < 5; i++) {
192ab173783SFrançois Revol 		struct sio *s = &mg->mg_si[i];
193ab173783SFrançois Revol 		dprintf("sio[%d] = {%08x, %u, %u, %u, %p, %u, %u, %p, %p, %p}\n", i,
194ab173783SFrançois Revol 				s->si_args, s->si_ctrl, s->si_unit, s->si_part,
195ab173783SFrançois Revol 				s->si_dev, s->si_blklen, s->si_lastlba,
196ab173783SFrançois Revol 				s->si_sadmem, s->si_protomem, s->si_devmem);
197ab173783SFrançois Revol 		s++;
198ab173783SFrançois Revol 	}
199ab173783SFrançois Revol #endif
200ab173783SFrançois Revol 
201ab173783SFrançois Revol 	//dprintf("test_msg\t%p\n", mg->test_msg);
202ab173783SFrançois Revol 	/* Framebuffer info */
203ab173783SFrançois Revol #if 1
204ab173783SFrançois Revol 	dprintf("km_coni = {%d, %d, %d, %d, %d, ... %d, %d, %d, ...%d}\n",
205ab173783SFrançois Revol 			mg->km_coni.pixels_per_word,
206ab173783SFrançois Revol 			mg->km_coni.bytes_per_scanline,
207ab173783SFrançois Revol 			mg->km_coni.dspy_w,
208ab173783SFrançois Revol 			mg->km_coni.dspy_max_w,
209ab173783SFrançois Revol 			mg->km_coni.dspy_h,
210ab173783SFrançois Revol 			//...
211ab173783SFrançois Revol 			mg->km_coni.slot_num,
212ab173783SFrançois Revol 			mg->km_coni.fb_num,
213ab173783SFrançois Revol 			mg->km_coni.byte_lane_id,
214ab173783SFrançois Revol 			mg->km_coni.access_stack);
215ab173783SFrançois Revol 	for (i = 0; i < KM_CON_MAP_ENTRIES; i++) {
216ab173783SFrançois Revol 		dprintf("km_coni.map_addr[%d] = {%08lx, %08lx, %08lx}\n", i,
217ab173783SFrançois Revol 				mg->km_coni.map_addr[i].phys_addr,
218ab173783SFrançois Revol 				mg->km_coni.map_addr[i].virt_addr,
219ab173783SFrançois Revol 				mg->km_coni.map_addr[i].size);
220ab173783SFrançois Revol 	}
221ab173783SFrançois Revol #endif
222ab173783SFrançois Revol 
223ab173783SFrançois Revol 	//XXX: this one crashes on older ROMs
224ab173783SFrançois Revol 	//dprintf("mg_cpu_clk\t%d\n", mg->mg_cpu_clk);
225ab173783SFrançois Revol }
226ab173783SFrançois Revol 
227ab173783SFrançois Revol 
228ec5a7997SFrançois Revol extern "C" void *
start_next(const char * boot_args,struct mon_global * monitor)229ec5a7997SFrançois Revol start_next(const char *boot_args, struct mon_global *monitor)
230ec5a7997SFrançois Revol {
231ec5a7997SFrançois Revol 	stage2_args args;
232ec5a7997SFrançois Revol 
233ec5a7997SFrançois Revol 	monitor->mg_putc('H');
234ec5a7997SFrançois Revol 
235ec5a7997SFrançois Revol 	//asm("cld");			// Ain't nothing but a GCC thang.
236ec5a7997SFrançois Revol 	//asm("fninit");		// initialize floating point unit
237ec5a7997SFrançois Revol 
238ab173783SFrançois Revol 	//clear_bss();
239ec5a7997SFrançois Revol 	/* save monitor ROM entry */
240ec5a7997SFrançois Revol 	mg = monitor;
241ec5a7997SFrançois Revol 	// DEBUG
242ec5a7997SFrançois Revol 	mg->mg_putc('A');
243ec5a7997SFrançois Revol 
244ec5a7997SFrançois Revol 	call_ctors();
245ec5a7997SFrançois Revol 		// call C++ constructors before doing anything else
246ec5a7997SFrançois Revol 	mg->mg_putc('I');
247ec5a7997SFrançois Revol 
248*10bba152SAugustin Cavalier 	args.heap_size = 0;
249ec5a7997SFrançois Revol 	args.arguments = NULL;
250ec5a7997SFrançois Revol 
251ec5a7997SFrançois Revol 	//serial_init();
252ec5a7997SFrançois Revol 	mg->mg_putc('K');
253ec5a7997SFrançois Revol 	console_init();
254ec5a7997SFrançois Revol 	mg->mg_putc('U');
255ec5a7997SFrançois Revol 	mg->mg_putc('\n');
256ec5a7997SFrançois Revol 
257ec5a7997SFrançois Revol 	dump_mg(mg);
258ec5a7997SFrançois Revol 	//while(1);
259ec5a7997SFrançois Revol 	//return NULL;
260ab173783SFrançois Revol 	cpu_init();
261ec5a7997SFrançois Revol #if 0
262ec5a7997SFrançois Revol 	// TODO
263ec5a7997SFrançois Revol 	mmu_init();
264ec5a7997SFrançois Revol 
265ec5a7997SFrançois Revol 	// wait a bit to give the user the opportunity to press a key
266ec5a7997SFrançois Revol 	spin(750000);
267ec5a7997SFrançois Revol 
268ec5a7997SFrançois Revol 	// reading the keyboard doesn't seem to work in graphics mode (maybe a bochs problem)
269ec5a7997SFrançois Revol 	sBootOptions = check_for_boot_keys();
270ec5a7997SFrançois Revol 	//if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT)
271ec5a7997SFrançois Revol 		//serial_enable();
272ec5a7997SFrançois Revol 
273ec5a7997SFrançois Revol 	//apm_init();
274ec5a7997SFrançois Revol 	//smp_init();
275ec5a7997SFrançois Revol #endif
276ec5a7997SFrançois Revol 	main(&args);
277ec5a7997SFrançois Revol 	return NULL;
278ec5a7997SFrançois Revol }
279