#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <machine/autoconf.h>
#include <dev/ofw/openfirm.h>
static int mbmatch(struct device *, void *, void *);
static void mbattach(struct device *, struct device *, void *);
static int mbprint(void *, const char *);
const struct cfattach mainbus_ca = {
sizeof(struct device), mbmatch, mbattach
};
struct cfdriver mainbus_cd = {
NULL, "mainbus", DV_DULL
};
#define HH_REG_CONF 0x90
static int
mbmatch(struct device *parent, void *cfdata, void *aux)
{
return(1);
}
static void
mbattach(struct device *parent, struct device *self, void *aux)
{
struct confargs nca;
char name[64], *t = NULL;
int reg[4], cpucnt;
int node, len, tlen;
node = OF_peer(0);
len = OF_getprop(node, "model", name, sizeof(name));
if (len > 1) {
name[len] = '\0';
tlen = strlen(name)+1;
if ((t = malloc(tlen, M_DEVBUF, M_NOWAIT)) != NULL)
strlcpy(t, name, tlen);
}
len = OF_getprop(node, "compatible", name, sizeof(name));
if (len > 1) {
name[len] = '\0';
if ((strncmp(name, "AAPL", 4)) == 0) {
size_t plen;
hw_vendor = "Apple Computer, Inc.";
plen = strlen(t) + strlen(name) - 3;
if ((hw_prod = malloc(plen, M_DEVBUF, M_NOWAIT)) != NULL) {
snprintf(hw_prod, plen, "%s %s", t, name + 5);
free(t, M_DEVBUF, tlen);
}
} else {
hw_vendor = "Apple Computer, Inc.";
hw_prod = t;
}
}
printf(": model %s\n", hw_prod);
cpucnt = 0;
ncpusfound = 0;
node = OF_finddevice("/cpus");
if (node != -1) {
for (node = OF_child(node); node != 0; node = OF_peer(node)) {
u_int32_t cpunum;
int len;
len = OF_getprop(node, "reg", &cpunum, sizeof cpunum);
if (len == 4 && cpucnt == cpunum) {
nca.ca_name = "cpu";
nca.ca_reg = reg;
reg[0] = cpucnt;
config_found(self, &nca, mbprint);
ncpusfound++;
cpucnt++;
}
}
}
if (cpucnt == 0) {
nca.ca_name = "cpu";
nca.ca_reg = reg;
reg[0] = 0;
ncpusfound++;
config_found(self, &nca, mbprint);
}
node = OF_finddevice("/hammerhead");
if (node != -1) {
len = OF_getprop(node, "reg", reg, sizeof(reg));
if (len >= 2) {
u_char *hh_base;
int twoway = 0;
if ((hh_base = mapiodev(reg[0], reg[1])) != NULL) {
twoway = in32rb(hh_base + HH_REG_CONF) & 0x02;
unmapiodev(hh_base, reg[1]);
}
if (twoway) {
nca.ca_name = "cpu";
nca.ca_reg = reg;
reg[0] = 1;
ncpusfound++;
config_found(self, &nca, mbprint);
}
}
}
for (node = OF_child(OF_peer(0)); node; node=OF_peer(node)) {
bzero (name, sizeof(name));
if (OF_getprop(node, "device_type", name, sizeof(name)) <= 0) {
if (OF_getprop(node, "name", name, sizeof(name)) <= 0) {
printf ("name not found on node %x\n", node);
continue;
}
}
if (strcmp(name, "memory") == 0) {
nca.ca_name = "mem";
nca.ca_node = node;
config_found(self, &nca, mbprint);
}
if (strcmp(name, "memory-controller") == 0) {
nca.ca_name = "memc";
nca.ca_node = node;
config_found(self, &nca, mbprint);
}
if (strcmp(name, "pci") == 0) {
nca.ca_name = "mpcpcibr";
nca.ca_node = node;
config_found(self, &nca, mbprint);
}
if (strcmp(name, "ht") == 0) {
nca.ca_name = "ht";
nca.ca_node = node;
config_found(self, &nca, mbprint);
}
if (strcmp(name, "smu") == 0) {
nca.ca_name = "smu";
nca.ca_node = node;
config_found(self, &nca, mbprint);
}
}
}
static int
mbprint(void *aux, const char *pnp)
{
struct confargs *ca = aux;
if (pnp)
printf("%s at %s", ca->ca_name, pnp);
return (UNCONF);
}