#include "locators.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rmixl_cpucore.c,v 1.7 2021/08/07 16:18:59 thorpej Exp $");
#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/cpu.h>
#include <uvm/uvm_extern.h>
#include <mips/rmi/rmixlvar.h>
#include <mips/rmi/rmixl_cpunodevar.h>
#include <mips/rmi/rmixl_cpucorevar.h>
#include <mips/rmi/rmixl_fmnvar.h>
static int cpucore_rmixl_match(device_t, cfdata_t, void *);
static void cpucore_rmixl_attach(device_t, device_t, void *);
static int cpucore_rmixl_print(void *, const char *);
CFATTACH_DECL_NEW(cpucore_rmixl, sizeof(struct cpucore_softc),
cpucore_rmixl_match, cpucore_rmixl_attach, NULL, NULL);
static int
cpucore_rmixl_match(device_t parent, cfdata_t cf, void *aux)
{
struct cpunode_attach_args *na = aux;
int core = cf->cf_loc[CPUNODECF_CORE];
if (!cpu_rmixl(mips_options.mips_cpu))
return 0;
if (strncmp(na->na_name, cf->cf_name, strlen(cf->cf_name)) == 0
#ifndef MULTIPROCESSOR
&& na->na_core == 0
#endif
&& (core == CPUNODECF_CORE_DEFAULT || core == na->na_core))
return 1;
return 0;
}
static void
cpucore_rmixl_attach(device_t parent, device_t self, void *aux)
{
struct cpucore_softc * const sc = device_private(self);
struct cpunode_attach_args *na = aux;
struct cpucore_attach_args ca;
u_int nthreads;
struct rmixl_config *rcp = &rmixl_configuration;
sc->sc_dev = self;
sc->sc_core = na->na_core;
KASSERT(sc->sc_hatched == false);
#if 0
#ifdef MULTIPROCESSOR
if (sc->sc_core == 0) {
sc->sc_tlbinfo = &pmap_tlb0_info;
} else {
const vaddr_t va = (vaddr_t)&sc->sc_tlbinfo0;
paddr_t pa;
if (! pmap_extract(pmap_kernel(), va, &pa))
panic("%s: pmap_extract fail, va %#"PRIxVADDR, __func__, va);
#ifdef _LP64
sc->sc_tlbinfo = (struct pmap_tlb_info *)
MIPS_PHYS_TO_XKPHYS_CACHED(pa);
#else
sc->sc_tlbinfo = (struct pmap_tlb_info *)
MIPS_PHYS_TO_KSEG0(pa);
#endif
pmap_tlb_info_init(sc->sc_tlbinfo);
}
#endif
#endif
aprint_normal("\n");
aprint_normal_dev(self, "%lu.%02luMHz (hz cycles = %lu, "
"delay divisor = %lu)\n",
curcpu()->ci_cpu_freq / 1000000,
(curcpu()->ci_cpu_freq % 1000000) / 10000,
curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay);
aprint_normal("%s: ", device_xname(self));
cpu_identify(self);
nthreads = MIPS_CIDFL_RMI_NTHREADS(mips_options.mips_cpu->cpu_cidflags);
aprint_normal_dev(self, "%d %s on core\n", nthreads,
nthreads == 1 ? "thread" : "threads");
u_int thread_mask = (1 << nthreads) - 1;
u_int core_shft = sc->sc_core * nthreads;
u_int threads_enb =
(u_int)(rcp->rc_psb_info.userapp_cpu_map >> core_shft) & thread_mask;
u_int threads_dis = (~threads_enb) & thread_mask;
sc->sc_threads_dis = threads_dis;
if (threads_dis != 0) {
aprint_normal_dev(self, "threads");
u_int d = threads_dis;
while (d != 0) {
const u_int t = ffs(d) - 1;
d ^= (1 << t);
aprint_normal(" %d%s", t, (d==0) ? "" : ",");
}
aprint_normal(" offline (disabled by firmware)\n");
}
u_int threads_try_attach = threads_enb;
while (threads_try_attach != 0) {
const u_int t = ffs(threads_try_attach) - 1;
const u_int bit = 1 << t;
threads_try_attach ^= bit;
ca.ca_name = "cpu";
ca.ca_thread = t;
ca.ca_core = sc->sc_core;
if (config_found(self, &ca, cpucore_rmixl_print,
CFARGS_NONE) == NULL) {
threads_enb ^= bit;
threads_dis |= bit;
}
}
sc->sc_threads_enb = threads_enb;
sc->sc_threads_dis = threads_dis;
if (sc->sc_core == RMIXL_CPU_CORE((curcpu()->ci_cpuid)))
cpucore_rmixl_run(self);
}
static int
cpucore_rmixl_print(void *aux, const char *pnp)
{
struct cpucore_attach_args *ca = aux;
if (pnp != NULL)
aprint_normal("%s:", pnp);
aprint_normal(" thread %d", ca->ca_thread);
return (UNCONF);
}
void
cpucore_rmixl_run(device_t self)
{
struct cpucore_softc * const sc = device_private(self);
if (sc->sc_running == false) {
sc->sc_running = true;
rmixl_mtcr(RMIXL_PCR_THREADEN, sc->sc_threads_enb);
rmixl_mtcr(RMIXL_PCR_SCHEDULING, 0);
}
}
#ifdef MULTIPROCESSOR
void
cpucore_rmixl_hatch(device_t self)
{
struct cpucore_softc * const sc = device_private(self);
if (sc->sc_hatched == false) {
if (sc->sc_core != 0)
rmixl_pcr_init_core();
rmixl_fmn_init_core();
sc->sc_hatched = true;
}
}
#endif