2022-01-24 15:10:38 +00:00
/**
* @ file gate . h
* @ author longjin
* @ brief 门 定 义
* @ date 2022 - 01 - 24
2022-04-05 06:40:26 +00:00
*
2022-01-24 15:10:38 +00:00
*/
2022-04-06 07:06:51 +00:00
# ifndef __GATE_H__
# define __GATE_H__
# include "../common/kprint.h"
2022-04-10 13:30:16 +00:00
# include <mm/mm.h>
2022-01-24 15:10:38 +00:00
2022-01-25 10:04:18 +00:00
//描述符表的结构体
struct desc_struct
{
unsigned char x [ 8 ] ;
} ;
//门的结构体
struct gate_struct
{
unsigned char x [ 16 ] ;
} ;
2022-04-05 06:40:26 +00:00
extern struct desc_struct GDT_Table [ ] ; // GDT_Table是head.S中的GDT_Table
extern struct gate_struct IDT_Table [ ] ; // IDT_Table是head.S中的IDT_Table
2022-04-13 09:58:06 +00:00
//extern unsigned int TSS64_Table[26];
2022-01-24 15:10:38 +00:00
2022-04-10 13:30:16 +00:00
struct gdtr
{
uint16_t size ;
uint64_t gdt_vaddr ;
} __attribute__ ( ( packed ) ) ;
struct idtr
{
uint16_t size ;
uint64_t idt_vaddr ;
} __attribute__ ( ( packed ) ) ;
2022-01-24 15:10:38 +00:00
/**
* @ brief 初 始 化 中 段 描 述 符 表 内 的 门 描 述 符 ( 每 个 16 B )
* @ param gate_selector_addr IDT表项的地址
* @ param attr P 、 DPL 、 TYPE的属性
* @ param ist 中 断 栈 表 号
2022-01-26 10:04:33 +00:00
* @ param code_addr 指 向 中 断 服 务 程 序 的 指 针 的 地 址
2022-01-24 15:10:38 +00:00
*/
2022-02-12 14:14:51 +00:00
2022-01-26 10:04:33 +00:00
void set_gate ( ul * gate_selector_addr , ul attr , unsigned char ist , ul * code_addr )
{
2022-04-05 06:40:26 +00:00
ul __d0 = 0 , __d1 = 0 ;
2022-01-26 10:04:33 +00:00
ul tmp_code_addr = * code_addr ;
__d0 = attr < < 40 ; //设置P、DPL、Type
__d0 | = ( ( ul ) ( ist ) < < 32 ) ; // 设置ist
__d0 | = 8 < < 16 ; //设置段选择子为0x1000
__d0 | = ( 0xffff & tmp_code_addr ) ; //设置段内偏移的[15:00]
tmp_code_addr > > = 16 ;
__d0 | = ( 0xffff & tmp_code_addr ) < < 48 ; // 设置段内偏移[31:16]
tmp_code_addr > > = 16 ;
__d1 = ( 0xffffffff & tmp_code_addr ) ; //设置段内偏移[63:32]
* gate_selector_addr = __d0 ;
* ( gate_selector_addr + 1 ) = __d1 ;
}
2022-01-25 10:04:18 +00:00
2022-04-06 07:06:51 +00:00
# define _set_gate(gate_selector_addr, attr, ist, code_addr) \
do \
{ \
unsigned long __d0 , __d1 ; \
__asm__ __volatile__ ( " movw %%dx, %%ax \n \t " \
" andq $0x7, %%rcx \n \t " \
" addq %4, %%rcx \n \t " \
" shlq $32, %%rcx \n \t " \
" addq %%rcx, %%rax \n \t " \
" xorq %%rcx, %%rcx \n \t " \
" movl %%edx, %%ecx \n \t " \
" shrq $16, %%rcx \n \t " \
" shlq $48, %%rcx \n \t " \
" addq %%rcx, %%rax \n \t " \
" movq %%rax, %0 \n \t " \
" shrq $32, %%rdx \n \t " \
" movq %%rdx, %1 \n \t " \
: " =m " ( * ( ( unsigned long * ) ( gate_selector_addr ) ) ) , \
" =m " ( * ( 1 + ( unsigned long * ) ( gate_selector_addr ) ) ) , " =&a " ( __d0 ) , " =&d " ( __d1 ) \
: " i " ( attr < < 8 ) , \
" 3 " ( ( unsigned long * ) ( code_addr ) ) , " 2 " ( 0x8 < < 16 ) , " c " ( ist ) \
: " memory " ) ; \
} while ( 0 )
2022-04-05 06:40:26 +00:00
void set_tss_descriptor ( unsigned int n , void * addr )
{
2022-02-12 14:14:51 +00:00
2022-04-06 07:06:51 +00:00
unsigned long limit = 103 ;
2022-04-10 13:30:16 +00:00
2022-04-10 15:03:16 +00:00
* ( unsigned long * ) ( phys_2_virt ( GDT_Table + n ) ) = ( limit & 0xffff ) | ( ( ( unsigned long ) addr & 0xffff ) < < 16 ) | ( ( ( ( unsigned long ) addr > > 16 ) & 0xff ) < < 32 ) | ( ( unsigned long ) 0x89 < < 40 ) | ( ( limit > > 16 & 0xf ) < < 48 ) | ( ( ( unsigned long ) addr > > 24 & 0xff ) < < 56 ) ; /////89 is attribute
* ( unsigned long * ) ( phys_2_virt ( GDT_Table + n + 1 ) ) = ( ( ( unsigned long ) addr > > 32 ) & 0xffffffff ) | 0 ;
2022-04-05 06:40:26 +00:00
}
2022-02-12 14:14:51 +00:00
2022-01-25 10:04:18 +00:00
/**
* @ brief 加 载 任 务 状 态 段 寄 存 器
* @ param n TSS基地址在GDT中的第几项
* 左 移 3 位 的 原 因 是 GDT每项占8字节
*/
2022-04-06 07:06:51 +00:00
# define load_TR(n) \
do \
{ \
__asm__ __volatile__ ( " ltr %%ax " : : " a " ( ( n ) < < 3 ) ) ; \
2022-01-25 10:04:18 +00:00
} while ( 0 )
/**
* @ brief 设 置 中 断 门
2022-04-05 06:40:26 +00:00
*
2022-01-25 10:04:18 +00:00
* @ param n 中 断 号
* @ param ist ist
* @ param addr 服 务 程 序 的 地 址
*/
void set_intr_gate ( unsigned int n , unsigned char ist , void * addr )
{
2022-04-10 13:30:16 +00:00
_set_gate ( phys_2_virt ( IDT_Table + n ) , 0x8E , ist , addr ) ; // p=1, DPL=0, type=E
//set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1, DPL=0, type=E
2022-01-25 10:04:18 +00:00
}
/**
* @ brief 设 置 64 位 , DPL = 0 的 陷 阱 门
2022-04-05 06:40:26 +00:00
*
2022-01-25 10:04:18 +00:00
* @ param n 中 断 号
* @ param ist ist
* @ param addr 服 务 程 序 的 地 址
*/
void set_trap_gate ( unsigned int n , unsigned char ist , void * addr )
{
2022-04-06 07:06:51 +00:00
// kdebug("addr=%#018lx", (ul)(addr));
2022-04-10 13:30:16 +00:00
//set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8F, ist, (ul *)(addr)); // p=1, DPL=0, type=F
_set_gate ( phys_2_virt ( IDT_Table + n ) , 0x8F , ist , addr ) ; // p=1, DPL=0, type=F
2022-01-25 10:04:18 +00:00
}
/**
* @ brief 设 置 64 位 , DPL = 3 的 陷 阱 门
2022-04-05 06:40:26 +00:00
*
2022-01-25 10:04:18 +00:00
* @ param n 中 断 号
* @ param ist ist
* @ param addr 服 务 程 序 的 地 址
*/
void set_system_trap_gate ( unsigned int n , unsigned char ist , void * addr )
{
2022-04-06 07:06:51 +00:00
// kdebug("addr=%#018lx", (ul)(addr));
2022-04-10 13:30:16 +00:00
//set_gate((ul *)phys_2_virt(IDT_Table + n), 0xEF, ist, (ul *)(addr)); // p=1, DPL=3, type=F
_set_gate ( phys_2_virt ( IDT_Table + n ) , 0xEF , ist , addr ) ; // p=1, DPL=3, type=F
2022-01-25 10:04:18 +00:00
}
2022-04-10 15:03:16 +00:00
static inline void set_system_intr_gate ( unsigned int n , unsigned char ist , void * addr ) //int3
{
_set_gate ( phys_2_virt ( IDT_Table + n ) , 0xEE , ist , addr ) ; //P,DPL=3,TYPE=E
}
2022-01-25 10:04:18 +00:00
/**
* @ brief 初 始 化 TSS表的内容
2022-04-05 06:40:26 +00:00
*
2022-01-25 10:04:18 +00:00
*/
2022-04-06 10:36:56 +00:00
2022-04-10 13:30:16 +00:00
void set_tss64 ( unsigned int * Table , unsigned long rsp0 , unsigned long rsp1 , unsigned long rsp2 , unsigned long ist1 , unsigned long ist2 , unsigned long ist3 ,
unsigned long ist4 , unsigned long ist5 , unsigned long ist6 , unsigned long ist7 )
2022-01-25 10:04:18 +00:00
{
2022-04-10 13:30:16 +00:00
* ( unsigned long * ) ( Table + 1 ) = rsp0 ;
* ( unsigned long * ) ( Table + 3 ) = rsp1 ;
* ( unsigned long * ) ( Table + 5 ) = rsp2 ;
* ( unsigned long * ) ( Table + 9 ) = ist1 ;
* ( unsigned long * ) ( Table + 11 ) = ist2 ;
* ( unsigned long * ) ( Table + 13 ) = ist3 ;
* ( unsigned long * ) ( Table + 15 ) = ist4 ;
* ( unsigned long * ) ( Table + 17 ) = ist5 ;
* ( unsigned long * ) ( Table + 19 ) = ist6 ;
* ( unsigned long * ) ( Table + 21 ) = ist7 ;
2022-04-06 07:06:51 +00:00
}
# endif