Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/machdep.c
Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | |||||
long Maxmem = 0; | long Maxmem = 0; | ||||
long realmem = 0; | long realmem = 0; | ||||
struct kva_md_info kmi; | struct kva_md_info kmi; | ||||
static struct trapframe proc0_tf; | static struct trapframe proc0_tf; | ||||
struct region_descriptor r_gdt, r_idt; | struct region_descriptor r_gdt, r_idt; | ||||
struct pcpu __pcpu[MAXCPU]; | struct pcpu *__pcpu; | ||||
struct pcpu temp_bsp_pcpu; | |||||
struct mtx icu_lock; | struct mtx icu_lock; | ||||
struct mem_range_softc mem_range_softc; | struct mem_range_softc mem_range_softc; | ||||
struct mtx dt_lock; /* lock for GDT and LDT */ | struct mtx dt_lock; /* lock for GDT and LDT */ | ||||
void (*vmm_resume_p)(void); | void (*vmm_resume_p)(void); | ||||
▲ Show 20 Lines • Show All 1,311 Lines • ▼ Show 20 Lines | wrmsr(MSR_LSTAR, pti ? (u_int64_t)IDTVEC(fast_syscall_pti) : | ||||
(u_int64_t)IDTVEC(fast_syscall)); | (u_int64_t)IDTVEC(fast_syscall)); | ||||
wrmsr(MSR_CSTAR, (u_int64_t)IDTVEC(fast_syscall32)); | wrmsr(MSR_CSTAR, (u_int64_t)IDTVEC(fast_syscall32)); | ||||
msr = ((u_int64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) | | msr = ((u_int64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) | | ||||
((u_int64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48); | ((u_int64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48); | ||||
wrmsr(MSR_STAR, msr); | wrmsr(MSR_STAR, msr); | ||||
wrmsr(MSR_SF_MASK, PSL_NT | PSL_T | PSL_I | PSL_C | PSL_D | PSL_AC); | wrmsr(MSR_SF_MASK, PSL_NT | PSL_T | PSL_I | PSL_C | PSL_D | PSL_AC); | ||||
} | } | ||||
void | |||||
amd64_bsp_pcpu_init1(struct pcpu *pc) | |||||
{ | |||||
PCPU_SET(prvspace, pc); | |||||
PCPU_SET(curthread, &thread0); | |||||
PCPU_SET(tssp, &common_tss[0]); | |||||
PCPU_SET(commontssp, &common_tss[0]); | |||||
PCPU_SET(tss, (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); | |||||
PCPU_SET(ldt, (struct system_segment_descriptor *)&gdt[GUSERLDT_SEL]); | |||||
PCPU_SET(fs32p, &gdt[GUFS32_SEL]); | |||||
PCPU_SET(gs32p, &gdt[GUGS32_SEL]); | |||||
} | |||||
void | |||||
amd64_bsp_pcpu_init2(uint64_t rsp0) | |||||
{ | |||||
PCPU_SET(rsp0, rsp0); | |||||
PCPU_SET(pti_rsp0, ((vm_offset_t)PCPU_PTR(pti_stack) + | |||||
PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful); | |||||
PCPU_SET(curpcb, thread0.td_pcb); | |||||
} | |||||
void | |||||
amd64_bsp_ist_init(struct pcpu *pc) | |||||
{ | |||||
struct nmi_pcpu *np; | |||||
/* doublefault stack space, runs on ist1 */ | |||||
common_tss[0].tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)]; | |||||
/* | |||||
* NMI stack, runs on ist2. The pcpu pointer is stored just | |||||
* above the start of the ist2 stack. | |||||
*/ | |||||
np = ((struct nmi_pcpu *)&nmi0_stack[sizeof(nmi0_stack)]) - 1; | |||||
markj: Style: extra space after the cast. This is duplicated below. | |||||
np->np_pcpu = (register_t)pc; | |||||
common_tss[0].tss_ist2 = (long)np; | |||||
/* | |||||
* MC# stack, runs on ist3. The pcpu pointer is stored just | |||||
* above the start of the ist3 stack. | |||||
*/ | |||||
np = ((struct nmi_pcpu *)&mce0_stack[sizeof(mce0_stack)]) - 1; | |||||
np->np_pcpu = (register_t)pc; | |||||
common_tss[0].tss_ist3 = (long)np; | |||||
/* | |||||
* DB# stack, runs on ist4. | |||||
*/ | |||||
np = ((struct nmi_pcpu *)&dbg0_stack[sizeof(dbg0_stack)]) - 1; | |||||
np->np_pcpu = (register_t)pc; | |||||
common_tss[0].tss_ist4 = (long)np; | |||||
} | |||||
u_int64_t | u_int64_t | ||||
hammer_time(u_int64_t modulep, u_int64_t physfree) | hammer_time(u_int64_t modulep, u_int64_t physfree) | ||||
{ | { | ||||
caddr_t kmdp; | caddr_t kmdp; | ||||
int gsel_tss, x; | int gsel_tss, x; | ||||
struct pcpu *pc; | struct pcpu *pc; | ||||
struct nmi_pcpu *np; | |||||
struct xstate_hdr *xhdr; | struct xstate_hdr *xhdr; | ||||
u_int64_t rsp0; | u_int64_t rsp0; | ||||
char *env; | char *env; | ||||
size_t kstack0_sz; | size_t kstack0_sz; | ||||
int late_console; | int late_console; | ||||
TSRAW(&thread0, TS_ENTER, __func__, NULL); | TSRAW(&thread0, TS_ENTER, __func__, NULL); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | hammer_time(u_int64_t modulep, u_int64_t physfree) | ||||
} | } | ||||
gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&common_tss[0]; | gdt_segs[GPROC0_SEL].ssd_base = (uintptr_t)&common_tss[0]; | ||||
ssdtosyssd(&gdt_segs[GPROC0_SEL], | ssdtosyssd(&gdt_segs[GPROC0_SEL], | ||||
(struct system_segment_descriptor *)&gdt[GPROC0_SEL]); | (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); | ||||
r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; | r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; | ||||
r_gdt.rd_base = (long) gdt; | r_gdt.rd_base = (long) gdt; | ||||
lgdt(&r_gdt); | lgdt(&r_gdt); | ||||
pc = &__pcpu[0]; | pc = &temp_bsp_pcpu; | ||||
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, 0); /* User value while in the kernel */ | wrmsr(MSR_KGSBASE, 0); /* User value while in the kernel */ | ||||
pcpu_init(pc, 0, sizeof(struct pcpu)); | pcpu_init(pc, 0, sizeof(struct pcpu)); | ||||
dpcpu_init((void *)(physfree + KERNBASE), 0); | dpcpu_init((void *)(physfree + KERNBASE), 0); | ||||
physfree += DPCPU_SIZE; | physfree += DPCPU_SIZE; | ||||
PCPU_SET(prvspace, pc); | amd64_bsp_pcpu_init1(pc); | ||||
PCPU_SET(curthread, &thread0); | |||||
/* Non-late cninit() and printf() can be moved up to here. */ | /* Non-late cninit() and printf() can be moved up to here. */ | ||||
PCPU_SET(tssp, &common_tss[0]); | |||||
PCPU_SET(commontssp, &common_tss[0]); | |||||
PCPU_SET(tss, (struct system_segment_descriptor *)&gdt[GPROC0_SEL]); | |||||
PCPU_SET(ldt, (struct system_segment_descriptor *)&gdt[GUSERLDT_SEL]); | |||||
PCPU_SET(fs32p, &gdt[GUFS32_SEL]); | |||||
PCPU_SET(gs32p, &gdt[GUGS32_SEL]); | |||||
/* | /* | ||||
* Initialize mutexes. | * Initialize mutexes. | ||||
* | * | ||||
* icu_lock: in order to allow an interrupt to occur in a critical | * icu_lock: in order to allow an interrupt to occur in a critical | ||||
* section, to set pcpu->ipending (etc...) properly, we | * section, to set pcpu->ipending (etc...) properly, we | ||||
* must be able to get the icu lock, so it can't be | * must be able to get the icu lock, so it can't be | ||||
* under witness. | * under witness. | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | #endif | ||||
TUNABLE_INT_FETCH("hw.spec_store_bypass_disable", &hw_ssb_disable); | TUNABLE_INT_FETCH("hw.spec_store_bypass_disable", &hw_ssb_disable); | ||||
TUNABLE_INT_FETCH("machdep.syscall_ret_l1d_flush", | TUNABLE_INT_FETCH("machdep.syscall_ret_l1d_flush", | ||||
&syscall_ret_l1d_flush_mode); | &syscall_ret_l1d_flush_mode); | ||||
TUNABLE_INT_FETCH("hw.mds_disable", &hw_mds_disable); | TUNABLE_INT_FETCH("hw.mds_disable", &hw_mds_disable); | ||||
finishidentcpu(); /* Final stage of CPU initialization */ | finishidentcpu(); /* Final stage of CPU initialization */ | ||||
initializecpu(); /* Initialize CPU registers */ | initializecpu(); /* Initialize CPU registers */ | ||||
/* doublefault stack space, runs on ist1 */ | amd64_bsp_ist_init(pc); | ||||
common_tss[0].tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)]; | |||||
/* | |||||
* NMI stack, runs on ist2. The pcpu pointer is stored just | |||||
* above the start of the ist2 stack. | |||||
*/ | |||||
np = ((struct nmi_pcpu *) &nmi0_stack[sizeof(nmi0_stack)]) - 1; | |||||
np->np_pcpu = (register_t) pc; | |||||
common_tss[0].tss_ist2 = (long) np; | |||||
/* | |||||
* MC# stack, runs on ist3. The pcpu pointer is stored just | |||||
* above the start of the ist3 stack. | |||||
*/ | |||||
np = ((struct nmi_pcpu *) &mce0_stack[sizeof(mce0_stack)]) - 1; | |||||
np->np_pcpu = (register_t) pc; | |||||
common_tss[0].tss_ist3 = (long) np; | |||||
/* | |||||
* DB# stack, runs on ist4. | |||||
*/ | |||||
np = ((struct nmi_pcpu *) &dbg0_stack[sizeof(dbg0_stack)]) - 1; | |||||
np->np_pcpu = (register_t) pc; | |||||
common_tss[0].tss_ist4 = (long) np; | |||||
/* Set the IO permission bitmap (empty due to tss seg limit) */ | /* Set the IO permission bitmap (empty due to tss seg limit) */ | ||||
common_tss[0].tss_iobase = sizeof(struct amd64tss) + IOPERM_BITMAP_SIZE; | common_tss[0].tss_iobase = sizeof(struct amd64tss) + IOPERM_BITMAP_SIZE; | ||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); | gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); | ||||
ltr(gsel_tss); | ltr(gsel_tss); | ||||
amd64_conf_fast_syscall(); | amd64_conf_fast_syscall(); | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | xhdr = (struct xstate_hdr *)(get_pcb_user_save_td(&thread0) + | ||||
1); | 1); | ||||
xhdr->xstate_bv = xsave_mask; | xhdr->xstate_bv = xsave_mask; | ||||
} | } | ||||
/* make an initial tss so cpu can get interrupt stack on syscall! */ | /* make an initial tss so cpu can get interrupt stack on syscall! */ | ||||
rsp0 = (vm_offset_t)thread0.td_pcb; | rsp0 = (vm_offset_t)thread0.td_pcb; | ||||
/* Ensure the stack is aligned to 16 bytes */ | /* Ensure the stack is aligned to 16 bytes */ | ||||
rsp0 &= ~0xFul; | rsp0 &= ~0xFul; | ||||
common_tss[0].tss_rsp0 = rsp0; | common_tss[0].tss_rsp0 = rsp0; | ||||
PCPU_SET(rsp0, rsp0); | amd64_bsp_pcpu_init2(rsp0); | ||||
PCPU_SET(pti_rsp0, ((vm_offset_t)PCPU_PTR(pti_stack) + | |||||
PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful); | |||||
PCPU_SET(curpcb, thread0.td_pcb); | |||||
/* transfer to user mode */ | /* transfer to user mode */ | ||||
_ucodesel = GSEL(GUCODE_SEL, SEL_UPL); | _ucodesel = GSEL(GUCODE_SEL, SEL_UPL); | ||||
_udatasel = GSEL(GUDATA_SEL, SEL_UPL); | _udatasel = GSEL(GUDATA_SEL, SEL_UPL); | ||||
_ucode32sel = GSEL(GUCODE32_SEL, SEL_UPL); | _ucode32sel = GSEL(GUCODE32_SEL, SEL_UPL); | ||||
_ufssel = GSEL(GUFS32_SEL, SEL_UPL); | _ufssel = GSEL(GUFS32_SEL, SEL_UPL); | ||||
_ugssel = GSEL(GUGS32_SEL, SEL_UPL); | _ugssel = GSEL(GUGS32_SEL, SEL_UPL); | ||||
▲ Show 20 Lines • Show All 876 Lines • Show Last 20 Lines |
Style: extra space after the cast. This is duplicated below.