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
205 printf("%016lx-%016lx dpl=%d %dbit %s %02X (\033[33;1m%s\033[m)\n",
206 b, b+l, (access & 0x60) >> 5,
208 access & 0x10 ? "code/data" : "system ",
209 access & 0x1f, type_str());
214 Idt_entry::selector() const
215 { return _selector; }
219 Idt_entry::show() const
225 printf("-------- sel=%04x dpl=%d %02X (\033[33;1m%s\033[m)\n",
226 selector(), dpl(), type(), type_str());
230 Address o = offset();
232 printf("%016lx sel=%04x dpl=%d %02X (\033[33;1m%s\033[m)\n",
233 o, selector(), dpl(), type(), type_str());
240 X86desc::show() const
244 if ((access() & 0x16) == 0x06)
245 static_cast<Idt_entry const*>(this)->show();
247 static_cast<Gdt_entry const*>(this)->show();
251 printf("-------- dpl=%d %02X (\033[33;1m%s\033[m)\n",
252 dpl(), type(), type_str());
265 unsigned X86desc::access() const
266 { return ((Unsigned8 const *)this)[5]; }
268 PUBLIC inline NEEDS[X86desc::access]
270 X86desc::present() const
272 return (access() & 0x80) >> 7;
275 PUBLIC inline NEEDS[X86desc::access]
277 X86desc::type() const
279 return access() & 0x1f;
282 PUBLIC inline NEEDS[X86desc::access]
286 return (access() & 0x60) >> 5;
289 PUBLIC inline NEEDS[X86desc::present, X86desc::dpl]
291 X86desc::unsafe() const
292 { return present() && (dpl() != 3); }
295 Pseudo_descriptor::Pseudo_descriptor()
299 Pseudo_descriptor::Pseudo_descriptor(Address base, Unsigned16 limit)
300 : _limit(limit), _base(base)
305 Pseudo_descriptor::base() const
312 Idt_entry::ist() const
317 Pseudo_descriptor::limit() const
320 PUBLIC inline NEEDS [<cstring>]
323 { memset(this, 0, sizeof(*this)); }
326 Gdt_entry::Gdt_entry(Address base, Unsigned32 limit,
327 Unsigned8 _access, Unsigned8 szbits)
329 limit_low = limit & 0x0000ffff;
330 base_low = base & 0x0000ffff;
331 base_med = (base & 0x00ff0000) >> 16;
332 access = _access | Access_present;
333 limit_high = ((limit & 0x000f0000) >> 16) |
334 (((Unsigned16)szbits) << 4);
335 base_high = (base & 0xff000000) >> 24;
339 Gdt_entry::Gdt_entry()
345 Gdt_entry::limit() const
346 { return (Mword)limit_low | (((Mword)limit_high & 0x0f) << 16); }
348 PUBLIC inline NEEDS[Gdt_entry::granularity, Gdt_entry::limit]
350 Gdt_entry::size() const
353 return (granularity()) ? ((l+1) << 12)-1 : l;
358 Gdt_entry::avl() const
360 return (limit_high & 0x10);
365 Gdt_entry::seg64() const
367 return (limit_high & 0x20);
372 Gdt_entry::seg32() const
374 return (limit_high & 0x40);
379 Gdt_entry::mode() const
380 { return (limit_high >> 5) & 3; }
384 Gdt_entry::granularity() const
386 return (limit_high & 0x80);
391 Gdt_entry::writable() const
393 return (type() & 0x02);
398 Gdt_entry::contents() const
400 return (type() & 0x0c) >> 2;
407 *(Unsigned64*)this = 0;