- if (is_boot_cpu) {
- /*
- * Master CPU uses the tables built at boot time.
- * Just set the index pointers to the high shared-mapping space.
- * Note that the sysenter stack uses empty space above the ktss
- * in the HIGH_FIXED_KTSS page. In this case we don't map the
- * the real master_sstk in low memory.
- */
- cdi->cdi_ktss = (struct i386_tss *)
- pmap_index_to_virt(HIGH_FIXED_KTSS) ;
- cdi->cdi_sstk = (vm_offset_t) (cdi->cdi_ktss + 1) +
- (vm_offset_t) &master_sstk.top -
- (vm_offset_t) &master_sstk;
-#if MACH_KDB
- cdi->cdi_dbtss = (struct i386_tss *)
- pmap_index_to_virt(HIGH_FIXED_DBTSS);
-#endif /* MACH_KDB */
- cdi->cdi_gdt = (struct fake_descriptor *)
- pmap_index_to_virt(HIGH_FIXED_GDT);
- cdi->cdi_idt = (struct fake_descriptor *)
- pmap_index_to_virt(HIGH_FIXED_IDT);
- cdi->cdi_ldt = (struct fake_descriptor *)
- pmap_index_to_virt(HIGH_FIXED_LDT_BEGIN);
-
- } else {
-
- vm_offset_t cpu_hi_desc;
-
- cpu_hi_desc = pmap_cpu_high_shared_remap(cdp->cpu_number,
- HIGH_CPU_DESC,
- (vm_offset_t) cdt, 1);
-
- /*
- * Per-cpu GDT, IDT, LDT, KTSS descriptors are allocated in one
- * block (cpu_desc_table) and double-mapped into high shared space
- * in one page window.
- * Also, a transient stack for the fast sysenter path. The top of
- * which is set at context switch time to point to the PCB using
- * the high address.
- */
- cdi->cdi_gdt = (struct fake_descriptor *) (cpu_hi_desc +
- offsetof(cpu_desc_table_t, gdt[0]));
- cdi->cdi_idt = (struct fake_descriptor *) (cpu_hi_desc +
- offsetof(cpu_desc_table_t, idt[0]));
- cdi->cdi_ktss = (struct i386_tss *) (cpu_hi_desc +
- offsetof(cpu_desc_table_t, ktss));
- cdi->cdi_sstk = cpu_hi_desc +
- offsetof(cpu_desc_table_t, sstk.top);
-
- /*
- * LDT descriptors are mapped into a seperate area.
- */
- cdi->cdi_ldt = (struct fake_descriptor *)
- pmap_cpu_high_shared_remap(
- cdp->cpu_number,
- HIGH_CPU_LDT_BEGIN,
- (vm_offset_t) cdp->cpu_ldtp,
- HIGH_CPU_LDT_END - HIGH_CPU_LDT_BEGIN + 1);
-
- /*
- * Copy the tables
- */
- bcopy((char *)master_idt,
- (char *)cdt->idt,
- sizeof(master_idt));
- bcopy((char *)master_gdt,
- (char *)cdt->gdt,
- sizeof(master_gdt));
- bcopy((char *)master_ldt,
- (char *)cdp->cpu_ldtp,
- sizeof(master_ldt));
- bzero((char *)&cdt->ktss,
- sizeof(struct i386_tss));
-
-#if MACH_KDB
- cdi->cdi_dbtss = (struct i386_tss *) (cpu_hi_desc +
- offsetof(cpu_desc_table_t, dbtss));
- bcopy((char *)&master_dbtss,
- (char *)&cdt->dbtss,
- sizeof(struct i386_tss));
-#endif /* MACH_KDB */
-
- /*
- * Fix up the entries in the GDT to point to
- * this LDT and this TSS.
- */
- cdt->gdt[sel_idx(KERNEL_LDT)] = ldt_desc_pattern;
- cdt->gdt[sel_idx(KERNEL_LDT)].offset = (vm_offset_t) cdi->cdi_ldt;
- fix_desc(&cdt->gdt[sel_idx(KERNEL_LDT)], 1);
-
- cdt->gdt[sel_idx(USER_LDT)] = ldt_desc_pattern;
- cdt->gdt[sel_idx(USER_LDT)].offset = (vm_offset_t) cdi->cdi_ldt;
- fix_desc(&cdt->gdt[sel_idx(USER_LDT)], 1);
-
- cdt->gdt[sel_idx(KERNEL_TSS)] = tss_desc_pattern;
- cdt->gdt[sel_idx(KERNEL_TSS)].offset = (vm_offset_t) cdi->cdi_ktss;
- fix_desc(&cdt->gdt[sel_idx(KERNEL_TSS)], 1);
-
- cdt->gdt[sel_idx(CPU_DATA_GS)] = cpudata_desc_pattern;
- cdt->gdt[sel_idx(CPU_DATA_GS)].offset = (vm_offset_t) cdp;
- fix_desc(&cdt->gdt[sel_idx(CPU_DATA_GS)], 1);
-
-#if MACH_KDB
- cdt->gdt[sel_idx(DEBUG_TSS)] = tss_desc_pattern;
- cdt->gdt[sel_idx(DEBUG_TSS)].offset = (vm_offset_t) cdi->cdi_dbtss;
- fix_desc(&cdt->gdt[sel_idx(DEBUG_TSS)], 1);
-
- cdt->dbtss.esp0 = (int)(db_task_stack_store +
- (INTSTACK_SIZE * (cdp->cpu_number)) - sizeof (natural_t));
- cdt->dbtss.esp = cdt->dbtss.esp0;
- cdt->dbtss.eip = (int)&db_task_start;
-#endif /* MACH_KDB */
-
- cdt->ktss.ss0 = KERNEL_DS;
- cdt->ktss.io_bit_map_offset = 0x0FFF; /* no IO bitmap */
-
- cpu_window_init(cdp->cpu_number);
+ 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);
+ }