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