haiku/headers/private/kernel/arch/x86/arch_cpu.h

380 lines
10 KiB
C
Raw Normal View History

/*
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _KERNEL_ARCH_x86_CPU_H
#define _KERNEL_ARCH_x86_CPU_H
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
#ifndef _ASSEMBLER
#include <module.h>
#include <arch/x86/descriptors.h>
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
#endif // !_ASSEMBLER
#undef PAUSE
#define PAUSE() asm volatile ("pause;")
// MSR registers (possibly Intel specific)
#define IA32_MSR_TSC 0x10
#define IA32_MSR_APIC_BASE 0x1b
#define IA32_MSR_MTRR_CAPABILITIES 0xfe
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
#define IA32_MSR_SYSENTER_CS 0x174
#define IA32_MSR_SYSENTER_ESP 0x175
#define IA32_MSR_SYSENTER_EIP 0x176
#define IA32_MSR_MTRR_DEFAULT_TYPE 0x2ff
#define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200
#define IA32_MSR_MTRR_PHYSICAL_MASK_0 0x201
// x86 features from cpuid eax 1, edx register
#define IA32_FEATURE_FPU 0x00000001 // x87 fpu
#define IA32_FEATURE_VME 0x00000002 // virtual 8086
#define IA32_FEATURE_DE 0x00000004 // debugging extensions
#define IA32_FEATURE_PSE 0x00000008 // page size extensions
#define IA32_FEATURE_TSC 0x00000010 // rdtsc instruction
#define IA32_FEATURE_MSR 0x00000020 // rdmsr/wrmsr instruction
#define IA32_FEATURE_PAE 0x00000040 // extended 3 level page table addressing
#define IA32_FEATURE_MCE 0x00000080 // machine check exception
#define IA32_FEATURE_CX8 0x00000100 // cmpxchg8b instruction
#define IA32_FEATURE_APIC 0x00000200 // local apic on chip
#define IA32_FEATURE_SEP 0x00000800 // SYSENTER/SYSEXIT
#define IA32_FEATURE_MTRR 0x00001000 // MTRR
#define IA32_FEATURE_PGE 0x00002000 // paging global bit
#define IA32_FEATURE_MCA 0x00004000 // machine check architecture
#define IA32_FEATURE_CMOV 0x00008000 // cmov instruction
#define IA32_FEATURE_PAT 0x00010000 // page attribute table
#define IA32_FEATURE_PSE36 0x00020000 // page size extensions with 4MB pages
#define IA32_FEATURE_PSN 0x00040000 // processor serial number
#define IA32_FEATURE_CLFSH 0x00080000 // cflush instruction
#define IA32_FEATURE_DS 0x00200000 // debug store
#define IA32_FEATURE_ACPI 0x00400000 // thermal monitor and clock ctrl
#define IA32_FEATURE_MMX 0x00800000 // mmx instructions
#define IA32_FEATURE_FXSR 0x01000000 // FXSAVE/FXRSTOR instruction
#define IA32_FEATURE_SSE 0x02000000 // SSE
#define IA32_FEATURE_SSE2 0x04000000 // SSE2
#define IA32_FEATURE_SS 0x08000000 // self snoop
#define IA32_FEATURE_HTT 0x10000000 // hyperthreading
#define IA32_FEATURE_TM 0x20000000 // thermal monitor
#define IA32_FEATURE_PBE 0x80000000 // pending break enable
// x86 features from cpuid eax 1, ecx register
#define IA32_FEATURE_EXT_SSE3 0x00000001 // SSE3
#define IA32_FEATURE_EXT_MONITOR 0x00000008 // MONITOR/MWAIT
#define IA32_FEATURE_EXT_DSCPL 0x00000010 // CPL qualified debug store
#define IA32_FEATURE_EXT_EST 0x00000080 // speedstep
#define IA32_FEATURE_EXT_TM2 0x00000100 // thermal monitor 2
#define IA32_FEATURE_EXT_CNXTID 0x00000400 // L1 context ID
// x86 features from cpuid eax 0x80000001, edx register (AMD)
// only care about the ones that are unique to this register
#define IA32_FEATURE_AMD_EXT_SYSCALL (1 << 11) // SYSCALL/SYSRET
#define IA32_FEATURE_AMD_EXT_NX (1 << 20) // no execute bit
#define IA32_FEATURE_AMD_EXT_MMXEXT (1 << 22) // mmx extensions
#define IA32_FEATURE_AMD_EXT_FFXSR (1 << 25) // fast FXSAVE/FXRSTOR
#define IA32_FEATURE_AMD_EXT_RDTSCP (1 << 27) // rdtscp instruction
#define IA32_FEATURE_AMD_EXT_LONG (1 << 29) // long mode
#define IA32_FEATURE_AMD_EXT_3DNOWEXT (1 << 30) // 3DNow! extensions
#define IA32_FEATURE_AMD_EXT_3DNOW (1 << 31) // 3DNow!
// cr4 flags
#define IA32_CR4_PAE (1UL << 5)
#define IA32_CR4_GLOBAL_PAGES (1UL << 7)
// Memory type ranges
#define IA32_MTR_UNCACHED 0
#define IA32_MTR_WRITE_COMBINING 1
#define IA32_MTR_WRITE_THROUGH 4
#define IA32_MTR_WRITE_PROTECTED 5
#define IA32_MTR_WRITE_BACK 6
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
// iframe types
#define IFRAME_TYPE_SYSCALL 0x1
#define IFRAME_TYPE_OTHER 0x2
#define IFRAME_TYPE_MASK 0xf
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
#ifndef _ASSEMBLER
struct X86PagingStructures;
* Added a set_mtrrs() hook to x86_cpu_module_info, which is supposed to set all MTRRs at once. * Added a respective x86_set_mtrrs() kernel function. * x86 CPU module: - Implemented the new hook. - Prefixed most debug output with the CPU index. Otherwise it gets quite confusing with multiple CPUs. - generic_init_mtrrs(): No longer clear all MTRRs, if they are already enabled. This lets us benefit from the BIOS's setup until we install our own -- otherwise with caching disabled things are *really* slow. * arch_vm.cpp: Completely rewrote the MTRR handling as the old one was not only slow (O(2^n)), but also broken (resulting in incorrect setups (e.g. with cachable ranges larger than requested)), and not working by design for certain cases (subtractive setups intersecting ranges added later). Now we maintain an array with the successfully set ranges. When a new range is added, we recompute the complete MTRR setup as we need to. The new algorithm analyzing the ranges has linear complexity and also handles range base addresses with an alignment not matching the range size (e.g. a range at address 0x1000 with size 0x2000) and joining of adjacent/overlapping ranges of the same type. This fixes the slow graphics on my 4 GB machine (though unfortunately the 8 MTRRs aren't enough to fully cover the complete frame buffer (about 35 pixel lines remain uncachable), but that can't be helped without rounding up the frame buffer size, for which we don't have enough information). It might also fix #1823. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34197 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-11-23 18:06:08 +03:00
typedef struct x86_mtrr_info {
uint64 base;
uint64 size;
uint8 type;
} x86_mtrr_info;
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
typedef struct x86_optimized_functions {
void (*memcpy)(void* dest, const void* source, size_t count);
void* memcpy_end;
void (*memset)(void* dest, int value, size_t count);
void* memset_end;
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
} x86_optimized_functions;
typedef struct x86_cpu_module_info {
module_info info;
uint32 (*count_mtrrs)(void);
void (*init_mtrrs)(void);
void (*set_mtrr)(uint32 index, uint64 base, uint64 length,
uint8 type);
status_t (*get_mtrr)(uint32 index, uint64* _base, uint64* _length,
uint8* _type);
void (*set_mtrrs)(uint8 defaultType, const x86_mtrr_info* infos,
uint32 count);
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
void (*get_optimized_functions)(x86_optimized_functions* functions);
} x86_cpu_module_info;
struct tss {
uint16 prev_task;
uint16 unused0;
uint32 sp0;
uint32 ss0;
uint32 sp1;
uint32 ss1;
uint32 sp2;
uint32 ss2;
uint32 cr3;
uint32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
uint32 es, cs, ss, ds, fs, gs;
uint32 ldt_seg_selector;
uint16 unused1;
uint16 io_map_base;
};
struct iframe {
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
uint32 type; // iframe type
uint32 gs;
uint32 fs;
uint32 es;
uint32 ds;
uint32 edi;
uint32 esi;
uint32 ebp;
uint32 esp;
uint32 ebx;
uint32 edx;
uint32 ecx;
uint32 eax;
uint32 orig_eax;
uint32 orig_edx;
uint32 vector;
uint32 error_code;
uint32 eip;
uint32 cs;
uint32 flags;
// user_esp and user_ss are only present when the iframe is a userland
// iframe (IFRAME_IS_USER()). A kernel iframe is shorter.
uint32 user_esp;
uint32 user_ss;
};
struct vm86_iframe {
uint32 type; // iframe type
uint32 __null_gs;
uint32 __null_fs;
uint32 __null_es;
uint32 __null_ds;
uint32 edi;
uint32 esi;
uint32 ebp;
uint32 __kern_esp;
uint32 ebx;
uint32 edx;
uint32 ecx;
uint32 eax;
uint32 orig_eax;
uint32 orig_edx;
uint32 vector;
uint32 error_code;
uint32 eip;
uint16 cs, __csh;
uint32 flags;
uint32 esp;
uint16 ss, __ssh;
/* vm86 mode specific part */
uint16 es, __esh;
uint16 ds, __dsh;
uint16 fs, __fsh;
uint16 gs, __gsh;
};
#define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SEG \
|| ((f)->flags & 0x20000) != 0)
#define IFRAME_IS_VM86(f) (((f)->flags & 0x20000) != 0)
// features
enum x86_feature_type {
FEATURE_COMMON = 0, // cpuid eax=1, ecx register
FEATURE_EXT, // cpuid eax=1, edx register
FEATURE_EXT_AMD, // cpuid eax=0x80000001, edx register (AMD)
FEATURE_NUM
};
enum x86_vendors {
VENDOR_INTEL = 0,
VENDOR_AMD,
VENDOR_CYRIX,
VENDOR_UMC,
VENDOR_NEXGEN,
VENDOR_CENTAUR,
VENDOR_RISE,
VENDOR_TRANSMETA,
VENDOR_NSC,
VENDOR_NUM,
VENDOR_UNKNOWN,
};
typedef struct arch_cpu_info {
// saved cpu info
enum x86_vendors vendor;
uint32 feature[FEATURE_NUM];
char model_name[49];
const char* vendor_name;
int type;
int family;
int extended_family;
int stepping;
int model;
int extended_model;
struct X86PagingStructures* active_paging_structures;
uint32 dr6; // temporary storage for debug registers (cf.
uint32 dr7; // x86_exit_user_debug_at_kernel_entry())
// local TSS for this cpu
struct tss tss;
struct tss double_fault_tss;
} arch_cpu_info;
#ifdef __cplusplus
extern "C" {
#endif
#define nop() __asm__ ("nop"::)
struct arch_thread;
void __x86_setup_system_time(uint32 conversionFactor,
uint32 conversionFactorNsecs, bool conversionFactorNsecsShift);
void x86_context_switch(struct arch_thread* oldState,
struct arch_thread* newState);
void x86_userspace_thread_exit(void);
void x86_end_userspace_thread_exit(void);
void x86_enter_userspace(addr_t entry, addr_t stackTop);
void x86_swap_pgdir(uint32 newPageDir);
void i386_set_tss_and_kstack(addr_t kstack);
void i386_fnsave(void* fpuState);
void i386_fxsave(void* fpuState);
void i386_frstor(const void* fpuState);
void i386_fxrstor(const void* fpuState);
void i386_fnsave_swap(void* oldFpuState, const void* newFpuState);
void i386_fxsave_swap(void* oldFpuState, const void* newFpuState);
uint32 x86_read_ebp();
uint32 x86_read_cr0();
void x86_write_cr0(uint32 value);
uint32 x86_read_cr4();
void x86_write_cr4(uint32 value);
uint64 x86_read_msr(uint32 registerNumber);
void x86_write_msr(uint32 registerNumber, uint64 value);
More work towards making our double fault handler less triple fault prone: * SMP: - Added smp_send_broadcast_ici_interrupts_disabled(), which is basically equivalent to smp_send_broadcast_ici(), but is only called with interrupts disabled and gets the CPU index, so it doesn't have to use smp_get_current_cpu() (which dereferences the current thread). - Added cpu index parameter to smp_intercpu_int_handler(). * x86: - arch_int.c -> arch_int.cpp - Set up an IDT per CPU. We were using a single IDT for all CPUs, but that can't work, since we need different tasks for the double fault interrupt vector. - Set the per CPU double fault task gates correctly. - Renamed set_intr_gate() to set_interrupt_gate and set_system_gate() to set_trap_gate() and documented them a bit. - Renamed double_fault_exception() x86_double_fault_exception() and fixed it not to use smp_get_current_cpu(). Instead we have the new x86_double_fault_get_cpu() that deducts the CPU index from the used stack. - Fixed the double_fault interrupt handler: It no longer calls int_bottom to avoid accessing the current thread. * debug.cpp: - Introduced explicit debug_double_fault() to enter the kernel debugger from a double fault handler. - Avoid using smp_get_current_cpu(). - Don't use kprintf() before sDebuggerOnCPU is set. Otherwise acquire_spinlock() is invoked by arch_debug_serial_puts(). Things look a bit better when the current thread pointer is broken -- we run into kernel_debugger_loop() and successfully print the "Welcome to KDL" message -- but we still dereference the thread pointer afterwards, so that we don't get a usable kernel debugger yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32050 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-08-01 05:53:54 +04:00
void x86_set_task_gate(int32 cpu, int32 n, int32 segment);
void* x86_get_idt(int32 cpu);
uint32 x86_count_mtrrs(void);
void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type);
status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length,
uint8* _type);
void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos,
uint32 count);
bool x86_check_feature(uint32 feature, enum x86_feature_type type);
void* x86_get_double_fault_stack(int32 cpu, size_t* _size);
More work towards making our double fault handler less triple fault prone: * SMP: - Added smp_send_broadcast_ici_interrupts_disabled(), which is basically equivalent to smp_send_broadcast_ici(), but is only called with interrupts disabled and gets the CPU index, so it doesn't have to use smp_get_current_cpu() (which dereferences the current thread). - Added cpu index parameter to smp_intercpu_int_handler(). * x86: - arch_int.c -> arch_int.cpp - Set up an IDT per CPU. We were using a single IDT for all CPUs, but that can't work, since we need different tasks for the double fault interrupt vector. - Set the per CPU double fault task gates correctly. - Renamed set_intr_gate() to set_interrupt_gate and set_system_gate() to set_trap_gate() and documented them a bit. - Renamed double_fault_exception() x86_double_fault_exception() and fixed it not to use smp_get_current_cpu(). Instead we have the new x86_double_fault_get_cpu() that deducts the CPU index from the used stack. - Fixed the double_fault interrupt handler: It no longer calls int_bottom to avoid accessing the current thread. * debug.cpp: - Introduced explicit debug_double_fault() to enter the kernel debugger from a double fault handler. - Avoid using smp_get_current_cpu(). - Don't use kprintf() before sDebuggerOnCPU is set. Otherwise acquire_spinlock() is invoked by arch_debug_serial_puts(). Things look a bit better when the current thread pointer is broken -- we run into kernel_debugger_loop() and successfully print the "Welcome to KDL" message -- but we still dereference the thread pointer afterwards, so that we don't get a usable kernel debugger yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32050 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-08-01 05:53:54 +04:00
int32 x86_double_fault_get_cpu(void);
void x86_double_fault_exception(struct iframe* frame);
* Renamed the ROUNDOWN macro to ROUNDDOWN. Also changed the implementation of ROUNDUP to use '*' and '/' -- the compiler will optimize that for powers of two anyway and this implementation works for other numbers as well. * The thread::fault_handler use in C[++] code was broken with gcc 4. At least when other functions were invoked. Trying to trick the compiler wasn't a particularly good idea anyway, since the next compiler version could break the trick again. So the general policy is to use the fault handlers only in assembly code where we have full control. Changed that for x86 (save for the vm86 mode, which has a similar mechanism), but not for the other architectures. * Introduced fault_handler, fault_handler_stack_pointer, and fault_jump_buffer fields in the cpu_ent structure, which must be used instead of thread::fault_handler in the kernel debugger. Consequently user_memcpy() must not be used in the kernel debugger either. Introduced a debug_memcpy() instead. * Introduced debug_call_with_fault_handler() function which calls a function in a setjmp() and fault handler context. The architecture specific backend arch_debug_call_with_fault_handler() has only been implemented for x86 yet. * Introduced debug_is_kernel_memory_accessible() for use in the kernel debugger. It determines whether a range of memory can be accessed in the way specified. The architecture specific back end arch_vm_translation_map_is_kernel_page_accessible() has only been implemented for x86 yet. * Added arch_debug_unset_current_thread() (only implemented for x86) to unset the current thread pointer in the kernel debugger. When entering the kernel debugger we do some basic sanity checks of the currently set thread structure and unset it, if they fail. This allows certain commands (most importantly the stack trace command) to avoid accessing the thread structure. * x86: When handling a double fault, we do now install a special handler for page faults. This allows us to gracefully catch faulting commands, even if e.g. the thread structure is toast. We are now in much better shape to deal with double faults. Hopefully avoiding the triple faults that some people have been experiencing on their hardware and ideally even allowing to use the kernel debugger normally. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32073 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-08-03 16:39:56 +04:00
void x86_page_fault_exception_double_fault(struct iframe* frame);
#define read_cr3(value) \
__asm__("movl %%cr3,%0" : "=r" (value))
#define write_cr3(value) \
__asm__("movl %0,%%cr3" : : "r" (value))
#define read_dr3(value) \
__asm__("movl %%dr3,%0" : "=r" (value))
#define write_dr3(value) \
__asm__("movl %0,%%dr3" : : "r" (value))
#define invalidate_TLB(va) \
__asm__("invlpg (%0)" : : "r" (va))
#define wbinvd() \
__asm__("wbinvd")
#define out8(value,port) \
__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
#define out16(value,port) \
__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
#define out32(value,port) \
__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
#define in8(port) ({ \
uint8 _v; \
__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
_v; \
})
#define in16(port) ({ \
uint16 _v; \
__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
_v; \
})
#define in32(port) ({ \
uint32 _v; \
__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
_v; \
})
#define out8_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:" : : "a" (value), "d" (port))
#define in8_p(port) ({ \
uint8 _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:" : "=a" (_v) : "d" (port)); \
_v; \
})
extern segment_descriptor* gGDT;
#ifdef __cplusplus
} // extern "C" {
#endif
Merged branch haiku/branches/developer/bonefish/optimization revision 23139 into trunk, with roughly the following changes (for details svn log the branch): * The int 99 syscall handler is now fully in assembly. * Added a sysenter/sysexit handler and use it on Pentiums that support it (via commpage). * Got rid of i386_handle_trap(). A bit of functionality was moved into the assembly handler which now uses a jump table to call C functions handling the respective interrupt. * Some optimizations to get user debugger support code out of the interrupt handling path. * Introduced a thread::flags fields which allows to skip handling of rare events (signals, user debug enabling/disabling) on the common interrupt handling path. * Got rid of the explicit iframe stack. The iframes can still be retrieved by iterating through the stack frames. * Made the commpage an architecture independent feature. It's used for the real time data stuff (instead of creating a separate area). * The x86 CPU modules can now provide processor optimized versions for common functions (currently memcpy() only). They are used in the kernel and are provided to the userland via commpage entries. * Introduced build system feature allowing easy use of C structure member offsets in assembly code. Changes after merging: * Fixed merge conflict in src/system/kernel/arch/x86/arch_debug.cpp (caused by refactoring and introduction of "call" debugger command). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23370 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-11 03:36:44 +03:00
#endif // !_ASSEMBLER
#endif /* _KERNEL_ARCH_x86_CPU_H */