1 #ifndef _KERNEL_ARCH_H_
2 #define _KERNEL_ARCH_H_
4 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
7 Desc: Machine-specific definitions for IBM PC hardware
11 #include <exec/nodes.h>
12 #include <exec/lists.h>
13 #include <aros/types/spinlock_s.h>
15 #include "apic_ia32.h"
17 #define PAGE_SIZE 0x1000
18 #define PAGE_MASK 0x0FFF
20 #define KERNELIRQ_NEEDSPRIVATE
21 #define KERNELIRQ_NEEDSCONTROLLERS
23 * Simulate SysBase access
24 * Disabled because global SysBase is moved away from zeropage.
26 /*#define EMULATE_SYSBASE*/
28 /* Platform-specific part of KernelBase */
32 APTR kb_APIC_TrampolineBase
; /* Starting address of secondary core bootstrap code */
33 struct List kb_SysCallHandlers
;
34 struct ACPIData
*kb_ACPI
;
35 struct APICData
*kb_APIC
;
36 struct IOAPICData
*kb_IOAPIC
;
37 struct List kb_FreeIPIHooks
;
38 struct List kb_BusyIPIHooks
;
39 spinlock_t kb_FreeIPIHooksLock
;
40 spinlock_t kb_BusyIPIHooksLock
;
43 #define PLATFORMF_HAVEMSI (1 << 1)
45 /* Hardware IRQs *********************************************************************************/
47 /* By default we only know about the xtpic's IRQs */
48 #define IRQ_COUNT I8259A_IRQCOUNT
51 * The first Hardware IRQ starts at 32
52 * (0 - 31 are cpu exceptions, see below..)
54 #define HW_IRQ_BASE X86_CPU_EXCEPT_COUNT
57 * We handle all 255 exception vectors. However vectors starting from 0x20
58 * are hardware IRQs which are handled separately. So - 32 raw exceptions.
60 #define EXCEPTIONS_COUNT (X86_CPU_EXCEPT_COUNT + APIC_CPU_EXCEPT_COUNT)
68 5 - Bound Range Exceeded
70 7 - Device Not Available
72 9 - Coprocessor Segment Overrun
74 11 - Segment Not Present
78 16 - x87 FPU Floating Point Error
81 19 - SIMD Floating-Point
84 /* Interrupt controller functions */
85 void ictl_enable_irq(unsigned char, struct KernelBase
*);
86 void ictl_disable_irq(unsigned char, struct KernelBase
*);
87 BOOL
ictl_is_irq_enabled(unsigned char, struct KernelBase
*);
89 #define IRQINTB_ENABLED 1
90 #define IRQINTF_ENABLED (1 << IRQINTB_ENABLED)
92 /* CPU Timer *************************************************************************************/
94 #define ADDTIME(dest, src) \
95 (dest)->tv_micro += (src)->tv_micro; \
96 (dest)->tv_secs += (src)->tv_secs; \
97 while((dest)->tv_micro > 999999) \
100 (dest)->tv_micro -= 1000000; \
104 * INTR_FROMUSERMODE uses arch-specific mechanisms to determine which CPL we
106 * For x86-64, every task has the SS register initialized to a valid segment
107 * descriptor. The descriptor itself isn't used by x86-64; however when a
108 * privilege level switch occurs upon an interrupt, SS is reset to zero and
109 * the old value is pushed to the stack as part of the interrupt context.
110 * Both steps are done as part of the CPU's atomic interrupt mechanism, so
111 * we can rely on the sequence not being only partly completed.
112 * On x86-32, we rely on a similar mechanism, but using the CS register
113 * instead of SS. CS is set to one value for user mode, but replaced with a
114 * new value specific to the kernel privilege level when an interrupt occurs.
117 #define INTR_FROMUSERMODE (regs->ss != 0)
119 #define INTR_FROMUSERMODE (regs->cs != KERNEL_CS)
123 static inline unsigned long long RDTSC() {
124 unsigned long _tsc_upper
, _tsc_lower
;
125 asm volatile (".byte 0x0f, 0x31" : "=a" (_tsc_lower
), "=d"(_tsc_upper
));
126 return _tsc_lower
| ((unsigned long long)_tsc_upper
<< 32);
129 static inline unsigned long long RDTSC() {
130 unsigned long long _tsc
;
131 asm volatile (".byte 0x0f, 0x31" : "=A" (_tsc
));
136 /* x86 specific SysCalls *************************************************************************/
138 struct syscallx86_Handler
141 void (*sc_SysCall
)();
144 #include "x86_syscalls.h"
146 BOOL
krnAddSysCallHandler(struct PlatformData
*, struct syscallx86_Handler
*, BOOL
, BOOL
);
148 #endif /* !_KERNEL_ARCH_H_ */