/** Set up the TSS for the current CPU. * @param cpu CPU to initialize for. */ static __init_text void tss_init(cpu_t *cpu) { /* Set up the contents of the TSS. Point the first IST entry at the * double fault stack. */ memset(&cpu->arch.tss, 0, sizeof(cpu->arch.tss)); cpu->arch.tss.ist1 = (ptr_t)cpu->arch.double_fault_stack + KSTACK_SIZE; cpu->arch.tss.io_bitmap = 104; /* Load the TSS segment into TR. */ x86_ltr(KERNEL_TSS); }
void x86_initialize_percpu_tss(void) { struct x86_percpu* percpu = x86_get_percpu(); uint cpu_num = percpu->cpu_num; tss_t* tss = &percpu->default_tss; memset(tss, 0, sizeof(*tss)); /* zeroed out TSS is okay for now */ set_global_desc_64(TSS_SELECTOR(cpu_num), (uintptr_t)tss, sizeof(*tss) - 1, 1, 0, 0, SEG_TYPE_TSS, 0, 0); x86_tss_assign_ists(percpu, tss); tss->iomap_base = offsetof(tss_64_t, tss_bitmap); // Need to have an extra byte at the end of the bitmap because it will always potentially read two bytes tss->tss_bitmap[IO_BITMAP_BYTES] = 0xff; x86_ltr(TSS_SELECTOR(cpu_num)); }
void arch_early_init(void) { x86_mmu_init(); platform_init_mmu_mappings(); /* enable caches here for now */ clear_in_cr0(X86_CR0_NW | X86_CR0_CD); memset(&system_tss, 0, sizeof(tss_t)); system_tss.esp0 = 0; system_tss.ss0 = DATA_SELECTOR; system_tss.ss1 = 0; system_tss.ss2 = 0; system_tss.eflags = 0x00003002; system_tss.bitmap = offsetof(tss_t, tss_bitmap); system_tss.trace = 1; // trap on hardware task switch set_global_desc(TSS_SELECTOR, &system_tss, sizeof(tss_t), 1, 0, 0, SEG_TYPE_TSS, 0, 0); x86_ltr(TSS_SELECTOR); }