Module Name: src Committed By: skrll Date: Thu Jan 13 21:15:16 UTC 2011
Modified Files: src/sys/arch/hp700/dev: astro.c dino.c gecko.c lasi.c pdc.c phantomas.c uturn.c src/sys/arch/hp700/gsc: gscbus.c src/sys/arch/hp700/hp700: autoconf.c machdep.c mainbus.c src/sys/arch/hp700/include: autoconf.h iomod.h pdc.h Log Message: Redo the way devices are found. Probe "Snake" machines with PDC_MEMMAP and others with PDC_SYSTEM_MAP. Some PDCs don't tell us about all devices and/or the whole device tree. Walk each bus to find these unreported devices. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/arch/hp700/dev/astro.c cvs rdiff -u -r1.27 -r1.28 src/sys/arch/hp700/dev/dino.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/hp700/dev/gecko.c cvs rdiff -u -r1.18 -r1.19 src/sys/arch/hp700/dev/lasi.c cvs rdiff -u -r1.37 -r1.38 src/sys/arch/hp700/dev/pdc.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/hp700/dev/phantomas.c cvs rdiff -u -r1.13 -r1.14 src/sys/arch/hp700/dev/uturn.c cvs rdiff -u -r1.20 -r1.21 src/sys/arch/hp700/gsc/gscbus.c cvs rdiff -u -r1.35 -r1.36 src/sys/arch/hp700/hp700/autoconf.c cvs rdiff -u -r1.95 -r1.96 src/sys/arch/hp700/hp700/machdep.c cvs rdiff -u -r1.75 -r1.76 src/sys/arch/hp700/hp700/mainbus.c cvs rdiff -u -r1.16 -r1.17 src/sys/arch/hp700/include/autoconf.h cvs rdiff -u -r1.8 -r1.9 src/sys/arch/hp700/include/iomod.h cvs rdiff -u -r1.17 -r1.18 src/sys/arch/hp700/include/pdc.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/hp700/dev/astro.c diff -u src/sys/arch/hp700/dev/astro.c:1.12 src/sys/arch/hp700/dev/astro.c:1.13 --- src/sys/arch/hp700/dev/astro.c:1.12 Tue Jan 4 10:42:33 2011 +++ src/sys/arch/hp700/dev/astro.c Thu Jan 13 21:15:13 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: astro.c,v 1.12 2011/01/04 10:42:33 skrll Exp $ */ +/* $NetBSD: astro.c,v 1.13 2011/01/13 21:15:13 skrll Exp $ */ /* $OpenBSD: astro.c,v 1.8 2007/10/06 23:50:54 krw Exp $ */ @@ -156,7 +156,7 @@ int astro_match(device_t, cfdata_t, void *); void astro_attach(device_t, device_t, void *); -static void astro_callback(device_t self, struct confargs *ca); +static device_t astro_callback(device_t self, struct confargs *ca); CFATTACH_DECL_NEW(astro, sizeof(struct astro_softc), astro_match, astro_attach, NULL, NULL); @@ -232,6 +232,7 @@ psize_t size; vaddr_t va; paddr_t pa; + void *p; struct vm_page *m; struct pglist mlist; int iova_bits; @@ -244,8 +245,8 @@ aprint_error(": can't map IO space\n"); return; } - sc->sc_regs = r = (struct astro_regs *)ca->ca_hpa; - + p = bus_space_vaddr(ca->ca_iot, ioh); + sc->sc_regs = r = p; rid = le32toh(r->rid); aprint_normal(": Astro rev %d.%d\n", (rid & 7) + 1, (rid >> 3) & 3); @@ -333,18 +334,17 @@ sc->sc_dmatag._cookie = sc; nca = *ca; /* clone from us */ -// nca.ca_hpamask = HPPA_IOBEGIN; nca.ca_dmatag = &sc->sc_dmatag; - nca.ca_hpabase = 0; /* HPPA_UNDEF */ + nca.ca_hpabase = IOMOD_IO_IO_LOW(p); nca.ca_nmodules = MAXMODBUS; pdc_scanbus(self, &nca, astro_callback); } -static void +static device_t astro_callback(device_t self, struct confargs *ca) { - config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); + return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); } int Index: src/sys/arch/hp700/dev/dino.c diff -u src/sys/arch/hp700/dev/dino.c:1.27 src/sys/arch/hp700/dev/dino.c:1.28 --- src/sys/arch/hp700/dev/dino.c:1.27 Sun Dec 5 12:19:09 2010 +++ src/sys/arch/hp700/dev/dino.c Thu Jan 13 21:15:13 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: dino.c,v 1.27 2010/12/05 12:19:09 skrll Exp $ */ +/* $NetBSD: dino.c,v 1.28 2011/01/13 21:15:13 skrll Exp $ */ /* $OpenBSD: dino.c,v 1.5 2004/02/13 20:39:31 mickey Exp $ */ @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.27 2010/12/05 12:19:09 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.28 2011/01/13 21:15:13 skrll Exp $"); /* #include "cardbus.h" */ @@ -135,12 +135,11 @@ int dinomatch(device_t, struct cfdata *, void *); void dinoattach(device_t, device_t, void *); -static void dino_callback(device_t, struct confargs *); +static device_t dino_callback(device_t, struct confargs *); CFATTACH_DECL_NEW(dino, sizeof(struct dino_softc), dinomatch, dinoattach, NULL, NULL); - void dino_attach_hook(device_t, device_t, struct pcibus_attach_args *); void dino_enable_bus(struct dino_softc *, int); @@ -1734,9 +1733,9 @@ config_found_ia(self, "pcibus", &pba, pcibusprint); } -static void +static device_t dino_callback(device_t self, struct confargs *ca) { - config_found_sm_loc(self, "dino", NULL, ca, mbprint, mbsubmatch); + return config_found_sm_loc(self, "dino", NULL, ca, mbprint, mbsubmatch); } Index: src/sys/arch/hp700/dev/gecko.c diff -u src/sys/arch/hp700/dev/gecko.c:1.2 src/sys/arch/hp700/dev/gecko.c:1.3 --- src/sys/arch/hp700/dev/gecko.c:1.2 Sat May 30 17:45:59 2009 +++ src/sys/arch/hp700/dev/gecko.c Thu Jan 13 21:15:13 2011 @@ -38,7 +38,7 @@ int gecko_match(device_t, cfdata_t, void *); void gecko_attach(device_t, device_t, void *); -static void gecko_callback(device_t, struct confargs *); +static device_t gecko_callback(device_t, struct confargs *); CFATTACH_DECL_NEW(gecko, sizeof(struct gecko_softc), gecko_match, gecko_attach, NULL, NULL); @@ -86,10 +86,11 @@ pdc_scanbus(self, &nca, gecko_callback); } -static void +static device_t gecko_callback(device_t self, struct confargs *ca) { - config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); + return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, + mbsubmatch); } Index: src/sys/arch/hp700/dev/lasi.c diff -u src/sys/arch/hp700/dev/lasi.c:1.18 src/sys/arch/hp700/dev/lasi.c:1.19 --- src/sys/arch/hp700/dev/lasi.c:1.18 Tue Jan 4 10:42:33 2011 +++ src/sys/arch/hp700/dev/lasi.c Thu Jan 13 21:15:13 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: lasi.c,v 1.18 2011/01/04 10:42:33 skrll Exp $ */ +/* $NetBSD: lasi.c,v 1.19 2011/01/13 21:15:13 skrll Exp $ */ /* $OpenBSD: lasi.c,v 1.4 2001/06/09 03:57:19 mickey Exp $ */ @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lasi.c,v 1.18 2011/01/04 10:42:33 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lasi.c,v 1.19 2011/01/13 21:15:13 skrll Exp $"); #undef LASIDEBUG @@ -197,15 +197,6 @@ /* Attach the GSC bus. */ ga.ga_ca = *ca; /* clone from us */ - if (strcmp(parent->dv_xname, "mainbus0") == 0) { - ga.ga_dp.dp_bc[0] = ga.ga_dp.dp_bc[1]; - ga.ga_dp.dp_bc[1] = ga.ga_dp.dp_bc[2]; - ga.ga_dp.dp_bc[2] = ga.ga_dp.dp_bc[3]; - ga.ga_dp.dp_bc[3] = ga.ga_dp.dp_bc[4]; - ga.ga_dp.dp_bc[4] = ga.ga_dp.dp_bc[5]; - ga.ga_dp.dp_bc[5] = ga.ga_dp.dp_mod; - ga.ga_dp.dp_mod = 0; - } ga.ga_name = "gsc"; ga.ga_int_reg = &sc->sc_int_reg; Index: src/sys/arch/hp700/dev/pdc.c diff -u src/sys/arch/hp700/dev/pdc.c:1.37 src/sys/arch/hp700/dev/pdc.c:1.38 --- src/sys/arch/hp700/dev/pdc.c:1.37 Tue Jan 4 10:42:33 2011 +++ src/sys/arch/hp700/dev/pdc.c Thu Jan 13 21:15:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pdc.c,v 1.37 2011/01/04 10:42:33 skrll Exp $ */ +/* $NetBSD: pdc.c,v 1.38 2011/01/13 21:15:14 skrll Exp $ */ /* $OpenBSD: pdc.c,v 1.14 2001/04/29 21:05:43 mickey Exp $ */ @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pdc.c,v 1.37 2011/01/04 10:42:33 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pdc.c,v 1.38 2011/01/13 21:15:14 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -48,6 +48,7 @@ #include <machine/autoconf.h> #include <hp700/hp700/machdep.h> +#include <hp700/dev/cpudevs.h> typedef struct pdc_softc { @@ -58,6 +59,8 @@ pdcio_t pdc; +enum pdc_type pdc_type; + static struct pdc_result pdcret1 PDC_ALIGNMENT; static struct pdc_result pdcret2 PDC_ALIGNMENT; @@ -145,6 +148,78 @@ todr_attach(&todr); } +void +pdc_settype(int modelno) +{ + switch (modelno) { + /* 720, 750, 730, 735, 755 */ + case HPPA_BOARD_HP720: + case HPPA_BOARD_HP750_66: + case HPPA_BOARD_HP730_66: + case HPPA_BOARD_HP735_99: + case HPPA_BOARD_HP755_99: + case HPPA_BOARD_HP755_125: + case HPPA_BOARD_HP735_130: + + /* 710, 705, 7[12]5 */ + case HPPA_BOARD_HP710: + case HPPA_BOARD_HP705: + case HPPA_BOARD_HP715_50: + case HPPA_BOARD_HP715_33: + case HPPA_BOARD_HP715S_50: + case HPPA_BOARD_HP715S_33: + case HPPA_BOARD_HP715T_50: + case HPPA_BOARD_HP715T_33: + case HPPA_BOARD_HP715_75: + case HPPA_BOARD_HP715_99: + case HPPA_BOARD_HP725_50: + case HPPA_BOARD_HP725_75: + case HPPA_BOARD_HP725_99: + + /* 745, 742, 747 */ + case HPPA_BOARD_HP745I_50: + case HPPA_BOARD_HP742I_50: + case HPPA_BOARD_HP747I_100: + + /* 712/{60,80,100,120}, 715/{64,80,100,...}, etc */ + case HPPA_BOARD_HP712_60: + case HPPA_BOARD_HP712_80: + case HPPA_BOARD_HP712_100: + case HPPA_BOARD_HP743I_64: + case HPPA_BOARD_HP743I_100: + case HPPA_BOARD_HP712_120: + case HPPA_BOARD_HP715_80: + case HPPA_BOARD_HP715_64: + case HPPA_BOARD_HP715_100: + case HPPA_BOARD_HP715_100XC: + case HPPA_BOARD_HP725_100: + case HPPA_BOARD_HP725_120: + case HPPA_BOARD_HP715_100L: + case HPPA_BOARD_HP715_120L: + case HPPA_BOARD_HP725_80L: + case HPPA_BOARD_HP725_100L: + case HPPA_BOARD_HP725_120L: + case HPPA_BOARD_HP743_50: + case HPPA_BOARD_HP743_100: + case HPPA_BOARD_HP715_80M: + case HPPA_BOARD_HP811: + case HPPA_BOARD_HP801: + case HPPA_BOARD_HP743T: + pdc_type = PDC_TYPE_SNAKE; + break; + + default: + pdc_type = PDC_TYPE_UNKNOWN; + } +} + +enum pdc_type +pdc_gettype(void) +{ + + return pdc_type; +} + int pdcmatch(device_t parent, cfdata_t cf, void *aux) { Index: src/sys/arch/hp700/dev/phantomas.c diff -u src/sys/arch/hp700/dev/phantomas.c:1.7 src/sys/arch/hp700/dev/phantomas.c:1.8 --- src/sys/arch/hp700/dev/phantomas.c:1.7 Tue Nov 3 05:07:25 2009 +++ src/sys/arch/hp700/dev/phantomas.c Thu Jan 13 21:15:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: phantomas.c,v 1.7 2009/11/03 05:07:25 snj Exp $ */ +/* $NetBSD: phantomas.c,v 1.8 2011/01/13 21:15:14 skrll Exp $ */ /* $OpenBSD: phantomas.c,v 1.1 2002/12/18 23:52:45 mickey Exp $ */ /* @@ -42,7 +42,7 @@ int phantomasmatch(device_t, cfdata_t, void *); void phantomasattach(device_t, device_t, void *); -static void phantomas_callback(device_t self, struct confargs *ca); +static device_t phantomas_callback(device_t self, struct confargs *ca); CFATTACH_DECL_NEW(phantomas, sizeof(struct phantomas_softc), phantomasmatch, phantomasattach, NULL, NULL); @@ -74,9 +74,9 @@ pdc_scanbus(self, &nca, phantomas_callback); } -static void +static device_t phantomas_callback(device_t self, struct confargs *ca) { - config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); + return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); } Index: src/sys/arch/hp700/dev/uturn.c diff -u src/sys/arch/hp700/dev/uturn.c:1.13 src/sys/arch/hp700/dev/uturn.c:1.14 --- src/sys/arch/hp700/dev/uturn.c:1.13 Sun Dec 12 08:23:14 2010 +++ src/sys/arch/hp700/dev/uturn.c Thu Jan 13 21:15:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uturn.c,v 1.13 2010/12/12 08:23:14 skrll Exp $ */ +/* $NetBSD: uturn.c,v 1.14 2011/01/13 21:15:14 skrll Exp $ */ /* $OpenBSD: uturn.c,v 1.6 2007/12/29 01:26:14 kettenis Exp $ */ @@ -112,7 +112,7 @@ int uturnmatch(device_t, cfdata_t, void *); void uturnattach(device_t, device_t, void *); -static void uturn_callback(device_t self, struct confargs *ca); +static device_t uturn_callback(device_t self, struct confargs *ca); CFATTACH_DECL_NEW(uturn, sizeof(struct uturn_softc), uturnmatch, uturnattach, NULL, NULL); @@ -201,36 +201,19 @@ * it always is module 63, hence the MAXMODBUS - 1 below. */ nca = *ca; - nca.ca_hpabase = 0; + nca.ca_hpabase = r->io_io_low << 16; nca.ca_dmatag = &sc->sc_dmatag; nca.ca_nmodules = MAXMODBUS - 1; pdc_scanbus(self, &nca, uturn_callback); - /* XXX On some machines, PDC doesn't tell us about all devices. */ - switch (cpu_modelno) { - case HPPA_BOARD_HP809: - case HPPA_BOARD_HP819: - case HPPA_BOARD_HP829: - case HPPA_BOARD_HP839: - case HPPA_BOARD_HP849: - case HPPA_BOARD_HP859: - case HPPA_BOARD_HP869: - - case HPPA_BOARD_HP800D: - case HPPA_BOARD_HP821: - nca.ca_hpabase = r->io_io_low << 16; - pdc_scanbus(self, &nca, uturn_callback); - break; - default: - break; - } } -static void +static device_t uturn_callback(device_t self, struct confargs *ca) { - config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); + return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, + mbsubmatch); } Index: src/sys/arch/hp700/gsc/gscbus.c diff -u src/sys/arch/hp700/gsc/gscbus.c:1.20 src/sys/arch/hp700/gsc/gscbus.c:1.21 --- src/sys/arch/hp700/gsc/gscbus.c:1.20 Sun Dec 5 12:19:09 2010 +++ src/sys/arch/hp700/gsc/gscbus.c Thu Jan 13 21:15:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: gscbus.c,v 1.20 2010/12/05 12:19:09 skrll Exp $ */ +/* $NetBSD: gscbus.c,v 1.21 2011/01/13 21:15:14 skrll Exp $ */ /* $OpenBSD: gscbus.c,v 1.13 2001/08/01 20:32:04 miod Exp $ */ @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gscbus.c,v 1.20 2010/12/05 12:19:09 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gscbus.c,v 1.21 2011/01/13 21:15:14 skrll Exp $"); #define GSCDEBUG @@ -106,8 +106,8 @@ * to fix up the module's attach arguments, then we match * and attach it. */ -static void gsc_module_callback(device_t, struct confargs *); -static void +static device_t gsc_module_callback(device_t, struct confargs *); +static device_t gsc_module_callback(device_t self, struct confargs *ca) { struct gsc_softc *sc = device_private(self); @@ -120,7 +120,7 @@ ga.ga_dmatag = sc->sc_ga.ga_dmatag; (*sc->sc_ga.ga_fix_args)(sc->sc_ga.ga_fix_args_cookie, &ga); - config_found_sm_loc(self, "gsc", NULL, &ga, mbprint, mbsubmatch); + return config_found_sm_loc(self, "gsc", NULL, &ga, mbprint, mbsubmatch); } int Index: src/sys/arch/hp700/hp700/autoconf.c diff -u src/sys/arch/hp700/hp700/autoconf.c:1.35 src/sys/arch/hp700/hp700/autoconf.c:1.36 --- src/sys/arch/hp700/hp700/autoconf.c:1.35 Tue Jan 4 10:42:34 2011 +++ src/sys/arch/hp700/hp700/autoconf.c Thu Jan 13 21:15:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.35 2011/01/04 10:42:34 skrll Exp $ */ +/* $NetBSD: autoconf.c,v 1.36 2011/01/13 21:15:14 skrll Exp $ */ /* $OpenBSD: autoconf.c,v 1.15 2001/06/25 00:43:10 mickey Exp $ */ @@ -86,7 +86,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.35 2011/01/04 10:42:34 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.36 2011/01/13 21:15:14 skrll Exp $"); #include "opt_kgdb.h" #include "opt_useleds.h" @@ -100,6 +100,7 @@ #include <sys/reboot.h> #include <sys/device.h> #include <sys/callout.h> +#include <sys/kmem.h> #ifdef KGDB #include <sys/kgdb.h> @@ -127,6 +128,23 @@ PSW_C | /* Instruction Address Translation Enable */ PSW_D; /* Data Address Translation Enable */ +static TAILQ_HEAD(hppa_pdcmodule_head, hppa_pdcmodule) hppa_pdcmodule_list = + TAILQ_HEAD_INITIALIZER(hppa_pdcmodule_list); + +struct hppa_pdcmodule { + TAILQ_ENTRY(hppa_pdcmodule) hm_link; + bool hm_registered; + struct pdc_iodc_read hm_pir; + struct iodc_data hm_type; + struct device_path hm_dp; + hppa_hpa_t hm_hpa; + u_int hm_hpasz; + u_int hm_naddrs; /* only PDC_SYSTEM_MAP */ + u_int hm_modindex; /* only PDC_SYSTEM_MAP */ +}; + +#define HPPA_SYSTEMMAPMODULES 256 + /* * LED blinking thing */ @@ -139,6 +157,12 @@ void (*cold_hook)(int); /* see below */ +struct hppa_pdcmodule *hppa_pdcmodule_create(struct hppa_pdcmodule *, + const char *); +void hppa_walkbus(struct confargs *ca); +static void hppa_pdc_snake_scan(void); +static void hppa_pdc_system_map_scan(void); + /* * cpu_configure: * called at boot time, configure all devices on system @@ -458,113 +482,160 @@ /*static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL };*/ #endif -static struct pdc_memmap pdc_memmap; -static struct pdc_system_map_find_mod pdc_find_mod; -static struct pdc_system_map_find_addr pdc_find_addr; - void -pdc_scanbus(device_t self, struct confargs *ca, - void (*callback)(device_t, struct confargs *)) +hppa_walkbus(struct confargs *ca) { + struct hppa_pdcmodule nhm, *hm; int i; + if (ca->ca_hpabase == 0) + return; + + aprint_verbose(">> Walking bus at HPA 0x%lx\n", ca->ca_hpabase); + for (i = 0; i < ca->ca_nmodules; i++) { - struct confargs nca; + int error; + + memset(&nhm, 0, sizeof(nhm)); + nhm.hm_dp.dp_bc[0] = ca->ca_dp.dp_bc[1]; + nhm.hm_dp.dp_bc[1] = ca->ca_dp.dp_bc[2]; + nhm.hm_dp.dp_bc[2] = ca->ca_dp.dp_bc[3]; + nhm.hm_dp.dp_bc[3] = ca->ca_dp.dp_bc[4]; + nhm.hm_dp.dp_bc[4] = ca->ca_dp.dp_bc[5]; + nhm.hm_dp.dp_bc[5] = ca->ca_dp.dp_mod; + nhm.hm_hpa = ca->ca_hpabase + IOMOD_HPASIZE * i; + nhm.hm_hpasz = 0; + nhm.hm_dp.dp_mod = i; + nhm.hm_naddrs = 0; + + error = pdcproc_iodc_read(nhm.hm_hpa, IODC_DATA, NULL, + &nhm.hm_pir, sizeof(nhm.hm_pir), &nhm.hm_type, + sizeof(nhm.hm_type)); + if (error < 0) + continue; + + aprint_verbose(">> HPA 0x%lx[0x%x]", nhm.hm_hpa, + nhm.hm_hpasz); + + TAILQ_FOREACH(hm, &hppa_pdcmodule_list, hm_link) { + if (nhm.hm_hpa == hm->hm_hpa) { + aprint_verbose(" found by firmware\n"); + break; + } + } + + /* If we've found the module move onto the next one. */ + if (hm) { + aprint_verbose("\n"); + continue; + } + + /* Expect PDC to report devices of the following types */ + if (nhm.hm_type.iodc_type == HPPA_TYPE_FIO) { + aprint_verbose(" expected to be missing\n"); + continue; + } + + hppa_pdcmodule_create(&nhm, "Bus walk"); + } +} + +void +pdc_scanbus(device_t self, struct confargs *ca, + device_t (*callback)(device_t, struct confargs *)) +{ + struct hppa_pdcmodule *hm; + struct confargs nca; + device_t dev; + int ia; + + hppa_walkbus(ca); + + TAILQ_FOREACH(hm, &hppa_pdcmodule_list, hm_link) { char buf[128]; int error; + if (hm->hm_registered) + continue; + + if (!(hm->hm_dp.dp_bc[0] == ca->ca_dp.dp_bc[1] && + hm->hm_dp.dp_bc[1] == ca->ca_dp.dp_bc[2] && + hm->hm_dp.dp_bc[2] == ca->ca_dp.dp_bc[3] && + hm->hm_dp.dp_bc[3] == ca->ca_dp.dp_bc[4] && + hm->hm_dp.dp_bc[4] == ca->ca_dp.dp_bc[5] && + hm->hm_dp.dp_bc[5] == ca->ca_dp.dp_mod)) + continue; + memset(&nca, 0, sizeof(nca)); nca.ca_iot = ca->ca_iot; nca.ca_dmatag = ca->ca_dmatag; - nca.ca_dp.dp_bc[0] = ca->ca_dp.dp_bc[1]; - nca.ca_dp.dp_bc[1] = ca->ca_dp.dp_bc[2]; - nca.ca_dp.dp_bc[2] = ca->ca_dp.dp_bc[3]; - nca.ca_dp.dp_bc[3] = ca->ca_dp.dp_bc[4]; - nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_bc[5]; - nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod; - nca.ca_dp.dp_mod = i; - nca.ca_naddrs = 0; - nca.ca_hpa = 0; - - if (ca->ca_hpabase) { - nca.ca_hpa = ca->ca_hpabase + IOMOD_HPASIZE * i; - nca.ca_dp.dp_mod = i; - } else if ((error = pdcproc_memmap(&pdc_memmap, - &nca.ca_dp)) == 0) - nca.ca_hpa = pdc_memmap.hpa; - else if ((error = pdcproc_system_map_trans_path(&pdc_memmap, - &nca.ca_dp)) == 0) { - struct device_path path; - int im, ia; - - nca.ca_hpa = pdc_memmap.hpa; - - for (im = 0; !(error = pdcproc_system_map_find_mod( - &pdc_find_mod, &path, im)) && - pdc_find_mod.hpa != nca.ca_hpa; im++) - ; - - if (!error) - nca.ca_hpasz = pdc_find_mod.size << PGSHIFT; - - if (!error && pdc_find_mod.naddrs) { - nca.ca_naddrs = pdc_find_mod.naddrs; - if (nca.ca_naddrs > HP700_MAXIOADDRS) { - nca.ca_naddrs = HP700_MAXIOADDRS; - aprint_error("WARNING: " - "too many (%d) addrs\n", - pdc_find_mod.naddrs); - } - - aprint_verbose(">> ADDRS: "); - for (ia = 0; ia < nca.ca_naddrs; ia++) { - error = pdcproc_system_map_find_addr( - &pdc_find_addr, im, ia + 1); - if (error) - break; - nca.ca_addrs[ia].addr = - pdc_find_addr.hpa; - nca.ca_addrs[ia].size = - pdc_find_addr.size << PGSHIFT; - - aprint_verbose(" 0x%lx[0x%x]", - nca.ca_addrs[ia].addr, - nca.ca_addrs[ia].size); - } - aprint_verbose("\n"); + nca.ca_pir = hm->hm_pir; + nca.ca_type = hm->hm_type; + nca.ca_hpa = hm->hm_hpa; + nca.ca_dp = hm->hm_dp; + nca.ca_hpa = hm->hm_hpa; + nca.ca_hpasz = hm->hm_hpasz; + + if (hm->hm_naddrs) { + if (hm->hm_naddrs > HP700_MAXIOADDRS) { + nca.ca_naddrs = HP700_MAXIOADDRS; + aprint_error("WARNING: too many (%d) addrs\n", + hm->hm_naddrs); + } else + nca.ca_naddrs = hm->hm_naddrs; + + aprint_verbose(">> ADDRS[%d/%d]: ", nca.ca_naddrs, + hm->hm_modindex); + + KASSERT(hm->hm_modindex != -1); + for (ia = 0; ia < nca.ca_naddrs; ia++) { + struct pdc_system_map_find_addr pdc_find_addr; + + error = pdcproc_system_map_find_addr( + &pdc_find_addr, hm->hm_modindex, ia + 1); + if (error < 0) + break; + nca.ca_addrs[ia].addr = pdc_find_addr.hpa; + nca.ca_addrs[ia].size = + pdc_find_addr.size << PGSHIFT; + + aprint_verbose(" 0x%lx[0x%x]", + nca.ca_addrs[ia].addr, + nca.ca_addrs[ia].size); } + aprint_verbose("\n"); } - if (!nca.ca_hpa) - continue; - aprint_verbose(">> HPA 0x%lx[0x%x]\n", nca.ca_hpa, nca.ca_hpasz); - if ((error = pdcproc_iodc_read(nca.ca_hpa, IODC_DATA, NULL, - &nca.ca_pir, sizeof(nca.ca_pir), - &nca.ca_type, sizeof(nca.ca_type))) < 0) { - aprint_verbose(">> iodc_data error %d\n", error); - continue; + snprintb(buf, sizeof(buf), PZF_BITS, nca.ca_dp.dp_flags); + aprint_verbose(">> probing: flags %s ", buf); + if (nca.ca_dp.dp_mod >=0) { + int n; + + aprint_verbose(" path "); + for (n = 0; n < 6; n++) { + if (nca.ca_dp.dp_bc[n] >= 0) + aprint_verbose("%d/", + nca.ca_dp.dp_bc[n]); + } + aprint_verbose("%d", nca.ca_dp.dp_mod); } - snprintb(buf, sizeof(buf), PZF_BITS, nca.ca_dp.dp_flags); - aprint_verbose(">> probing: flags %s bc %d/%d/%d/%d/%d/%d ", - buf, - nca.ca_dp.dp_bc[0], nca.ca_dp.dp_bc[1], - nca.ca_dp.dp_bc[2], nca.ca_dp.dp_bc[3], - nca.ca_dp.dp_bc[4], nca.ca_dp.dp_bc[5]); - aprint_verbose("mod %x hpa %lx type %x sv %x\n", - nca.ca_dp.dp_mod, nca.ca_hpa, + aprint_verbose(" type %x sv %x\n", nca.ca_type.iodc_type, nca.ca_type.iodc_sv_model); nca.ca_irq = HP700CF_IRQ_UNDEF; nca.ca_name = hppa_mod_info(nca.ca_type.iodc_type, nca.ca_type.iodc_sv_model); - (*callback)(self, &nca); - } + dev = callback(self, &nca); + if (dev) + hm->hm_registered = true; + + } } static const struct hppa_mod_info hppa_knownmods[] = { @@ -586,3 +657,203 @@ } else return mi->mi_name; } + +/* + * Create the device on our device list. Keep the devices in order. */ +struct hppa_pdcmodule * +hppa_pdcmodule_create(struct hppa_pdcmodule *hm, const char *who) +{ + struct hppa_pdcmodule *nhm, *ahm; + int i; + + nhm = kmem_zalloc(sizeof(*nhm), KM_SLEEP); + + nhm->hm_registered = false; + nhm->hm_type = hm->hm_type; + nhm->hm_dp = hm->hm_dp; + nhm->hm_hpa = hm->hm_hpa; + nhm->hm_hpasz = hm->hm_hpasz; + nhm->hm_naddrs = hm->hm_naddrs; + nhm->hm_modindex = hm->hm_modindex; + + /* Find start of new path */ + for (i = 0; i < 6; i++) { + if (hm->hm_dp.dp_bc[i] != -1) + break; + } + + /* + * Look, in reverse, for the first device that has a path before our + * new one. In reverse because PDC reports most (all?) devices in path + * order and therefore the common case is to add to the end of the + * list. + */ + TAILQ_FOREACH_REVERSE(ahm, &hppa_pdcmodule_list, hppa_pdcmodule_head, + hm_link) { + int check; + int j, k; + + for (j = 0; j < 6; j++) { + if (ahm->hm_dp.dp_bc[j] != -1) + break; + } + + for (check = 0, k = i; j < 7 && k < 7; j++, k++) { + char nid, aid; + + nid = (k == 6) ? hm->hm_dp.dp_mod : hm->hm_dp.dp_bc[k]; + aid = (j == 6) ? ahm->hm_dp.dp_mod : ahm->hm_dp.dp_bc[j]; + + if (nid == aid) + continue; + check = nid - aid; + break; + } + if (check >= 0) + break; + else if (check < 0) + continue; + } + if (ahm == NULL) + TAILQ_INSERT_HEAD(&hppa_pdcmodule_list, nhm, hm_link); + else + TAILQ_INSERT_AFTER(&hppa_pdcmodule_list, ahm, nhm, hm_link); + + if (hm->hm_dp.dp_mod >= 0) { + int n; + + aprint_verbose(">> %s device at path ", who); + for (n = 0; n < 6; n++) { + if (hm->hm_dp.dp_bc[n] >= 0) + aprint_verbose("%d/", hm->hm_dp.dp_bc[n]); + } + aprint_verbose("%d addrs %d\n", hm->hm_dp.dp_mod, + hm->hm_naddrs); + } + + return nhm; +} + +/* + * This is used for Snake machines + */ +static struct hppa_pdcmodule * +hppa_memmap_query(struct device_path *devp) +{ + static struct hppa_pdcmodule nhm; + struct pdc_memmap pdc_memmap; + int error; + + error = pdcproc_memmap(&pdc_memmap, devp); + + if (error < 0) + return NULL; + + memset(&nhm, 0, sizeof(nhm)); + nhm.hm_dp = *devp; + nhm.hm_hpa = pdc_memmap.hpa; + nhm.hm_hpasz = pdc_memmap.morepages; + nhm.hm_naddrs = 0; + nhm.hm_modindex = -1; + + error = pdcproc_iodc_read(nhm.hm_hpa, IODC_DATA, NULL, &nhm.hm_pir, + sizeof(nhm.hm_pir), &nhm.hm_type, sizeof(nhm.hm_type)); + + if (error < 0) + return NULL; + + return hppa_pdcmodule_create(&nhm, "PDC (memmap)"); +} + + +static void +hppa_pdc_snake_scan(void) +{ + struct device_path path; + struct hppa_pdcmodule *hm; + int im, ba; + + memset(&path, 0, sizeof(path)); + for (im = 0; im < 16; im++) { + path.dp_bc[0] = path.dp_bc[1] = path.dp_bc[2] = + path.dp_bc[3] = path.dp_bc[4] = path.dp_bc[5] = -1; + path.dp_mod = im; + + hm = hppa_memmap_query(&path); + + if (!hm) + continue; + + if (hm->hm_type.iodc_type != HPPA_TYPE_BHA) + continue; + + path.dp_bc[0] = path.dp_bc[1] = + path.dp_bc[2] = path.dp_bc[3] = -1; + path.dp_bc[4] = im; + path.dp_bc[5] = 0; + + for (ba = 0; ba < 16; ba++) { + path.dp_mod = ba; + hppa_memmap_query(&path); + } + } +} + +static void +hppa_pdc_system_map_scan(void) +{ + struct pdc_system_map_find_mod pdc_find_mod; + struct device_path path; + struct hppa_pdcmodule hm; + int error; + int im; + + for (im = 0; im < HPPA_SYSTEMMAPMODULES; im++) { + memset(&path, 0, sizeof(path)); + error = pdcproc_system_map_find_mod(&pdc_find_mod, &path, im); + if (error == PDC_ERR_NMOD) + break; + + if (error < 0) + continue; + + memset(&hm, 0, sizeof(hm)); + hm.hm_dp = path; + hm.hm_hpa = pdc_find_mod.hpa; + hm.hm_hpasz = pdc_find_mod.size << PGSHIFT; + hm.hm_naddrs = pdc_find_mod.naddrs; + hm.hm_modindex = im; + + error = pdcproc_iodc_read(hm.hm_hpa, IODC_DATA, NULL, + &hm.hm_pir, sizeof(hm.hm_pir), &hm.hm_type, + sizeof(hm.hm_type)); + if (error < 0) + continue; + + hppa_pdcmodule_create(&hm, "PDC (system map)"); + } +} + +void +hppa_modules_scan(void) +{ + switch (pdc_gettype()) { + case PDC_TYPE_SNAKE: + hppa_pdc_snake_scan(); + break; + + case PDC_TYPE_UNKNOWN: + hppa_pdc_system_map_scan(); + } +} + +void +hppa_modules_done(void) +{ + struct hppa_pdcmodule *hm, *nhm; + + TAILQ_FOREACH_SAFE(hm, &hppa_pdcmodule_list, hm_link, nhm) { + TAILQ_REMOVE(&hppa_pdcmodule_list, hm, hm_link); + kmem_free(hm, sizeof(*hm)); + } +} Index: src/sys/arch/hp700/hp700/machdep.c diff -u src/sys/arch/hp700/hp700/machdep.c:1.95 src/sys/arch/hp700/hp700/machdep.c:1.96 --- src/sys/arch/hp700/hp700/machdep.c:1.95 Tue Jan 4 10:42:34 2011 +++ src/sys/arch/hp700/hp700/machdep.c Thu Jan 13 21:15:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.95 2011/01/04 10:42:34 skrll Exp $ */ +/* $NetBSD: machdep.c,v 1.96 2011/01/13 21:15:15 skrll Exp $ */ /*- * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.95 2011/01/04 10:42:34 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.96 2011/01/13 21:15:15 skrll Exp $"); #include "opt_cputype.h" #include "opt_ddb.h" @@ -658,6 +658,7 @@ #ifdef DEBUG printf("%s: model %s\n", __func__, model); #endif + pdc_settype(cpu_modelno); memset(&pdc_cpuid, 0, sizeof(pdc_cpuid)); error = pdcproc_model_cpuid(&pdc_cpuid); Index: src/sys/arch/hp700/hp700/mainbus.c diff -u src/sys/arch/hp700/hp700/mainbus.c:1.75 src/sys/arch/hp700/hp700/mainbus.c:1.76 --- src/sys/arch/hp700/hp700/mainbus.c:1.75 Tue Jan 4 10:42:34 2011 +++ src/sys/arch/hp700/hp700/mainbus.c Thu Jan 13 21:15:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: mainbus.c,v 1.75 2011/01/04 10:42:34 skrll Exp $ */ +/* $NetBSD: mainbus.c,v 1.76 2011/01/13 21:15:15 skrll Exp $ */ /*- * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.75 2011/01/04 10:42:34 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.76 2011/01/13 21:15:15 skrll Exp $"); #include "locators.h" #include "power.h" @@ -1333,22 +1333,24 @@ return 1; } -static void +static device_t mb_module_callback(device_t self, struct confargs *ca) { if (ca->ca_type.iodc_type == HPPA_TYPE_NPROC || ca->ca_type.iodc_type == HPPA_TYPE_MEMORY) - return; - config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); + return NULL; + + return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); } -static void +static device_t mb_cpu_mem_callback(device_t self, struct confargs *ca) { - if ((ca->ca_type.iodc_type == HPPA_TYPE_NPROC || - ca->ca_type.iodc_type == HPPA_TYPE_MEMORY)) - config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, - mbsubmatch); + if ((ca->ca_type.iodc_type != HPPA_TYPE_NPROC && + ca->ca_type.iodc_type != HPPA_TYPE_MEMORY)) + return NULL; + + return config_found_sm_loc(self, "gedoens", NULL, ca, mbprint, mbsubmatch); } void @@ -1357,7 +1359,6 @@ struct mainbus_softc *sc = device_private(self); struct confargs nca; bus_space_handle_t ioh; - hppa_hpa_t hpabase; hppa_hpa_t prochpa; int err; @@ -1427,48 +1428,13 @@ } #endif - switch (cpu_modelno) { - case HPPA_BOARD_HPE23: - case HPPA_BOARD_HPE25: - case HPPA_BOARD_HPE35: - case HPPA_BOARD_HPE45: - - case HPPA_BOARD_HP809: - case HPPA_BOARD_HP819: - case HPPA_BOARD_HP829: - case HPPA_BOARD_HP839: - case HPPA_BOARD_HP849: - case HPPA_BOARD_HP859: - case HPPA_BOARD_HP869: -#if 0 - case HPPA_BOARD_HP770_J200: - case HPPA_BOARD_HP770_J210: - case HPPA_BOARD_HP770_J210XC: - case HPPA_BOARD_HP780_J282: - case HPPA_BOARD_HP782_J2240: -#endif - case HPPA_BOARD_HP780_C160: - case HPPA_BOARD_HP780_C180P: - case HPPA_BOARD_HP780_C180XP: - case HPPA_BOARD_HP780_C200: - case HPPA_BOARD_HP780_C230: - case HPPA_BOARD_HP780_C240: - case HPPA_BOARD_HP785_C360: - - case HPPA_BOARD_HP800D: - case HPPA_BOARD_HP821: - hpabase = HPPA_FPA; - break; - default: - hpabase = 0; - break; - } + hppa_modules_scan(); /* Search and attach all CPUs and memory controllers. */ memset(&nca, 0, sizeof(nca)); nca.ca_name = "mainbus"; nca.ca_hpa = 0; - nca.ca_hpabase = hpabase; + nca.ca_hpabase = HPPA_FPA; /* Central bus */ nca.ca_nmodules = MAXMODBUS; nca.ca_irq = HP700CF_IRQ_UNDEF; nca.ca_iot = &hppa_bustag; @@ -1482,7 +1448,7 @@ memset(&nca, 0, sizeof(nca)); nca.ca_name = "mainbus"; nca.ca_hpa = 0; - nca.ca_hpabase = hpabase; + nca.ca_hpabase = 0; /* Central bus already walked above */ nca.ca_nmodules = MAXMODBUS; nca.ca_irq = HP700CF_IRQ_UNDEF; nca.ca_iot = &hppa_bustag; @@ -1491,6 +1457,8 @@ nca.ca_dp.dp_bc[3] = nca.ca_dp.dp_bc[4] = nca.ca_dp.dp_bc[5] = -1; nca.ca_dp.dp_mod = -1; pdc_scanbus(self, &nca, mb_module_callback); + + hppa_modules_done(); } /* Index: src/sys/arch/hp700/include/autoconf.h diff -u src/sys/arch/hp700/include/autoconf.h:1.16 src/sys/arch/hp700/include/autoconf.h:1.17 --- src/sys/arch/hp700/include/autoconf.h:1.16 Wed Jan 5 07:40:16 2011 +++ src/sys/arch/hp700/include/autoconf.h Thu Jan 13 21:15:16 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.h,v 1.16 2011/01/05 07:40:16 skrll Exp $ */ +/* $NetBSD: autoconf.h,v 1.17 2011/01/13 21:15:16 skrll Exp $ */ /* $OpenBSD: autoconf.h,v 1.10 2001/05/05 22:33:42 art Exp $ */ @@ -58,7 +58,7 @@ bus_dma_tag_t ca_dmatag; /* DMA tag */ int ca_irq; /* module IRQ */ int ca_naddrs; /* number of valid addr ents */ - hppa_hpa_t ca_hpabase; /* HPA base to use or 0 for PDC */ + hppa_hpa_t ca_hpabase; /* HPA base to use */ int ca_nmodules; /* check for modules 0 to nmodules - 1 */ }; @@ -82,8 +82,11 @@ const char *hppa_mod_info(int, int); -void pdc_scanbus(device_t, struct confargs *, - void (*)(device_t, struct confargs *)); +void hppa_modules_scan(void); +void hppa_modules_done(void); + +void pdc_scanbus(device_t, struct confargs *, + device_t (*)(device_t, struct confargs *)); int mbprint(void *, const char *); int mbsubmatch(device_t, struct cfdata *, const int *, void *); Index: src/sys/arch/hp700/include/iomod.h diff -u src/sys/arch/hp700/include/iomod.h:1.8 src/sys/arch/hp700/include/iomod.h:1.9 --- src/sys/arch/hp700/include/iomod.h:1.8 Fri Apr 23 15:04:09 2010 +++ src/sys/arch/hp700/include/iomod.h Thu Jan 13 21:15:16 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: iomod.h,v 1.8 2010/04/23 15:04:09 skrll Exp $ */ +/* $NetBSD: iomod.h,v 1.9 2011/01/13 21:15:16 skrll Exp $ */ /* $OpenBSD: iomod.h,v 1.18 2007/10/20 16:41:45 miod Exp $ */ @@ -356,6 +356,10 @@ u_int hvrs[512]; /* HVRSes (HVERSION-dependent Register Sets) */ }; + +#define IOMOD_IO_IO_LOW(mod) (((struct iomod *)(mod))->io_io_low) +#define IOMOD_IO_IO_HIGH(mod) (((struct iomod *)(mod))->io_io_high) + #endif /* !_LOCORE */ /* primarily for a "reboot" and "_rtt" routines */ Index: src/sys/arch/hp700/include/pdc.h diff -u src/sys/arch/hp700/include/pdc.h:1.17 src/sys/arch/hp700/include/pdc.h:1.18 --- src/sys/arch/hp700/include/pdc.h:1.17 Tue Jan 4 10:42:34 2011 +++ src/sys/arch/hp700/include/pdc.h Thu Jan 13 21:15:16 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pdc.h,v 1.17 2011/01/04 10:42:34 skrll Exp $ */ +/* $NetBSD: pdc.h,v 1.18 2011/01/13 21:15:16 skrll Exp $ */ /* $OpenBSD: pdc.h,v 1.35 2007/07/15 20:03:48 kettenis Exp $ */ @@ -755,7 +755,15 @@ extern int kernelmapped; +enum pdc_type { + PDC_TYPE_UNKNOWN, + PDC_TYPE_SNAKE +}; + void pdc_init(void); +void pdc_settype(int); +enum pdc_type pdc_gettype(void); + int pdc_call(iodcio_t, int, ...); void pdccnprobe(struct consdev *);