SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /hwcore/idt.c (Article 9) and /hwcore/idt.c (Article 8)


001 /* Copyright (C) 2004  David Decotigny            001 /* Copyright (C) 2004  David Decotigny
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007    
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012    
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA. 
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  * An entry in the IDT, or "IDTE" in the follo    023  * An entry in the IDT, or "IDTE" in the following, ie a reference to
024  * a interrupt/trap routine or a task gate to     024  * a interrupt/trap routine or a task gate to handle the sw/hw
025  * interrupts and exceptions.                     025  * interrupts and exceptions.
026  *                                                026  *
027  * @see figure 5-2, intel x86 doc, vol 3          027  * @see figure 5-2, intel x86 doc, vol 3
028  */                                               028  */
029 struct x86_idt_entry                              029 struct x86_idt_entry
030 {                                                 030 {
031   /* Low dword */                                 031   /* Low dword */
032   sos_ui16_t offset_low;  /* 15..0, offset of     032   sos_ui16_t offset_low;  /* 15..0, offset of the routine in the segment */
033   sos_ui16_t seg_sel;     /* 31..16, the ID of    033   sos_ui16_t seg_sel;     /* 31..16, the ID of the segment */
034                                                   034 
035   /* High dword */                                035   /* High dword */
036   sos_ui8_t reserved:5;   /* 4..0 */              036   sos_ui8_t reserved:5;   /* 4..0 */
037   sos_ui8_t flags:3;      /* 7..5 */              037   sos_ui8_t flags:3;      /* 7..5 */
038   sos_ui8_t type:3;       /* 10..8 (interrupt     038   sos_ui8_t type:3;       /* 10..8 (interrupt gate, trap gate...) */
039   sos_ui8_t op_size:1;    /* 11 (0=16bits inst    039   sos_ui8_t op_size:1;    /* 11 (0=16bits instructions, 1=32bits instr.) */
040   sos_ui8_t zero:1;       /* 12 */                040   sos_ui8_t zero:1;       /* 12 */
041   sos_ui8_t dpl:2;        /* 14..13 */            041   sos_ui8_t dpl:2;        /* 14..13 */
042   sos_ui8_t present:1;    /* 15 */                042   sos_ui8_t present:1;    /* 15 */
043   sos_ui16_t offset_high; /* 31..16 */            043   sos_ui16_t offset_high; /* 31..16 */
044 } __attribute__((packed));                        044 } __attribute__((packed));
045                                                   045 
046                                                   046 
047 /**                                               047 /**
048  * The IDT register, which stores the address     048  * The IDT register, which stores the address and size of the
049  * IDT.                                           049  * IDT.
050  *                                                050  *
051  * @see Intel x86 doc vol 3, section 2.4, figu    051  * @see Intel x86 doc vol 3, section 2.4, figure 2-4
052  */                                               052  */
053 struct x86_idt_register                           053 struct x86_idt_register
054 {                                                 054 {
055   /* The maximum GDT offset allowed to access     055   /* The maximum GDT offset allowed to access an entry in the GDT */
056   sos_ui16_t  limit;                              056   sos_ui16_t  limit;
057                                                   057 
058   /* This is not exactly a "virtual" address,     058   /* This is not exactly a "virtual" address, ie an adddress such as
059      those of instructions and data; this is a    059      those of instructions and data; this is a "linear" address, ie an
060      address in the paged memory. However, in     060      address in the paged memory. However, in SOS we configure the
061      segmented memory as a "flat" space: the 0    061      segmented memory as a "flat" space: the 0-4GB segment-based (ie
062      "virtual") addresses directly map to the     062      "virtual") addresses directly map to the 0-4GB paged memory (ie
063      "linear"), so that the "linear" addresses    063      "linear"), so that the "linear" addresses are numerically equal
064      to the "virtual" addresses: this base_add    064      to the "virtual" addresses: this base_addr will thus be the same
065      as the address of the gdt array */           065      as the address of the gdt array */
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       /* Setup an empty IDTE interrupt gate, s    083       /* Setup an empty IDTE interrupt gate, see figure 5-2 in Intel
084          x86 doc, vol 3 */                        084          x86 doc, vol 3 */
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; /* Interrupt gate    088       idte->type      = 0x6; /* Interrupt gate (110b) */
089       idte->op_size   = 1;   /* 32bits instruc    089       idte->op_size   = 1;   /* 32bits instructions */
090       idte->zero      = 0;                        090       idte->zero      = 0;
091                                                   091 
092       /* Disable this IDT entry for the moment    092       /* Disable this IDT entry for the moment */
093       sos_idt_set_handler(i, (sos_vaddr_t)NULL    093       sos_idt_set_handler(i, (sos_vaddr_t)NULL, 0/* Don't care */);
094     }                                             094     }
095                                                   095 
096   /*                                              096   /*
097    * Setup the IDT register, see Intel x86 doc    097    * Setup the IDT register, see Intel x86 doc vol 3, section 5.8.
098    */                                             098    */
099                                                   099 
100   /* Address of the IDT */                        100   /* Address of the IDT */
101   idtr.base_addr  = (sos_ui32_t) idt;             101   idtr.base_addr  = (sos_ui32_t) idt;
102                                                   102 
103   /* The limit is the maximum offset in bytes     103   /* The limit is the maximum offset in bytes from the base address of
104      the IDT */                                   104      the IDT */
105   idtr.limit      = sizeof(idt) - 1;              105   idtr.limit      = sizeof(idt) - 1;
106                                                   106 
107   /* Commit the IDT into the CPU */               107   /* Commit the IDT into the CPU */
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 /* 0..3 */)
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;   /* Yes, there i    131       idte->present     = 1;   /* Yes, there is a handler */
132     }                                             132     }
133   else /* Disable this IDT entry */               133   else /* Disable this IDT entry */
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;   /* No, there is    138       idte->present     = 0;   /* No, there is no handler */
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 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]