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 ]

001 /* Copyright (C) 2004  David Decotigny
002    Copyright (C) 1999  Free Software Foundation, Inc.
003 
004    This program is free software; you can redistribute it and/or
005    modify it under the terms of the GNU General Public License
006    as published by the Free Software Foundation; either version 2
007    of the License, or (at your option) any later version.
008    
009    This program is distributed in the hope that it will be useful,
010    but WITHOUT ANY WARRANTY; without even the implied warranty of
011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012    GNU General Public License for more details.
013    
014    You should have received a copy of the GNU General Public License
015    along with this program; if not, write to the Free Software
016    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
017    USA. 
018 */
019 #include "segment.h"
020 
021 #include "gdt.h"
022 
023 
024 /**
025  * The sructure of a segment descriptor.
026  *
027  * @see Intel x86 doc, Vol 3, section 3.4.3, figure 3-8. For segment
028  * types, see section 3.5
029  */
030 struct x86_segment_descriptor
031 {
032   /* Lowest dword */
033   sos_ui16_t limit_15_0;            /* Segment limit, bits 15..0 */
034   sos_ui16_t base_paged_addr_15_0;  /* Base address, bits 15..0 */
035 
036   /* Highest dword */
037   sos_ui8_t  base_paged_addr_23_16; /* Base address bits 23..16 */
038   sos_ui8_t  segment_type:4;        /* Section 3.4.3.1 (code/data)
039                                        and 3.5 (system) of Intel x86 vol 3 */
040   sos_ui8_t  descriptor_type:1;     /* 0=system, 1=Code/Data */
041   sos_ui8_t  dpl:2;
042   sos_ui8_t  present:1;
043 
044   sos_ui8_t  limit_19_16:4;         /* Segment limit, bits 19..16 */
045   sos_ui8_t  custom:1;
046   sos_ui8_t  zero:1;
047   sos_ui8_t  op_size:1;             /* 0=16bits instructions, 1=32bits */
048   sos_ui8_t  granularity:1;         /* 0=limit in bytes, 1=limit in pages */
049   
050   sos_ui8_t  base_paged_addr_31_24; /* Base address bits 31..24 */
051 } __attribute__ ((packed, aligned (8)));
052 
053 
054 /**
055  * The GDT register, which stores the address and size of the
056  * GDT.
057  *
058  * @see Intel x86 doc vol 3, section 2.4, figure 2-4; and section
059  * 3.5.1
060  */
061 struct x86_gdt_register {
062   /* The maximum GDT offset allowed to access an entry in the GDT */
063   sos_ui16_t  limit;
064 
065   /* This is not exactly a "virtual" address, ie an adddress such as
066      those of instructions and data; this is a "linear" address, ie an
067      address in the paged memory. However, in SOS we configure the
068      segmented memory as a "flat" space: the 0-4GB segment-based (ie
069      "virtual") addresses directly map to the 0-4GB paged memory (ie
070      "linear"), so that the "linear" addresses are numerically equal
071      to the "virtual" addresses: this base_addr will thus be the same
072      as the address of the gdt array */
073   sos_ui32_t base_addr;
074 } __attribute__((packed, aligned(8)));
075 
076 
077 /**
078  * Helper macro that builds a Segment descriptor for the virtual
079  * 0..4GB addresses to be mapped to the linear 0..4GB linear
080  * addresses.
081  */
082 #define BUILD_GDTE(descr_privilege_level,is_code)               \
083   ((struct x86_segment_descriptor) {                            \
084       .limit_15_0=            0xffff,                           \
085       .base_paged_addr_15_0=  0,                                \
086       .base_paged_addr_23_16= 0,                                \
087       .segment_type=          ((is_code)?0xb:0x3),              \
088              /* With descriptor_type (below) = 1 (code/data),   \
089               * see Figure 3-1 of section 3.4.3.1 in Intel      \
090               * x86 vol 3:                                      \
091               *   - Code (bit 3 = 1):                           \
092               *     bit 0: 1=Accessed                           \
093               *     bit 1: 1=Readable                           \
094               *     bit 2: 0=Non-Conforming                     \
095               *   - Data (bit 3 = 0):                           \
096               *     bit 0: 1=Accessed                           \
097               *     bit 1: 1=Writable                           \
098               *     bit 2: 0=Expand up (stack-related)          \
099               * For Conforming/non conforming segments, see     \
100               * Intel x86 Vol 3 section 4.8.1.1                 \
101               */                                                \
102       .descriptor_type=       1,  /* 1=Code/Data */             \
103       .dpl=                   ((descr_privilege_level) & 0x3),  \
104       .present=               1,                                \
105       .limit_19_16=           0xf,                              \
106       .custom=                0,                                \
107       .op_size=               1,  /* 32 bits instr/data */      \
108       .granularity=           1   /* limit is in 4kB Pages */   \
109   })
110 
111 
112 /** The actual GDT */
113 static struct x86_segment_descriptor gdt[] = {
114   [SOS_SEG_NULL]  = (struct x86_segment_descriptor){ 0, },
115   [SOS_SEG_KCODE] = BUILD_GDTE(0, 1),
116   [SOS_SEG_KDATA] = BUILD_GDTE(0, 0),
117 };
118 
119 sos_ret_t sos_gdt_setup(void)
120 {
121   struct x86_gdt_register gdtr;
122 
123   /* Address of the GDT */
124   gdtr.base_addr = (sos_ui32_t) gdt;
125 
126   /* The limit is the maximum offset in bytes from the base address of
127      the GDT */
128   gdtr.limit     = sizeof(gdt) - 1;
129 
130   /* Commit the GDT into the CPU, and update the segment
131      registers. The CS register may only be updated with a long jump
132      to an absolute address in the given segment (see Intel x86 doc
133      vol 3, section 4.8.1). */
134   asm volatile ("lgdt %0          \n\
135                  ljmp %1,$1f      \n\
136                  1:               \n\
137                  movw %2, %%ax    \n\
138                  movw %%ax,  %%ss \n\
139                  movw %%ax,  %%ds \n\
140                  movw %%ax,  %%es \n\
141                  movw %%ax,  %%fs \n\
142                  movw %%ax,  %%gs"
143                 :
144                 :"m"(gdtr),
145                  "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE)),
146                  "i"(SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA))
147                 :"memory","eax");
148 
149   return SOS_OK;
150 }

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