#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.12 2012/10/20 14:53:37 kiyohara Exp $");
#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <powerpc/oea/hid.h>
#include <powerpc/oea/spr.h>
#include <powerpc/spr.h>
#include <uvm/uvm.h>
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;
return 1;
}
void
cpuattach(device_t parent, device_t self, void *aux)
{
struct confargs *ca = aux;
struct cpu_info *ci;
int id = ca->ca_node;
ci = cpu_attach_common(self, id);
if (ci == NULL)
return;
#ifdef MULTIPROCESSOR
if (id > 0)
cpu_spinup(self, ci);
#endif
}
#ifdef MULTIPROCESSOR
extern volatile u_int cpu_spinstart_ack, cpu_spinstart_cpunum;
int
md_setup_trampoline(volatile struct cpu_hatch_data *h, struct cpu_info *ci)
{
int blocks, i;
extern void cache_flush_invalidate_all(int blocks);
h->hatch_running = -1;
cpu_spinstart_ack = -1;
blocks = curcpu()->ci_ci.dcache_size / curcpu()->ci_ci.dcache_line_size;
cache_flush_invalidate_all(blocks);
cpu_spinstart_cpunum = ci->ci_cpuid;
__asm volatile("dcbf 0,%0"::"r"(&cpu_spinstart_cpunum):"memory");
for (i = 0; i < 100000000; i++) {
if (cpu_spinstart_ack != -1)
break;
__asm volatile("dcbi 0,%0"::"r"(&cpu_spinstart_ack):"memory");
__asm volatile("sync; isync");
}
return 1;
}
void
md_presync_timebase(volatile struct cpu_hatch_data *h)
{
uint64_t tb;
tb = mftb();
tb += 1000000;
h->hatch_tbu = tb >> 32;
h->hatch_tbl = tb & 0xffffffff;
while (tb > mftb())
;
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, tbl;
do {
__asm volatile("dcbi 0,%0"::"r"(&h->hatch_running):"memory");
__asm volatile("sync; isync");
__asm volatile("dcbst 0,%0"::"r"(&h->hatch_running):"memory");
__asm volatile("sync; isync");
} while (h->hatch_running == -1);
__asm volatile("dcbi 0,%0"::"r"(&h->hatch_tbu):"memory");
__asm volatile("dcbi 0,%0"::"r"(&h->hatch_tbl):"memory");
__asm volatile("sync; isync");
__asm volatile("dcbst 0,%0"::"r"(&h->hatch_tbu):"memory");
__asm volatile("dcbst 0,%0"::"r"(&h->hatch_tbl):"memory");
__asm volatile("sync; isync");
tbu = h->hatch_tbu;
tbl = h->hatch_tbl;
__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)
{
CLEAR_BEBOX_REG(CPU1_INT_MASK, BEBOX_INTR_MASK);
}
#endif