From 7208e95f0ebfb66272c2059aa23bc45446ad4e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 6 Jan 2003 08:02:44 +0000 Subject: [PATCH] Moved the gdt_idt_descr struct from arch_stage2.h to stage2_priv.h. Moved the tss_descriptor structure to descriptor.h, updated it to be a segment_descriptor structure, and provided inlines for set_tss_descriptor(), set_segment_descriptor(), set_segment_descriptor_base(), and clear_segment_descriptor(). Also added defines for the different privilege levels and descriptor types. Removed the unusused and incorrect TSS definition, introduced new TSS_BASE_SEGMENT and TLS_BASE_SEGMENT macros. Removed include of arch/cpu.h in arch_cpu.h. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2360 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/x86/arch_cpu.h | 29 +---- headers/private/kernel/arch/x86/arch_stage2.h | 9 +- headers/private/kernel/arch/x86/descriptors.h | 123 +++++++++++++++++- headers/private/kernel/arch/x86/stage2_priv.h | 5 + 4 files changed, 128 insertions(+), 38 deletions(-) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index db7847dc72..f9875ae333 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -5,8 +5,6 @@ #ifndef _KERNEL_ARCH_x86_CPU_H #define _KERNEL_ARCH_x86_CPU_H -/* ??? why include this as we're normally included from that file! */ -#include #include #include @@ -15,10 +13,6 @@ #define _BIG_ENDIAN 0 #define _LITTLE_ENDIAN 1 -typedef struct desc_struct { - unsigned int a,b; -} desc_table; - struct tss { uint16 prev_task; uint16 unused0; @@ -38,23 +32,9 @@ struct tss { uint16 io_map_base; }; -struct tss_descriptor { - uint16 limit_00_15; - uint16 base_00_15; - uint32 base_23_16 : 8; - uint32 type : 4; - uint32 zero : 1; - uint32 dpl : 2; - uint32 present : 1; - uint32 limit_19_16 : 4; - uint32 avail : 1; - uint32 zero1 : 1; - uint32 zero2 : 1; - uint32 granularity : 1; - uint32 base_31_24 : 8; -}; +/**************************************************************************/ -typedef struct ptentry { +typedef struct ptentry { // page table entry unsigned int present:1; unsigned int rw:1; unsigned int user:1; @@ -68,7 +48,7 @@ typedef struct ptentry { unsigned int addr:20; } ptentry; -typedef struct pdentry { +typedef struct pdentry { // page directory entry unsigned int present:1; unsigned int rw:1; unsigned int user:1; @@ -175,5 +155,6 @@ __asm__ volatile ("inb %%dx,%%al\n" \ _v; \ }) -#endif +extern segment_descriptor *gGDT; +#endif /* _KERNEL_ARCH_x86_CPU_H */ diff --git a/headers/private/kernel/arch/x86/arch_stage2.h b/headers/private/kernel/arch/x86/arch_stage2.h index 8bbf73d84e..3eac90b787 100644 --- a/headers/private/kernel/arch/x86/arch_stage2.h +++ b/headers/private/kernel/arch/x86/arch_stage2.h @@ -15,12 +15,6 @@ #define IDT_LIMIT 0x800 #define GDT_LIMIT 0x800 -struct gdt_idt_descr { - unsigned short a; - unsigned int *b; -} _PACKED; - - // kernel args typedef struct { // architecture specific @@ -45,5 +39,4 @@ typedef struct { unsigned int cpu_apic_version[MAX_BOOT_CPUS]; } arch_kernel_args; -#endif - +#endif /* _KERNEL_ARCH_x86_STAGE2_H */ diff --git a/headers/private/kernel/arch/x86/descriptors.h b/headers/private/kernel/arch/x86/descriptors.h index 76fe8ff5e5..67be588c32 100644 --- a/headers/private/kernel/arch/x86/descriptors.h +++ b/headers/private/kernel/arch/x86/descriptors.h @@ -5,11 +5,122 @@ #ifndef _KERNEL_ARCH_x86_DESCRIPTORS_H #define _KERNEL_ARCH_x86_DESCRIPTORS_H -#define KERNEL_CODE_SEG 0x8 -#define KERNEL_DATA_SEG 0x10 -#define USER_CODE_SEG 0x1b -#define USER_DATA_SEG 0x23 -#define TSS 0x28 -#endif /* _KERNEL_ARCH_x86_DESCRIPTORS_H */ +#define KERNEL_CODE_SEG 0x8 +#define KERNEL_DATA_SEG 0x10 +#define USER_CODE_SEG 0x1b +#define USER_DATA_SEG 0x23 + + +#ifndef _ASSEMBLER + // this file can also be included from assembler as well + // (and is in arch_interrupts.S) + +#define TSS_BASE_SEGMENT 5 +#define TLS_BASE_SEGMENT (TSS_BASE_SEGMENT + smp_get_num_cpus()) + + +// defines entries in the GDT/LDT + +typedef struct segment_descriptor { + uint16 limit_00_15; // bit 0 - 15 + uint16 base_00_15; // 16 - 31 + uint32 base_23_16 : 8; // 0 - 7 + uint32 type : 4; // 8 - 11 + uint32 desc_type : 1; // 12 (0 = system, 1 = code/data) + uint32 privilege_level : 2; // 13 - 14 + uint32 present : 1; // 15 + uint32 limit_19_16 : 4; // 16 - 19 + uint32 available : 1; // 20 + uint32 zero : 1; // 21 + uint32 d_b : 1; // 22 + uint32 granularity : 1; // 23 + uint32 base_31_24 : 8; // 24 - 31 +} segment_descriptor; + +enum descriptor_privilege_levels { + DPL_KERNEL = 0, + DPL_USER = 3, +}; + +enum descriptor_types { + // segment types + DT_CODE_EXECUTE_ONLY = 0x8, + DT_CODE_ACCESSED = 0x9, + DT_CODE_READABLE = 0xa, + DT_CODE_CONFORM = 0xc, + DT_DATA_READ_ONLY = 0x0, + DT_DATA_ACCESSED = 0x1, + DT_DATA_WRITEABLE = 0x2, + DT_DATA_EXPANSION_DOWN = 0x4, + + DT_TSS = 9, + + // descriptor types + DT_SYSTEM_SEGMENT = 0, + DT_CODE_DATA_SEGMENT = 1, +}; + +static inline void +clear_segment_descriptor(struct segment_descriptor *desc) +{ + *(long long *)desc = 0; +} + + +static inline void +set_segment_descriptor_base(struct segment_descriptor *desc, addr base) +{ + desc->base_00_15 = (addr)base & 0xffff; // base is 32 bits long + desc->base_23_16 = ((addr)base >> 16) & 0xff; + desc->base_31_24 = ((addr)base >> 24) & 0xff; +} + + +static inline void +set_segment_descriptor(struct segment_descriptor *desc, addr base, uint32 limit, + uint8 type, uint8 privilegeLevel) +{ + set_segment_descriptor_base(desc, base); + + desc->limit_00_15 = (addr)limit & 0x0ffff; // limit is 20 bits long + desc->limit_19_16 = ((addr)limit >> 16) & 0xf; + + desc->type = type; + desc->desc_type = DT_CODE_DATA_SEGMENT; + desc->privilege_level = privilegeLevel; + + desc->present = 1; + desc->granularity = 1; // 4 GB size (in page size steps) + desc->available = 0; // system available bit is currently not used + desc->d_b = 1; + + desc->zero = 0; +} + + +static inline void +set_tss_descriptor(struct segment_descriptor *desc, addr base, uint32 limit) +{ + // the TSS descriptor has a special layout different from the standard descriptor + set_segment_descriptor_base(desc, base); + + desc->limit_00_15 = (addr)limit & 0x0ffff; + desc->limit_19_16 = 0; + + desc->type = DT_TSS; + desc->desc_type = DT_SYSTEM_SEGMENT; + desc->privilege_level = DPL_KERNEL; + + desc->present = 1; + desc->granularity = 1; // 4 GB size (in page size steps) + desc->available = 0; // system available bit is currently not used + desc->d_b = 0; + + desc->zero = 0; +} + +#endif /* _ASSEMBLER */ + +#endif /* _KERNEL_ARCH_x86_DESCRIPTORS_H */ diff --git a/headers/private/kernel/arch/x86/stage2_priv.h b/headers/private/kernel/arch/x86/stage2_priv.h index b27030ccef..11713a7195 100755 --- a/headers/private/kernel/arch/x86/stage2_priv.h +++ b/headers/private/kernel/arch/x86/stage2_priv.h @@ -39,6 +39,11 @@ void cpuid(unsigned int selector, unsigned int *data); #define SCREEN_HEIGHT 24 #define ADDR_MASK 0xfffff000 +struct gdt_idt_descr { + unsigned short a; + unsigned int *b; +} _PACKED; + // SMP stuff extern int smp_boot(kernel_args *ka, unsigned int kernel_entry); extern void smp_trampoline(void);