revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-mingw32 / kernel / kernel_startup.c
blob8a874433801127984e899296e044366deebfbc18
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/kernel.h>
7 #include <aros/multiboot.h>
8 #include <aros/symbolsets.h>
9 #include <exec/execbase.h>
10 #include <exec/resident.h>
11 #include <utility/tagitem.h>
12 #include <proto/arossupport.h>
13 #include <proto/exec.h>
15 #include <inttypes.h>
16 #include <stdlib.h>
17 #include <string.h>
19 #include "hostinterface.h"
20 #include "kernel_base.h"
21 #include "kernel_intern.h"
22 #include "kernel_debug.h"
23 #include "kernel_romtags.h"
25 #define D(x)
27 /* Some globals we can't live without */
28 struct HostInterface *HostIFace;
29 struct KernelInterface KernelIFace;
30 static const char *kernel_functions[];
32 /* rom startup */
33 int __startup startup(struct TagItem *msg, ULONG magic)
35 void *_stack = AROS_GET_SP;
36 void *hostlib;
37 char *errstr;
38 unsigned int i;
39 struct MemHeader *mh;
40 struct TagItem *tag, *tstate = msg;
41 struct HostInterface *hif = NULL;
42 struct mb_mmap *mmap = NULL;
43 ULONG memflags = MEMF_CHIP|MEMF_PUBLIC|MEMF_LOCAL|MEMF_KICK;
44 UWORD *ranges[] = {NULL, NULL, (UWORD *)-1};
46 /* Fail if we are ocassionally started from within AROS command line */
47 if (magic != AROS_BOOT_MAGIC)
48 return -1;
50 while ((tag = LibNextTagItem(&tstate)))
52 switch (tag->ti_Tag)
54 case KRN_KernelLowest:
55 ranges[0] = (UWORD *)tag->ti_Data;
56 break;
58 case KRN_KernelHighest:
59 ranges[1] = (UWORD *)tag->ti_Data;
60 break;
62 case KRN_MMAPAddress:
63 mmap = (struct mb_mmap *)tag->ti_Data;
64 break;
66 case KRN_KernelBss:
67 __clear_bss((struct KernelBSS *)tag->ti_Data);
68 break;
70 case KRN_HostInterface:
71 hif = (struct HostInterface *)tag->ti_Data;
72 break;
76 /* If there's no HostIFace, we can't even say anything */
77 if (!hif)
78 return -1;
80 /* Set globals only AFTER __clear_bss() */
81 BootMsg = msg;
82 HostIFace = hif;
84 /* Validate our HostInterface version */
85 if (strcmp(HostIFace->System, "Windows"))
86 return -1;
87 if (HostIFace->Version != HOSTINTERFACE_VERSION)
88 return -1;
90 /* Now we have debug output, we can bug() */
91 hostlib = HostIFace->hostlib_Open("Libs\\Host\\kernel.dll", &errstr);
92 if (!hostlib)
94 bug("[Kernel] Failed to load host-side module: %s\n", errstr);
95 HostIFace->hostlib_FreeErrorStr(errstr);
96 return -1;
99 for (i = 0; kernel_functions[i]; i++)
101 void *func = HostIFace->hostlib_GetPointer(hostlib, kernel_functions[i], &errstr);
103 if (!func)
105 bug("[Kernel] Failed to find symbol %s in host-side module: %s\n", kernel_functions[i], errstr);
106 HostIFace->hostlib_FreeErrorStr(errstr);
107 HostIFace->hostlib_Close(hostlib, NULL);
109 return -1;
111 ((void **)&KernelIFace)[i] = func;
114 /* Now we have core_alert(), krnDisplayAlert() works */
115 if ((!ranges[0]) || (!ranges[1]) || (!mmap))
117 krnPanic(KernelBase, "Not enough information from the bootstrap\n"
118 "Kickstart start 0x%p, end 0x%p\n"
119 "Memory map address: 0x%p",
120 ranges[0], ranges[1], mmap);
121 return -1;
124 #if __WORDSIZE > 32
126 * On x86-64 VirtualAlloc() still seems to return memory within 32-bit region.
127 * The documentation doesn't specify it explicitly, so we make a check, just in case.
128 * Looks like the lowest possible region is returned.
130 if (mmap->addr + mmap->len <= 0x80000000)
131 memflags |= MEMF_31BIT;
132 #endif
135 * Prepare the first mem header and hand it to PrepareExecBase to take SysBase live
136 * We know that memory map has only one RAM element.
138 D(bug("[Kernel] preparing first mem header\n"));
139 mh = (struct MemHeader *)mmap->addr;
140 krnCreateMemHeader("Normal RAM", -5, mh, mmap->len, memflags);
143 * TODO: this needs to be replaced by SysBase address validation.
144 * This will make KickTags and capture vectors working.
146 SysBase = NULL;
148 D(bug("[Kernel] calling krnPrepareExecBase(), mh_First = 0x%p, msg = 0x%p\n", mh->mh_First, msg));
149 if (!krnPrepareExecBase(ranges, mh, msg))
150 return -1;
152 D(bug("[Kernel] SysBase=0x%p, mh_First=0x%p\n", SysBase, mh->mh_First);)
155 * ROM memory header. This special memory header covers all ROM code and data sections
156 * so that TypeOfMem() will not return 0 for addresses pointing into the kickstart.
158 krnCreateROMHeader("Kickstart ROM", ranges[0], ranges[1]);
161 * Stack memory header. This special memory header covers a little part of the programs
162 * stack so that TypeOfMem() will not return 0 for addresses pointing into the stack
163 * during initialization.
165 krnCreateROMHeader("Boot stack", _stack - AROS_STACKSIZE, _stack);
167 D(bug("[Kernel] calling InitCode(RTF_SINGLETASK,0)\n"));
168 InitCode(RTF_SINGLETASK, 0);
169 InitCode(RTF_COLDSTART, 0);
171 krnPanic(KernelBase, "Failed to start up the system");
172 HostIFace->hostlib_Close(hostlib, NULL);
173 return 1;
176 /* Functions we want from Libs/Host/kernel.dll */
177 static const char *kernel_functions[] =
179 "core_init",
180 "core_raise",
181 "core_protect",
182 "core_putc",
183 "core_getc",
184 "core_alert",
185 "TrapVector",
186 "IRQVector",
187 "Supervisor",
188 "Ints_Enabled",
189 "Sleep_Mode",
190 "LastErrorPtr",
191 NULL
194 static int Platform_Init(struct KernelBase *KernelBase)
196 char *args;
198 /* Our VBlank is software-driven, we can ask the user what frequency to use. Default is 50 Hz. */
199 SysBase->VBlankFrequency = 50;
201 args = (char *)LibGetTagData(KRN_CmdLine, 0, BootMsg);
202 if (args)
204 char *s = strstr(args, "vblank=");
206 if (s)
207 SysBase->VBlankFrequency = atoi(&s[7]);
210 D(bug("[Kernel] initializing host-side kernel module, timer frequency is %u\n", SysBase->VBlankFrequency));
212 *KernelIFace.TrapVector = core_TrapHandler;
213 *KernelIFace.IRQVector = core_IRQHandler;
215 return KernelIFace.core_init(SysBase->VBlankFrequency);
218 ADD2INITLIB(Platform_Init, 10);