#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: platform_160x.c,v 1.9 2014/03/26 17:44:36 christos Exp $");
#include <sys/param.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <machine/cpu.h>
#include <machine/bootinfo.h>
#include <machine/pio.h>
#include <machine/platform.h>
#include <arch/powerpc/pic/picvar.h>
static int p160x_match(struct platform *);
static void p160x_pci_intr_fixup(int, int, int *);
static void p160x_cpu_setup(device_t);
static void p160x_reset(void);
static void p160x_pic_setup(void);
struct platform platform_160x = {
NULL,
p160x_pic_setup,
p160x_match,
p160x_pci_intr_fixup,
p160x_cpu_setup,
p160x_reset
};
struct ppcbug_brdid {
char version[4];
char serial[12];
char id[16];
char pwa[16];
char reserved_0[4];
char ethernet_adr[6];
char reserved_1[2];
char lscsiid[2];
char speed_mpu[3];
char speed_bus[3];
char reserved[187];
char cksum[1];
};
#define NVRAM_BRDID_OFF 0x1ef8
static void p160x_get_brdid(struct ppcbug_brdid *);
static char p160x_model[64];
static u_int32_t p160x_dram_size[] = {
0x08000000, 0x02000000, 0x00800000, 0x00000000,
0x10000000, 0x04000000, 0x01000000, 0x00000000
};
extern struct pic_ops *isa_pic;
static int
p160x_match(struct platform *p)
{
struct ppcbug_brdid bid;
char speed[4], *cp;
u_int8_t dsr;
if (MVMEPPC_FAMILY(bootinfo.bi_modelnumber) != MVMEPPC_FAMILY_160x)
return(0);
p160x_get_brdid(&bid);
for (cp = &bid.id[sizeof(bid.id) - 1]; *cp == ' '; cp--)
*cp = '\0';
for (cp = &bid.serial[sizeof(bid.serial) - 1]; *cp == ' '; cp--)
*cp = '\0';
for (cp = &bid.pwa[sizeof(bid.pwa) - 1]; *cp == ' '; cp--)
*cp = '\0';
snprintf(p160x_model, sizeof(p160x_model),
"%s, Serial: %s, PWA: %s", bid.id, bid.serial, bid.pwa);
p->model = p160x_model;
speed[3] = '\0';
strncpy(speed, bid.speed_mpu, sizeof(bid.speed_mpu));
bootinfo.bi_mpuspeed = strtoul(speed, NULL, 10) * 1000000;
strncpy(speed, bid.speed_bus, sizeof(bid.speed_bus));
bootinfo.bi_busspeed = strtoul(speed, NULL, 10) * 1000000;
bootinfo.bi_clocktps = bootinfo.bi_busspeed / 4;
dsr = inb(0x80000804);
bootinfo.bi_memsize = p160x_dram_size[dsr & 0x7];
bootinfo.bi_memsize += p160x_dram_size[(dsr >> 4) & 0x7];
return(1);
}
static void
p160x_pci_intr_fixup(int bus, int dev, int *line)
{
aprint_verbose("p160x_pci_intr_fixup: bus=%d, dev=%d, line=%d\n",
bus, dev, *line);
}
static void
p160x_cpu_setup(device_t dev)
{
}
static void
p160x_pic_setup(void)
{
pic_init();
isa_pic = setup_i8259();
oea_install_extint(pic_ext_intr);
}
static void
p160x_reset(void)
{
outb(0x80000092, inb(0x80000092) | 1);
}
static void
p160x_get_brdid(struct ppcbug_brdid *bid)
{
u_int8_t *pbid = (u_int8_t *)bid;
int off;
int i;
for (i = 0, off = NVRAM_BRDID_OFF; i < sizeof(*bid); i++, off++) {
outb(0x80000074, off & 0xff);
outb(0x80000075, (off >> 8) & 0xff);
pbid[i] = inb(0x80000077);
}
}