#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18 2011/07/01 20:52:02 dyoung Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <sys/bus.h>
#include <machine/cpu.h>
#include <machine/platform.h>
#ifdef MULTIPROCESSOR
#include <arch/powerpc/pic/picvar.h>
#include <arch/powerpc/pic/ipivar.h>
#include <powerpc/openpic.h>
#include <powerpc/trap.h>
extern void openpic_set_priority(int, int);
#endif
int cpumatch(device_t, cfdata_t, void *);
void cpuattach(device_t, device_t, void *);
CFATTACH_DECL_NEW(cpu, 0,
cpumatch, cpuattach, NULL, NULL);
extern struct cfdriver cpu_cd;
int
cpumatch(device_t parent, cfdata_t cfdata, void *aux)
{
struct confargs *ca = aux;
if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0)
return (0);
#if 0
if (cpu_info[0].ci_dev != NULL)
return (0);
#endif
return (1);
}
void
cpuattach(device_t parent, device_t self, void *aux)
{
struct cpu_info *ci;
struct confargs *ca = aux;
int id = ca->ca_node;
ci = cpu_attach_common(self, id);
if (ci == NULL)
return;
#ifdef MULTIPROCESSOR
if (id > 0) {
cpu_spinup(self, ci);
return;
}
#endif
cpu_setup_prep_generic(self);
}
#ifdef MULTIPROCESSOR
int
md_setup_trampoline(volatile struct cpu_hatch_data *h, struct cpu_info *ci)
{
if (!openpic_base)
return -1;
*(u_int *)EXC_RST = 0x48000002 | (u_int)cpu_spinup_trampoline;
__syncicache((void *)EXC_RST, 0x100);
h->hatch_running = -1;
openpic_write(OPENPIC_PROC_INIT, (1 << 1));
return 1;
}
void
md_presync_timebase(volatile struct cpu_hatch_data *h)
{
uint64_t tb;
tb = mftb();
tb += 100000;
h->hatch_tbu = tb >> 32;
h->hatch_tbl = tb & 0xffffffff;
while (tb > mftb())
;
__asm volatile ("sync; isync");
h->hatch_running = 0;
delay(500000);
}
void
md_start_timebase(volatile struct cpu_hatch_data *h)
{
}
void
md_sync_timebase(volatile struct cpu_hatch_data *h)
{
u_int tbu = h->hatch_tbu;
u_int tbl = h->hatch_tbl;
while (h->hatch_running == -1)
;
__asm volatile ("sync; isync");
__asm volatile ("mttbl %0" :: "r"(0));
__asm volatile ("mttbu %0" :: "r"(tbu));
__asm volatile ("mttbl %0" :: "r"(tbl));
}
void
md_setup_interrupts(void)
{
if (!openpic_base)
return;
openpic_write(OPENPIC_PROC_INIT, 0);
openpic_set_priority(cpu_number(), 0);
}
#endif