Home | History | Annotate | Line # | Download | only in podulebus
podulebus.c revision 1.8
      1  1.8  thorpej /* $NetBSD: podulebus.c,v 1.8 2002/04/05 16:58:02 thorpej Exp $ */
      2  1.1  reinoud 
      3  1.1  reinoud /*
      4  1.1  reinoud  * Copyright (c) 1994-1996 Mark Brinicombe.
      5  1.1  reinoud  * Copyright (c) 1994 Brini.
      6  1.1  reinoud  * All rights reserved.
      7  1.1  reinoud  *
      8  1.1  reinoud  * Redistribution and use in source and binary forms, with or without
      9  1.1  reinoud  * modification, are permitted provided that the following conditions
     10  1.1  reinoud  * are met:
     11  1.1  reinoud  * 1. Redistributions of source code must retain the above copyright
     12  1.1  reinoud  *    notice, this list of conditions and the following disclaimer.
     13  1.1  reinoud  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  reinoud  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  reinoud  *    documentation and/or other materials provided with the distribution.
     16  1.1  reinoud  * 3. All advertising materials mentioning features or use of this software
     17  1.1  reinoud  *    must display the following acknowledgement:
     18  1.1  reinoud  *	This product includes software developed by Brini.
     19  1.1  reinoud  * 4. The name of the company nor the name of the author may be used to
     20  1.1  reinoud  *    endorse or promote products derived from this software without specific
     21  1.1  reinoud  *    prior written permission.
     22  1.1  reinoud  *
     23  1.1  reinoud  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
     24  1.1  reinoud  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     25  1.1  reinoud  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  1.1  reinoud  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     27  1.1  reinoud  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     28  1.1  reinoud  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     29  1.1  reinoud  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1  reinoud  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1  reinoud  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1  reinoud  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1  reinoud  * SUCH DAMAGE.
     34  1.1  reinoud  *
     35  1.1  reinoud  * RiscBSD kernel project
     36  1.1  reinoud  *
     37  1.1  reinoud  * podulebus.c
     38  1.1  reinoud  *
     39  1.1  reinoud  * Podule probe and configuration routines
     40  1.1  reinoud  *
     41  1.1  reinoud  * Created      : 07/11/94
     42  1.1  reinoud  */
     43  1.1  reinoud 
     44  1.1  reinoud #include <sys/param.h>
     45  1.5    bjh21 
     46  1.8  thorpej __KERNEL_RCSID(0, "$NetBSD: podulebus.c,v 1.8 2002/04/05 16:58:02 thorpej Exp $");
     47  1.5    bjh21 
     48  1.1  reinoud #include <sys/systm.h>
     49  1.1  reinoud #include <sys/kernel.h>
     50  1.1  reinoud #include <sys/conf.h>
     51  1.1  reinoud #include <sys/malloc.h>
     52  1.1  reinoud #include <sys/device.h>
     53  1.1  reinoud #include <uvm/uvm_extern.h>
     54  1.1  reinoud #include <machine/io.h>
     55  1.2  thorpej #include <arm/arm32/katelib.h>
     56  1.4  thorpej #include <machine/intr.h>
     57  1.1  reinoud #include <machine/bootconfig.h>
     58  1.1  reinoud #include <machine/pmap.h>
     59  1.1  reinoud #include <arm/iomd/iomdreg.h>
     60  1.1  reinoud #include <arm/iomd/iomdvar.h>
     61  1.1  reinoud #include <acorn32/podulebus/podulebus.h>
     62  1.1  reinoud #include <dev/podulebus/podules.h>
     63  1.1  reinoud #include <dev/podulebus/podule_data.h>
     64  1.1  reinoud 
     65  1.1  reinoud #include "locators.h"
     66  1.1  reinoud 
     67  1.1  reinoud /* Array of podule structures, one per possible podule */
     68  1.1  reinoud 
     69  1.1  reinoud podule_t podules[MAX_PODULES + MAX_NETSLOTS];
     70  1.1  reinoud 
     71  1.1  reinoud extern struct bus_space podulebus_bs_tag;
     72  1.1  reinoud 
     73  1.1  reinoud /* Declare prototypes */
     74  1.1  reinoud 
     75  1.1  reinoud u_int poduleread __P((u_int, int));
     76  1.5    bjh21 int podulebusmatch(struct device *, struct cfdata *, void *);
     77  1.5    bjh21 void podulebusattach(struct device *, struct device *, void *);
     78  1.5    bjh21 int podulebusprint(void *, const char *);
     79  1.5    bjh21 int podulebussubmatch(struct device *, struct cfdata *, void *);
     80  1.5    bjh21 void podulechunkdirectory(podule_t *);
     81  1.5    bjh21 void podulescan(struct device *);
     82  1.1  reinoud 
     83  1.1  reinoud /*
     84  1.1  reinoud  * int podulebusmatch(struct device *parent, void *match, void *aux)
     85  1.1  reinoud  *
     86  1.1  reinoud  * Probe for the podule bus. Currently all this does is return 1 to
     87  1.1  reinoud  * indicate that the podule bus was found.
     88  1.1  reinoud  */
     89  1.1  reinoud 
     90  1.1  reinoud int
     91  1.1  reinoud podulebusmatch(parent, cf, aux)
     92  1.1  reinoud 	struct device *parent;
     93  1.1  reinoud 	struct cfdata *cf;
     94  1.1  reinoud 	void *aux;
     95  1.1  reinoud {
     96  1.1  reinoud 	switch (IOMD_ID) {
     97  1.1  reinoud 	case RPC600_IOMD_ID:
     98  1.1  reinoud 	case ARM7500_IOC_ID:
     99  1.1  reinoud 	case ARM7500FE_IOC_ID:
    100  1.1  reinoud 		return(1);
    101  1.1  reinoud 	}
    102  1.1  reinoud 	return (0);
    103  1.1  reinoud }
    104  1.1  reinoud 
    105  1.1  reinoud 
    106  1.1  reinoud int
    107  1.1  reinoud podulebusprint(aux, name)
    108  1.1  reinoud 	void *aux;
    109  1.1  reinoud 	const char *name;
    110  1.1  reinoud {
    111  1.1  reinoud 	struct podule_attach_args *pa = aux;
    112  1.1  reinoud 
    113  1.1  reinoud 	if (name)
    114  1.1  reinoud 		printf("podule at %s", name);
    115  1.1  reinoud 	if (pa->pa_podule->slottype == SLOT_POD)
    116  1.1  reinoud 		printf(" slot %d", pa->pa_podule_number);
    117  1.1  reinoud 	else if (pa->pa_podule->slottype == SLOT_NET)
    118  1.1  reinoud 		printf(" [ netslot %d ]", pa->pa_podule_number - MAX_PODULES);
    119  1.1  reinoud #ifdef DIAGNOSTIC
    120  1.1  reinoud 	else
    121  1.1  reinoud 		panic("Invalid slot type\n");
    122  1.1  reinoud #endif
    123  1.1  reinoud 
    124  1.1  reinoud 	return (UNCONF);
    125  1.1  reinoud }
    126  1.1  reinoud 
    127  1.1  reinoud 
    128  1.1  reinoud int
    129  1.5    bjh21 podulebussubmatch(parent, cf, aux)
    130  1.1  reinoud 	struct device *parent;
    131  1.5    bjh21 	struct cfdata *cf;
    132  1.1  reinoud 	void *aux;
    133  1.1  reinoud {
    134  1.1  reinoud 	struct podule_attach_args *pa = aux;
    135  1.1  reinoud 
    136  1.1  reinoud 	/* Return priority 0 or 1 for wildcarded podule */
    137  1.1  reinoud 
    138  1.1  reinoud 	if (cf->cf_loc[PODULEBUSCF_SLOT] == PODULEBUSCF_SLOT_DEFAULT)
    139  1.5    bjh21 		return((*cf->cf_attach->ca_match)(parent, cf, aux));
    140  1.1  reinoud 
    141  1.1  reinoud 	/* Return higher priority if we match the specific podule */
    142  1.1  reinoud 
    143  1.1  reinoud 	else if (cf->cf_loc[PODULEBUSCF_SLOT] == pa->pa_podule_number)
    144  1.5    bjh21 		return((*cf->cf_attach->ca_match)(parent, cf, aux) * 8);
    145  1.1  reinoud 
    146  1.1  reinoud 	/* Fail */
    147  1.1  reinoud 	return(0);
    148  1.1  reinoud }
    149  1.1  reinoud 
    150  1.1  reinoud 
    151  1.1  reinoud #if 0
    152  1.1  reinoud void
    153  1.1  reinoud dump_podule(podule)
    154  1.1  reinoud 	podule_t *podule;
    155  1.1  reinoud {
    156  1.1  reinoud 	printf("podule%d: ", podule->podulenum);
    157  1.1  reinoud 	printf("flags0=%02x ", podule->flags0);
    158  1.1  reinoud 	printf("flags1=%02x ", podule->flags1);
    159  1.1  reinoud 	printf("reserved=%02x ", podule->reserved);
    160  1.1  reinoud 	printf("product=%02x ", podule->product);
    161  1.1  reinoud 	printf("manufacturer=%02x ", podule->manufacturer);
    162  1.1  reinoud 	printf("country=%02x ", podule->country);
    163  1.1  reinoud 	printf("irq_addr=%08x ", podule->irq_addr);
    164  1.1  reinoud 	printf("irq_mask=%02x ", podule->irq_mask);
    165  1.1  reinoud 	printf("fiq_addr=%08x ", podule->fiq_addr);
    166  1.1  reinoud 	printf("fiq_mask=%02x ", podule->fiq_mask);
    167  1.1  reinoud 	printf("fast_base=%08x ", podule->fast_base);
    168  1.1  reinoud 	printf("medium_base=%08x ", podule->medium_base);
    169  1.1  reinoud 	printf("slow_base=%08x ", podule->slow_base);
    170  1.1  reinoud 	printf("sync_base=%08x ", podule->sync_base);
    171  1.1  reinoud 	printf("mod_base=%08x ", podule->mod_base);
    172  1.1  reinoud 	printf("easi_base=%08x ", podule->easi_base);
    173  1.1  reinoud 	printf("attached=%d ", podule->attached);
    174  1.1  reinoud 	printf("slottype=%d ", podule->slottype);
    175  1.1  reinoud 	printf("podulenum=%d ", podule->podulenum);
    176  1.1  reinoud 	printf("description=%s ", podule->description);
    177  1.1  reinoud 	printf("\n");
    178  1.1  reinoud }
    179  1.1  reinoud #endif
    180  1.1  reinoud 
    181  1.1  reinoud void
    182  1.1  reinoud podulechunkdirectory(podule)
    183  1.1  reinoud 	podule_t *podule;
    184  1.1  reinoud {
    185  1.1  reinoud 	u_int address;
    186  1.1  reinoud 	u_int id;
    187  1.1  reinoud 	u_int size;
    188  1.1  reinoud 	u_int addr;
    189  1.1  reinoud 	int loop;
    190  1.1  reinoud 	int done_f5;
    191  1.1  reinoud 
    192  1.1  reinoud 	done_f5 = 0;
    193  1.1  reinoud 	address = 0x40;
    194  1.1  reinoud 
    195  1.1  reinoud 	do {
    196  1.1  reinoud 		id = podule->read_rom(podule->sync_base, address);
    197  1.1  reinoud 		size = podule->read_rom(podule->sync_base, address + 4);
    198  1.1  reinoud 		size |= (podule->read_rom(podule->sync_base, address + 8) << 8);
    199  1.1  reinoud 		size |= (podule->read_rom(podule->sync_base, address + 12) << 16);
    200  1.1  reinoud 		if (id == 0xf5) {
    201  1.1  reinoud 			addr = podule->read_rom(podule->sync_base, address + 16);
    202  1.1  reinoud 			addr |= (podule->read_rom(podule->sync_base, address + 20) << 8);
    203  1.1  reinoud 			addr |= (podule->read_rom(podule->sync_base, address + 24) << 16);
    204  1.1  reinoud 			addr |= (podule->read_rom(podule->sync_base, address + 28) << 24);
    205  1.1  reinoud 			if (addr < 0x800 && done_f5 == 0) {
    206  1.1  reinoud 				done_f5 = 1;
    207  1.1  reinoud 				for (loop = 0; loop < size; ++loop) {
    208  1.1  reinoud 					if (loop < PODULE_DESCRIPTION_LENGTH) {
    209  1.1  reinoud 						podule->description[loop] =
    210  1.1  reinoud 						    podule->read_rom(podule->sync_base, (addr + loop)*4);
    211  1.1  reinoud 						podule->description[loop + 1] = 0;
    212  1.1  reinoud 					}
    213  1.1  reinoud 				}
    214  1.1  reinoud 			}
    215  1.1  reinoud 		}
    216  1.1  reinoud #ifdef DEBUG_CHUNK_DIR
    217  1.1  reinoud 		if (id == 0xf5 || id == 0xf1 || id == 0xf2 || id == 0xf3 || id == 0xf4 || id == 0xf6) {
    218  1.1  reinoud 			addr = podule->read_rom(podule->sync_base, address + 16);
    219  1.1  reinoud 			addr |= (podule->read_rom(podule->sync_base, address + 20) << 8);
    220  1.1  reinoud 			addr |= (podule->read_rom(podule->sync_base, address + 24) << 16);
    221  1.1  reinoud 			addr |= (podule->read_rom(podule->sync_base, address + 28) << 24);
    222  1.1  reinoud 			printf("<%04x.%04x.%04x.%04x>", id, address, addr, size);
    223  1.1  reinoud 			if (addr < 0x800) {
    224  1.1  reinoud 				for (loop = 0; loop < size; ++loop) {
    225  1.1  reinoud 					printf("%c", podule->read_rom(podule->sync_base, (addr + loop)*4));
    226  1.1  reinoud 				}
    227  1.1  reinoud 				printf("\\n\n");
    228  1.1  reinoud 			}
    229  1.1  reinoud 		}
    230  1.1  reinoud #endif
    231  1.1  reinoud 		address += 32;
    232  1.1  reinoud 	} while (id != 0 && address < 0x800);
    233  1.1  reinoud }
    234  1.1  reinoud 
    235  1.1  reinoud 
    236  1.1  reinoud void
    237  1.1  reinoud poduleexamine(podule, dev, slottype)
    238  1.1  reinoud 	podule_t *podule;
    239  1.1  reinoud 	struct device *dev;
    240  1.1  reinoud 	int slottype;
    241  1.1  reinoud {
    242  1.1  reinoud 	struct podule_list *pod_list;
    243  1.1  reinoud 	struct podule_description *pod_desc;
    244  1.1  reinoud 
    245  1.1  reinoud 	/* Test to see if the podule is present */
    246  1.1  reinoud 
    247  1.1  reinoud 	if ((podule->flags0 & 0x02) == 0x00) {
    248  1.1  reinoud 		podule->slottype = slottype;
    249  1.1  reinoud 		if (slottype == SLOT_NET)
    250  1.1  reinoud 			printf("netslot%d at %s : ", podule->podulenum - MAX_PODULES,
    251  1.1  reinoud 			    dev->dv_xname);
    252  1.1  reinoud 		else
    253  1.1  reinoud 			printf("podule%d  at %s : ", podule->podulenum,
    254  1.1  reinoud 			    dev->dv_xname);
    255  1.1  reinoud 
    256  1.1  reinoud 		/* Is it Acorn conformant ? */
    257  1.1  reinoud 
    258  1.1  reinoud 		if (podule->flags0 & 0x80)
    259  1.1  reinoud 			printf("Non-Acorn conformant expansion card\n");
    260  1.1  reinoud 		else {
    261  1.1  reinoud 			int id;
    262  1.1  reinoud 
    263  1.1  reinoud 			/* Is it a simple podule ? */
    264  1.1  reinoud 
    265  1.1  reinoud 			id = (podule->flags0 >> 3) & 0x0f;
    266  1.1  reinoud 			if (id != 0)
    267  1.1  reinoud 				printf("Simple expansion card <%x>\n", id);
    268  1.1  reinoud 			else {
    269  1.1  reinoud 				/* Scan the chunk directory if present for tags we use */
    270  1.1  reinoud 				if (podule->flags1 & PODULE_FLAGS_CD)
    271  1.1  reinoud 					podulechunkdirectory(podule);
    272  1.1  reinoud 
    273  1.1  reinoud 				/* Do we know this manufacturer ? */
    274  1.1  reinoud 				pod_list = known_podules;
    275  1.1  reinoud 				while (pod_list->description) {
    276  1.1  reinoud 					if (pod_list->manufacturer_id == podule->manufacturer)
    277  1.1  reinoud 						break;
    278  1.1  reinoud 					++pod_list;
    279  1.1  reinoud 				}
    280  1.1  reinoud 				if (!pod_list->description)
    281  1.1  reinoud 					printf("man=%04x   : ", podule->manufacturer);
    282  1.1  reinoud 				else
    283  1.1  reinoud 					printf("%s : ", pod_list->description);
    284  1.1  reinoud 
    285  1.1  reinoud 				/* Do we know this product ? */
    286  1.1  reinoud 
    287  1.1  reinoud 				pod_desc = pod_list->products;
    288  1.1  reinoud 				while (pod_desc->description) {
    289  1.1  reinoud 					if (pod_desc->product_id == podule->product)
    290  1.1  reinoud 						break;
    291  1.1  reinoud 					++pod_desc;
    292  1.1  reinoud 				}
    293  1.1  reinoud 				if (!pod_desc->description) {
    294  1.1  reinoud 					printf("prod=%04x : ", podule->product);
    295  1.1  reinoud 					printf("%s\n", podule->description);
    296  1.1  reinoud 				} else
    297  1.1  reinoud 					printf("%s : %s\n", pod_desc->description, podule->description);
    298  1.1  reinoud 			}
    299  1.1  reinoud 		}
    300  1.1  reinoud 	}
    301  1.1  reinoud }
    302  1.1  reinoud 
    303  1.1  reinoud 
    304  1.1  reinoud u_int
    305  1.1  reinoud poduleread(address, offset)
    306  1.1  reinoud 	u_int address;
    307  1.1  reinoud 	int offset;
    308  1.1  reinoud {
    309  1.1  reinoud 
    310  1.1  reinoud 	return(ReadByte(address + offset));
    311  1.1  reinoud }
    312  1.1  reinoud 
    313  1.1  reinoud void
    314  1.1  reinoud podulescan(dev)
    315  1.1  reinoud 	struct device *dev;
    316  1.1  reinoud {
    317  1.1  reinoud 	int loop;
    318  1.1  reinoud 	podule_t *podule;
    319  1.1  reinoud 	u_char *address;
    320  1.1  reinoud 	u_int offset = 0;
    321  1.1  reinoud 
    322  1.1  reinoud 	/* Loop round all the podules */
    323  1.1  reinoud 
    324  1.1  reinoud 	for (loop = 0; loop < MAX_PODULES; ++loop, offset += SIMPLE_PODULE_SIZE) {
    325  1.1  reinoud 		podule = &podules[loop];
    326  1.1  reinoud 		podule->podulenum = loop;
    327  1.1  reinoud 		podule->attached = 0;
    328  1.1  reinoud 		podule->slottype = SLOT_NONE;
    329  1.1  reinoud 		podule->interrupt = IRQ_PODULE;
    330  1.1  reinoud 		podule->read_rom = poduleread;
    331  1.1  reinoud 		podule->dma_channel = -1;
    332  1.1  reinoud 		podule->dma_interrupt = -1;
    333  1.1  reinoud 		podule->description[0] = 0;
    334  1.1  reinoud 
    335  1.1  reinoud 		if (loop == 4) offset += PODULE_GAP;
    336  1.1  reinoud 		address = ((u_char *)SYNC_PODULE_BASE) + offset;
    337  1.1  reinoud 
    338  1.1  reinoud 		if ((address[0] & 0x02) == 0x00) {
    339  1.1  reinoud 			podule->fast_base = FAST_PODULE_BASE + offset;
    340  1.1  reinoud 			podule->medium_base = MEDIUM_PODULE_BASE + offset;
    341  1.1  reinoud 			podule->slow_base = SLOW_PODULE_BASE + offset;
    342  1.1  reinoud 			podule->sync_base = SYNC_PODULE_BASE + offset;
    343  1.1  reinoud 			podule->mod_base = MOD_PODULE_BASE + offset;
    344  1.1  reinoud 			podule->easi_base = EASI_BASE + loop * EASI_SIZE;
    345  1.1  reinoud 		} else {
    346  1.1  reinoud 			address = ((u_char *)EASI_BASE) + loop * EASI_SIZE;
    347  1.1  reinoud 			if ((address[0] & 0x02) != 0x00)
    348  1.1  reinoud 				continue;
    349  1.1  reinoud 
    350  1.1  reinoud 			podule->fast_base = 0;
    351  1.1  reinoud 			podule->medium_base = 0;
    352  1.1  reinoud 			podule->slow_base = 0;
    353  1.1  reinoud 			podule->sync_base = 0;
    354  1.1  reinoud 			podule->mod_base = 0;
    355  1.1  reinoud 			podule->easi_base = EASI_BASE + loop * EASI_SIZE;
    356  1.1  reinoud 		}
    357  1.1  reinoud 
    358  1.1  reinoud 		/* XXX - Really needs to be linked to a DMA manager */
    359  1.1  reinoud 		if (IOMD_ID == RPC600_IOMD_ID) {
    360  1.1  reinoud 			switch (loop) {
    361  1.1  reinoud 			case 0:
    362  1.1  reinoud 				podule->dma_channel = 2;
    363  1.1  reinoud 				podule->dma_interrupt = IRQ_DMACH2;
    364  1.1  reinoud 				break;
    365  1.1  reinoud 			case 1:
    366  1.1  reinoud 				podule->dma_channel = 3;
    367  1.1  reinoud 				podule->dma_interrupt = IRQ_DMACH3;
    368  1.1  reinoud 				break;
    369  1.1  reinoud 			}
    370  1.1  reinoud 		}
    371  1.1  reinoud 
    372  1.1  reinoud 		/* Get information from the podule header */
    373  1.1  reinoud 
    374  1.1  reinoud 		podule->flags0 = address[0];
    375  1.1  reinoud 		if ((podule->flags0 & 0x78) == 0) {
    376  1.1  reinoud 			podule->flags1 = address[4];
    377  1.1  reinoud 			podule->reserved = address[8];
    378  1.1  reinoud 			podule->product = address[12] + (address[16] << 8);
    379  1.1  reinoud 			podule->manufacturer = address[20] + (address[24] << 8);
    380  1.1  reinoud 			podule->country = address[28];
    381  1.1  reinoud 			if (podule->flags1 & PODULE_FLAGS_IS) {
    382  1.1  reinoud 				podule->irq_addr = address[52] + (address[56] << 8) + (address[60] << 16);
    383  1.1  reinoud 				podule->irq_addr += podule->slow_base;
    384  1.1  reinoud 				podule->irq_mask = address[48];
    385  1.1  reinoud 				if (podule->irq_mask == 0)
    386  1.1  reinoud 					podule->irq_mask = 0x01;
    387  1.1  reinoud 				podule->fiq_addr = address[36] + (address[40] << 8) + (address[44] << 16);
    388  1.1  reinoud 				podule->fiq_addr += podule->slow_base;
    389  1.1  reinoud 				podule->fiq_mask = address[32];
    390  1.1  reinoud 				if (podule->fiq_mask == 0)
    391  1.1  reinoud 					podule->fiq_mask = 0x04;
    392  1.1  reinoud 			} else {
    393  1.1  reinoud 				podule->irq_addr = podule->slow_base;
    394  1.1  reinoud 				podule->irq_mask = 0x01;
    395  1.1  reinoud 				podule->fiq_addr = podule->slow_base;
    396  1.1  reinoud 				podule->fiq_mask = 0x04;
    397  1.1  reinoud 			}
    398  1.1  reinoud 		}
    399  1.1  reinoud 
    400  1.1  reinoud 		poduleexamine(podule, dev, SLOT_POD);
    401  1.1  reinoud 	}
    402  1.1  reinoud }
    403  1.1  reinoud 
    404  1.1  reinoud 
    405  1.1  reinoud /*
    406  1.1  reinoud  * void podulebusattach(struct device *parent, struct device *dev, void *aux)
    407  1.1  reinoud  *
    408  1.1  reinoud  * Attach podulebus.
    409  1.1  reinoud  * This probes all the podules and sets up the podules array with
    410  1.1  reinoud  * information found in the podule headers.
    411  1.1  reinoud  * After identifing all the podules, all the children of the podulebus
    412  1.1  reinoud  * are probed and attached.
    413  1.1  reinoud  */
    414  1.1  reinoud 
    415  1.1  reinoud void
    416  1.1  reinoud podulebusattach(parent, self, aux)
    417  1.1  reinoud 	struct device *parent;
    418  1.1  reinoud 	struct device *self;
    419  1.1  reinoud 	void *aux;
    420  1.1  reinoud {
    421  1.1  reinoud 	int loop;
    422  1.1  reinoud 	struct podule_attach_args pa;
    423  1.1  reinoud #if 0
    424  1.1  reinoud 	int easi_time;
    425  1.1  reinoud 	int bit;
    426  1.1  reinoud #endif
    427  1.1  reinoud 	unsigned int value;
    428  1.1  reinoud 	char argstring[20];
    429  1.1  reinoud 
    430  1.1  reinoud #if 0
    431  1.1  reinoud 	easi_time = IOMD_READ_BYTE(IOMD_ECTCR);
    432  1.1  reinoud 	printf(": easi timings=");
    433  1.1  reinoud 	for (bit = 0x01; bit < 0x100; bit = bit << 1)
    434  1.1  reinoud 		if (easi_time & bit)
    435  1.1  reinoud 			printf("C");
    436  1.1  reinoud 		else
    437  1.1  reinoud 			printf("A");
    438  1.1  reinoud #endif
    439  1.1  reinoud 	printf("\n");
    440  1.1  reinoud 
    441  1.1  reinoud 	/* Ok we need to map in the podulebus */
    442  1.1  reinoud 
    443  1.1  reinoud 	/* Map the FAST and SYNC simple podules */
    444  1.1  reinoud 
    445  1.6  thorpej 	pmap_map_section((vm_offset_t)pmap_kernel()->pm_pdir,
    446  1.6  thorpej 	    SYNC_PODULE_BASE & 0xfff00000, SYNC_PODULE_HW_BASE & 0xfff00000,
    447  1.6  thorpej 	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
    448  1.1  reinoud 	cpu_tlb_flushD();
    449  1.1  reinoud 
    450  1.1  reinoud 	/* Now map the EASI space */
    451  1.1  reinoud 
    452  1.1  reinoud 	for (loop = 0; loop < MAX_PODULES; ++loop) {
    453  1.1  reinoud 		int loop1;
    454  1.1  reinoud 
    455  1.1  reinoud 		for (loop1 = loop * EASI_SIZE; loop1 < ((loop + 1) * EASI_SIZE);
    456  1.8  thorpej 		    loop1 += L1_S_SIZE)
    457  1.6  thorpej 		pmap_map_section((vm_offset_t)pmap_kernel()->pm_pdir,
    458  1.6  thorpej 		    EASI_BASE + loop1, EASI_HW_BASE + loop1,
    459  1.6  thorpej 		    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
    460  1.1  reinoud 	}
    461  1.1  reinoud 	cpu_tlb_flushD();
    462  1.1  reinoud 
    463  1.1  reinoud 	/*
    464  1.1  reinoud 	 * The MEDIUM and SLOW simple podules and the module space will have been
    465  1.1  reinoud 	 * mapped when the IOMD and COMBO we mapped in for the RPC
    466  1.1  reinoud 	 */
    467  1.1  reinoud 
    468  1.1  reinoud 	/* Find out what hardware is bolted on */
    469  1.1  reinoud 
    470  1.1  reinoud 	podulescan(self);
    471  1.1  reinoud 	netslotscan(self);
    472  1.1  reinoud 
    473  1.1  reinoud 	/* Look for drivers to attach */
    474  1.1  reinoud 
    475  1.1  reinoud 	for (loop = 0; loop < MAX_PODULES+MAX_NETSLOTS; ++loop) {
    476  1.1  reinoud #if 1
    477  1.1  reinoud 		/* Provide backwards compat for a while */
    478  1.1  reinoud 		sprintf(argstring, "podule%d.disable", loop);
    479  1.1  reinoud 		if (get_bootconf_option(boot_args, argstring,
    480  1.1  reinoud 		    BOOTOPT_TYPE_BOOLEAN, &value)) {
    481  1.1  reinoud 			if (value) {
    482  1.1  reinoud 				if (podules[loop].slottype != SLOT_NONE)
    483  1.1  reinoud 					printf("podule%d: Disabled\n", loop);
    484  1.1  reinoud 				continue;
    485  1.1  reinoud 			}
    486  1.1  reinoud  		}
    487  1.1  reinoud #endif
    488  1.1  reinoud  		sprintf(argstring, "podule%d=", loop);
    489  1.1  reinoud  		if (get_bootconf_option(boot_args, argstring,
    490  1.1  reinoud  		    BOOTOPT_TYPE_HEXINT, &value)) {
    491  1.1  reinoud 			/* Override the ID */
    492  1.1  reinoud 			podules[loop].manufacturer = value >> 16;
    493  1.1  reinoud  			podules[loop].product = value & 0xffff;
    494  1.1  reinoud 			/* Any old description is now wrong */
    495  1.1  reinoud 			podules[loop].description[0] = 0;
    496  1.1  reinoud 			if (value != 0xffff) {
    497  1.1  reinoud 				printf("podule%d: ID overriden man=%04x prod=%04x\n",
    498  1.1  reinoud 				    loop, podules[loop].manufacturer,
    499  1.1  reinoud 				    podules[loop].product);
    500  1.1  reinoud 				podules[loop].slottype = SLOT_POD;
    501  1.1  reinoud 				pa.pa_podule_number = loop;
    502  1.1  reinoud 				pa.pa_ih = pa.pa_podule_number;
    503  1.1  reinoud 				pa.pa_podule = &podules[loop];
    504  1.1  reinoud 				pa.pa_iot = &podulebus_bs_tag;
    505  1.1  reinoud 				config_found_sm(self, &pa, podulebusprint,
    506  1.1  reinoud 				    podulebussubmatch);
    507  1.1  reinoud 				continue;
    508  1.1  reinoud 			}
    509  1.1  reinoud 			if (value == 0xffff) {
    510  1.1  reinoud 				printf("podule%d: Disabled\n", loop);
    511  1.1  reinoud 				continue;
    512  1.1  reinoud 			}
    513  1.1  reinoud 		}
    514  1.1  reinoud 
    515  1.1  reinoud 		if (podules[loop].slottype != SLOT_NONE) {
    516  1.1  reinoud 			pa.pa_podule_number = loop;
    517  1.1  reinoud 			pa.pa_ih = pa.pa_podule_number;
    518  1.1  reinoud 			pa.pa_podule = &podules[loop];
    519  1.1  reinoud 			pa.pa_iot = &podulebus_bs_tag;
    520  1.1  reinoud 			config_found_sm(self, &pa, podulebusprint, podulebussubmatch);
    521  1.1  reinoud 		}
    522  1.1  reinoud 	}
    523  1.1  reinoud }
    524  1.1  reinoud 
    525  1.1  reinoud 
    526  1.1  reinoud struct cfattach podulebus_ca = {
    527  1.1  reinoud 	sizeof(struct device), podulebusmatch, podulebusattach
    528  1.1  reinoud };
    529  1.1  reinoud 
    530  1.1  reinoud /* Useful functions that drivers may share */
    531  1.1  reinoud 
    532  1.1  reinoud /*
    533  1.1  reinoud  * Match a podule structure with the specified parameters
    534  1.1  reinoud  * Returns 0 if the match failed
    535  1.1  reinoud  * The required_slot is not used at the moment.
    536  1.1  reinoud  */
    537  1.1  reinoud 
    538  1.1  reinoud int
    539  1.1  reinoud matchpodule(pa, manufacturer, product, required_slot)
    540  1.1  reinoud 	struct podule_attach_args *pa;
    541  1.1  reinoud 	int manufacturer;
    542  1.1  reinoud 	int product;
    543  1.1  reinoud 	int required_slot;
    544  1.1  reinoud {
    545  1.1  reinoud 	if (pa->pa_podule->attached)
    546  1.1  reinoud 		panic("podulebus: Podule already attached\n");
    547  1.1  reinoud 
    548  1.1  reinoud 	if (IS_PODULE(pa, manufacturer, product))
    549  1.1  reinoud 		return(1);
    550  1.1  reinoud 
    551  1.1  reinoud 	return(0);
    552  1.1  reinoud }
    553  1.1  reinoud 
    554  1.1  reinoud void *
    555  1.1  reinoud podulebus_irq_establish(ih, ipl, func, arg, ev)
    556  1.1  reinoud 	podulebus_intr_handle_t ih;
    557  1.1  reinoud 	int ipl;
    558  1.1  reinoud 	int (*func) __P((void *));
    559  1.1  reinoud 	void *arg;
    560  1.1  reinoud 	struct evcnt *ev;
    561  1.1  reinoud {
    562  1.1  reinoud 
    563  1.1  reinoud 	/* XXX We don't actually use the evcnt supplied, just its name. */
    564  1.1  reinoud 	return intr_claim(podules[ih].interrupt, ipl, ev->ev_group, func,
    565  1.1  reinoud 	    arg);
    566  1.1  reinoud }
    567  1.1  reinoud 
    568  1.1  reinoud /*
    569  1.1  reinoud  * Generate a bus_space_tag_t with the specified address-bus shift.
    570  1.1  reinoud  */
    571  1.1  reinoud void
    572  1.1  reinoud podulebus_shift_tag(tag, shift, tagp)
    573  1.1  reinoud 	bus_space_tag_t tag, *tagp;
    574  1.1  reinoud 	u_int shift;
    575  1.1  reinoud {
    576  1.1  reinoud 
    577  1.1  reinoud 	/*
    578  1.1  reinoud 	 * For the podulebus, the bus tag cookie is the shift to apply
    579  1.1  reinoud 	 * to registers, so duplicate the bus space tag and change the
    580  1.1  reinoud 	 * cookie.
    581  1.1  reinoud 	 */
    582  1.1  reinoud 
    583  1.1  reinoud 	/* XXX never freed, but podules are never detached anyway. */
    584  1.1  reinoud         *tagp = malloc(sizeof(struct bus_space), M_DEVBUF, M_WAITOK);
    585  1.1  reinoud 	**tagp = *tag;
    586  1.1  reinoud 	(*tagp)->bs_cookie = (void *)shift;
    587  1.1  reinoud }
    588  1.1  reinoud 
    589  1.1  reinoud int
    590  1.1  reinoud podulebus_initloader(struct podulebus_attach_args *pa)
    591  1.1  reinoud {
    592  1.1  reinoud 
    593  1.1  reinoud 	/* No loader support at present on arm32, so always fail. */
    594  1.1  reinoud 	return -1;
    595  1.1  reinoud }
    596  1.1  reinoud 
    597  1.1  reinoud int
    598  1.1  reinoud podloader_readbyte(struct podulebus_attach_args *pa, u_int addr)
    599  1.1  reinoud {
    600  1.1  reinoud 
    601  1.1  reinoud 	panic("podloader_readbyte");
    602  1.1  reinoud }
    603  1.1  reinoud 
    604  1.1  reinoud void
    605  1.1  reinoud podloader_writebyte(struct podulebus_attach_args *pa, u_int addr, int val)
    606  1.1  reinoud {
    607  1.1  reinoud 
    608  1.1  reinoud 	panic("podloader_writebyte");
    609  1.1  reinoud }
    610  1.1  reinoud 
    611  1.1  reinoud void
    612  1.1  reinoud podloader_reset(struct podulebus_attach_args *pa)
    613  1.1  reinoud {
    614  1.1  reinoud 
    615  1.1  reinoud 	panic("podloader_reset");
    616  1.1  reinoud }
    617  1.1  reinoud 
    618  1.1  reinoud int
    619  1.1  reinoud podloader_callloader(struct podulebus_attach_args *pa, u_int r0, u_int r1)
    620  1.1  reinoud {
    621  1.1  reinoud 
    622  1.1  reinoud 	panic("podloader_callloader");
    623  1.1  reinoud }
    624  1.1  reinoud 
    625  1.1  reinoud /* End of podulebus.c */
    626