#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.35 2023/12/20 15:29:07 thorpej Exp $");
#include "opt_pci.h"
#include "pci.h"
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <machine/autoconf.h>
#include <machine/bootinfo.h>
#include <machine/isa_machdep.h>
#include <powerpc/oea/spr.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pciconf.h>
int mainbus_match(device_t, cfdata_t, void *);
void mainbus_attach(device_t, device_t, void *);
int mainbus_print(void *, const char *);
CFATTACH_DECL_NEW(mainbus, 0,
mainbus_match, mainbus_attach, NULL, NULL);
struct powerpc_isa_chipset genppc_ict;
#define PCI_IO_START 0x00001000
#define PCI_IO_END 0x0000ffff
#define PCI_IO_SIZE ((PCI_IO_END - PCI_IO_START) + 1)
#define PCI_MEM_START 0x80000000U
#define PCI_MEM_END 0x8fffffffU
#define PCI_MEM_SIZE ((PCI_MEM_END - PCI_MEM_START) + 1)
int
mainbus_match(device_t parent, cfdata_t match, void *aux)
{
return 1;
}
void
mainbus_attach(device_t parent, device_t self, void *aux)
{
struct mainbus_attach_args mba;
struct pcibus_attach_args pba;
struct btinfo_prodfamily *pfam;
aprint_naive("\n");
aprint_normal("\n");
mba.ma_name = "cpu";
config_found(self, &mba, mainbus_print,
CFARGS(.iattr = "mainbus"));
mba.ma_name = "eumb";
mba.ma_bst = &sandpoint_eumb_space_tag;
config_found(self, &mba, mainbus_print,
CFARGS(.iattr = "mainbus"));
pfam = lookup_bootinfo(BTINFO_PRODFAMILY);
if (pfam != NULL && strcmp(pfam->name, "nhnas") == 0) {
mba.ma_name = "nhpow";
mba.ma_bst = &sandpoint_nhgpio_space_tag;
config_found(self, &mba, mainbus_print,
CFARGS(.iattr = "mainbus"));
}
mba.ma_name = "cfi";
mba.ma_bst = &sandpoint_flash_space_tag;
config_found(self, &mba, mainbus_print,
CFARGS(.iattr = "mainbus"));
#if NPCI > 0
#if defined(PCI_NETBSD_CONFIGURE)
struct pciconf_resources *pcires = pciconf_resource_init();
pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
PCI_IO_START, PCI_IO_SIZE);
pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
PCI_MEM_START, PCI_MEM_SIZE);
pci_configure_bus(0, pcires, 0, 32);
pciconf_resource_fini(pcires);
#endif
pba.pba_iot = &sandpoint_io_space_tag;
pba.pba_memt = &sandpoint_mem_space_tag;
pba.pba_dmat = &pci_bus_dma_tag;
pba.pba_dmat64 = NULL;
pba.pba_bus = 0;
pba.pba_pc = 0;
pba.pba_bridgetag = NULL;
pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
config_found(self, &pba, pcibusprint,
CFARGS(.iattr = "pcibus"));
#endif
}
static int cpu_match(device_t, cfdata_t, void *);
static void cpu_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(cpu, 0, cpu_match, cpu_attach, NULL, NULL);
extern struct cfdriver cpu_cd;
int
cpu_match(device_t parent, cfdata_t cf, void *aux)
{
struct mainbus_attach_args *mba = aux;
if (strcmp(mba->ma_name, cpu_cd.cd_name) != 0)
return 0;
if (cpu_info[0].ci_dev != NULL)
return 0;
return 1;
}
void
cpu_attach(device_t parent, device_t self, void *aux)
{
static uint8_t mem_to_cpuclk[] = {
25, 30, 45, 20, 20, 00, 10, 30,
30, 20, 45, 30, 25, 35, 30, 35,
20, 25, 20, 30, 35, 40, 40, 20,
30, 25, 40, 30, 30, 25, 35, 00
};
extern u_long ticks_per_sec;
struct cpu_info *ci;
u_int hid1, vers;
ci = cpu_attach_common(self, 0);
if (ci == NULL)
return;
vers = (mfpvr() >> 16) & 0xffff;
if (ci->ci_khz == 0 && vers == MPC8245) {
asm volatile ("mfspr %0,1009" : "=r"(hid1));
ci->ci_khz = ((uint64_t)ticks_per_sec * 4 *
mem_to_cpuclk[hid1 >> 27] + 10) / 10000;
aprint_normal_dev(self, "%u.%02u MHz\n",
ci->ci_khz / 1000, (ci->ci_khz / 10) % 100);
}
}
int
mainbus_print(void *aux, const char *pnp)
{
struct mainbus_attach_args *mba = aux;
if (pnp)
aprint_normal("%s at %s", mba->ma_name, pnp);
return UNCONF;
}