#include <sys/types.h>
#include <sys/systm.h>
#include <sys/archsystm.h>
#include <sys/machsystm.h>
#include <sys/cpu_module.h>
#include <sys/xc_impl.h>
#include <sys/intreg.h>
#include <sys/kdi_impl.h>
static int kdi_dcache_size;
static int kdi_dcache_linesize;
static int kdi_icache_size;
static int kdi_icache_linesize;
extern int idsr_busy(void);
extern void init_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2);
extern void shipit(int, int);
extern void kdi_flush_idcache(int, int, int, int);
extern int kdi_get_stick(uint64_t *);
static void kdi_tickwait(clock_t);
static int
kdi_cpu_ready_iter(int (*cb)(int, void *), void *arg)
{
int rc, i;
for (rc = 0, i = 0; i < NCPU; i++) {
if (CPU_IN_SET(cpu_ready_set, i))
rc += cb(i, arg);
}
return (rc);
}
static int
kdi_xc_one(int cpuid, void (*func)(uintptr_t, uintptr_t), uintptr_t arg1,
uintptr_t arg2)
{
uint64_t idsr;
uint64_t endtick, tick;
init_mondo_nocheck((xcfunc_t *)func, arg1, arg2);
shipit(cpuid, 0);
endtick = gettick() + (uint64_t)sys_tick_freq;
idsr = getidsr();
if (idsr & IDSR_BUSY) {
do {
idsr = getidsr();
tick = gettick();
if (tick > endtick) {
return (KDI_XC_RES_BUSY);
}
} while (idsr & IDSR_BUSY);
}
kdi_tickwait(20000);
if (idsr & IDSR_NACK)
return (KDI_XC_RES_NACK);
else
return (KDI_XC_RES_OK);
}
static void
kdi_tickwait(clock_t nticks)
{
clock_t endtick = gettick() + nticks;
while (gettick() < endtick)
;
}
static void
kdi_cpu_init(int dcache_size, int dcache_linesize, int icache_size,
int icache_linesize)
{
kdi_dcache_size = dcache_size;
kdi_dcache_linesize = dcache_linesize;
kdi_icache_size = icache_size;
kdi_icache_linesize = icache_linesize;
}
void
kdi_flush_caches(void)
{
kdi_flush_idcache(kdi_dcache_size, kdi_dcache_linesize,
kdi_icache_size, kdi_icache_linesize);
}
void
cpu_kdi_init(kdi_t *kdi)
{
kdi->kdi_flush_caches = kdi_flush_caches;
kdi->mkdi_cpu_init = kdi_cpu_init;
kdi->mkdi_cpu_ready_iter = kdi_cpu_ready_iter;
kdi->mkdi_xc_one = kdi_xc_one;
kdi->mkdi_tickwait = kdi_tickwait;
kdi->mkdi_get_stick = kdi_get_stick;
}