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
This commit is contained in:
Axel Dörfler 2003-01-06 08:02:44 +00:00
parent 5c339b0237
commit 7208e95f0e
4 changed files with 128 additions and 38 deletions

View File

@ -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 <arch/cpu.h>
#include <arch/x86/thread_struct.h>
#include <arch/x86/descriptors.h>
@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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);