14 Access_present = 0x80,
17 Access_intr_gate = 0x0e,
18 Access_trap_gate = 0x0f,
20 Long_mode = 0x02, // XXX for code segments
25 class Gdt_entry : public X86desc
30 Access_type_user = 0x10,
31 Access_code_read = 0x1a,
32 Access_data_write = 0x12,
44 } __attribute__((packed));
47 class Idt_entry : public X86desc
50 Unsigned16 _offset_low;
54 Unsigned16 _offset_high;
55 } __attribute__((packed));
59 class Pseudo_descriptor
63 } __attribute__((packed));
67 //----------------------------------------------------------------------------
68 IMPLEMENTATION [ia32 | ux]:
71 Address Idt_entry::offset() const
72 { return (Address)_offset_low | ((Address)_offset_high << 16); }
75 Idt_entry::Idt_entry()
80 Idt_entry::Idt_entry(Address entry, Unsigned16 selector, Unsigned8 access, unsigned = 0)
82 _offset_low = entry & 0x0000ffff;
85 _access = access | X86desc::Access_present;
86 _offset_high = (entry & 0xffff0000) >> 16;
91 Idt_entry::Idt_entry(Unsigned16 selector, Unsigned8 access)
96 _access = access | X86desc::Access_present;
102 Gdt_entry::base() const
104 return (Address)base_low | ((Address)base_med << 16)
105 | ((Address)base_high << 24);
108 //----------------------------------------------------------------------------
114 Unsigned32 _offset_high1;
119 //-----------------------------------------------------------------------------
120 IMPLEMENTATION [amd64]:
125 Address Idt_entry::offset() const
127 return (Address)_offset_low | ((Address)_offset_high << 16)
128 | ((Address)_offset_high1 << 32);
133 Idt_entry::Idt_entry(Address entry, Unsigned16 selector, Unsigned8 access, Unsigned8 ist_entry = 0)
135 _offset_low = entry & 0x000000000000ffffLL;
136 _selector = selector;
138 _access = access | Access_present;
139 _offset_high = (entry & 0x00000000ffff0000LL) >> 16;
140 _offset_high1 = (entry & 0xffffffff00000000LL) >> 32;
147 Gdt_entry::base() const
149 Address b = (Address)base_low | ((Address)base_med << 16)
150 | ((Address)base_high << 24);
154 return b | ((Unsigned64 const *)this)[1] << 32;
159 Idt_entry::Idt_entry(Unsigned16, Unsigned8)
160 { panic("AMD64 does not support task gates"); }
163 IMPLEMENTATION[debug]:
170 X86desc::type_str() const
172 static char const * const desc_type[32] =
174 "reserved", "16-bit tss (avail)",
175 "ldt", "16-bit tss (busy)",
176 "16-bit call gate", "task gate",
177 "16-bit int gate", "16-bit trap gate",
178 "reserved", "32-bit tss (avail)",
179 "reserved", "32-bit tss (busy)",
180 "32-bit call gate", "reserved",
181 "32-bit int gate", "32-bit trap gate",
182 "data r/o", "data r/o acc",
183 "data r/w", "data r/w acc",
184 "data r/o exp-dn", "data r/o exp-dn",
185 "data r/w exp-dn", "data r/w exp-dn acc",
186 "code x/o", "code x/o acc",
187 "code x/r", "code x/r acc",
188 "code x/r conf", "code x/o conf acc",
189 "code x/r conf", "code x/r conf acc"
192 Unsigned8 const *t = (Unsigned8 const *)this;
194 return desc_type[t[5] & 0x1f];
199 Gdt_entry::show() const
201 static char const modes[] = { 16, 64, 32, -1 };
202 // segment descriptor
204 printf("%016lx-%016lx dpl=%d %dbit %s %02X (\033[33;1m%s\033[m)\n",
205 b, b + size(), (access & 0x60) >> 5,
207 access & 0x10 ? "code/data" : "system ",
208 access & 0x1f, type_str());
213 Idt_entry::selector() const
214 { return _selector; }
218 Idt_entry::show() const
224 printf("-------- sel=%04x dpl=%d %02X (\033[33;1m%s\033[m)\n",
225 selector(), dpl(), type(), type_str());
229 Address o = offset();
231 printf("%016lx sel=%04x dpl=%d %02X (\033[33;1m%s\033[m)\n",
232 o, selector(), dpl(), type(), type_str());
239 X86desc::show() const
243 if ((access() & 0x16) == 0x06)
244 static_cast<Idt_entry const*>(this)->show();
246 static_cast<Gdt_entry const*>(this)->show();
250 printf("-------- dpl=%d %02X (\033[33;1m%s\033[m)\n",
251 dpl(), type(), type_str());
264 unsigned X86desc::access() const
265 { return ((Unsigned8 const *)this)[5]; }
267 PUBLIC inline NEEDS[X86desc::access]
269 X86desc::present() const
271 return (access() & 0x80) >> 7;
274 PUBLIC inline NEEDS[X86desc::access]
276 X86desc::type() const
278 return access() & 0x1f;
281 PUBLIC inline NEEDS[X86desc::access]
285 return (access() & 0x60) >> 5;
288 PUBLIC inline NEEDS[X86desc::present, X86desc::dpl]
290 X86desc::unsafe() const
291 { return present() && (dpl() != 3); }
294 Pseudo_descriptor::Pseudo_descriptor()
298 Pseudo_descriptor::Pseudo_descriptor(Address base, Unsigned16 limit)
299 : _limit(limit), _base(base)
304 Pseudo_descriptor::base() const
311 Idt_entry::ist() const
316 Pseudo_descriptor::limit() const
319 PUBLIC inline NEEDS [<cstring>]
322 { memset(this, 0, sizeof(*this)); }
325 Gdt_entry::Gdt_entry(Address base, Unsigned32 limit,
326 Unsigned8 _access, Unsigned8 szbits)
328 limit_low = limit & 0x0000ffff;
329 base_low = base & 0x0000ffff;
330 base_med = (base & 0x00ff0000) >> 16;
331 access = _access | Access_present;
332 limit_high = ((limit & 0x000f0000) >> 16) |
333 (((Unsigned16)szbits) << 4);
334 base_high = (base & 0xff000000) >> 24;
338 Gdt_entry::Gdt_entry()
344 Gdt_entry::limit() const
345 { return (Mword)limit_low | (((Mword)limit_high & 0x0f) << 16); }
347 PUBLIC inline NEEDS[Gdt_entry::granularity, Gdt_entry::limit]
349 Gdt_entry::size() const
352 return granularity() ? ((l+1) << 12)-1 : l;
357 Gdt_entry::avl() const
359 return (limit_high & 0x10);
364 Gdt_entry::seg64() const
366 return (limit_high & 0x20);
371 Gdt_entry::seg32() const
373 return (limit_high & 0x40);
378 Gdt_entry::mode() const
379 { return (limit_high >> 5) & 3; }
383 Gdt_entry::granularity() const
385 return (limit_high & 0x80);
390 Gdt_entry::writable() const
392 return (type() & 0x02);
397 Gdt_entry::contents() const
399 return (type() & 0x0c) >> 2;
406 *(Unsigned64*)this = 0;