Index: sys/riscv/include/md_var.h =================================================================== --- sys/riscv/include/md_var.h +++ sys/riscv/include/md_var.h @@ -39,6 +39,7 @@ extern uint64_t *vm_page_dump; extern int vm_page_dump_size; extern u_long elf_hwcap; +extern u_int cpuid_hart_map[]; struct dumperinfo; Index: sys/riscv/riscv/machdep.c =================================================================== --- sys/riscv/riscv/machdep.c +++ sys/riscv/riscv/machdep.c @@ -118,8 +118,9 @@ int64_t icache_line_size; /* The minimum I cache line size */ int64_t idcache_line_size; /* The minimum cache line size */ -uint32_t boot_hart; /* The hart we booted on. */ +uint32_t boot_hart; /* The hart we booted on. */ cpuset_t all_harts; +u_int cpuid_hart_map[MAXCPU]; /* Mapping between cpuid and hart number */ extern int *end; extern int *initstack_end; @@ -846,6 +847,9 @@ PCPU_SET(curthread, &thread0); + /* Set the boot hart mapping */ + cpuid_hart_map[0] = boot_hart; + /* Set the module data location */ lastaddr = fake_preload_metadata(rvbp); Index: sys/riscv/riscv/mp_machdep.c =================================================================== --- sys/riscv/riscv/mp_machdep.c +++ sys/riscv/riscv/mp_machdep.c @@ -62,6 +62,7 @@ #include #include +#include #include #include @@ -424,6 +425,9 @@ dpcpu[cpuid - 1] = (void *)kmem_malloc(DPCPU_SIZE, M_WAITOK | M_ZERO); dpcpu_init(dpcpu[cpuid - 1], cpuid); + /* Set the cpuid to hart mapping */ + cpuid_hart_map[cpuid] = hart; + printf("Starting CPU %u (hart %lx)\n", cpuid, hart); __riscv_boot_ap[hart] = 1; Index: sys/riscv/riscv/plic.c =================================================================== --- sys/riscv/riscv/plic.c +++ sys/riscv/riscv/plic.c @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -101,16 +102,16 @@ struct plic_softc *sc; struct trapframe *tf; uint32_t pending; - uint32_t cpu; + uint32_t hart; sc = arg; - cpu = PCPU_GET(cpuid); + hart = cpuid_hart_map[PCPU_GET(cpuid)]; - pending = RD4(sc, PLIC_CLAIM(cpu)); + pending = RD4(sc, PLIC_CLAIM(hart)); if (pending) { tf = curthread->td_intr_frame; plic_irq_dispatch(sc, pending, tf); - WR4(sc, PLIC_CLAIM(cpu), pending); + WR4(sc, PLIC_CLAIM(hart), pending); } return (FILTER_HANDLED); @@ -123,14 +124,16 @@ struct plic_irqsrc *src; uint32_t reg; uint32_t cpu; + uint32_t hart; sc = device_get_softc(dev); src = (struct plic_irqsrc *)isrc; CPU_FOREACH(cpu) { - reg = RD4(sc, PLIC_ENABLE(src->irq, cpu)); + hart = cpuid_hart_map[cpu]; + reg = RD4(sc, PLIC_ENABLE(src->irq, hart)); reg &= ~(1 << (src->irq % 32)); - WR4(sc, PLIC_ENABLE(src->irq, cpu), reg); + WR4(sc, PLIC_ENABLE(src->irq, hart), reg); } } @@ -141,14 +144,16 @@ struct plic_irqsrc *src; uint32_t reg; uint32_t cpu; + uint32_t hart; sc = device_get_softc(dev); src = (struct plic_irqsrc *)isrc; CPU_FOREACH(cpu) { - reg = RD4(sc, PLIC_ENABLE(src->irq, cpu)); + hart = cpuid_hart_map[cpu]; + reg = RD4(sc, PLIC_ENABLE(src->irq, hart)); reg |= (1 << (src->irq % 32)); - WR4(sc, PLIC_ENABLE(src->irq, cpu), reg); + WR4(sc, PLIC_ENABLE(src->irq, hart), reg); } } @@ -200,6 +205,7 @@ phandle_t node; phandle_t xref; uint32_t cpu; + uint32_t hart; int error; int rid; @@ -247,13 +253,16 @@ */ WR4(sc, PLIC_PRIORITY(irq), 0); CPU_FOREACH(cpu) { - reg = RD4(sc, PLIC_ENABLE(irq, cpu)); + hart = cpuid_hart_map[cpu]; + reg = RD4(sc, PLIC_ENABLE(irq, hart)); reg &= ~(1 << (irq % 32)); - WR4(sc, PLIC_ENABLE(irq, cpu), reg); + WR4(sc, PLIC_ENABLE(irq, hart), reg); } } - CPU_FOREACH(cpu) - WR4(sc, PLIC_THRESHOLD(cpu), 0); + CPU_FOREACH(cpu) { + hart = cpuid_hart_map[cpu]; + WR4(sc, PLIC_THRESHOLD(hart), 0); + } xref = OF_xref_from_node(node); pic = intr_pic_register(sc->dev, xref);