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