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