19209acd2SAxel Dörfler /*
234dc9962SFrançois Revol * Copyright 2008-2010, François Revol, revol@free.fr. All rights reserved.
39209acd2SAxel Dörfler * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de.
49209acd2SAxel Dörfler * Distributed under the terms of the MIT License.
59209acd2SAxel Dörfler */
69209acd2SAxel Dörfler
79209acd2SAxel Dörfler
89209acd2SAxel Dörfler #include <KernelExport.h>
99209acd2SAxel Dörfler #include <boot/platform.h>
109209acd2SAxel Dörfler #include <boot/heap.h>
119209acd2SAxel Dörfler #include <boot/stage2.h>
129209acd2SAxel Dörfler #include <arch/cpu.h>
139209acd2SAxel Dörfler
149209acd2SAxel Dörfler #include <string.h>
159209acd2SAxel Dörfler
169209acd2SAxel Dörfler #include "console.h"
179209acd2SAxel Dörfler #include "cpu.h"
189209acd2SAxel Dörfler #include "mmu.h"
199209acd2SAxel Dörfler #include "keyboard.h"
209209acd2SAxel Dörfler #include "toscalls.h"
219209acd2SAxel Dörfler
229209acd2SAxel Dörfler
239209acd2SAxel Dörfler // GCC defined globals
249209acd2SAxel Dörfler extern void (*__ctor_list)(void);
259209acd2SAxel Dörfler extern void (*__ctor_end)(void);
269209acd2SAxel Dörfler extern uint8 __bss_start;
279209acd2SAxel Dörfler extern uint8 _end;
289209acd2SAxel Dörfler
299209acd2SAxel Dörfler extern "C" int main(stage2_args *args);
309209acd2SAxel Dörfler extern "C" void _start(void);
319209acd2SAxel Dörfler
329209acd2SAxel Dörfler
339209acd2SAxel Dörfler static uint32 sBootOptions;
349209acd2SAxel Dörfler
359209acd2SAxel Dörfler
369209acd2SAxel Dörfler static void
clear_bss(void)379209acd2SAxel Dörfler clear_bss(void)
389209acd2SAxel Dörfler {
399209acd2SAxel Dörfler memset(&__bss_start, 0, &_end - &__bss_start);
409209acd2SAxel Dörfler }
419209acd2SAxel Dörfler
429209acd2SAxel Dörfler
439209acd2SAxel Dörfler static void
call_ctors(void)449209acd2SAxel Dörfler call_ctors(void)
459209acd2SAxel Dörfler {
469209acd2SAxel Dörfler void (**f)(void);
479209acd2SAxel Dörfler
489209acd2SAxel Dörfler for (f = &__ctor_list; f < &__ctor_end; f++) {
499209acd2SAxel Dörfler (**f)();
509209acd2SAxel Dörfler }
519209acd2SAxel Dörfler }
529209acd2SAxel Dörfler
539209acd2SAxel Dörfler
549209acd2SAxel Dörfler extern "C" uint32
platform_boot_options(void)559209acd2SAxel Dörfler platform_boot_options(void)
569209acd2SAxel Dörfler {
579209acd2SAxel Dörfler #if 0
589209acd2SAxel Dörfler if (!gKernelArgs.fb.enabled)
599209acd2SAxel Dörfler sBootOptions |= check_for_boot_keys();
609209acd2SAxel Dörfler #endif
619209acd2SAxel Dörfler return sBootOptions;
629209acd2SAxel Dörfler }
639209acd2SAxel Dörfler
649209acd2SAxel Dörfler
659209acd2SAxel Dörfler extern "C" void
platform_start_kernel(void)669209acd2SAxel Dörfler platform_start_kernel(void)
679209acd2SAxel Dörfler {
689209acd2SAxel Dörfler static struct kernel_args *args = &gKernelArgs;
699209acd2SAxel Dörfler // something goes wrong when we pass &gKernelArgs directly
709209acd2SAxel Dörfler // to the assembler inline below - might be a bug in GCC
719209acd2SAxel Dörfler // or I don't see something important...
729209acd2SAxel Dörfler addr_t stackTop
739209acd2SAxel Dörfler = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
749209acd2SAxel Dörfler
75f1244978SAlex Smith preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
76acda52f5SAlex Smith gKernelArgs.kernel_image.Pointer());
77f1244978SAlex Smith
789209acd2SAxel Dörfler //smp_init_other_cpus();
799209acd2SAxel Dörfler //serial_cleanup();
809209acd2SAxel Dörfler mmu_init_for_kernel();
819209acd2SAxel Dörfler //smp_boot_other_cpus();
829209acd2SAxel Dörfler
839209acd2SAxel Dörfler #warning M68K: stop ints
849209acd2SAxel Dörfler
85f1244978SAlex Smith dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
869209acd2SAxel Dörfler
879209acd2SAxel Dörfler asm volatile (
889209acd2SAxel Dörfler "move.l %0,%%sp; " // move stack out of way
899209acd2SAxel Dörfler : : "m" (stackTop));
909209acd2SAxel Dörfler
919209acd2SAxel Dörfler asm volatile (
929209acd2SAxel Dörfler "or #0x0700,%%sr; " : : ); // disable interrupts
939209acd2SAxel Dörfler
949209acd2SAxel Dörfler asm volatile (
959209acd2SAxel Dörfler "move.l #0x0,-(%%sp); " // we're the BSP cpu (0)
969209acd2SAxel Dörfler "move.l %0,-(%%sp); " // kernel args
979209acd2SAxel Dörfler "move.l #0x0,-(%%sp);" // dummy retval for call to main
989209acd2SAxel Dörfler "move.l %1,-(%%sp); " // this is the start address
999209acd2SAxel Dörfler "rts; " // jump.
100f1244978SAlex Smith : : "g" (args), "g" (image->elf_header.e_entry));
1019209acd2SAxel Dörfler
1029209acd2SAxel Dörfler // Huston, we have a problem!
1039209acd2SAxel Dörfler
1049209acd2SAxel Dörfler asm volatile (
1059209acd2SAxel Dörfler "and #0xf8ff,%%sr; " : : ); // reenable interrupts
1069209acd2SAxel Dörfler
1079209acd2SAxel Dörfler panic("kernel returned!\n");
1089209acd2SAxel Dörfler
1099209acd2SAxel Dörfler }
1109209acd2SAxel Dörfler
1119209acd2SAxel Dörfler
1129209acd2SAxel Dörfler extern "C" void
platform_exit(void)1139209acd2SAxel Dörfler platform_exit(void)
1149209acd2SAxel Dörfler {
115180ffdeaSFrançois Revol // Terminate if running under ARAnyM
116180ffdeaSFrançois Revol int32 nfShutdownId = nat_feat_getid("NF_SHUTDOWN");
117180ffdeaSFrançois Revol if (nfShutdownId)
118180ffdeaSFrançois Revol nat_feat_call(nfShutdownId, 0);
119180ffdeaSFrançois Revol
120180ffdeaSFrançois Revol // This crashes...
1219209acd2SAxel Dörfler // TODO: Puntaes() instead ?
1229209acd2SAxel Dörfler Pterm0();
1239209acd2SAxel Dörfler }
1249209acd2SAxel Dörfler
1259209acd2SAxel Dörfler
1269209acd2SAxel Dörfler extern "C" void
_start(void)1279209acd2SAxel Dörfler _start(void)
1289209acd2SAxel Dörfler {
1299209acd2SAxel Dörfler stage2_args args;
1309209acd2SAxel Dörfler Bconout(DEV_CON, 'H');
1319209acd2SAxel Dörfler
1329209acd2SAxel Dörfler //asm("cld"); // Ain't nothing but a GCC thang.
1339209acd2SAxel Dörfler //asm("fninit"); // initialize floating point unit
1349209acd2SAxel Dörfler
1359209acd2SAxel Dörfler clear_bss();
1369209acd2SAxel Dörfler Bconout(DEV_CON, 'A');
1379209acd2SAxel Dörfler call_ctors();
1389209acd2SAxel Dörfler // call C++ constructors before doing anything else
1399209acd2SAxel Dörfler Bconout(DEV_CON, 'I');
1409209acd2SAxel Dörfler
141*10bba152SAugustin Cavalier args.heap_size = 0;
1429209acd2SAxel Dörfler args.arguments = NULL;
1439209acd2SAxel Dörfler
1449209acd2SAxel Dörfler // so we can dprintf
1459209acd2SAxel Dörfler init_nat_features();
1469209acd2SAxel Dörfler
1479209acd2SAxel Dörfler //serial_init();
1489209acd2SAxel Dörfler Bconout(DEV_CON, 'K');
1499209acd2SAxel Dörfler console_init();
1509209acd2SAxel Dörfler Bconout(DEV_CON, 'U');
151180ffdeaSFrançois Revol Bconout(DEV_CON, '\n');
1529209acd2SAxel Dörfler dprintf("membot = %p\n", (void*)*TOSVAR_membot);
1539209acd2SAxel Dörfler dprintf("memtop = %p\n", (void*)*TOSVAR_memtop);
1549209acd2SAxel Dörfler dprintf("v_bas_ad = %p\n", *TOSVAR_v_bas_ad);
1559209acd2SAxel Dörfler dprintf("phystop = %p\n", (void*)*TOSVARphystop);
1569209acd2SAxel Dörfler dprintf("ramtop = %p\n", (void*)*TOSVARramtop);
1579209acd2SAxel Dörfler cpu_init();
1589209acd2SAxel Dörfler mmu_init();
1599209acd2SAxel Dörfler
1609209acd2SAxel Dörfler // wait a bit to give the user the opportunity to press a key
1619209acd2SAxel Dörfler spin(750000);
1629209acd2SAxel Dörfler
1639209acd2SAxel Dörfler // reading the keyboard doesn't seem to work in graphics mode (maybe a bochs problem)
1649209acd2SAxel Dörfler sBootOptions = check_for_boot_keys();
1659209acd2SAxel Dörfler //if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT)
1669209acd2SAxel Dörfler //serial_enable();
1679209acd2SAxel Dörfler
1689209acd2SAxel Dörfler //apm_init();
1699209acd2SAxel Dörfler //smp_init();
1709209acd2SAxel Dörfler main(&args);
1719209acd2SAxel Dörfler }
172