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