+fix_desc(void *d, int num_desc) {
+ //early_kprintf("fix_desc(%x, %x)\n", d, num_desc);
+ uint8_t *desc = (uint8_t*) d;
+
+ do {
+ if ((desc[7] & 0x14) == 0x04) { /* gate */
+ uint32_t offset;
+ uint16_t selector;
+ uint8_t wordcount;
+ uint8_t acc;
+
+ offset = *((uint32_t*)(desc));
+ selector = *((uint32_t*)(desc+4));
+ wordcount = desc[6] >> 4;
+ acc = desc[7];
+
+ *((uint16_t*)desc) = offset & 0xFFFF;
+ *((uint16_t*)(desc+2)) = selector;
+ desc[4] = wordcount;
+ desc[5] = acc;
+ *((uint16_t*)(desc+6)) = offset >> 16;
+
+ } else { /* descriptor */
+ uint32_t base;
+ uint16_t limit;
+ uint8_t acc1, acc2;
+
+ base = *((uint32_t*)(desc));
+ limit = *((uint16_t*)(desc+4));
+ acc2 = desc[6];
+ acc1 = desc[7];
+
+ *((uint16_t*)(desc)) = limit;
+ *((uint16_t*)(desc+2)) = base & 0xFFFF;
+ desc[4] = (base >> 16) & 0xFF;
+ desc[5] = acc1;
+ desc[6] = acc2;
+ desc[7] = base >> 24;
+ }
+ desc += 8;
+ } while (--num_desc);
+}
+
+void
+fix_desc64(void *descp, int count)
+{
+ struct fake_descriptor64 *fakep;
+ union {
+ struct real_gate64 gate;
+ struct real_descriptor64 desc;
+ } real;
+ int i;
+
+ fakep = (struct fake_descriptor64 *) descp;
+
+ for (i = 0; i < count; i++, fakep++) {
+ /*
+ * Construct the real decriptor locally.
+ */
+
+ bzero((void *) &real, sizeof(real));
+
+ switch (fakep->access & ACC_TYPE) {
+ case 0:
+ break;
+ case ACC_CALL_GATE:
+ case ACC_INTR_GATE:
+ case ACC_TRAP_GATE:
+ real.gate.offset_low16 = (uint16_t)(fakep->offset64 & 0xFFFF);
+ real.gate.selector16 = fakep->lim_or_seg & 0xFFFF;
+ real.gate.IST = fakep->size_or_IST & 0x7;
+ real.gate.access8 = fakep->access;
+ real.gate.offset_high16 = (uint16_t)((fakep->offset64>>16) & 0xFFFF);
+ real.gate.offset_top32 = (uint32_t)(fakep->offset64>>32);
+ break;
+ default: /* Otherwise */
+ real.desc.limit_low16 = fakep->lim_or_seg & 0xFFFF;
+ real.desc.base_low16 = (uint16_t)(fakep->offset64 & 0xFFFF);
+ real.desc.base_med8 = (uint8_t)((fakep->offset64 >> 16) & 0xFF);
+ real.desc.access8 = fakep->access;
+ real.desc.limit_high4 = (fakep->lim_or_seg >> 16) & 0xFF;
+ real.desc.granularity4 = fakep->size_or_IST;
+ real.desc.base_high8 = (uint8_t)((fakep->offset64 >> 24) & 0xFF);
+ real.desc.base_top32 = (uint32_t)(fakep->offset64>>32);
+ }
+
+ /*
+ * Now copy back over the fake structure.
+ */
+ bcopy((void *) &real, (void *) fakep, sizeof(real));
+ }
+}
+
+#ifdef __i386__
+void
+cpu_desc_init(cpu_data_t *cdp)