Files
lk/arch/riscv/mp.c
Travis Geiselbrecht 90dc9e50ef [platform][sifive-e] get the hifive1 hardware working again
Had rotted a bit. Had to reimplement a few tweaks.
Also generally #if out a lot of the SMP code when unused on riscv.
2020-01-18 18:39:07 -08:00

81 lines
1.9 KiB
C

/*
* Copyright (c) 2019 Elliot Berman
*
* Use of this source code is governed by a MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT
*/
#include <lk/reg.h>
#include <lk/debug.h>
#include <lk/trace.h>
#include <lk/err.h>
#include <arch/ops.h>
#include <arch/mp.h>
#if WITH_SMP
#define LOCAL_TRACE 0
int hart_cpu_map[SMP_MAX_CPUS] = { [0 ... SMP_MAX_CPUS-1] = -1 };
static mp_ipi_t ipi_data[SMP_MAX_CPUS];
extern void clint_ipi_send(unsigned long target_hart);
extern void clint_ipi_clear(unsigned long target_hart);
status_t arch_mp_send_ipi(mp_cpu_mask_t target, mp_ipi_t ipi) {
LTRACEF("target 0x%x, ipi %u\n", target, ipi);
unsigned long hart_mask = 0;
unsigned long c = 0, h;
mp_cpu_mask_t m = target;
for (; c < SMP_MAX_CPUS && m; c++, m >>= 1) {
h = hart_cpu_map[c];
if (m & 1) {
hart_mask |= (1 << h);
}
// TODO: set the ipi_data based on the incoming ipi
}
asm volatile(" fence iorw,iorw");
#if RISCV_M_MODE
clint_send_ipis(&hart_mask);
#else
sbi_send_ipis(&hart_mask);
#endif
return NO_ERROR;
}
enum handler_return riscv_software_exception(void) {
#if RISCV_M_MODE
clint_ipi_clear(riscv_current_hart());
#else
sbi_clear_ipi();
#endif
asm volatile(" fence ir,ir");
mp_ipi_t reason = ipi_data[riscv_current_hart()];
ipi_data[riscv_current_hart()] = 0;
switch (reason) {
case MP_IPI_RESCHEDULE:
return INT_RESCHEDULE;
case MP_IPI_GENERIC:
break;
default:
TRACEF("unhandled ipi cause %#x, hartid %#x\n", reason, riscv_current_hart());
panic("stopping");
break;
}
return INT_NO_RESCHEDULE;
}
void arch_mp_init_percpu(void) {
dprintf(INFO, "\nRISCV: Booting hart%d (cpu%d)\n", riscv_current_hart(), arch_curr_cpu_num());
riscv_csr_set(RISCV_CSR_XIE, RISCV_CSR_XIE_SIE);
}
#endif