2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
6 #define __KERNEL_NOLIBBASE__
8 #include <aros/multiboot.h>
9 #include <aros/symbolsets.h>
12 #include <exec/lists.h>
13 #include <proto/exec.h>
14 #include <proto/kernel.h>
18 #include "kernel_base.h"
19 #include "kernel_intern.h"
20 #include "kernel_debug.h"
21 #include "kernel_intr.h"
27 This file contains code that is run once Exec has been brought up - and is launched
28 via the RomTag/Autoinit routines in Exec.
30 Here we do the platform setup that requires Exec to have minimal configuration
31 but still running inthe SINGLETASK environment.
34 extern struct syscallx86_Handler x86_SCSupervisorHandler
;
36 #if defined(EMULATE_SYSBASE)
37 /* CPU exceptions are processed here */
38 void core_IRQ0EHandle(struct ExceptionContext
*regs
, void *HandlerData
, void *HandlerData2
)
40 uint64_t ptr
= rdcr(cr2
);
41 unsigned char *ip
= (unsigned char *)regs
->rip
;
43 D(bug("[Kernel] Page fault exception\n"));
45 if (ptr
== EMULATE_SYSBASE
)
47 D(bug("[Kernel] ** Code at 0x%p is trying to access the SysBase at 0x%p.\n", ip
, ptr
));
49 if ((ip
[0] & 0xfb) == 0x48 &&
51 (ip
[2] & 0xc7) == 0x04 &&
54 int reg
= ((ip
[2] >> 3) & 0x07) | ((ip
[0] & 0x04) << 1);
59 regs
->rax
= (UQUAD
)SysBase
;
62 regs
->rcx
= (UQUAD
)SysBase
;
65 regs
->rdx
= (UQUAD
)SysBase
;
68 regs
->rbx
= (UQUAD
)SysBase
;
70 // case 4: /* Cannot put SysBase into rSP register */
71 // regs->rsp = (UQUAD)SysBase;
74 regs
->rbp
= (UQUAD
)SysBase
;
77 regs
->rsi
= (UQUAD
)SysBase
;
80 regs
->rdi
= (UQUAD
)SysBase
;
83 regs
->r8
= (UQUAD
)SysBase
;
86 regs
->r9
= (UQUAD
)SysBase
;
89 regs
->r10
= (UQUAD
)SysBase
;
92 regs
->r11
= (UQUAD
)SysBase
;
95 regs
->r12
= (UQUAD
)SysBase
;
98 regs
->r13
= (UQUAD
)SysBase
;
101 regs
->r14
= (UQUAD
)SysBase
;
104 regs
->r15
= (UQUAD
)SysBase
;
110 core_LeaveInterrupt(regs
);
112 else if ((ip
[0] & 0xfb) == 0x48 &&
114 (ip
[2] & 0xc7) == 0x05)
116 int reg
= ((ip
[2] >> 3) & 0x07) | ((ip
[0] & 0x04) << 1);
121 regs
->rax
= (UQUAD
)SysBase
;
124 regs
->rcx
= (UQUAD
)SysBase
;
127 regs
->rdx
= (UQUAD
)SysBase
;
130 regs
->rbx
= (UQUAD
)SysBase
;
132 // case 4: /* Cannot put SysBase into rSP register */
133 // regs->rsp = (UQUAD)SysBase;
136 regs
->rbp
= (UQUAD
)SysBase
;
139 regs
->rsi
= (UQUAD
)SysBase
;
142 regs
->rdi
= (UQUAD
)SysBase
;
145 regs
->r8
= (UQUAD
)SysBase
;
148 regs
->r9
= (UQUAD
)SysBase
;
151 regs
->r10
= (UQUAD
)SysBase
;
154 regs
->r11
= (UQUAD
)SysBase
;
157 regs
->r12
= (UQUAD
)SysBase
;
160 regs
->r13
= (UQUAD
)SysBase
;
163 regs
->r14
= (UQUAD
)SysBase
;
166 regs
->r15
= (UQUAD
)SysBase
;
172 core_LeaveInterrupt(regs
);
174 D(else bug("[Kernel] Instruction not recognized\n"));
180 bug("[Kernel] PAGE FAULT accessing 0x%p\n", ptr
);
181 bug("[Kernel] Insn: ");
182 for (i
= 0; i
< 16; i
++)
191 int core_SysCallHandler(struct ExceptionContext
*regs
, struct KernelBase
*KernelBase
, void *HandlerData2
);
193 static int Platform_Init(struct KernelBase
*LIBBASE
)
195 struct PlatformData
*pdata
;
196 struct KernelBase
*KernelBase
= LIBBASE
;
202 bug("[Kernel:x86_64] %s: Performing Post-Exec initialization\n", __func__
);
203 bug("[Kernel:x86_64] %s: KernelBase @ %p\n", __func__
, LIBBASE
);)
206 * Setup the Interrupt Controller Environment ...
208 NEWLIST(&LIBBASE
->kb_ICList
);
209 NEWLIST(&LIBBASE
->kb_InterruptMappings
);
210 LIBBASE
->kb_ICTypeBase
= KBL_INTERNAL
+ 1;
212 D(bug("[Kernel:x86_64] %s: Interrupt Controller Base ID = %d\n", __func__
, LIBBASE
->kb_ICTypeBase
));
214 for (i
= 0; i
< HW_IRQ_COUNT
; i
++)
216 LIBBASE
->kb_Interrupts
[i
].ki_Priv
&= ~IRQINTF_ENABLED
;
217 LIBBASE
->kb_Interrupts
[i
].ki_List
.lh_Type
= KBL_INTERNAL
;
220 D(bug("[Kernel:x86_64] %s: Interrupt Lists initialised\n", __func__
));
223 * Setup our Platform Data ...
225 pdata
= AllocMem(sizeof(struct PlatformData
), MEMF_PUBLIC
|MEMF_CLEAR
);
229 D(bug("[Kernel:x86_64] %s: Platform Data allocated @ 0x%p\n", __func__
, pdata
));
231 LIBBASE
->kb_PlatformData
= pdata
;
234 * Setup the base syscall handler(s) ...
236 NEWLIST(&pdata
->kb_SysCallHandlers
);
238 // we need to setup the BSP's syscall gate early..
239 if (!core_SetIDTGate((apicidt_t
*)__KernBootPrivate
->BOOTIDT
, APIC_CPU_EXCEPT_TO_VECTOR(APIC_EXCEPT_SYSCALL
), (uintptr_t)IntrDefaultGates
[APIC_CPU_EXCEPT_TO_VECTOR(APIC_EXCEPT_SYSCALL
)], TRUE
))
241 krnPanic(NULL
, "Failed to set BSP Syscall Vector\n"
243 APIC_CPU_EXCEPT_TO_VECTOR(APIC_EXCEPT_SYSCALL
));
245 KrnAddExceptionHandler(APIC_EXCEPT_SYSCALL
, core_SysCallHandler
, LIBBASE
, NULL
);
246 krnAddSysCallHandler(pdata
, &x86_SCSupervisorHandler
, FALSE
, TRUE
);
248 D(bug("[Kernel:x86_64] %s: SysCall set up\n", __func__
));
250 #if defined(EMULATE_SYSBASE)
251 // KrnAddExceptionHandler(0x0E, core_IRQ0EHandle, void *handlerData, void *handlerData2);
257 ADD2INITLIB(Platform_Init
, 10)