Diff markup
001 001
002 <<
003 002
004 003
005 004
006 005
007 006
008 007
009 008
010 009
011 010
012 011
013 012
014 013
015 014
016 015
017 016
018 017
019 #include "segment.h" 018 #include "segment.h"
020 019
021 #include "idt.h" 020 #include "idt.h"
022 021
023 022
024 023
025 024
026 025
027 026
028 027
029 028
030 struct x86_idt_entry 029 struct x86_idt_entry
031 { 030 {
032 031
033 sos_ui16_t offset_low; 032 sos_ui16_t offset_low;
034 sos_ui16_t seg_sel; 033 sos_ui16_t seg_sel;
035 034
036 035
037 sos_ui8_t reserved:5; 036 sos_ui8_t reserved:5;
038 sos_ui8_t flags:3; 037 sos_ui8_t flags:3;
039 sos_ui8_t type:3; 038 sos_ui8_t type:3;
040 sos_ui8_t op_size:1; 039 sos_ui8_t op_size:1;
041 sos_ui8_t zero:1; 040 sos_ui8_t zero:1;
042 sos_ui8_t dpl:2; 041 sos_ui8_t dpl:2;
043 sos_ui8_t present:1; 042 sos_ui8_t present:1;
044 sos_ui16_t offset_high; 043 sos_ui16_t offset_high;
045 } __attribute__((packed)); 044 } __attribute__((packed));
046 045
047 046
048 047
049 048
050 049
051 050
052 051
053 052
054 struct x86_idt_register 053 struct x86_idt_register
055 { 054 {
056 055
057 sos_ui16_t limit; 056 sos_ui16_t limit;
058 057
059 058
060 059
061 060
062 061
063 062
064 063
065 064
066 065
067 sos_ui32_t base_addr; 066 sos_ui32_t base_addr;
068 } __attribute__((packed, aligned (8))); 067 } __attribute__((packed, aligned (8)));
069 068
070 069
071 static struct x86_idt_entry idt[SOS_IDTE_NU 070 static struct x86_idt_entry idt[SOS_IDTE_NUM];
072 071
073 sos_ret_t sos_idt_setup() !! 072 sos_ret_t sos_idt_subsystem_setup()
074 { 073 {
075 struct x86_idt_register idtr; 074 struct x86_idt_register idtr;
076 int i; 075 int i;
077 076
078 for (i = 0 ; 077 for (i = 0 ;
079 i < SOS_IDTE_NUM ; 078 i < SOS_IDTE_NUM ;
080 i++) 079 i++)
081 { 080 {
082 struct x86_idt_entry *idte = idt + i; 081 struct x86_idt_entry *idte = idt + i;
083 082
084 083
085 084
086 idte->seg_sel = SOS_BUILD_SEGMENT_REG_ 085 idte->seg_sel = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE);
087 idte->reserved = 0; 086 idte->reserved = 0;
088 idte->flags = 0; 087 idte->flags = 0;
089 idte->type = 0x6; 088 idte->type = 0x6;
090 idte->op_size = 1; 089 idte->op_size = 1;
091 idte->zero = 0; 090 idte->zero = 0;
092 091
093 092
094 sos_idt_set_handler(i, (sos_vaddr_t)NULL 093 sos_idt_set_handler(i, (sos_vaddr_t)NULL, 0);
095 } 094 }
096 095
097 096
098 097
099 098
100 099
101 100
102 idtr.base_addr = (sos_ui32_t) idt; 101 idtr.base_addr = (sos_ui32_t) idt;
103 102
104 103
105 104
106 idtr.limit = sizeof(idt) - 1; 105 idtr.limit = sizeof(idt) - 1;
107 106
108 107
109 asm volatile ("lidt %0\n"::"m"(idtr):"memory 108 asm volatile ("lidt %0\n"::"m"(idtr):"memory");
110 109
111 return SOS_OK; 110 return SOS_OK;
112 } 111 }
113 112
114 113
115 sos_ret_t sos_idt_set_handler(int index, 114 sos_ret_t sos_idt_set_handler(int index,
116 sos_vaddr_t hand 115 sos_vaddr_t handler_address,
117 int lowest_privi 116 int lowest_priviledge )
118 { 117 {
119 struct x86_idt_entry *idte; 118 struct x86_idt_entry *idte;
120 119
121 if ((index < 0) || (index >= SOS_IDTE_NUM)) 120 if ((index < 0) || (index >= SOS_IDTE_NUM))
122 return -SOS_EINVAL; 121 return -SOS_EINVAL;
123 if ((lowest_priviledge < 0) || (lowest_privi 122 if ((lowest_priviledge < 0) || (lowest_priviledge > 3))
124 return -SOS_EINVAL; 123 return -SOS_EINVAL;
125 124
126 idte = idt + index; 125 idte = idt + index;
127 if (handler_address != (sos_vaddr_t)NULL) 126 if (handler_address != (sos_vaddr_t)NULL)
128 { 127 {
129 idte->offset_low = handler_address & 0x 128 idte->offset_low = handler_address & 0xffff;
130 idte->offset_high = (handler_address >> 129 idte->offset_high = (handler_address >> 16) & 0xffff;
131 idte->dpl = lowest_priviledge; 130 idte->dpl = lowest_priviledge;
132 idte->present = 1; 131 idte->present = 1;
133 } 132 }
134 else 133 else
135 { 134 {
136 idte->offset_low = 0; 135 idte->offset_low = 0;
137 idte->offset_high = 0; 136 idte->offset_high = 0;
138 idte->dpl = 0; 137 idte->dpl = 0;
139 idte->present = 0; 138 idte->present = 0;
140 } 139 }
141 140
142 return SOS_OK; 141 return SOS_OK;
143 } 142 }
144 143
145 144
146 sos_ret_t sos_idt_get_handler(int index, 145 sos_ret_t sos_idt_get_handler(int index,
147 sos_vaddr_t *han 146 sos_vaddr_t *handler_address,
148 int *lowest_priv 147 int *lowest_priviledge)
149 { 148 {
150 if ((index < 0) || (index >= SOS_IDTE_NUM)) 149 if ((index < 0) || (index >= SOS_IDTE_NUM))
151 return -SOS_EINVAL; 150 return -SOS_EINVAL;
152 151
153 if (handler_address != NULL) 152 if (handler_address != NULL)
154 *handler_address = idt[index].offset_low 153 *handler_address = idt[index].offset_low
155 | (idt[index].offset_hi 154 | (idt[index].offset_high << 16);
156 if (lowest_priviledge != NULL) 155 if (lowest_priviledge != NULL)
157 *lowest_priviledge = idt[index].dpl; 156 *lowest_priviledge = idt[index].dpl;
158 157
159 return SOS_OK; 158 return SOS_OK;
160 } 159 }