00001
00002
00003 #ifndef x86desc_h
00004 #define x86desc_h
00005
00006 #include "l4_types.h"
00007
00008
00009
00010
00011
00012
00013 class X86desc
00014 {
00015 public:
00016 enum
00017 {
00018 Accessed = 0x01,
00019 Access_kernel = 0x00,
00020 Access_user = 0x60,
00021 Access_present = 0x80,
00022
00023 Access_tss = 0x09,
00024 Access_intr_gate = 0x0e,
00025 Access_trap_gate = 0x0f,
00026 };
00027
00028 protected:
00029
00030 struct Idt_entry_desc
00031 {
00032 Unsigned16 _offset_low;
00033 Unsigned16 _selector __attribute__((packed));
00034 Unsigned8 _zero __attribute__((packed));
00035 Unsigned8 _access __attribute__((packed));
00036 Unsigned16 _offset_high __attribute__((packed));
00037 };
00038
00039
00040 struct Gdt_entry_desc
00041 {
00042 Unsigned16 _limit_low;
00043 Unsigned16 _base_low __attribute__((packed));
00044 Unsigned8 _base_med __attribute__((packed));
00045 Unsigned8 _access __attribute__((packed));
00046 Unsigned8 _limit_high __attribute__((packed));
00047 Unsigned8 _base_high __attribute__((packed));
00048 };
00049
00050 struct Task_gate_desc
00051 {
00052 Unsigned16 _avail1;
00053 Unsigned16 _selector __attribute__((packed));
00054 Unsigned8 _avail2 __attribute__((packed));
00055 Unsigned8 _access __attribute__((packed));
00056 Unsigned16 _avail3 __attribute__((packed));
00057 };
00058
00059
00060 struct Not_present_desc
00061 {
00062 Unsigned32 _avail1;
00063 Unsigned8 _avail2 __attribute__((packed));
00064 Unsigned8 _access __attribute__((packed));
00065 Unsigned16 _avail3 __attribute__((packed));
00066 };
00067
00068 union
00069 {
00070 Idt_entry_desc i;
00071 Gdt_entry_desc g;
00072 Task_gate_desc t;
00073 Not_present_desc n;
00074 Unsigned64 r;
00075 } _data;
00076
00077 public:
00078 const char* type_str() const;
00079
00080 void gdt_entry_show();
00081
00082 void idt_entry_show();
00083
00084 void task_gate_show();
00085
00086 void show();
00087
00088 inline Unsigned64 get_raw();
00089
00090 inline void get_raw(Unsigned32 *low, Unsigned32 *high);
00091
00092 inline void set_raw(Unsigned64 val);
00093
00094 inline void set_raw(Unsigned32 low, Unsigned32 high);
00095
00096 inline X86desc();
00097
00098 inline X86desc(Unsigned64 val);
00099
00100 inline Address gdt_entry_base();
00101
00102 inline Unsigned32 gdt_entry_limit();
00103
00104 inline Unsigned32 gdt_entry_size();
00105
00106 inline Address idt_entry_offset();
00107
00108 inline Unsigned8 access();
00109
00110 inline int present();
00111
00112 inline Unsigned8 type();
00113
00114 inline Unsigned8 dpl();
00115
00116 inline bool unsafe();
00117 };
00118
00119 class Pseudo_descriptor
00120 {
00121 Unsigned16 _limit;
00122 Unsigned32 _base __attribute__((packed));
00123 Unsigned16 _pad __attribute__((packed));
00124
00125 public:
00126 inline Pseudo_descriptor();
00127
00128 inline Pseudo_descriptor(Address base, Unsigned16 limit);
00129
00130 inline Address base() const;
00131
00132 inline Unsigned16 limit() const;
00133 };
00134
00135
00136
00137
00138
00139
00140
00141
00142 inline Unsigned64
00143 X86desc::get_raw()
00144 {
00145 return _data.r;
00146 }
00147
00148
00149
00150 inline void
00151 X86desc::get_raw(Unsigned32 *low, Unsigned32 *high)
00152 {
00153 *low = _data.r & 0xffffffff;
00154 *high = _data.r >> 32;
00155 }
00156
00157
00158
00159 inline void
00160 X86desc::set_raw(Unsigned64 val)
00161 {
00162 _data.r = val;
00163 }
00164
00165
00166
00167 inline void
00168 X86desc::set_raw(Unsigned32 low, Unsigned32 high)
00169 {
00170 _data.r = ((Unsigned64)high << 32 | low);
00171 }
00172
00173
00174
00175 inline X86desc::X86desc()
00176 {
00177 }
00178
00179
00180
00181 inline X86desc::X86desc(Unsigned64 val)
00182 {
00183 set_raw(val);
00184 }
00185
00186
00187
00188 inline Address
00189 X86desc::gdt_entry_base()
00190 {
00191 return (Address)_data.g._base_low
00192 | ((Address)_data.g._base_med << 16)
00193 | ((Address)_data.g._base_high << 24);
00194 }
00195
00196
00197
00198 inline Unsigned32
00199 X86desc::gdt_entry_limit()
00200 {
00201 return (Unsigned32)_data.g._limit_low
00202 | (((Unsigned32)_data.g._limit_high & 0x0f) << 16);
00203 }
00204
00205
00206
00207 inline Unsigned32
00208 X86desc::gdt_entry_size()
00209 {
00210 Address l = gdt_entry_limit();
00211 return _data.g._limit_high & 0x80 ? ((l+1) << 12)-1 : l;
00212 }
00213
00214
00215
00216 inline Address
00217 X86desc::idt_entry_offset()
00218 {
00219 return (Address)_data.i._offset_low
00220 | ((Address)_data.i._offset_high << 16);
00221 }
00222
00223
00224
00225 inline Unsigned8
00226 X86desc::access()
00227 {
00228 return _data.n._access;
00229 }
00230
00231
00232
00233 inline int
00234 X86desc::present()
00235 {
00236 return (access() & 0x80) >> 7;
00237 }
00238
00239
00240
00241 inline Unsigned8
00242 X86desc::type()
00243 {
00244 return _data.n._access & 0x1f;
00245 }
00246
00247
00248
00249 inline Unsigned8
00250 X86desc::dpl()
00251 {
00252 return (_data.n._access & 0x60) >> 5;
00253 }
00254
00255
00256
00257 inline bool
00258 X86desc::unsafe()
00259 {
00260 return present() && (dpl() != 3);
00261 }
00262
00263
00264
00265 inline Pseudo_descriptor::Pseudo_descriptor()
00266 {}
00267
00268
00269
00270 inline Pseudo_descriptor::Pseudo_descriptor(Address base, Unsigned16 limit)
00271 : _limit(limit), _base(base)
00272 {}
00273
00274
00275
00276 inline Address
00277 Pseudo_descriptor::base() const
00278 {
00279 return _base;
00280 }
00281
00282
00283
00284 inline Unsigned16
00285 Pseudo_descriptor::limit() const
00286 {
00287 return _limit;
00288 }
00289
00290 #endif // x86desc_h