revert between 56095 -> 55830 in arch
[AROS.git] / arch / i386-pc / kernel / platform_init.c
blob743f230584ffab6b2d21c9727ed5cde6e9f4214f
1 /*
2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define __KERNEL_NOLIBBASE__
8 #include <aros/symbolsets.h>
9 #include <asm/cpu.h>
10 #include <exec/execbase.h>
11 #include <proto/exec.h>
12 #include <proto/kernel.h>
14 #include "kernel_base.h"
15 #include "kernel_debug.h"
16 #include "kernel_intern.h"
17 #include "kernel_intr.h"
19 #include "utils.h"
21 #define D(x)
22 #define DSYSCALL(x)
24 #define TSS_SELECTOR 0x30
26 extern struct syscallx86_Handler x86_SCSupervisorHandler;
28 int core_SysCallHandler(struct ExceptionContext *regs, struct KernelBase *KernelBase, void *HandlerData2);
30 static int PlatformInit(struct KernelBase *KernelBase)
32 struct PlatformData *data;
33 struct tss *tss = __KernBootPrivate->TSS;
34 apicidt_t *idt = __KernBootPrivate->BOOTIDT;
35 struct segment_desc *GDT = __KernBootPrivate->BOOTGDT;
36 int i;
38 NEWLIST(&KernelBase->kb_ICList);
39 NEWLIST(&KernelBase->kb_InterruptMappings);
40 KernelBase->kb_ICTypeBase = KBL_INTERNAL + 1;
42 for (i = 0; i < HW_IRQ_COUNT; i++)
44 KernelBase->kb_Interrupts[i].ki_Priv &= ~IRQINTF_ENABLED;
45 KernelBase->kb_Interrupts[i].ki_List.lh_Type = KBL_INTERNAL;
48 data = AllocMem(sizeof(struct PlatformData), MEMF_PUBLIC|MEMF_CLEAR);
49 if (!data)
50 return FALSE;
52 D(bug("[Kernel:i386] %s: Allocated platform data at 0x%p\n", __func__, data));
53 KernelBase->kb_PlatformData = data;
56 * Now we have a complete memory list and working AllocMem().
57 * We can build IDT and TSS now to make interrupts work.
59 SysBase->SysStkLower = AllocMem(0x10000, MEMF_PUBLIC); /* 64KB of system stack */
61 if (!SysBase->SysStkLower)
62 return FALSE;
64 tss->ssp_seg = KERNEL_DS; /* SSP segment descriptor */
65 tss->cs = USER_CS;
66 tss->ds = USER_DS;
67 tss->es = USER_DS;
68 tss->ss = USER_DS;
69 tss->iomap = 104;
71 /* Set up system stack */
72 SysBase->SysStkUpper = SysBase->SysStkLower + 0x10000;
73 tss->ssp = (IPTR)SysBase->SysStkUpper;
75 /* Restore IDT structure */
76 core_SetupIDT(0, idt);
78 // Set up the base syscall handler(s)
79 NEWLIST(&data->kb_SysCallHandlers);
80 if (!core_SetIDTGate(idt, APIC_CPU_EXCEPT_TO_VECTOR(APIC_EXCEPT_SYSCALL),
81 (uintptr_t)IntrDefaultGates[APIC_CPU_EXCEPT_TO_VECTOR(APIC_EXCEPT_SYSCALL)], TRUE))
83 krnPanic(NULL, "Failed to set BSP Syscall Vector\n"
84 "Vector #%02X\n",
85 APIC_CPU_EXCEPT_TO_VECTOR(APIC_EXCEPT_SYSCALL));
87 KrnAddExceptionHandler(APIC_EXCEPT_SYSCALL, core_SysCallHandler, KernelBase, NULL);
88 krnAddSysCallHandler(data, &x86_SCSupervisorHandler, FALSE, TRUE);
90 /* Set correct TSS address in the GDT */
91 GDT[6].base_low = ((unsigned long)tss) & 0xffff;
92 GDT[6].base_mid = (((unsigned long)tss) >> 16) & 0xff;
93 GDT[6].base_high = (((unsigned long)tss) >> 24) & 0xff;
96 * As we prepared all necessary stuff, we can hopefully load IDT
97 * into CPU. We may also play a bit with TSS
99 asm
101 "ltr %%ax\n\t"
102 ::"ax"(TSS_SELECTOR)
105 D(bug("[Kernel:i386] %s: System restored\n", __func__));
107 return TRUE;
110 ADD2INITLIB(PlatformInit, 10);