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


001 /* Copyright (C) 2004  David Decotigny            001 /* Copyright (C) 2004  David Decotigny
002    Copyright (C) 2003  Thomas Petazzoni        !! 002    Copyright (C) 1999  Free Software Foundation, Inc.
003                                                   003 
004    This program is free software; you can redi    004    This program is free software; you can redistribute it and/or
005    modify it under the terms of the GNU Genera    005    modify it under the terms of the GNU General Public License
006    as published by the Free Software Foundatio    006    as published by the Free Software Foundation; either version 2
007    of the License, or (at your option) any lat    007    of the License, or (at your option) any later version.
008                                                   008    
009    This program is distributed in the hope tha    009    This program is distributed in the hope that it will be useful,
010    but WITHOUT ANY WARRANTY; without even the     010    but WITHOUT ANY WARRANTY; without even the implied warranty of
011    MERCHANTABILITY or FITNESS FOR A PARTICULAR    011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012    GNU General Public License for more details    012    GNU General Public License for more details.
013                                                   013    
014    You should have received a copy of the GNU     014    You should have received a copy of the GNU General Public License
015    along with this program; if not, write to t    015    along with this program; if not, write to the Free Software
016    Foundation, Inc., 59 Temple Place - Suite 3    016    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
017    USA.                                           017    USA. 
018 */                                                018 */
019 #include "segment.h"                              019 #include "segment.h"
020                                                   020 
021 #include "gdt.h"                                  021 #include "gdt.h"
022                                                   022 
023                                                   023 
024 /**                                               024 /**
025  * The sructure of a segment descriptor.          025  * The sructure of a segment descriptor.
026  *                                                026  *
027  * @see Intel x86 doc, Vol 3, section 3.4.3, f    027  * @see Intel x86 doc, Vol 3, section 3.4.3, figure 3-8. For segment
028  * types, see section 3.5                         028  * types, see section 3.5
029  */                                               029  */
030 struct x86_segment_descriptor                     030 struct x86_segment_descriptor
031 {                                                 031 {
032   /* Lowest dword */                              032   /* Lowest dword */
033   sos_ui16_t limit_15_0;            /* Segment    033   sos_ui16_t limit_15_0;            /* Segment limit, bits 15..0 */
034   sos_ui16_t base_paged_addr_15_0;  /* Base ad    034   sos_ui16_t base_paged_addr_15_0;  /* Base address, bits 15..0 */
035                                                   035 
036   /* Highest dword */                             036   /* Highest dword */
037   sos_ui8_t  base_paged_addr_23_16; /* Base ad    037   sos_ui8_t  base_paged_addr_23_16; /* Base address bits 23..16 */
038   sos_ui8_t  segment_type:4;        /* Section    038   sos_ui8_t  segment_type:4;        /* Section 3.4.3.1 (code/data)
039                                        and 3.5    039                                        and 3.5 (system) of Intel x86 vol 3 */
040   sos_ui8_t  descriptor_type:1;     /* 0=syste    040   sos_ui8_t  descriptor_type:1;     /* 0=system, 1=Code/Data */
041   sos_ui8_t  dpl:2;                 /* Descrip !! 041   sos_ui8_t  dpl:2;
042   sos_ui8_t  present:1;                           042   sos_ui8_t  present:1;
043                                                   043 
044   sos_ui8_t  limit_19_16:4;         /* Segment    044   sos_ui8_t  limit_19_16:4;         /* Segment limit, bits 19..16 */
045   sos_ui8_t  custom:1;                            045   sos_ui8_t  custom:1;
046   sos_ui8_t  zero:1;                              046   sos_ui8_t  zero:1;
047   sos_ui8_t  op_size:1;             /* 0=16bit    047   sos_ui8_t  op_size:1;             /* 0=16bits instructions, 1=32bits */
048   sos_ui8_t  granularity:1;         /* 0=limit    048   sos_ui8_t  granularity:1;         /* 0=limit in bytes, 1=limit in pages */
049                                                   049   
050   sos_ui8_t  base_paged_addr_31_24; /* Base ad    050   sos_ui8_t  base_paged_addr_31_24; /* Base address bits 31..24 */
051 } __attribute__ ((packed, aligned(8)));        !! 051 } __attribute__ ((packed, aligned (8)));
052                                                   052 
053                                                   053 
054 /**                                               054 /**
055  * The GDT register, which stores the address     055  * The GDT register, which stores the address and size of the
056  * GDT.                                           056  * GDT.
057  *                                                057  *
058  * @see Intel x86 doc vol 3, section 2.4, figu    058  * @see Intel x86 doc vol 3, section 2.4, figure 2-4; and section
059  * 3.5.1                                          059  * 3.5.1
060  */                                               060  */
061 struct x86_gdt_register {                         061 struct x86_gdt_register {
062   /** Intel doc says that the real GDT registe !! 062   /* The maximum GDT offset allowed to access an entry in the GDT */
063       should be odd-word aligned. That's why w << 
064       Credits to Romain for having signalled t << 
065   sos_ui16_t  padding;                         << 
066                                                << 
067   /** The maximum GDT offset allowed to access << 
068   sos_ui16_t  limit;                              063   sos_ui16_t  limit;
069                                                !! 064 
070   /**                                          !! 065   /* This is not exactly a "virtual" address, ie an adddress such as
071    * This is not exactly a "virtual" address,  !! 066      those of instructions and data; this is a "linear" address, ie an
072    * those of instructions and data; this is a !! 067      address in the paged memory. However, in SOS we configure the
073    * address in the paged memory. However, in  !! 068      segmented memory as a "flat" space: the 0-4GB segment-based (ie
074    * segmented memory as a "flat" space: the 0 !! 069      "virtual") addresses directly map to the 0-4GB paged memory (ie
075    * "virtual") addresses directly map to the  !! 070      "linear"), so that the "linear" addresses are numerically equal
076    * "linear"), so that the "linear" addresses !! 071      to the "virtual" addresses: this base_addr will thus be the same
077    * to the "virtual" addresses: this base_add !! 072      as the address of the gdt array */
078    * as the address of the gdt array           !! 073   sos_ui32_t base_addr;
079    */                                          !! 074 } __attribute__((packed, aligned(8)));
080     sos_ui32_t base_addr;                      << 
081 } __attribute__((packed, aligned(4)));         << 
082                                                   075 
083                                                   076 
084 /**                                               077 /**
085  * Helper macro that builds a Segment descript    078  * Helper macro that builds a Segment descriptor for the virtual
086  * 0..4GB addresses to be mapped to the linear    079  * 0..4GB addresses to be mapped to the linear 0..4GB linear
087  * addresses.                                     080  * addresses.
088  */                                               081  */
089 #define BUILD_GDTE(descr_privilege_level,is_co    082 #define BUILD_GDTE(descr_privilege_level,is_code)               \
090   ((struct x86_segment_descriptor) {              083   ((struct x86_segment_descriptor) {                            \
091       .limit_15_0=            0xffff,             084       .limit_15_0=            0xffff,                           \
092       .base_paged_addr_15_0=  0,                  085       .base_paged_addr_15_0=  0,                                \
093       .base_paged_addr_23_16= 0,                  086       .base_paged_addr_23_16= 0,                                \
094       .segment_type=          ((is_code)?0xb:0    087       .segment_type=          ((is_code)?0xb:0x3),              \
095              /* With descriptor_type (below) =    088              /* With descriptor_type (below) = 1 (code/data),   \
096               * see Figure 3-1 of section 3.4.    089               * see Figure 3-1 of section 3.4.3.1 in Intel      \
097               * x86 vol 3:                        090               * x86 vol 3:                                      \
098               *   - Code (bit 3 = 1):             091               *   - Code (bit 3 = 1):                           \
099               *     bit 0: 1=Accessed             092               *     bit 0: 1=Accessed                           \
100               *     bit 1: 1=Readable             093               *     bit 1: 1=Readable                           \
101               *     bit 2: 0=Non-Conforming       094               *     bit 2: 0=Non-Conforming                     \
102               *   - Data (bit 3 = 0):             095               *   - Data (bit 3 = 0):                           \
103               *     bit 0: 1=Accessed             096               *     bit 0: 1=Accessed                           \
104               *     bit 1: 1=Writable             097               *     bit 1: 1=Writable                           \
105               *     bit 2: 0=Expand up (stack-    098               *     bit 2: 0=Expand up (stack-related)          \
106               * For Conforming/non conforming     099               * For Conforming/non conforming segments, see     \
107               * Intel x86 Vol 3 section 4.8.1.    100               * Intel x86 Vol 3 section 4.8.1.1                 \
108               */                                  101               */                                                \
109       .descriptor_type=       1,  /* 1=Code/Da    102       .descriptor_type=       1,  /* 1=Code/Data */             \
110       .dpl=                   ((descr_privileg    103       .dpl=                   ((descr_privilege_level) & 0x3),  \
111       .present=               1,                  104       .present=               1,                                \
112       .limit_19_16=           0xf,                105       .limit_19_16=           0xf,                              \
113       .custom=                0,                  106       .custom=                0,                                \
114       .zero=                  0,               << 
115       .op_size=               1,  /* 32 bits i    107       .op_size=               1,  /* 32 bits instr/data */      \
116       .granularity=           1,  /* limit is  !! 108       .granularity=           1   /* limit is in 4kB Pages */   \
117       .base_paged_addr_31_24= 0                << 
118   })                                              109   })
119                                                   110 
120                                                   111 
121 /** The actual GDT */                             112 /** The actual GDT */
122 static struct x86_segment_descriptor gdt[] = {    113 static struct x86_segment_descriptor gdt[] = {
123   [SOS_SEG_NULL]  = (struct x86_segment_descri    114   [SOS_SEG_NULL]  = (struct x86_segment_descriptor){ 0, },
124   [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),             115   [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),
125   [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),             116   [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),
126   [SOS_SEG_UCODE] = BUILD_GDTE(3, 1),          << 
127   [SOS_SEG_UDATA] = BUILD_GDTE(3, 0),          << 
128   [SOS_SEG_KERNEL_TSS] = { 0, } /* Initialized << 
129                                    register_ke << 
130 };                                                117 };
131                                                   118 
132                                                << 
133 sos_ret_t sos_gdt_subsystem_setup(void)           119 sos_ret_t sos_gdt_subsystem_setup(void)
134 {                                                 120 {
135   struct x86_gdt_register gdtr;                   121   struct x86_gdt_register gdtr;
136                                                   122 
137   /* Put some garbage in the padding field of  << 
138   gdtr.padding   = ~0;                         << 
139                                                << 
140   /* Address of the GDT */                        123   /* Address of the GDT */
141   gdtr.base_addr = (sos_ui32_t) gdt;              124   gdtr.base_addr = (sos_ui32_t) gdt;
142                                                   125 
143   /* The limit is the maximum offset in bytes     126   /* The limit is the maximum offset in bytes from the base address of
144      the GDT */                                   127      the GDT */
145   gdtr.limit     = sizeof(gdt) - 1;               128   gdtr.limit     = sizeof(gdt) - 1;
146                                                   129 
147   /* Commit the GDT into the CPU, and update t    130   /* Commit the GDT into the CPU, and update the segment
148      registers. The CS register may only be up    131      registers. The CS register may only be updated with a long jump
149      to an absolute address in the given segme    132      to an absolute address in the given segment (see Intel x86 doc
150      vol 3, section 4.8.1). */                    133      vol 3, section 4.8.1). */
151   asm volatile ("lgdt %0          \n\             134   asm volatile ("lgdt %0          \n\
152                  ljmp %1,$1f      \n\             135                  ljmp %1,$1f      \n\
153                  1:               \n\             136                  1:               \n\
154                  movw %2, %%ax    \n\             137                  movw %2, %%ax    \n\
155                  movw %%ax,  %%ss \n\             138                  movw %%ax,  %%ss \n\
156                  movw %%ax,  %%ds \n\             139                  movw %%ax,  %%ds \n\
157                  movw %%ax,  %%es \n\             140                  movw %%ax,  %%es \n\
158                  movw %%ax,  %%fs \n\             141                  movw %%ax,  %%fs \n\
159                  movw %%ax,  %%gs"                142                  movw %%ax,  %%gs"
160                 :                                 143                 :
161                 :"m"(gdtr.limit) /* The real b !! 144                 :"m"(gdtr),
162                                     register i << 
163                                     field, ie  << 
164                                     field. */, << 
165                  "i"(SOS_BUILD_SEGMENT_REG_VAL    145                  "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE)),
166                  "i"(SOS_BUILD_SEGMENT_REG_VAL    146                  "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA))
167                 :"memory","eax");                 147                 :"memory","eax");
168                                                   148 
169   return SOS_OK;                                  149   return SOS_OK;
170 }                                                 150 }
171                                                << 
172                                                << 
173 sos_ret_t sos_gdt_register_kernel_tss(sos_vadd << 
174 {                                              << 
175   sos_ui16_t regval_tss;                       << 
176                                                << 
177   /* Initialize the GDT entry */               << 
178   gdt[SOS_SEG_KERNEL_TSS]                      << 
179     = (struct x86_segment_descriptor) {        << 
180       .limit_15_0=            0x67, /* See Int << 
181       .base_paged_addr_15_0=  (tss_vaddr) & 0x << 
182       .base_paged_addr_23_16= (tss_vaddr >> 16 << 
183       .segment_type=          0x9,  /* See Int << 
184       .descriptor_type=       0,    /* (idem)  << 
185       .dpl=                   3,    /* Allowed << 
186       .present=               1,               << 
187       .limit_19_16=           0,    /* Size of << 
188       .custom=                0,    /* Unused  << 
189       .zero=                  0,               << 
190       .op_size=               0,    /* See Int << 
191       .granularity=           1,    /* limit i << 
192       .base_paged_addr_31_24= (tss_vaddr >> 24 << 
193     };                                         << 
194                                                << 
195   /* Load the TSS register into the processor  << 
196   regval_tss = SOS_BUILD_SEGMENT_REG_VALUE(0,  << 
197                                            SOS << 
198   asm ("ltr %0" : :"r"(regval_tss));           << 
199                                                << 
200   return SOS_OK;                               << 
201 }                                              << 
202                                                << 
203                                                << 
                                                      

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