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 7) and /hwcore/idt.c (Article 6)


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

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