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


001 /* Copyright (C) 2004  David Decotigny            001 /* Copyright (C) 2004  David Decotigny
002    Copyright (C) 1999  Free Software Foundatio    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;                               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   /* The maximum GDT offset allowed to access     062   /* The maximum GDT offset allowed to access an entry in the GDT */
063   sos_ui16_t  limit;                              063   sos_ui16_t  limit;
064                                                   064 
065   /* This is not exactly a "virtual" address,     065   /* This is not exactly a "virtual" address, ie an adddress such as
066      those of instructions and data; this is a    066      those of instructions and data; this is a "linear" address, ie an
067      address in the paged memory. However, in     067      address in the paged memory. However, in SOS we configure the
068      segmented memory as a "flat" space: the 0    068      segmented memory as a "flat" space: the 0-4GB segment-based (ie
069      "virtual") addresses directly map to the     069      "virtual") addresses directly map to the 0-4GB paged memory (ie
070      "linear"), so that the "linear" addresses    070      "linear"), so that the "linear" addresses are numerically equal
071      to the "virtual" addresses: this base_add    071      to the "virtual" addresses: this base_addr will thus be the same
072      as the address of the gdt array */           072      as the address of the gdt array */
073   sos_ui32_t base_addr;                           073   sos_ui32_t base_addr;
074 } __attribute__((packed, aligned(8)));            074 } __attribute__((packed, aligned(8)));
075                                                   075 
076                                                   076 
077 /**                                               077 /**
078  * Helper macro that builds a Segment descript    078  * Helper macro that builds a Segment descriptor for the virtual
079  * 0..4GB addresses to be mapped to the linear    079  * 0..4GB addresses to be mapped to the linear 0..4GB linear
080  * addresses.                                     080  * addresses.
081  */                                               081  */
082 #define BUILD_GDTE(descr_privilege_level,is_co    082 #define BUILD_GDTE(descr_privilege_level,is_code)               \
083   ((struct x86_segment_descriptor) {              083   ((struct x86_segment_descriptor) {                            \
084       .limit_15_0=            0xffff,             084       .limit_15_0=            0xffff,                           \
085       .base_paged_addr_15_0=  0,                  085       .base_paged_addr_15_0=  0,                                \
086       .base_paged_addr_23_16= 0,                  086       .base_paged_addr_23_16= 0,                                \
087       .segment_type=          ((is_code)?0xb:0    087       .segment_type=          ((is_code)?0xb:0x3),              \
088              /* With descriptor_type (below) =    088              /* With descriptor_type (below) = 1 (code/data),   \
089               * see Figure 3-1 of section 3.4.    089               * see Figure 3-1 of section 3.4.3.1 in Intel      \
090               * x86 vol 3:                        090               * x86 vol 3:                                      \
091               *   - Code (bit 3 = 1):             091               *   - Code (bit 3 = 1):                           \
092               *     bit 0: 1=Accessed             092               *     bit 0: 1=Accessed                           \
093               *     bit 1: 1=Readable             093               *     bit 1: 1=Readable                           \
094               *     bit 2: 0=Non-Conforming       094               *     bit 2: 0=Non-Conforming                     \
095               *   - Data (bit 3 = 0):             095               *   - Data (bit 3 = 0):                           \
096               *     bit 0: 1=Accessed             096               *     bit 0: 1=Accessed                           \
097               *     bit 1: 1=Writable             097               *     bit 1: 1=Writable                           \
098               *     bit 2: 0=Expand up (stack-    098               *     bit 2: 0=Expand up (stack-related)          \
099               * For Conforming/non conforming     099               * For Conforming/non conforming segments, see     \
100               * Intel x86 Vol 3 section 4.8.1.    100               * Intel x86 Vol 3 section 4.8.1.1                 \
101               */                                  101               */                                                \
102       .descriptor_type=       1,  /* 1=Code/Da    102       .descriptor_type=       1,  /* 1=Code/Data */             \
103       .dpl=                   ((descr_privileg    103       .dpl=                   ((descr_privilege_level) & 0x3),  \
104       .present=               1,                  104       .present=               1,                                \
105       .limit_19_16=           0xf,                105       .limit_19_16=           0xf,                              \
106       .custom=                0,                  106       .custom=                0,                                \
107       .op_size=               1,  /* 32 bits i    107       .op_size=               1,  /* 32 bits instr/data */      \
108       .granularity=           1   /* limit is     108       .granularity=           1   /* limit is in 4kB Pages */   \
109   })                                              109   })
110                                                   110 
111                                                   111 
112 /** The actual GDT */                             112 /** The actual GDT */
113 static struct x86_segment_descriptor gdt[] = {    113 static struct x86_segment_descriptor gdt[] = {
114   [SOS_SEG_NULL]  = (struct x86_segment_descri    114   [SOS_SEG_NULL]  = (struct x86_segment_descriptor){ 0, },
115   [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),             115   [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),
116   [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),             116   [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),
117 };                                                117 };
118                                                   118 
119 sos_ret_t sos_gdt_setup(void)                     119 sos_ret_t sos_gdt_setup(void)
120 {                                                 120 {
121   struct x86_gdt_register gdtr;                   121   struct x86_gdt_register gdtr;
122                                                   122 
123   /* Address of the GDT */                        123   /* Address of the GDT */
124   gdtr.base_addr = (sos_ui32_t) gdt;              124   gdtr.base_addr = (sos_ui32_t) gdt;
125                                                   125 
126   /* The limit is the maximum offset in bytes     126   /* The limit is the maximum offset in bytes from the base address of
127      the GDT */                                   127      the GDT */
128   gdtr.limit     = sizeof(gdt) - 1;               128   gdtr.limit     = sizeof(gdt) - 1;
129                                                   129 
130   /* Commit the GDT into the CPU, and update t    130   /* Commit the GDT into the CPU, and update the segment
131      registers. The CS register may only be up    131      registers. The CS register may only be updated with a long jump
132      to an absolute address in the given segme    132      to an absolute address in the given segment (see Intel x86 doc
133      vol 3, section 4.8.1). */                    133      vol 3, section 4.8.1). */
134   asm volatile ("lgdt %0          \n\             134   asm volatile ("lgdt %0          \n\
135                  ljmp %1,$1f      \n\             135                  ljmp %1,$1f      \n\
136                  1:               \n\             136                  1:               \n\
137                  movw %2, %%ax    \n\             137                  movw %2, %%ax    \n\
138                  movw %%ax,  %%ss \n\             138                  movw %%ax,  %%ss \n\
139                  movw %%ax,  %%ds \n\             139                  movw %%ax,  %%ds \n\
140                  movw %%ax,  %%es \n\             140                  movw %%ax,  %%es \n\
141                  movw %%ax,  %%fs \n\             141                  movw %%ax,  %%fs \n\
142                  movw %%ax,  %%gs"                142                  movw %%ax,  %%gs"
143                 :                                 143                 :
144                 :"m"(gdtr),                       144                 :"m"(gdtr),
145                  "i"(SOS_BUILD_SEGMENT_REG_VAL    145                  "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE)),
146                  "i"(SOS_BUILD_SEGMENT_REG_VAL    146                  "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA))
147                 :"memory","eax");                 147                 :"memory","eax");
148                                                   148 
149   return SOS_OK;                                  149   return SOS_OK;
150 }                                                 150 }
                                                      

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