00001
00002
00003 #ifndef gdt_h
00004 #define gdt_h
00005
00006 #include "config_gdt.h"
00007 #include "l4_types.h"
00008 #include "x86desc.h"
00009
00010
00011
00012
00013
00014
00015 class Gdt_entry : public X86desc
00016 {
00017 public:
00018 enum
00019 {
00020 Access_type_user = 0x10,
00021 Access_code_read = 0x1a,
00022 Access_data_write = 0x12,
00023 Size_32 = 0x04,
00024 };
00025
00026 public:
00027 inline Gdt_entry(Address base, Unsigned32 limit, Unsigned8 access, Unsigned8 szbits);
00028
00029 inline Gdt_entry(Unsigned64 raw);
00030
00031 inline Address base();
00032
00033 inline size_t limit();
00034
00035 inline size_t size();
00036
00037 inline int avl();
00038
00039 inline int seg32();
00040
00041 inline int granularity();
00042
00043 inline int writable();
00044
00045 inline int contents();
00046 };
00047
00048
00049 class Gdt
00050 {
00051 public:
00053 enum
00054 {
00055 gdt_tss = GDT_TSS,
00056 gdt_code_kernel = GDT_CODE_KERNEL,
00057 gdt_data_kernel = GDT_DATA_KERNEL,
00058 gdt_code_user = GDT_CODE_USER,
00059 gdt_data_user = GDT_DATA_USER,
00060 gdt_tss_dbf = GDT_TSS_DBF,
00061 gdt_utcb = GDT_UTCB,
00062 gdt_ldt = GDT_LDT,
00063 gdt_tls1 = GDT_TLS1,
00064 gdt_tls2 = GDT_TLS2,
00065 gdt_tls3 = GDT_TLS3,
00066 gdt_max = GDT_MAX,
00067 };
00068
00069 enum
00070 {
00071 Selector_user = 0x03,
00072 Selector_kernel = 0x00,
00073 };
00074
00075 private:
00076 Gdt_entry _entries[];
00077
00078 public:
00079 inline void set_entry_byte(int nr, Address base, Unsigned32 limit, Unsigned8 access, Unsigned8 szbits);
00080
00081 inline void set_entry_4k(int nr, Address base, Unsigned32 limit, Unsigned8 access, Unsigned8 szbits);
00082
00083 inline void set_raw(int nr, Unsigned32 low, Unsigned32 high);
00084
00085 inline void set_raw(int nr, Unsigned64 val);
00086
00087 inline void get_raw(int nr, Unsigned32 *low, Unsigned32 *high);
00088
00089 inline void clear_entry(int nr);
00090
00091 inline Gdt_entry* entries();
00092
00093 static inline void set(Pseudo_descriptor *desc);
00094
00095 static inline void get(Pseudo_descriptor *desc);
00096
00097 static inline int data_segment(bool );
00098 };
00099
00100
00101
00102
00103
00104
00105
00106
00107 inline Gdt_entry::Gdt_entry(Address base, Unsigned32 limit,
00108 Unsigned8 access, Unsigned8 szbits)
00109 {
00110 _data.g._limit_low = limit & 0x0000ffff;
00111 _data.g._base_low = base & 0x0000ffff;
00112 _data.g._base_med = (base & 0x00ff0000) >> 16;
00113 _data.g._access = access | Access_present;
00114 _data.g._limit_high = ((limit & 0x000f0000) >> 16) |
00115 (((Unsigned16)szbits) << 4);
00116 _data.g._base_high = (base & 0xff000000) >> 24;
00117 }
00118
00119
00120
00121 inline Gdt_entry::Gdt_entry(Unsigned64 raw)
00122 : X86desc(raw)
00123 {}
00124
00125
00126
00127 inline Address
00128 Gdt_entry::base()
00129 {
00130 return gdt_entry_base();
00131 }
00132
00133
00134
00135 inline size_t
00136 Gdt_entry::limit()
00137 {
00138 return gdt_entry_limit();
00139 }
00140
00141
00142
00143 inline size_t
00144 Gdt_entry::size()
00145 {
00146 return gdt_entry_size();
00147 }
00148
00149
00150
00151 inline int
00152 Gdt_entry::avl()
00153 {
00154 return (_data.g._limit_high & 0x10) >> 4;
00155 }
00156
00157
00158
00159 inline int
00160 Gdt_entry::seg32()
00161 {
00162 return (_data.g._limit_high & 0x40) >> 6;
00163 }
00164
00165
00166
00167 inline int
00168 Gdt_entry::granularity()
00169 {
00170 return (_data.g._limit_high & 0x80) >> 7;
00171 }
00172
00173
00174
00175 inline int
00176 Gdt_entry::writable()
00177 {
00178 return (type() & 0x02) >> 1;
00179 }
00180
00181
00182
00183 inline int
00184 Gdt_entry::contents()
00185 {
00186 return (type() & 0x0c) >> 2;
00187 }
00188
00189
00190
00191 inline void
00192 Gdt::set_entry_byte(int nr, Address base, Unsigned32 limit,
00193 Unsigned8 access, Unsigned8 szbits)
00194 {
00195 _entries[nr] = Gdt_entry(base, limit, access, szbits);
00196 }
00197
00198
00199
00200 inline void
00201 Gdt::set_entry_4k(int nr, Address base, Unsigned32 limit,
00202 Unsigned8 access, Unsigned8 szbits)
00203 {
00204 _entries[nr] = Gdt_entry(base, limit >> 12, access, szbits | 0x08);
00205 }
00206
00207
00208
00209 inline void
00210 Gdt::set_raw(int nr, Unsigned32 low, Unsigned32 high)
00211 {
00212 _entries[nr].set_raw(low, high);
00213 }
00214
00215
00216
00217 inline void
00218 Gdt::set_raw(int nr, Unsigned64 val)
00219 {
00220 _entries[nr].set_raw(val);
00221 }
00222
00223
00224
00225 inline void
00226 Gdt::get_raw(int nr, Unsigned32 *low, Unsigned32 *high)
00227 {
00228 _entries[nr].get_raw(low, high);
00229 }
00230
00231
00232
00233 inline void
00234 Gdt::clear_entry(int nr)
00235 {
00236 set_raw(nr, 0, 0);
00237 }
00238
00239
00240
00241 inline Gdt_entry*
00242 Gdt::entries()
00243 {
00244 return _entries;
00245 }
00246
00247
00248
00249 inline void
00250 Gdt::set(Pseudo_descriptor *desc)
00251 {
00252 asm volatile ("lgdt %0" : : "m" (*desc));
00253 }
00254
00255
00256
00257 inline void
00258 Gdt::get(Pseudo_descriptor *desc)
00259 {
00260 asm volatile ("sgdt %0" : "=m" (*desc) : : "memory");
00261 }
00262
00263
00264
00265 inline int
00266 Gdt::data_segment(bool )
00267 {
00268 return gdt_data_user | Selector_user;
00269 }
00270
00271 #endif // gdt_h