diff options
author | Martin Reindl <martin@cvs.openbsd.org> | 2005-04-26 21:09:36 +0000 |
---|---|---|
committer | Martin Reindl <martin@cvs.openbsd.org> | 2005-04-26 21:09:36 +0000 |
commit | 1f74e84d37ca184a156fd6d003ce0f50dc1d6431 (patch) | |
tree | 0e230146d3d65b66d3f5a0f92db85a7605de39dc /sys/arch/mac68k/dev | |
parent | 0e4080575310866849f515933449d85237bc6acc (diff) |
new NuBus slot space mapping/probing code utilizing bus_space(9)
ok miod@
from NetBSD
Diffstat (limited to 'sys/arch/mac68k/dev')
-rw-r--r-- | sys/arch/mac68k/dev/grf_mv.c | 132 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/grfvar.h | 5 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/if_ae_nubus.c | 46 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/if_sn_nubus.c | 6 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/nubus.c | 757 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/nubus.h | 30 |
6 files changed, 496 insertions, 480 deletions
diff --git a/sys/arch/mac68k/dev/grf_mv.c b/sys/arch/mac68k/dev/grf_mv.c index f68647c0e5d..939c3a8a29d 100644 --- a/sys/arch/mac68k/dev/grf_mv.c +++ b/sys/arch/mac68k/dev/grf_mv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grf_mv.c,v 1.20 2004/11/26 21:21:24 miod Exp $ */ +/* $OpenBSD: grf_mv.c,v 1.21 2005/04/26 21:09:35 martin Exp $ */ /* $NetBSD: grf_mv.c,v 1.24 1997/05/03 02:29:54 briggs Exp $ */ /* @@ -137,44 +137,54 @@ grfmv_attach(parent, self, aux) nubus_dir dir, mode_dir; int mode; + sc->sc_tag = na->na_tag; sc->card_id = na->drhw; bcopy(na->fmt, &sc->sc_slot, sizeof(nubus_slot)); + if (bus_space_map(sc->sc_tag, + NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &sc->sc_regh)) { + printf(": grfmv_attach: failed to map slot %d\n", na->slot); + return; + } + nubus_get_main_dir(&sc->sc_slot, &dir); - if (nubus_find_rsrc(&sc->sc_slot, &dir, na->rsrcid, &dirent) <= 0) + if (nubus_find_rsrc(sc->sc_tag, sc->sc_regh, + &sc->sc_slot, &dir, na->rsrcid, &dirent) <= 0) { +bad: + bus_space_unmap(sc->sc_tag, sc->sc_regh, NBMEMSIZE); return; + } nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &sc->board_dir); - if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, - NUBUS_RSRC_TYPE, &dirent) <= 0) + if (nubus_find_rsrc(sc->sc_tag, sc->sc_regh, + &sc->sc_slot, &sc->board_dir, NUBUS_RSRC_TYPE, &dirent) <= 0) if ((na->rsrcid != 128) || - (nubus_find_rsrc(&sc->sc_slot, &dir, 129, &dirent) <= 0)) - return; + (nubus_find_rsrc(sc->sc_tag, sc->sc_regh, + &sc->sc_slot, &dir, 129, &dirent) <= 0)) + goto bad; mode = NUBUS_RSRC_FIRSTMODE; - if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) { - printf("\n%s: probe failed to get board rsrc.\n", - sc->sc_dev.dv_xname); - return; + if (nubus_find_rsrc(sc->sc_tag, sc->sc_regh, + &sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) { + printf(": probe failed to get board rsrc.\n"); + goto bad; } nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &mode_dir); - if (nubus_find_rsrc(&sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) - <= 0) { - printf("\n%s: probe failed to get mode dir.\n", - sc->sc_dev.dv_xname); - return; + if (nubus_find_rsrc(sc->sc_tag, sc->sc_regh, + &sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) <= 0) { + printf(": probe failed to get mode dir.\n"); + goto bad; } - if (nubus_get_ind_data(&sc->sc_slot, &dirent, (caddr_t)&image_store, - sizeof(struct image_data)) <= 0) { - printf("\n%s: probe failed to get indirect mode data.\n", - sc->sc_dev.dv_xname); - return; + if (nubus_get_ind_data(sc->sc_tag, sc->sc_regh, &sc->sc_slot, + &dirent, (caddr_t)&image_store, sizeof(struct image_data)) <= 0) { + printf(": probe failed to get indirect mode data.\n"); + goto bad; } /* Need to load display info (and driver?), etc... (?) */ @@ -183,8 +193,8 @@ grfmv_attach(parent, self, aux) gm = &sc->curr_mode; gm->mode_id = mode; - gm->fbbase = (caddr_t)(sc->sc_slot.virtual_base + - m68k_trunc_page(image.offset)); + gm->fbbase = (caddr_t)(sc->sc_regh + + m68k_trunc_page(image.offset)); /* XXX evil! */ gm->fboff = image.offset & PGOFSET; gm->rowbytes = image.rowbytes; gm->width = image.right - image.left; @@ -195,8 +205,8 @@ grfmv_attach(parent, self, aux) gm->ptype = image.pixelType; gm->psize = image.pixelSize; - strncpy(cardname, nubus_get_card_name(&sc->sc_slot), - CARD_NAME_LEN); + strncpy(cardname, nubus_get_card_name(sc->sc_tag, sc->sc_regh, + &sc->sc_slot), CARD_NAME_LEN); cardname[CARD_NAME_LEN-1] = '\0'; printf(": %s\n", cardname); @@ -210,7 +220,7 @@ grfmv_attach(parent, self, aux) if (strncmp(cardname, "Samsung 768", 11) == 0) sc->card_id = NUBUS_DRHW_SAM768; else if (strncmp(cardname, "Toby frame", 10) != 0) - printf("%s: card masquerades as Toby Framebuffer", + printf("%s: This display card pretends to be a TFB!\n", sc->sc_dev.dv_xname); } @@ -219,36 +229,36 @@ grfmv_attach(parent, self, aux) case NUBUS_DRHW_TFB: sc->cli_offset = 0xa0000; sc->cli_value = 0; - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_generic, sc, + add_nubus_intr(na->slot, grfmv_intr_generic, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_WVC: sc->cli_offset = 0xa00000; sc->cli_value = 0; - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_generic, sc, + add_nubus_intr(na->slot, grfmv_intr_generic, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_RPC8XJ: - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_radius, sc, + add_nubus_intr(na->slot, grfmv_intr_radius, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_FIILX: case NUBUS_DRHW_FIISXDSP: - sc->cli_offset = 0xF05000; + sc->cli_offset = 0xf05000; sc->cli_value = 0x80; - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_generic, sc, + add_nubus_intr(na->slot, grfmv_intr_generic, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_SAM768: - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_cti, sc, + add_nubus_intr(na->slot, grfmv_intr_cti, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_CB264: - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_cb264, sc, + add_nubus_intr(na->slot, grfmv_intr_cb264, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_CB364: - add_nubus_intr(sc->sc_slot.slot, grfmv_intr_cb364, sc, + add_nubus_intr(na->slot, grfmv_intr_cb364, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_SE30: @@ -293,7 +303,7 @@ grfmv_phys(gp, addr) vm_offset_t addr; { return (caddr_t)(NUBUS_SLOT2PA(gp->sc_slot->slot) + - (addr - gp->sc_slot->virtual_base)); + (addr - gp->sc_regh)); /* XXX evil hack */ } /* Interrupt handlers... */ @@ -304,32 +314,26 @@ grfmv_phys(gp, addr) */ /*ARGSUSED*/ static int -grfmv_intr_generic(void *vsc) +grfmv_intr_generic(vsc) + void *vsc; { - struct grfbus_softc *sc; - volatile char *slotbase; + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; - sc = (struct grfbus_softc *)vsc; - slotbase = (volatile char *)sc->sc_slot.virtual_base; - slotbase[sc->cli_offset] = sc->cli_value; + bus_space_write_1(sc->sc_tag, sc->sc_regh, + sc->cli_offset, sc->cli_value); return (1); } /* - * Generic routine to clear interrupts for cards where it simply takes - * a CLR.B to clear the interrupt. The offset of this byte varies between - * cards. + * Routine to clear interrupts for the Radius PrecisionColor 8xj card. */ /*ARGSUSED*/ static int -grfmv_intr_radius(void *vsc) +grfmv_intr_radius(vsc) + void *vsc; { - unsigned char c; - struct grfbus_softc *sc; - volatile char *slotbase; - - sc = (struct grfbus_softc *)vsc; - slotbase = (volatile char *)sc->sc_slot.virtual_base; + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t c; /* * The value 0x66 was the observed value on one card. It is read @@ -339,9 +343,9 @@ grfmv_intr_radius(void *vsc) c = 0x66; c |= 0x80; - slotbase[0xD00403] = c; - c &= 0x7F; - slotbase[0xD00403] = c; + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xd00403, c); + c &= 0x7f; + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xd00403, c); return (1); } @@ -356,15 +360,17 @@ grfmv_intr_radius(void *vsc) */ /*ARGSUSED*/ static int -grfmv_intr_cti(void *vsc) +grfmv_intr_cti(vsc) + void *vsc; { - struct grfbus_softc *sc; - volatile char *slotbase; - - sc = (struct grfbus_softc *)vsc; - slotbase = ((volatile char *)sc->sc_slot.virtual_base) + 0x00080000; - *slotbase = (*slotbase | 0x02); - *slotbase = (*slotbase & 0xFD); + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t c; + + c = bus_space_read_1(sc->sc_tag, sc->sc_regh, 0x80000); + c |= 0x02; + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x80000, c); + c &= 0xfd; + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x80000, c); return (1); } @@ -376,7 +382,7 @@ grfmv_intr_cb264(void *vsc) volatile char *slotbase; sc = (struct grfbus_softc *)vsc; - slotbase = (volatile char *)sc->sc_slot.virtual_base; + slotbase = (volatile char *)sc->sc_regh; /* XXX evil hack */ asm volatile(" movl %0,a0 movl a0@(0xff6028),d0 andl #0x2,d0 @@ -430,7 +436,7 @@ grfmv_intr_cb364(void *vsc) volatile char *slotbase; sc = (struct grfbus_softc *)vsc; - slotbase = (volatile char *)sc->sc_slot.virtual_base; + slotbase = (volatile char *)sc->sc_regh; /* XXX evil hack */ asm volatile(" movl %0,a0 movl a0@(0xfe6028),d0 andl #0x2,d0 diff --git a/sys/arch/mac68k/dev/grfvar.h b/sys/arch/mac68k/dev/grfvar.h index a69b4d5735d..712b59c3cee 100644 --- a/sys/arch/mac68k/dev/grfvar.h +++ b/sys/arch/mac68k/dev/grfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: grfvar.h,v 1.13 2003/09/23 16:51:11 millert Exp $ */ +/* $OpenBSD: grfvar.h,v 1.14 2005/04/26 21:09:35 martin Exp $ */ /* $NetBSD: grfvar.h,v 1.11 1996/08/04 06:03:58 scottr Exp $ */ /* @@ -66,6 +66,9 @@ struct grfbus_softc { struct grf_softc { struct device sc_dev; /* device glue */ + bus_space_tag_t sc_tag; + bus_space_handle_t sc_regh; + int sc_flags; /* software flags */ struct grfmode *sc_grfmode; /* forwarded ... */ nubus_slot *sc_slot; diff --git a/sys/arch/mac68k/dev/if_ae_nubus.c b/sys/arch/mac68k/dev/if_ae_nubus.c index bbcf6ed0f77..4621bafb93c 100644 --- a/sys/arch/mac68k/dev/if_ae_nubus.c +++ b/sys/arch/mac68k/dev/if_ae_nubus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ae_nubus.c,v 1.13 2005/03/04 00:38:37 martin Exp $ */ +/* $OpenBSD: if_ae_nubus.c,v 1.14 2005/04/26 21:09:35 martin Exp $ */ /* $NetBSD: if_ae_nubus.c,v 1.17 1997/05/01 18:17:16 briggs Exp $ */ /* @@ -71,8 +71,10 @@ static int ae_nubus_match(struct device *, void *, void *); static void ae_nubus_attach(struct device *, struct device *, void *); -static int ae_nb_card_vendor(struct nubus_attach_args *); -static int ae_nb_get_enaddr(struct nubus_attach_args *, u_int8_t *); +static int ae_nb_card_vendor(bus_space_tag_t, bus_space_handle_t, + struct nubus_attach_args *); +static int ae_nb_get_enaddr(bus_space_tag_t, bus_space_handle_t, + struct nubus_attach_args *, u_int8_t *); #ifdef DEBUG static void ae_nb_watchdog(struct ifnet *); #endif @@ -99,7 +101,7 @@ ae_nubus_match(parent, vcf, aux) if (na->category == NUBUS_CATEGORY_NETWORK && na->type == NUBUS_TYPE_ETHERNET) { - switch (ae_nb_card_vendor(na)) { + switch (ae_nb_card_vendor(na->na_tag, bsh, na)) { case AE_VENDOR_APPLE: case AE_VENDOR_ASANTE: case AE_VENDOR_FARALLON: @@ -149,8 +151,8 @@ ae_nubus_attach(parent, self, aux) sc->sc_regt = sc->sc_buft = bst; sc->sc_flags = self->dv_cfdata->cf_flags; sc->use16bit = 1; - sc->vendor = ae_nb_card_vendor(na); - strncpy(sc->type_str, nubus_get_card_name(na->fmt), + sc->vendor = ae_nb_card_vendor(bst, bsh, na); + strncpy(sc->type_str, nubus_get_card_name(bst, bsh, na->fmt), INTERFACE_NAME_LEN); sc->type_str[INTERFACE_NAME_LEN-1] = '\0'; sc->mem_size = 0; @@ -185,7 +187,7 @@ ae_nubus_attach(parent, self, aux) sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(bst, bsh, (AE_ROM_OFFSET + i * 2)); #else - if (ae_nb_get_enaddr(na, sc->sc_arpcom.ac_enaddr)) { + if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) { printf(": can't find MAC address\n"); break; } @@ -216,7 +218,7 @@ ae_nubus_attach(parent, self, aux) sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(bst, bsh, (DP_ROM_OFFSET + i * 2)); #else - if (ae_nb_get_enaddr(na, sc->sc_arpcom.ac_enaddr)) { + if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) { printf(": can't find MAC address\n"); break; } @@ -283,7 +285,7 @@ ae_nubus_attach(parent, self, aux) /* reset the NIC chip */ bus_space_write_1(bst, bsh, GC_RESET_OFFSET, 0); - if (ae_nb_get_enaddr(na, sc->sc_arpcom.ac_enaddr)) { + if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) { /* Fall back to snarf directly from ROM. Ick. */ for (i = 0; i < ETHER_ADDR_LEN; ++i) sc->sc_arpcom.ac_enaddr[i] = @@ -315,7 +317,7 @@ ae_nubus_attach(parent, self, aux) printf(": failed to map register space\n"); break; } - if (ae_nb_get_enaddr(na, sc->sc_arpcom.ac_enaddr)) { + if (ae_nb_get_enaddr(bst, bsh, na, sc->sc_arpcom.ac_enaddr)) { printf(": can't find MAC address\n"); break; } @@ -345,7 +347,9 @@ ae_nubus_attach(parent, self, aux) } static int -ae_nb_card_vendor(na) +ae_nb_card_vendor(bst, bsh, na) + bus_space_tag_t bst; + bus_space_handle_t bsh; struct nubus_attach_args *na; { int vendor; @@ -393,8 +397,8 @@ ae_nb_card_vendor(na) vendor = AE_VENDOR_INTERLAN; break; case NUBUS_DRHW_KINETICS: - if (strncmp( - nubus_get_card_name(na->fmt), "EtherPort", 9) == 0) + if (strncmp(nubus_get_card_name(bst, bsh, na->fmt), + "EtherPort", 9) == 0) vendor = AE_VENDOR_KINETICS; else vendor = AE_VENDOR_DAYNA; @@ -408,7 +412,9 @@ ae_nb_card_vendor(na) } static int -ae_nb_get_enaddr(na, ep) +ae_nb_get_enaddr(bst, bsh, na, ep) + bus_space_tag_t bst; + bus_space_handle_t bsh; struct nubus_attach_args *na; u_int8_t *ep; { @@ -422,23 +428,25 @@ ae_nb_get_enaddr(na, ep) * we find out more about Ethernet card resources. */ nubus_get_main_dir(na->fmt, &dir); - switch (ae_nb_card_vendor(na)) { + switch (ae_nb_card_vendor(bst, bsh, na)) { case AE_VENDOR_APPLE: if (na->drsw == NUBUS_DRSW_TFLLAN) { /* TFL LAN E410/E420 */ - rv = nubus_find_rsrc(na->fmt, &dir, 0x80, &dirent); + rv = nubus_find_rsrc(bst, bsh, na->fmt, + &dir, 0x80, &dirent); break; } /* FALLTHROUGH */ default: - rv = nubus_find_rsrc(na->fmt, &dir, 0x80, &dirent); + rv = nubus_find_rsrc(bst, bsh, na->fmt, &dir, 0x80, &dirent); break; } if (rv <= 0) return 1; nubus_get_dir_from_rsrc(na->fmt, &dirent, &dir); - if (nubus_find_rsrc(na->fmt, &dir, 0x80, &dirent) <= 0) + if (nubus_find_rsrc(bst, bsh, na->fmt, &dir, 0x80, &dirent) <= 0) return 1; - if (nubus_get_ind_data(na->fmt, &dirent, ep, ETHER_ADDR_LEN) <= 0) + if (nubus_get_ind_data(bst, bsh, + na->fmt, &dirent, ep, ETHER_ADDR_LEN) <= 0) return 1; return 0; diff --git a/sys/arch/mac68k/dev/if_sn_nubus.c b/sys/arch/mac68k/dev/if_sn_nubus.c index e8732920cfd..376de141ed7 100644 --- a/sys/arch/mac68k/dev/if_sn_nubus.c +++ b/sys/arch/mac68k/dev/if_sn_nubus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sn_nubus.c,v 1.16 2004/11/26 21:21:24 miod Exp $ */ +/* $OpenBSD: if_sn_nubus.c,v 1.17 2005/04/26 21:09:35 martin Exp $ */ /* $NetBSD: if_sn_nubus.c,v 1.13 1997/05/11 19:11:34 scottr Exp $ */ /* * Copyright (C) 1997 Allen Briggs @@ -126,7 +126,7 @@ sn_nubus_attach(parent, self, aux) sc->sc_regt = bst; - strncpy(cardtype, nubus_get_card_name(na->fmt), + strncpy(cardtype, nubus_get_card_name(bst, bsh, na->fmt), INTERFACE_NAME_LEN); success = 0; @@ -291,7 +291,7 @@ sn_nb_card_vendor(bst, bsh, na) break; case NUBUS_DRSW_GATOR: if (na->drhw == NUBUS_DRHW_KINETICS && - strncmp(nubus_get_card_name(na->fmt), + strncmp(nubus_get_card_name(bst, bsh, na->fmt), "EtherPort", 9) != 0) vendor = SN_VENDOR_DAYNA; break; diff --git a/sys/arch/mac68k/dev/nubus.c b/sys/arch/mac68k/dev/nubus.c index c7920255057..81d6f4f18b3 100644 --- a/sys/arch/mac68k/dev/nubus.c +++ b/sys/arch/mac68k/dev/nubus.c @@ -1,5 +1,5 @@ -/* $OpenBSD: nubus.c,v 1.29 2004/11/28 14:04:24 miod Exp $ */ -/* $NetBSD: nubus.c,v 1.35 1997/04/22 20:20:32 scottr Exp $ */ +/* $OpenBSD: nubus.c,v 1.30 2005/04/26 21:09:35 martin Exp $ */ +/* $NetBSD: nubus.c,v 1.45 1998/06/02 02:24:03 scottr Exp $ */ /* * Copyright (c) 1995, 1996 Allen Briggs. All rights reserved. @@ -46,30 +46,34 @@ #include <machine/pte.h> #include <machine/viareg.h> -#include "nubus.h" +#include <mac68k/dev/nubus.h> #ifdef DEBUG -static int nubus_debug = 0x01; #define NDB_PROBE 0x1 #define NDB_FOLLOW 0x2 #define NDB_ARITH 0x4 +static int nubus_debug = 0 /* | NDB_PROBE */; #endif static int nubus_print(void *, const char *); static int nubus_match(struct device *, void *, void *); static void nubus_attach(struct device *, struct device *, void *); -int nubus_video_resource(int); +static int nubus_video_resource(int); -static int probe_slot(int slot, nubus_slot *fmt); -static u_long IncPtr(nubus_slot *fmt, u_long base, long amt); -static u_long nubus_calc_CRC(nubus_slot *fmt); -static u_char GetByte(nubus_slot *fmt, u_long ptr); +static int nubus_probe_slot(bus_space_tag_t, bus_space_handle_t, + int, nubus_slot *); +static u_int32_t nubus_calc_CRC(bus_space_tag_t, bus_space_handle_t, + nubus_slot *); + +static u_long nubus_adjust_ptr(u_int8_t, u_long, long); +static u_int8_t nubus_read_1(bus_space_tag_t, bus_space_handle_t, + u_int8_t, u_long); #ifdef notyet -/* unused */ static u_short GetWord(nubus_slot *fmt, u_long ptr); +static u_int16_t nubus_read_2(bus_space_tag_t, bus_space_handle_t, + u_int8_t, u_long); #endif -static u_long GetLong(nubus_slot *fmt, u_long ptr); - -static int nubus_peek(vm_offset_t, int); +static u_int32_t nubus_read_4(bus_space_tag_t, bus_space_handle_t, + u_int8_t, u_long); struct cfattach nubus_ca = { sizeof(struct nubus_softc), nubus_match, nubus_attach @@ -80,9 +84,9 @@ struct cfdriver nubus_cd = { }; static int -nubus_match(parent, vcf, aux) +nubus_match(parent, cf, aux) struct device *parent; - void *vcf; + void *cf; void *aux; { static int nubus_matched = 0; @@ -101,20 +105,42 @@ nubus_attach(parent, self, aux) void *aux; { struct nubus_attach_args na_args; + bus_space_tag_t bst; + bus_space_handle_t bsh; nubus_slot fmtblock; nubus_dir dir; nubus_dirent dirent; nubus_type slottype; u_long entry; int i, rsrcid; + u_int8_t lanes; - printf("\n"); - - for (i = NUBUS_MIN_SLOT; i <= NUBUS_MAX_SLOT; i++) { - if (probe_slot(i, &fmtblock) <= 0) + printf("\n"); + + for (i = NUBUS_MIN_SLOT; i <= NUBUS_MAX_SLOT; i++) { + na_args.slot = i; + na_args.na_tag = bst = MAC68K_BUS_SPACE_MEM; + + if (bus_space_map(bst, + NUBUS_SLOT2PA(na_args.slot), NBMEMSIZE, 0, &bsh)) { +#ifdef DEBUG + if (nubus_debug & NDB_PROBE) + printf("%s: failed to map slot %x, " + "address %p (in use?)\n", + self->dv_xname, i, + (void *)NUBUS_SLOT2PA(i)); +#endif continue; + } + if (nubus_probe_slot(bst, bsh, i, &fmtblock) <= 0) { +notfound: + bus_space_unmap(bst, bsh, NBMEMSIZE); + continue; + } + rsrcid = 0x80; + lanes = fmtblock.bytelanes; nubus_get_main_dir(&fmtblock, &dir); @@ -127,7 +153,8 @@ nubus_attach(parent, self, aux) * doesn't work either, take the first resource following * the board resource. */ - if (nubus_find_rsrc(&fmtblock, &dir, rsrcid, &dirent) <= 0) { + if (nubus_find_rsrc(bst, bsh, + &fmtblock, &dir, rsrcid, &dirent) <= 0) { if ((rsrcid = nubus_video_resource(i)) == -1) { /* * Since nubus_find_rsrc failed, the directory @@ -140,65 +167,65 @@ nubus_attach(parent, self, aux) * resource, but be sure that's what it * is before we skip it. */ - rsrcid = GetByte(&fmtblock, entry); + rsrcid = nubus_read_1(bst, bsh, + lanes, entry); if (rsrcid == 0x1) - entry = - IncPtr(&fmtblock, dir.curr_ent, 4); + entry = nubus_adjust_ptr(lanes, + dir.curr_ent, 4); - rsrcid = GetByte(&fmtblock, entry); + rsrcid = nubus_read_1(bst, bsh, lanes, entry); #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("\tUsing rsrc 0x%x.\n", rsrcid); #endif - if (rsrcid == 0xff) - continue; /* end of chain */ + if (rsrcid == 0xff) /* end of chain */ + goto notfound; } /* * Try to find the resource passed by the booter * or the one we just tracked down. */ - if (nubus_find_rsrc(&fmtblock, &dir, - rsrcid, &dirent) <= 0) { - continue; - } + if (nubus_find_rsrc(bst, bsh, + &fmtblock, &dir, rsrcid, &dirent) <= 0) + goto notfound; } nubus_get_dir_from_rsrc(&fmtblock, &dirent, &dir); - if (nubus_find_rsrc(&fmtblock, &dir, NUBUS_RSRC_TYPE, - &dirent) <= 0) - continue; + if (nubus_find_rsrc(bst, bsh, + &fmtblock, &dir, NUBUS_RSRC_TYPE, &dirent) <= 0) + goto notfound; - if (nubus_get_ind_data(&fmtblock, &dirent, - (caddr_t) &slottype, sizeof(nubus_type)) <= 0) - continue; + if (nubus_get_ind_data(bst, bsh, &fmtblock, &dirent, + (caddr_t)&slottype, sizeof(nubus_type)) <= 0) + goto notfound; /* * If this is a display card, try to pull out the correct * display mode as passed by the booter. */ if (slottype.category == NUBUS_CATEGORY_DISPLAY) { - int r; + int r; if ((r = nubus_video_resource(i)) != -1) { nubus_get_main_dir(&fmtblock, &dir); - if (nubus_find_rsrc(&fmtblock, &dir, - r, &dirent) <= 0) - continue; + if (nubus_find_rsrc(bst, bsh, + &fmtblock, &dir, r, &dirent) <= 0) + goto notfound; nubus_get_dir_from_rsrc(&fmtblock, - &dirent, &dir); + &dirent, &dir); - if (nubus_find_rsrc(&fmtblock, &dir, - NUBUS_RSRC_TYPE, &dirent) <= 0) - continue; + if (nubus_find_rsrc(bst, bsh, &fmtblock, &dir, + NUBUS_RSRC_TYPE, &dirent) <= 0) + goto notfound; - if (nubus_get_ind_data(&fmtblock, &dirent, - (caddr_t) &slottype, - sizeof(nubus_type)) <= 0) - continue; + if (nubus_get_ind_data(bst, bsh, + &fmtblock, &dirent, (caddr_t)&slottype, + sizeof(nubus_type)) <= 0) + goto notfound; rsrcid = r; } @@ -212,38 +239,48 @@ nubus_attach(parent, self, aux) na_args.drhw = slottype.drhw; na_args.fmt = &fmtblock; + bus_space_unmap(bst, bsh, NBMEMSIZE); + config_found(self, &na_args, nubus_print); - } + } - /* - * enable nubus interrupts here. - */ enable_nubus_intr(); } static int -nubus_print(aux, name) +nubus_print(aux, pnp) void *aux; - const char *name; + const char *pnp; { - struct nubus_attach_args *na = (struct nubus_attach_args *) aux; - - if (name) { - printf("%s: slot %x: %s", name, na->fmt->slot, - nubus_get_card_name(na->fmt)); - printf(" (Vendor: %s,", - nubus_get_vendor(na->fmt, NUBUS_RSRC_VEND_ID)); - printf(" Part: %s", - nubus_get_vendor(na->fmt, NUBUS_RSRC_VEND_PART)); + struct nubus_attach_args *na = (struct nubus_attach_args *)aux; + bus_space_tag_t bst = na->na_tag; + bus_space_handle_t bsh; + + if (pnp) { + printf("%s slot %x", pnp, na->slot); + if (bus_space_map(bst, + NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh) == 0) { + printf(": %s", nubus_get_card_name(bst, bsh, na->fmt)); + printf(" (Vendor: %s,", nubus_get_vendor(bst, bsh, + na->fmt, NUBUS_RSRC_VEND_ID)); + printf(" Part: %s)", nubus_get_vendor(bst, bsh, + na->fmt, NUBUS_RSRC_VEND_PART)); + + bus_space_unmap(bst, bsh, NBMEMSIZE); + } #ifdef DIAGNOSTIC + else + printf(":"); printf(" Type: %04x %04x %04x %04x", na->category, na->type, na->drsw, na->drhw); #endif + } else { + printf(" slot %x", na->slot); } return (UNCONF); } -int +static int nubus_video_resource(slot) int slot; { @@ -283,116 +320,109 @@ nubus_video_resource(slot) * * If a valid */ -static u_char nbits[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; +static u_int8_t nbits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; static int -probe_slot(slot, fmt) - int slot; - nubus_slot *fmt; +nubus_probe_slot(bst, bsh, slot, fmt) + bus_space_tag_t bst; + bus_space_handle_t bsh; + int slot; + nubus_slot *fmt; { - caddr_t rom_probe; - vm_offset_t hdr; -#ifdef DEBUG - vm_offset_t pa; -#endif - u_int data; - int hdr_size, i; - - fmt->bytelanes = 0; - fmt->slot = (u_long)slot; - - rom_probe = (caddr_t) (NUBUS_SLOT2PA(fmt->slot) + NBMEMSIZE); + u_long ofs, hdr; + int i, j, found, hdr_size; + u_int8_t lanes; #ifdef DEBUG - if (nubus_debug & NDB_PROBE) { - pmap_extract(pmap_kernel(), (vm_offset_t) rom_probe - 1, &pa); - printf("probing slot %d, first probe at %p (PA %lx).\n", - slot, rom_probe - 1, pa); - } + if (nubus_debug & NDB_PROBE) + printf("probing slot %x\n", slot); #endif - for (i = 4; i && (fmt->bytelanes == 0); i--) { - - rom_probe--; - - data = nubus_peek((vm_offset_t) rom_probe, 1); - - if (data == (u_int) -1) - continue; - - if (data == 0) - continue; - - if ( ((((data & 0xf0) >> 4) ^ (data & 0x0f)) == 0x0f) - && ((data & 0x0f) < (1 << i)) ) { - fmt->bytelanes = data; - fmt->step = nbits[(data & 0x0f)]; + /* + * The idea behind this glorious work of art is to probe for only + * valid bytelanes values at appropriate locations (see DC&D p. 159 + * for a list). Note the pattern: the first 8 values are at offset + * 0xffffff in the slot's space; the next 4 values at 0xfffffe; the + * next 2 values at 0xfffffd; and the last one at 0xfffffc. + * + * The nested loops implement an efficient search of this space, + * probing first for a valid address, then checking for each of the + * valid bytelanes values at that address. + */ + ofs = NBMEMSIZE; + lanes = 0xf; + + for (j = 8, found = 0; j > 0 && !found; j >>= 1) { + ofs--; + for (i = j; i > 0; i--, lanes--) { + if (!mac68k_bus_space_probe(bst, bsh, ofs, 1)) { + lanes -= i; + break; + } + if (bus_space_read_1(bst, bsh, ofs) == + (((~lanes & 0xf) << 4) | lanes)) { + found = 1; + break; + } } } + + if (!found) { #ifdef DEBUG - if (nubus_debug & NDB_PROBE) - if (fmt->bytelanes == 0) - printf("bytelanes not found for slot 0x%x.\n", slot); + if (nubus_debug & NDB_PROBE) + printf("bytelanes not found for slot %x\n", slot); #endif - - if (fmt->bytelanes == 0) return 0; + } + + fmt->bytelanes = lanes; + fmt->step = nbits[(lanes & 0x0f)]; + fmt->slot = slot; /* XXX redundant; get rid of this someday */ #ifdef DEBUG if (nubus_debug & NDB_PROBE) printf("bytelanes of 0x%x found for slot 0x%x.\n", - fmt->bytelanes, slot); + fmt->bytelanes, slot); #endif - hdr_size = 20; - /* * Go ahead and attempt to load format header. * First, we need to find the first byte beyond memory that * would be valid. This is necessary for NUBUS_ROM_offset() * to work. */ - hdr = (vm_offset_t) - nubus_mapin(NUBUS_SLOT2PA(fmt->slot), NBMEMSIZE); - if (hdr == NULL) { - printf("Failed to map %d bytes for NuBUS slot %d probe. ", - NBMEMSIZE, fmt->slot); - printf("Physical slot address %x\n", - (unsigned int) NUBUS_SLOT2PA(fmt->slot)); - } - fmt->virtual_base = hdr; - hdr += NBMEMSIZE; + hdr = NBMEMSIZE; + hdr_size = 20; - i = 0x10 | (fmt->bytelanes & 0x0f); + i = 0x10 | (lanes & 0x0f); while ((i & 1) == 0) { hdr++; i >>= 1; } fmt->top = hdr; - hdr = IncPtr(fmt, hdr, -hdr_size); + hdr = nubus_adjust_ptr(lanes, hdr, -hdr_size); #ifdef DEBUG if (nubus_debug & NDB_PROBE) printf("fmt->top is 0x%lx, that minus 0x%x puts us at 0x%lx.\n", - fmt->top, hdr_size, hdr); -#if 0 - for (i=1 ; i < 8 ; i++) { - printf("0x%x - 0x%x = 0x%x, + 0x%x = 0x%x.\n", - hdr, i, IncPtr(fmt, hdr, -i), - i, IncPtr(fmt, hdr, i)); - } -#endif + fmt->top, hdr_size, hdr); + if (nubus_debug & NDB_ARITH) + for (i = 1 ; i < 8 ; i++) + printf("0x%lx - 0x%x = 0x%lx, + 0x%x = 0x%lx.\n", + hdr, i, nubus_adjust_ptr(lanes, hdr, -i), + i, nubus_adjust_ptr(lanes, hdr, i)); #endif - fmt->directory_offset = 0xff000000 | GetLong(fmt, hdr); - hdr = IncPtr(fmt, hdr, 4); - fmt->length = GetLong(fmt, hdr); - hdr = IncPtr(fmt, hdr, 4); - fmt->crc = GetLong(fmt, hdr); - hdr = IncPtr(fmt, hdr, 4); - fmt->revision_level = GetByte(fmt, hdr); - hdr = IncPtr(fmt, hdr, 1); - fmt->format = GetByte(fmt, hdr); - hdr = IncPtr(fmt, hdr, 1); - fmt->test_pattern = GetLong(fmt, hdr); + fmt->directory_offset = + 0xff000000 | nubus_read_4(bst, bsh, lanes, hdr); + hdr = nubus_adjust_ptr(lanes, hdr, 4); + fmt->length = nubus_read_4(bst, bsh, lanes, hdr); + hdr = nubus_adjust_ptr(lanes, hdr, 4); + fmt->crc = nubus_read_4(bst, bsh, lanes, hdr); + hdr = nubus_adjust_ptr(lanes, hdr, 4); + fmt->revision_level = nubus_read_1(bst, bsh, lanes, hdr); + hdr = nubus_adjust_ptr(lanes, hdr, 1); + fmt->format = nubus_read_1(bst, bsh, lanes, hdr); + hdr = nubus_adjust_ptr(lanes, hdr, 1); + fmt->test_pattern = nubus_read_4(bst, bsh, lanes, hdr); #ifdef DEBUG if (nubus_debug & NDB_PROBE) { @@ -407,28 +437,58 @@ probe_slot(slot, fmt) if ((fmt->directory_offset & 0x00ff0000) == 0) { printf("Invalid looking directory offset (0x%x)!\n", - fmt->directory_offset); + fmt->directory_offset); return 0; } if (fmt->test_pattern != NUBUS_ROM_TEST_PATTERN) { printf("Nubus--test pattern invalid:\n"); - printf(" slot 0x%x, bytelanes 0x%x?\n", - fmt->slot, fmt->bytelanes); + printf(" slot 0x%x, bytelanes 0x%x?\n", fmt->slot, lanes); printf(" read test 0x%x, compare with 0x%x.\n", - fmt->test_pattern, NUBUS_ROM_TEST_PATTERN); + fmt->test_pattern, NUBUS_ROM_TEST_PATTERN); return 0; } /* Perform CRC */ - if (fmt->crc != nubus_calc_CRC(fmt)) { - printf("Nubus--crc check failed, slot 0x%x.\n", - fmt->slot); + if (fmt->crc != nubus_calc_CRC(bst, bsh, fmt)) { + printf("Nubus--crc check failed, slot 0x%x.\n", fmt->slot); return 0; } return 1; } +static u_int32_t +nubus_calc_CRC(bst, bsh, fmt) + bus_space_tag_t bst; + bus_space_handle_t bsh; + nubus_slot *fmt; +{ +#if 0 + u_long base, ptr, crc_loc; + u_int32_t sum; + u_int8_t lanes = fmt->bytelanes; + + base = fmt->top; + crc_loc = NUBUS_ROM_offset(fmt, base, -12); + ptr = NUBUS_ROM_offset(fmt, base, -fmt->length); + + sum = 0; + while (ptr < base) + roll #1, sum + if (ptr == crc_loc) { + roll #3, sum + ptr = nubus_adjust_ptr(lanes, ptr, 3); + } else { + sum += nubus_read_1(bst, bsh, lanes, ptr); + } + ptr = nubus_adjust_ptr(lanes, ptr, 1); + } + + return sum; +#endif + return fmt->crc; +} + /* * Compute byte offset on card, taking into account bytelanes. * Base must be on a valid bytelane for this function to work. @@ -437,25 +497,25 @@ probe_slot(slot, fmt) * XXX -- There has GOT to be a better way to do this. */ static u_long -IncPtr(fmt, base, amt) - nubus_slot *fmt; - u_long base; - long amt; +nubus_adjust_ptr(lanes, base, amt) + u_int8_t lanes; + u_long base; + long amt; { - u_char b, t; + u_int8_t b, t; if (!amt) return base; if (amt < 0) { amt = -amt; - b = fmt->bytelanes; + b = lanes; t = (b << 4); b <<= (3 - (base & 0x3)); while (amt) { b <<= 1; if (b == t) - b = fmt->bytelanes; + b = lanes; if (b & 0x08) amt--; base--; @@ -463,7 +523,7 @@ IncPtr(fmt, base, amt) return base; } - t = (fmt->bytelanes & 0xf) | 0x10; + t = (lanes & 0xf) | 0x10; b = t >> (base & 0x3); while (amt) { b >>= 1; @@ -477,112 +537,111 @@ IncPtr(fmt, base, amt) return base; } -static u_long -nubus_calc_CRC(fmt) - nubus_slot *fmt; -{ -#if 0 - u_long base, ptr, crc_loc, sum; - int i; - - base = fmt->top; - crc_loc = NUBUS_ROM_offset(fmt, base, -12); - ptr = NUBUS_ROM_offset(fmt, base, -fmt->length); - - sum = 0; - while (ptr < base) - roll #1, sum - if (ptr == crc_loc) { - roll #3, sum - ptr = IncPtr(fmt, ptr, 3); - } else { - sum += GetByte(fmt, ptr); - } - ptr = IncPtr(fmt, ptr, 1); - } - - return sum; -#endif - return fmt->crc; -} - -static u_char -GetByte(fmt, ptr) - nubus_slot *fmt; - u_long ptr; +static u_int8_t +nubus_read_1(bst, bsh, lanes, ofs) + bus_space_tag_t bst; + bus_space_handle_t bsh; + u_int8_t lanes; + u_long ofs; { - return *(caddr_t)ptr; + return bus_space_read_1(bst, bsh, ofs); } #ifdef notyet /* Nothing uses this, yet */ -static u_short -GetWord(fmt, ptr) - nubus_slot *fmt; - u_long ptr; +static u_int16_t +nubus_read_2(bst, bsh, lanes, ofs) + bus_space_tag_t bst; + bus_space_handle_t bsh; + u_int8_t lanes; + u_long ofs; { - u_short s; + u_int16_t s; - s = (GetByte(fmt, ptr) << 8); - ptr = IncPtr(fmt, ptr, 1); - s |= GetByte(fmt, ptr); + s = (nubus_read_1(bst, bsh, lanes, ofs) << 8); + ofs = nubus_adjust_ptr(lanes, ofs, 1); + s |= nubus_read_1(bst, bsh, lanes, ofs); return s; } #endif -static u_long -GetLong(fmt, ptr) - nubus_slot *fmt; - u_long ptr; +static u_int32_t +nubus_read_4(bst, bsh, lanes, ofs) + bus_space_tag_t bst; + bus_space_handle_t bsh; + u_int8_t lanes; + u_long ofs; { - register u_long l; - register int i; + u_int32_t l; + int i; l = 0; - for ( i = 0; i < 4; i++) { - l = (l << 8) | GetByte(fmt, ptr); - ptr = IncPtr(fmt, ptr, 1); + for (i = 0; i < 4; i++) { + l = (l << 8) | nubus_read_1(bst, bsh, lanes, ofs); + ofs = nubus_adjust_ptr(lanes, ofs, 1); } return l; } void -nubus_get_main_dir(slot, dir_return) - nubus_slot *slot; - nubus_dir *dir_return; +nubus_get_main_dir(fmt, dir_return) + nubus_slot *fmt; + nubus_dir *dir_return; { #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_main_dir(0x%x, 0x%x)\n", - (u_int) slot, (u_int) dir_return); + printf("nubus_get_main_dir(%p, %p)\n", + fmt, dir_return); #endif - dir_return->dirbase = IncPtr(slot, slot->top, - slot->directory_offset - 20); + dir_return->dirbase = nubus_adjust_ptr(fmt->bytelanes, fmt->top, + fmt->directory_offset - 20); + dir_return->curr_ent = dir_return->dirbase; +} + +void +nubus_get_dir_from_rsrc(fmt, dirent, dir_return) + nubus_slot *fmt; + nubus_dirent *dirent; + nubus_dir *dir_return; +{ + u_long loc; + +#ifdef DEBUG + if (nubus_debug & NDB_FOLLOW) + printf("nubus_get_dir_from_rsrc(%p, %p, %p).\n", + fmt, dirent, dir_return); +#endif + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + dir_return->dirbase = + nubus_adjust_ptr(fmt->bytelanes, dirent->myloc, loc); dir_return->curr_ent = dir_return->dirbase; } int -nubus_find_rsrc(slot, dir, rsrcid, dirent_return) - nubus_slot *slot; - nubus_dir *dir; - u_int8_t rsrcid; - nubus_dirent *dirent_return; +nubus_find_rsrc(bst, bsh, fmt, dir, rsrcid, dirent_return) + bus_space_tag_t bst; + bus_space_handle_t bsh; + nubus_slot *fmt; + nubus_dir *dir; + u_int8_t rsrcid; + nubus_dirent *dirent_return; { - u_long entry; - u_char byte; + u_long entry; + u_int8_t byte, lanes = fmt->bytelanes; #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_find_rsrc(0x%x, 0x%x, 0x%x, 0x%x)\n", - (u_int) slot, (u_int) dir, (u_int) rsrcid, - (u_int) dirent_return); + printf("nubus_find_rsrc(%p, %p, 0x%x, %p)\n", + fmt, dir, rsrcid, dirent_return); #endif - if (slot->test_pattern != NUBUS_ROM_TEST_PATTERN) + if (fmt->test_pattern != NUBUS_ROM_TEST_PATTERN) return -1; entry = dir->curr_ent; do { - byte = GetByte(slot, entry); + byte = nubus_read_1(bst, bsh, lanes, entry); #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("\tFound rsrc 0x%x.\n", byte); @@ -590,243 +649,181 @@ nubus_find_rsrc(slot, dir, rsrcid, dirent_return) if (byte == rsrcid) { dirent_return->myloc = entry; dirent_return->rsrc_id = rsrcid; - entry = GetLong(slot, entry); + entry = nubus_read_4(bst, bsh, lanes, entry); dirent_return->offset = (entry & 0x00ffffff); return 1; } if (byte == 0xff) { entry = dir->dirbase; } else { - entry = IncPtr(slot, entry, 4); + entry = nubus_adjust_ptr(lanes, entry, 4); } - } while (entry != (u_long) dir->curr_ent); + } while (entry != (u_long)dir->curr_ent); return 0; } -void -nubus_get_dir_from_rsrc(slot, dirent, dir_return) - nubus_slot *slot; - nubus_dirent *dirent; - nubus_dir *dir_return; -{ - u_long loc; - -#ifdef DEBUG - if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_dir_from_rsrc(0x%x, 0x%x, 0x%x).\n", - (u_int) slot, (u_int) dirent, (u_int) dir_return); -#endif - if ((loc = dirent->offset) & 0x800000) { - loc |= 0xff000000; - } - dir_return->dirbase = IncPtr(slot, dirent->myloc, loc); - dir_return->curr_ent = dir_return->dirbase; -} - int -nubus_get_ind_data(slot, dirent, data_return, nbytes) - nubus_slot *slot; +nubus_get_ind_data(bst, bsh, fmt, dirent, data_return, nbytes) + bus_space_tag_t bst; + bus_space_handle_t bsh; + nubus_slot *fmt; nubus_dirent *dirent; caddr_t data_return; int nbytes; { - u_long loc; + u_long loc; + u_int8_t lanes = fmt->bytelanes; #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_ind_data(0x%x, 0x%x, 0x%x, %d).\n", - (u_int) slot, (u_int) dirent, (u_int) data_return, - nbytes); + printf("nubus_get_ind_data(%p, %p, %p, %d).\n", + fmt, dirent, data_return, nbytes); #endif if ((loc = dirent->offset) & 0x800000) { loc |= 0xff000000; } - loc = IncPtr(slot, dirent->myloc, loc); + loc = nubus_adjust_ptr(lanes, dirent->myloc, loc); while (nbytes--) { - *data_return++ = GetByte(slot, loc); - loc = IncPtr(slot, loc, 1); + *data_return++ = nubus_read_1(bst, bsh, lanes, loc); + loc = nubus_adjust_ptr(lanes, loc, 1); } return 1; } int -nubus_get_c_string(slot, dirent, data_return, max_bytes) - nubus_slot *slot; +nubus_get_c_string(bst, bsh, fmt, dirent, data_return, max_bytes) + bus_space_tag_t bst; + bus_space_handle_t bsh; + nubus_slot *fmt; nubus_dirent *dirent; caddr_t data_return; int max_bytes; { - u_long loc; + u_long loc; + u_int8_t lanes = fmt->bytelanes; #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_c_string(0x%x, 0x%x, 0x%x, %d).\n", - (u_int) slot, (u_int) dirent, (u_int) data_return, - max_bytes); + printf("nubus_get_c_string(%p, %p, %p, %d).\n", + fmt, dirent, data_return, max_bytes); #endif - if ((loc = dirent->offset) & 0x800000) { + if ((loc = dirent->offset) & 0x800000) loc |= 0xff000000; - } - loc = IncPtr(slot, dirent->myloc, loc); + + loc = nubus_adjust_ptr(lanes, dirent->myloc, loc); *data_return = '\0'; while (max_bytes--) { - if ((*data_return++ = GetByte(slot, loc)) == 0) + if ((*data_return++ = + nubus_read_1(bst, bsh, lanes, loc)) == 0) return 1; - loc = IncPtr(slot, loc, 1); + loc = nubus_adjust_ptr(lanes, loc, 1); } + *(data_return-1) = '\0'; return 0; } static char *huh = "???"; char * -nubus_get_vendor(slot, rsrc) - nubus_slot *slot; - int rsrc; +nubus_get_vendor(bst, bsh, fmt, rsrc) + bus_space_tag_t bst; + bus_space_handle_t bsh; + nubus_slot *fmt; + int rsrc; { -static char str_ret[64]; - nubus_dir dir; - nubus_dirent ent; + static char str_ret[64]; + nubus_dir dir; + nubus_dirent ent; #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_vendor(0x%x, 0x%x).\n", (u_int) slot, rsrc); + printf("nubus_get_vendor(%p, 0x%x).\n", fmt, rsrc); #endif - nubus_get_main_dir(slot, &dir); - if (nubus_find_rsrc(slot, &dir, 1, &ent) <= 0) + nubus_get_main_dir(fmt, &dir); + if (nubus_find_rsrc(bst, bsh, fmt, &dir, 1, &ent) <= 0) return huh; - nubus_get_dir_from_rsrc(slot, &ent, &dir); + nubus_get_dir_from_rsrc(fmt, &ent, &dir); - if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_VENDORINFO, &ent) <= 0) + if (nubus_find_rsrc(bst, bsh, fmt, &dir, NUBUS_RSRC_VENDORINFO, &ent) + <= 0) return huh; - nubus_get_dir_from_rsrc(slot, &ent, &dir); + nubus_get_dir_from_rsrc(fmt, &ent, &dir); - if (nubus_find_rsrc(slot, &dir, rsrc, &ent) <= 0) + if (nubus_find_rsrc(bst, bsh, fmt, &dir, rsrc, &ent) <= 0) return huh; - nubus_get_c_string(slot, &ent, str_ret, 64); + nubus_get_c_string(bst, bsh, fmt, &ent, str_ret, 64); return str_ret; } char * -nubus_get_card_name(slot) - nubus_slot *slot; +nubus_get_card_name(bst, bsh, fmt) + bus_space_tag_t bst; + bus_space_handle_t bsh; + nubus_slot *fmt; { -static char name_ret[64]; - nubus_dir dir; - nubus_dirent ent; + static char name_ret[64]; + nubus_dir dir; + nubus_dirent ent; #ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_card_name(0x%lx).\n", (u_long) slot); + printf("nubus_get_card_name(%p).\n", fmt); #endif - nubus_get_main_dir(slot, &dir); + nubus_get_main_dir(fmt, &dir); - if (nubus_find_rsrc(slot, &dir, 1, &ent) <= 0) + if (nubus_find_rsrc(bst, bsh, fmt, &dir, 1, &ent) <= 0) return huh; - nubus_get_dir_from_rsrc(slot, &ent, &dir); + nubus_get_dir_from_rsrc(fmt, &ent, &dir); - if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_NAME, &ent) <= 0) + if (nubus_find_rsrc(bst, bsh, fmt, &dir, NUBUS_RSRC_NAME, &ent) <= 0) return huh; - nubus_get_c_string(slot, &ent, name_ret, 64); + nubus_get_c_string(bst, bsh, fmt, &ent, name_ret, 64); return name_ret; } -/* - * bus_*() functions adapted from sun3 generic "bus" support - * by Allen Briggs. - */ - -vm_offset_t tmp_vpages[1]; - -/* - * Read addr with size len (1,2,4) into val. - * If this generates a bus error, return -1 - * - * Create a temporary mapping, - * Try the access using peek_* - * Clean up temp. mapping - */ -static int -nubus_peek(paddr, sz) - vm_offset_t paddr; - int sz; +#ifdef DEBUG +void +nubus_scan_slot(bst, slotno) + bus_space_tag_t bst; + int slotno; { - int off, pte, rv; - vm_offset_t pgva; - caddr_t va; - - off = paddr & PGOFSET; - paddr -= off; - pte = (paddr & PG_FRAME) | (PG_V | PG_W | PG_CI); + int i=0, state=0; + char twirl[] = "-\\|/"; + bus_space_handle_t sc_bsh; - pgva = tmp_vpages[0]; - va = (caddr_t)pgva + off; - - mac68k_set_pte(pgva, pte); - TBIS(pgva); - - /* - * OK, try the access using one of the assembly routines - * that will set pcb_onfault and catch any bus errors. - */ - rv = -1; - switch (sz) { - case 1: - if (!badbaddr(va)) - rv = *((u_char *) va); - break; - case 2: - if (!badwaddr(va)) - rv = *((u_int16_t *) va); - break; - case 4: - if (!badladdr(va)) - rv = *((u_int32_t *) va); - break; - default: - printf("bus_peek: invalid size=%d\n", sz); - rv = -1; + if (bus_space_map(bst, NUBUS_SLOT2PA(slotno), NBMEMSIZE, 0, &sc_bsh)) { + printf("nubus_scan_slot: failed to map slot %x\n", slotno); + return; } - mac68k_set_pte(pgva, PG_NV); - TBIS(pgva); - - return rv; -} - -char * -nubus_mapin(paddr, sz) - int paddr, sz; -{ - int off, pa, pmt=0; - vm_offset_t va, retval; - - off = paddr & PGOFSET; - pa = paddr - off; - sz += off; - sz = m68k_round_page(sz); - - /* Get some kernel virtual address space. */ - va = uvm_km_valloc_wait(kernel_map, sz); - if (va == 0) - panic("bus_mapin"); - retval = va + off; - - /* Map it to the specified bus. */ - do { - pmap_enter(pmap_kernel(), va, pa | pmt, - VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE); - va += PAGE_SIZE; - pa += PAGE_SIZE; - } while ((sz -= PAGE_SIZE) > 0); - pmap_update(pmap_kernel()); - - return ((char *)retval); + printf("Scanning slot %c for accessible regions:\n", + slotno == 9 ? '9' : slotno - 10 + 'A'); + for (i=0 ; i<NBMEMSIZE; i++) { + if (mac68k_bus_space_probe(bst, sc_bsh, i, 1)) { + if (state == 0) { + printf("\t0x%x-", i); + state = 1; + } + } else { + if (state) { + printf("0x%x\n", i); + state = 0; + } + } + if (i%100 == 0) { + printf("%c\b", twirl[(i/100)%4]); + } + } + if (state) { + printf("0x%x\n", i); + } + return; } +#endif diff --git a/sys/arch/mac68k/dev/nubus.h b/sys/arch/mac68k/dev/nubus.h index e9699c29dc1..20c50ac3996 100644 --- a/sys/arch/mac68k/dev/nubus.h +++ b/sys/arch/mac68k/dev/nubus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nubus.h,v 1.19 2005/03/04 00:38:37 martin Exp $ */ +/* $OpenBSD: nubus.h,v 1.20 2005/04/26 21:09:35 martin Exp $ */ /* $NetBSD: nubus.h,v 1.25 1997/05/02 00:54:28 briggs Exp $ */ /* @@ -44,7 +44,6 @@ * and DrHW 1 (TFB). */ -#include <machine/bus.h> #include <machine/cpu.h> #define NUBUS_CATEGORY_BOARD 0x0001 @@ -122,7 +121,6 @@ typedef struct _nubus_slot { u_int32_t crc; u_int32_t length; u_int32_t directory_offset; - vm_offset_t virtual_base; } nubus_slot; /* @@ -265,16 +263,20 @@ struct nubus_softc { }; void nubus_get_main_dir(nubus_slot *slot, nubus_dir *dir_return); -int nubus_find_rsrc(nubus_slot *slot, nubus_dir *dir, u_int8_t rsrcid, - nubus_dirent *dirent_return); void nubus_get_dir_from_rsrc(nubus_slot *slot, nubus_dirent *dirent, - nubus_dir *dir_return); -int nubus_get_ind_data(nubus_slot *slot, nubus_dirent *dirent, - caddr_t data_return, int nbytes); -int nubus_get_c_string(nubus_slot *slot, nubus_dirent *dirent, - caddr_t data_return, int max_bytes); -char *nubus_get_vendor(nubus_slot *slot, int rsrc); -char *nubus_get_card_name(nubus_slot *slot); -char *nubus_mapin(int paddr, int sz); - int paddr, sz; + nubus_dir *dir_return); +int nubus_find_rsrc(bus_space_tag_t, bus_space_handle_t, + nubus_slot *slot, nubus_dir *dir, u_int8_t rsrcid, + nubus_dirent *dirent_return); +int nubus_get_ind_data(bus_space_tag_t, bus_space_handle_t, + nubus_slot *slot, nubus_dirent *dirent, + caddr_t data_return, int nbytes); +int nubus_get_c_string(bus_space_tag_t, bus_space_handle_t, + nubus_slot *slot, nubus_dirent *dirent, + caddr_t data_return, int max_bytes); + +char *nubus_get_vendor(bus_space_tag_t, bus_space_handle_t, + nubus_slot *slot, int rsrc); +char *nubus_get_card_name(bus_space_tag_t, bus_space_handle_t, + nubus_slot *slot); |