2018-09-28 20:35:51 +02:00
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hord<72> Nicolas */
/* */
2018-08-31 02:48:03 +02:00
# include "gdt.h"
# include "asm.h"
# include "types.h"
2018-10-02 02:16:14 +02:00
# include "memory.h"
2018-08-31 02:48:03 +02:00
2018-09-01 22:58:05 +02:00
/* registre gdt */
static struct gdtr gdtreg ;
/* table de GDT */
2018-10-02 02:16:14 +02:00
static gdtdes gdt [ GDT_SIZE ] ;
2018-09-01 22:58:05 +02:00
2018-09-18 15:11:50 +02:00
/* TSS */
static struct tss tss0 ;
2018-08-31 02:48:03 +02:00
/*******************************************************************************/
/* Initialise la GDT */
2018-09-17 18:17:11 +02:00
void initgdt ( u32 offset )
2018-08-31 02:48:03 +02:00
{
2018-09-27 17:47:27 +02:00
makegdtdes ( 0x0 , 0x00000 , 0x00 , 0x00 , & gdt [ 0 ] ) ; /* descripteur nul */
2018-10-02 02:16:14 +02:00
makegdtdes ( 0x0 , 0xFFFFF , SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING0 | SEG_READ | SEG_ACCESSED , GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE , & gdt [ 1 ] ) ; /* code -> SEL_KERNEL_CODE */
makegdtdes ( 0x0 , 0x00000 , SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED , GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE , & gdt [ 2 ] ) ; /* pile -> SEL_KERNEL_STACK */
makegdtdes ( 0x0 , 0xFFFFF , SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING3 | SEG_CONFORMING | SEG_READ | SEG_ACCESSED , GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE , & gdt [ 3 ] ) ; /* code -> SEL_USER_CODE */
makegdtdes ( 0x0 , 0x00000 , SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED , GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE , & gdt [ 4 ] ) ; /* pile -> SEL_USER_STACK */
makegdtdes ( 0x0 , 0xFFFFF , SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_READ_WRITE | SEG_ACCESSED , GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE , & gdt [ 5 ] ) ; /* data -> SEL_KERNEL_DATA */
makegdtdes ( 0x0 , 0xFFFFF , SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_READ_WRITE | SEG_ACCESSED , GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE , & gdt [ 6 ] ) ; /* data -> SEL_USER_DATA */
2018-09-18 14:29:35 +02:00
2018-09-18 15:11:50 +02:00
tss0 . trapflag = 0x00 ;
tss0 . iomap = 0x00 ;
tss0 . esp0 = 0x1FFF0 ;
tss0 . ss0 = SEL_TSS ;
2018-10-02 02:16:14 +02:00
makegdtdes ( & tss0 , 0x67 , SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED , 0x00 , & gdt [ 7 ] ) ; /* descripteur de tss */
2018-09-18 15:11:50 +02:00
2018-09-01 22:58:05 +02:00
/* initialise le registre gdt */
2018-10-02 02:16:14 +02:00
gdtreg . limite = GDT_SIZE * 8 ;
gdtreg . base = GDT_ADDR ;
2018-09-01 22:58:05 +02:00
/* recopie de la GDT a son adresse */
memcpy ( & gdt , ( u8 * ) gdtreg . base , gdtreg . limite , 1 ) ;
/* chargement du registre GDT */
lgdt ( & gdtreg ) ;
/* initialisation des segments */
2018-09-17 18:17:11 +02:00
initselectors ( offset ) ;
}
/*******************************************************************************/
2018-09-18 15:11:50 +02:00
/* Initialise le registre de t<> che (TSR) */
2018-09-27 17:47:27 +02:00
void inittr ( void )
2018-09-18 15:11:50 +02:00
{
2018-09-27 17:47:27 +02:00
ltr ( SEL_TSS ) ;
2018-09-18 15:11:50 +02:00
}
/*******************************************************************************/
2018-09-17 18:17:11 +02:00
/* Initialise les selecteurs avec la GDT */
void initselectors ( u32 executingoffset )
{
2018-09-27 17:47:27 +02:00
asm ( " movw %[data], %%ax \n \
2018-09-17 18:17:11 +02:00
movw % % ax , % % ds \ n \
movw % % ax , % % es \ n \
movw % % ax , % % fs \ n \
movw % % ax , % % gs \ n \
movl % [ offset ] , % % ebx \ n \
movw % [ stack ] , % % ax \ n \
movw % % ax , % % ss \ n \
movl % [ stackoff ] , % % esp \ n \
ljmp % [ code ] , $ raz \ n \
2018-09-01 22:58:05 +02:00
raz : \ n \
2018-09-17 18:17:11 +02:00
pushl % % ebx \ n \
2018-10-02 02:16:14 +02:00
ret \ n " ::[data] " i " (SEL_KERNEL_DATA),[code] " i " (SEL_KERNEL_CODE),[stack] " i " (SEL_KERNEL_STACK),[stackoff] " i " (KERNEL_STACK_ADDR),[offset] " m " (executingoffset));
2018-08-31 02:48:03 +02:00
}
/*******************************************************************************/
/* Cr<43> <72> un descripteur GDT */
2018-09-27 17:47:27 +02:00
void makegdtdes ( u32 base , u32 limite , u8 acces , u8 flags , gdtdes * desc )
2018-08-31 02:48:03 +02:00
{
2018-09-27 17:47:27 +02:00
desc - > lim0_15 = ( limite & 0xffff ) ;
desc - > base0_15 = ( base & 0xffff ) ;
desc - > base16_23 = ( base & 0xff0000 ) > > 16 ;
desc - > acces = acces ;
desc - > lim16_19 = ( limite & 0xf0000 ) > > 16 ;
desc - > flags = ( flags & 0xf ) ;
desc - > base24_31 = ( base & 0xff000000 ) > > 24 ;
return ;
2018-08-31 02:48:03 +02:00
}