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