1 /* 2 * Copyright (c) 1993 Adam Glass 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Adam Glass. 16 * 4. The name of the Author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL Adam Glass BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $Id: obio.c,v 1.10 1994/05/06 07:49:18 gwr Exp $ 32 */ 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 37 #include <machine/autoconf.h> 38 #include <machine/obio.h> 39 #include <machine/pte.h> 40 #include <machine/param.h> 41 #include <machine/mon.h> 42 #include <machine/isr.h> 43 44 #define ALL 0xFF 45 46 unsigned char *interrupt_reg = NULL; 47 vm_offset_t eeprom_va = NULL; 48 vm_offset_t memerr_va = NULL; 49 vm_offset_t zs0_va = NULL; /* ttya, ttyb */ 50 vm_offset_t zs1_va = NULL; /* kbd, mouse */ 51 52 static struct obio_internal { 53 vm_offset_t *obio_internal_va; 54 vm_offset_t obio_addr; 55 unsigned char obio_cpu_mask; 56 unsigned int obio_size; 57 int obio_rw; 58 } obio_internal_dev[] = { 59 {&eeprom_va, OBIO_EEPROM, ALL, OBIO_EEPROM_SIZE ,1}, 60 {&memerr_va, OBIO_MEMERR, ALL, OBIO_MEMERR_SIZE ,1}, 61 {&zs0_va, OBIO_ZS, ALL, OBIO_ZS_SIZE ,1}, 62 {&zs1_va, OBIO_KEYBD_MS, ALL, OBIO_ZS_SIZE ,1}, 63 {NULL, 0, 0, 0 ,0} 64 /* {&ecc_va, OBIO_MEMERR, ALL, OBIO_MEMERR_SIZE }, */ 65 }; 66 67 extern void obioattach __P((struct device *, struct device *, void *)); 68 69 struct obio_softc { 70 struct device obio_dev; 71 }; 72 73 struct cfdriver obiocd = 74 { NULL, "obio", always_match, obioattach, DV_DULL, 75 sizeof(struct obio_softc), 0}; 76 77 void obio_print(addr, level) 78 caddr_t addr; 79 int level; 80 { 81 printf(" addr 0x%x", addr); 82 if (level >=0) 83 printf(" level %d", level); 84 } 85 86 void obioattach(parent, self, args) 87 struct device *parent; 88 struct device *self; 89 void *args; 90 { 91 struct cfdata *new_match; 92 93 printf("\n"); 94 while (1) { 95 new_match = config_search(NULL, self, NULL); 96 if (!new_match) break; 97 config_attach(self, new_match, NULL, NULL); 98 } 99 } 100 101 /* 102 * this routine "configures" any internal OBIO devices which must be 103 * accessible before the mainline OBIO autoconfiguration as part of 104 * configure(). 105 * 106 * In reality this maps in a few control registers. VA space is allocated 107 * out of the high_segment... 108 * XXX - Is it worth the trouble to go find and re-use the mappings 109 * created by the PROM monitor? -gwr 110 * 111 */ 112 void obio_internal_configure() 113 { 114 struct obio_internal *oip; 115 extern unsigned char cpu_machine_id; 116 vm_offset_t va, high_segment_alloc(), pte_proto,obio_pa; 117 int npages; 118 119 for (oip = obio_internal_dev; oip->obio_internal_va; oip++) { 120 if ((cpu_machine_id & oip->obio_cpu_mask) == 0) continue; 121 npages = PA_PGNUM(sun3_round_page(oip->obio_size)); 122 va = high_segment_alloc(npages); 123 if (!va) 124 mon_panic("obio_internal_configure: short pages for internal devs"); 125 *oip->obio_internal_va = va; 126 pte_proto = PG_VALID|PG_SYSTEM|PG_NC|MAKE_PGTYPE(PG_OBIO); 127 if (oip->obio_rw) 128 pte_proto |= PG_WRITE; 129 obio_pa = oip->obio_addr; 130 for (; npages != 0; npages--, va += NBPG, obio_pa += NBPG) 131 set_pte(va, pte_proto | PA_PGNUM(obio_pa)); 132 } 133 } 134 135 caddr_t obio_alloc(obio_addr, obio_size, obio_flags) 136 caddr_t obio_addr; 137 int obio_size; 138 int obio_flags; 139 { 140 int npages; 141 vm_offset_t va, high_segment_alloc(), obio_pa, obio_va, pte_proto; 142 143 npages = PA_PGNUM(sun3_round_page(obio_size)); 144 if (!npages) 145 panic("obio_alloc: attempt to allocate 0 pages for obio"); 146 va = high_segment_alloc(npages); 147 if (!va) 148 va = (vm_offset_t) obio_vm_alloc(npages); 149 if (!va) 150 panic("obio_alloc: unable to allocate va for obio mapping"); 151 pte_proto = PG_VALID|PG_SYSTEM|MAKE_PGTYPE(PG_OBIO); 152 if ((obio_flags & OBIO_CACHE) == 0) 153 pte_proto |= PG_NC; 154 if (obio_flags & OBIO_WRITE) 155 pte_proto |= PG_WRITE; 156 obio_va = va; 157 obio_pa = (vm_offset_t) obio_addr; 158 for (; npages ; npages--, obio_va += NBPG, obio_pa += NBPG) 159 set_pte(obio_va, pte_proto | PA_PGNUM(obio_pa)); 160 return (caddr_t) va; 161 } 162 163 int 164 obio_probe_byte(oba) 165 caddr_t oba; /* OBIO address to probe */ 166 { 167 /* XXX - Not yet... */ 168 return 0; 169 } 170