Index: head/sys/conf/ldscript.riscv =================================================================== --- head/sys/conf/ldscript.riscv +++ head/sys/conf/ldscript.riscv @@ -89,7 +89,11 @@ can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ . = ALIGN(8); - .sdata : { *(.sdata) } + .sdata : + { + __global_pointer$ = . + 0x800; + *(.sdata) + } _edata = .; PROVIDE (edata = .); /* Ensure __bss_start is associated with the next section in case orphan Index: head/sys/riscv/include/asm.h =================================================================== --- head/sys/riscv/include/asm.h +++ head/sys/riscv/include/asm.h @@ -59,7 +59,7 @@ .set alias,sym #define SET_FAULT_HANDLER(handler, tmp) \ - ld tmp, PC_CURTHREAD(gp); \ + ld tmp, PC_CURTHREAD(tp); \ ld tmp, TD_PCB(tmp); /* Load the pcb */ \ sd handler, PCB_ONFAULT(tmp) /* Set the handler */ Index: head/sys/riscv/include/pcpu.h =================================================================== --- head/sys/riscv/include/pcpu.h +++ head/sys/riscv/include/pcpu.h @@ -60,7 +60,7 @@ { struct pcpu *pcpu; - __asm __volatile("mv %0, gp" : "=&r"(pcpu)); + __asm __volatile("mv %0, tp" : "=&r"(pcpu)); return (pcpu); } @@ -70,7 +70,7 @@ { struct thread *td; - __asm __volatile("ld %0, 0(gp)" : "=&r"(td)); + __asm __volatile("ld %0, 0(tp)" : "=&r"(td)); return (td); } Index: head/sys/riscv/riscv/exception.S =================================================================== --- head/sys/riscv/riscv/exception.S +++ head/sys/riscv/riscv/exception.S @@ -44,11 +44,18 @@ addi sp, sp, -(TF_SIZE) sd ra, (TF_RA)(sp) - sd tp, (TF_TP)(sp) -.if \el == 0 /* We came from userspace. Load our pcpu */ +.if \el == 0 /* We came from userspace. */ sd gp, (TF_GP)(sp) - ld gp, (TF_SIZE)(sp) +.option push +.option norelax + /* Load the kernel's global pointer */ + la gp, __global_pointer$ +.option pop + + /* Load our pcpu */ + sd tp, (TF_TP)(sp) + ld tp, (TF_SIZE)(sp) .endif sd t0, (TF_T + 0 * 8)(sp) @@ -128,13 +135,15 @@ ld t0, (TF_SP)(sp) csrw sscratch, t0 - /* And store our pcpu */ - sd gp, (TF_SIZE)(sp) + /* Store our pcpu */ + sd tp, (TF_SIZE)(sp) + ld tp, (TF_TP)(sp) + + /* And restore the user's global pointer */ ld gp, (TF_GP)(sp) .endif ld ra, (TF_RA)(sp) - ld tp, (TF_TP)(sp) ld t0, (TF_T + 0 * 8)(sp) ld t1, (TF_T + 1 * 8)(sp) @@ -175,7 +184,7 @@ 1: csrci sstatus, (SSTATUS_SIE) - ld a1, PC_CURTHREAD(gp) + ld a1, PC_CURTHREAD(tp) lw a2, TD_FLAGS(a1) li a3, (TDF_ASTPENDING|TDF_NEEDRESCHED) Index: head/sys/riscv/riscv/locore.S =================================================================== --- head/sys/riscv/riscv/locore.S +++ head/sys/riscv/riscv/locore.S @@ -171,12 +171,18 @@ li t0, 0 csrw sscratch, t0 + /* Set the global pointer */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop + /* Initialize stack pointer */ la s3, initstack_end mv sp, s3 addi sp, sp, -PCB_SIZE - /* Clear BSS */ + /* Clear BSS */ la s0, _C_LABEL(__bss_start) la s1, _C_LABEL(_end) 1: @@ -251,12 +257,6 @@ hart_lottery: .space 4 - /* Not in use, but required for linking. */ - .align 3 - .globl __global_pointer$ -__global_pointer$: - .space 8 - .globl init_pt_va init_pt_va: .quad pagetable_l2 /* XXX: Keep page tables VA */ @@ -323,6 +323,12 @@ /* Ensure sscratch is zero */ li t0, 0 csrw sscratch, t0 + + /* Set the global pointer */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop call init_secondary END(mpentry) Index: head/sys/riscv/riscv/machdep.c =================================================================== --- head/sys/riscv/riscv/machdep.c +++ head/sys/riscv/riscv/machdep.c @@ -822,7 +822,7 @@ pcpup->pc_hart = boot_hart; /* Set the pcpu pointer */ - __asm __volatile("mv gp, %0" :: "r"(pcpup)); + __asm __volatile("mv tp, %0" :: "r"(pcpup)); PCPU_SET(curthread, &thread0); Index: head/sys/riscv/riscv/mp_machdep.c =================================================================== --- head/sys/riscv/riscv/mp_machdep.c +++ head/sys/riscv/riscv/mp_machdep.c @@ -234,7 +234,7 @@ /* Setup the pcpu pointer */ pcpup = &__pcpu[cpuid]; - __asm __volatile("mv gp, %0" :: "r"(pcpup)); + __asm __volatile("mv tp, %0" :: "r"(pcpup)); /* Workaround: make sure wfi doesn't halt the hart */ csr_set(sie, SIE_SSIE); Index: head/sys/riscv/riscv/swtch.S =================================================================== --- head/sys/riscv/riscv/swtch.S +++ head/sys/riscv/riscv/swtch.S @@ -217,15 +217,14 @@ mv a0, s0 /* Store the new curthread */ - sd a0, PC_CURTHREAD(gp) + sd a0, PC_CURTHREAD(tp) /* And the new pcb */ ld x13, TD_PCB(a0) - sd x13, PC_CURPCB(gp) + sd x13, PC_CURPCB(tp) /* Load registers */ ld ra, (PCB_RA)(x13) ld sp, (PCB_SP)(x13) - ld tp, (PCB_TP)(x13) /* s[0-11] */ ld s0, (PCB_S + 0 * 8)(x13) @@ -267,10 +266,10 @@ */ ENTRY(cpu_switch) /* Store the new curthread */ - sd a1, PC_CURTHREAD(gp) + sd a1, PC_CURTHREAD(tp) /* And the new pcb */ ld x13, TD_PCB(a1) - sd x13, PC_CURPCB(gp) + sd x13, PC_CURPCB(tp) /* Save the old context. */ ld x13, TD_PCB(a0) @@ -278,7 +277,6 @@ /* Store ra, sp and the callee-saved registers */ sd ra, (PCB_RA)(x13) sd sp, (PCB_SP)(x13) - sd tp, (PCB_TP)(x13) /* s[0-11] */ sd s0, (PCB_S + 0 * 8)(x13) @@ -340,7 +338,6 @@ ld x13, TD_PCB(a1) /* Restore the registers */ - ld tp, (PCB_TP)(x13) ld ra, (PCB_RA)(x13) ld sp, (PCB_SP)(x13) @@ -429,15 +426,16 @@ ld a6, (TF_A + 6 * 8)(sp) ld a7, (TF_A + 7 * 8)(sp) - /* Load user ra and sp */ + /* Load user ra and gp */ ld ra, (TF_RA)(sp) + ld gp, (TF_GP)(sp) /* * Store our pcpup on stack, we will load it back * on kernel mode trap. */ - sd gp, (TF_SIZE)(sp) - ld gp, (TF_GP)(sp) + sd tp, (TF_SIZE)(sp) + ld tp, (TF_TP)(sp) /* Save kernel stack so we can use it doing a user trap */ addi sp, sp, TF_SIZE @@ -454,6 +452,7 @@ sd ra, (PCB_RA)(a0) sd sp, (PCB_SP)(a0) sd tp, (PCB_TP)(a0) + sd gp, (PCB_GP)(a0) /* s[0-11] */ sd s0, (PCB_S + 0 * 8)(a0) Index: head/sys/riscv/riscv/vm_machdep.c =================================================================== --- head/sys/riscv/riscv/vm_machdep.c +++ head/sys/riscv/riscv/vm_machdep.c @@ -69,23 +69,12 @@ { struct pcb *pcb2; struct trapframe *tf; - register_t val; if ((flags & RFPROC) == 0) return; - if (td1 == curthread) { - /* - * Save the tp. These normally happen in cpu_switch, - * but if userland changes this then forks this may - * not have happened. - */ - __asm __volatile("mv %0, tp" : "=&r"(val)); - td1->td_pcb->pcb_tp = val; + /* RISCVTODO: save the FPU state here */ - /* RISCVTODO: save the FPU state here */ - } - pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1; @@ -205,15 +194,15 @@ int cpu_set_user_tls(struct thread *td, void *tls_base) { - struct pcb *pcb; if ((uintptr_t)tls_base >= VM_MAXUSER_ADDRESS) return (EINVAL); - pcb = td->td_pcb; - pcb->pcb_tp = (register_t)tls_base + TP_OFFSET; - if (td == curthread) - __asm __volatile("mv tp, %0" :: "r"(pcb->pcb_tp)); + /* + * The user TLS is set by modifying the trapframe's tp value, which + * will be restored when returning to userspace. + */ + td->td_frame->tf_tp = (register_t)tls_base + TP_OFFSET; return (0); }