Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/amd64/mp_machdep.c
Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
#define CMOS_DATA (0x71) | #define CMOS_DATA (0x71) | ||||
#define BIOS_RESET (0x0f) | #define BIOS_RESET (0x0f) | ||||
#define BIOS_WARM (0x0a) | #define BIOS_WARM (0x0a) | ||||
extern struct pcpu __pcpu[]; | extern struct pcpu __pcpu[]; | ||||
/* Temporary variables for init_secondary() */ | /* Temporary variables for init_secondary() */ | ||||
char *doublefault_stack; | char *doublefault_stack; | ||||
char *mce_stack; | |||||
char *nmi_stack; | char *nmi_stack; | ||||
/* | /* | ||||
* Local data and functions. | * Local data and functions. | ||||
*/ | */ | ||||
static int start_ap(int apic_id); | static int start_ap(int apic_id); | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | init_secondary(void) | ||||
common_tss[cpu].tss_iobase = sizeof(struct amd64tss) + | common_tss[cpu].tss_iobase = sizeof(struct amd64tss) + | ||||
IOPERM_BITMAP_SIZE; | IOPERM_BITMAP_SIZE; | ||||
common_tss[cpu].tss_ist1 = (long)&doublefault_stack[PAGE_SIZE]; | common_tss[cpu].tss_ist1 = (long)&doublefault_stack[PAGE_SIZE]; | ||||
/* The NMI stack runs on IST2. */ | /* The NMI stack runs on IST2. */ | ||||
np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; | np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; | ||||
common_tss[cpu].tss_ist2 = (long) np; | common_tss[cpu].tss_ist2 = (long) np; | ||||
/* The MC# stack runs on IST3. */ | |||||
np = ((struct nmi_pcpu *) &mce_stack[PAGE_SIZE]) - 1; | |||||
common_tss[cpu].tss_ist3 = (long) np; | |||||
/* Prepare private GDT */ | /* Prepare private GDT */ | ||||
gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu]; | gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu]; | ||||
for (x = 0; x < NGDT; x++) { | for (x = 0; x < NGDT; x++) { | ||||
if (x != GPROC0_SEL && x != (GPROC0_SEL + 1) && | if (x != GPROC0_SEL && x != (GPROC0_SEL + 1) && | ||||
x != GUSERLDT_SEL && x != (GUSERLDT_SEL + 1)) | x != GUSERLDT_SEL && x != (GUSERLDT_SEL + 1)) | ||||
ssdtosd(&gdt_segs[x], &gdt[NGDT * cpu + x]); | ssdtosd(&gdt_segs[x], &gdt[NGDT * cpu + x]); | ||||
} | } | ||||
ssdtosyssd(&gdt_segs[GPROC0_SEL], | ssdtosyssd(&gdt_segs[GPROC0_SEL], | ||||
Show All 22 Lines | pc->pc_ldt = (struct system_segment_descriptor *)&gdt[NGDT * cpu + | ||||
GUSERLDT_SEL]; | GUSERLDT_SEL]; | ||||
pc->pc_curpmap = kernel_pmap; | pc->pc_curpmap = kernel_pmap; | ||||
pc->pc_pcid_gen = 1; | pc->pc_pcid_gen = 1; | ||||
pc->pc_pcid_next = PMAP_PCID_KERN + 1; | pc->pc_pcid_next = PMAP_PCID_KERN + 1; | ||||
common_tss[cpu].tss_rsp0 = pti ? ((vm_offset_t)&pc->pc_pti_stack + | common_tss[cpu].tss_rsp0 = pti ? ((vm_offset_t)&pc->pc_pti_stack + | ||||
PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful : 0; | PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful : 0; | ||||
/* Save the per-cpu pointer for use by the NMI handler. */ | /* Save the per-cpu pointer for use by the NMI handler. */ | ||||
np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; | |||||
np->np_pcpu = (register_t) pc; | np->np_pcpu = (register_t) pc; | ||||
/* Save the per-cpu pointer for use by the MC# handler. */ | |||||
np = ((struct nmi_pcpu *) &mce_stack[PAGE_SIZE]) - 1; | |||||
np->np_pcpu = (register_t) pc; | |||||
wrmsr(MSR_FSBASE, 0); /* User value */ | wrmsr(MSR_FSBASE, 0); /* User value */ | ||||
wrmsr(MSR_GSBASE, (u_int64_t)pc); | wrmsr(MSR_GSBASE, (u_int64_t)pc); | ||||
wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* XXX User value while we're in the kernel */ | wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* XXX User value while we're in the kernel */ | ||||
fix_cpuid(); | fix_cpuid(); | ||||
lidt(&r_idt); | lidt(&r_idt); | ||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); | gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | native_start_all_aps(void) | ||||
for (cpu = 1; cpu < mp_ncpus; cpu++) { | for (cpu = 1; cpu < mp_ncpus; cpu++) { | ||||
apic_id = cpu_apic_ids[cpu]; | apic_id = cpu_apic_ids[cpu]; | ||||
/* allocate and set up an idle stack data page */ | /* allocate and set up an idle stack data page */ | ||||
bootstacks[cpu] = (void *)kmem_malloc(kernel_arena, | bootstacks[cpu] = (void *)kmem_malloc(kernel_arena, | ||||
kstack_pages * PAGE_SIZE, M_WAITOK | M_ZERO); | kstack_pages * PAGE_SIZE, M_WAITOK | M_ZERO); | ||||
doublefault_stack = (char *)kmem_malloc(kernel_arena, | doublefault_stack = (char *)kmem_malloc(kernel_arena, | ||||
PAGE_SIZE, M_WAITOK | M_ZERO); | PAGE_SIZE, M_WAITOK | M_ZERO); | ||||
mce_stack = (char *)kmem_malloc(kernel_arena, PAGE_SIZE, | |||||
M_WAITOK | M_ZERO); | |||||
nmi_stack = (char *)kmem_malloc(kernel_arena, PAGE_SIZE, | nmi_stack = (char *)kmem_malloc(kernel_arena, PAGE_SIZE, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
dpcpu = (void *)kmem_malloc(kernel_arena, DPCPU_SIZE, | dpcpu = (void *)kmem_malloc(kernel_arena, DPCPU_SIZE, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8; | bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8; | ||||
bootAP = cpu; | bootAP = cpu; | ||||
▲ Show 20 Lines • Show All 103 Lines • Show Last 20 Lines |