revert between 56095 -> 55830 in arch
[AROS.git] / arch / x86_64-pc / kernel / platform_init.c
blobace0f0dc6ffe1aed2ce44914a42eaa49dc05bb54
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define __KERNEL_NOLIBBASE__
8 #include <aros/multiboot.h>
9 #include <aros/symbolsets.h>
10 #include <asm/cpu.h>
11 #include <asm/io.h>
12 #include <exec/lists.h>
13 #include <proto/exec.h>
14 #include <proto/kernel.h>
16 #include <inttypes.h>
18 #include "kernel_base.h"
19 #include "kernel_intern.h"
20 #include "kernel_debug.h"
21 #include "kernel_intr.h"
23 #define D(x)
24 #define DAPIC(x)
26 /*
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 &&
50 ip[1] == 0x8b &&
51 (ip[2] & 0xc7) == 0x04 &&
52 ip[3] == 0x25)
54 int reg = ((ip[2] >> 3) & 0x07) | ((ip[0] & 0x04) << 1);
56 switch(reg)
58 case 0:
59 regs->rax = (UQUAD)SysBase;
60 break;
61 case 1:
62 regs->rcx = (UQUAD)SysBase;
63 break;
64 case 2:
65 regs->rdx = (UQUAD)SysBase;
66 break;
67 case 3:
68 regs->rbx = (UQUAD)SysBase;
69 break;
70 // case 4: /* Cannot put SysBase into rSP register */
71 // regs->rsp = (UQUAD)SysBase;
72 // break;
73 case 5:
74 regs->rbp = (UQUAD)SysBase;
75 break;
76 case 6:
77 regs->rsi = (UQUAD)SysBase;
78 break;
79 case 7:
80 regs->rdi = (UQUAD)SysBase;
81 break;
82 case 8:
83 regs->r8 = (UQUAD)SysBase;
84 break;
85 case 9:
86 regs->r9 = (UQUAD)SysBase;
87 break;
88 case 10:
89 regs->r10 = (UQUAD)SysBase;
90 break;
91 case 11:
92 regs->r11 = (UQUAD)SysBase;
93 break;
94 case 12:
95 regs->r12 = (UQUAD)SysBase;
96 break;
97 case 13:
98 regs->r13 = (UQUAD)SysBase;
99 break;
100 case 14:
101 regs->r14 = (UQUAD)SysBase;
102 break;
103 case 15:
104 regs->r15 = (UQUAD)SysBase;
105 break;
108 regs->rip += 8;
110 core_LeaveInterrupt(regs);
112 else if ((ip[0] & 0xfb) == 0x48 &&
113 ip[1] == 0x8b &&
114 (ip[2] & 0xc7) == 0x05)
116 int reg = ((ip[2] >> 3) & 0x07) | ((ip[0] & 0x04) << 1);
118 switch(reg)
120 case 0:
121 regs->rax = (UQUAD)SysBase;
122 break;
123 case 1:
124 regs->rcx = (UQUAD)SysBase;
125 break;
126 case 2:
127 regs->rdx = (UQUAD)SysBase;
128 break;
129 case 3:
130 regs->rbx = (UQUAD)SysBase;
131 break;
132 // case 4: /* Cannot put SysBase into rSP register */
133 // regs->rsp = (UQUAD)SysBase;
134 // break;
135 case 5:
136 regs->rbp = (UQUAD)SysBase;
137 break;
138 case 6:
139 regs->rsi = (UQUAD)SysBase;
140 break;
141 case 7:
142 regs->rdi = (UQUAD)SysBase;
143 break;
144 case 8:
145 regs->r8 = (UQUAD)SysBase;
146 break;
147 case 9:
148 regs->r9 = (UQUAD)SysBase;
149 break;
150 case 10:
151 regs->r10 = (UQUAD)SysBase;
152 break;
153 case 11:
154 regs->r11 = (UQUAD)SysBase;
155 break;
156 case 12:
157 regs->r12 = (UQUAD)SysBase;
158 break;
159 case 13:
160 regs->r13 = (UQUAD)SysBase;
161 break;
162 case 14:
163 regs->r14 = (UQUAD)SysBase;
164 break;
165 case 15:
166 regs->r15 = (UQUAD)SysBase;
167 break;
170 regs->rip += 7;
172 core_LeaveInterrupt(regs);
174 D(else bug("[Kernel] Instruction not recognized\n"));
177 #ifdef DUMP_CONTEXT
178 unsigned int i;
180 bug("[Kernel] PAGE FAULT accessing 0x%p\n", ptr);
181 bug("[Kernel] Insn: ");
182 for (i = 0; i < 16; i++)
183 bug("%02x ", ip[i]);
184 bug("\n");
185 #endif
187 return FALSE;
189 #endif
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;
197 #if 1
198 int i;
199 #endif
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);
226 if (!pdata)
227 return FALSE;
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"
242 "Vector #%02X\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);
252 #endif
254 return TRUE;
257 ADD2INITLIB(Platform_Init, 10)