1 #include "sys/systm.h" 2 #include "sys/device.h" 3 4 #include "machine/autoconf.h" 5 #include "machine/obio.h" 6 #include "machine/pte.h" 7 #include "machine/param.h" 8 #include "machine/mon.h" 9 #include "machine/isr.h" 10 11 #define ALL 0xFF 12 13 unsigned char *interrupt_reg = NULL; 14 vm_offset_t eeprom_va = NULL; 15 vm_offset_t memerr_va = NULL; 16 17 static struct obio_internal { 18 vm_offset_t *obio_internal_va; 19 vm_offset_t obio_addr; 20 unsigned char obio_cpu_mask; 21 unsigned int obio_size; 22 int obio_rw; 23 } obio_internal_dev[] = { 24 {&eeprom_va, OBIO_EEPROM, ALL, OBIO_EEPROM_SIZE ,1}, 25 {&memerr_va, OBIO_MEMERR, ALL, OBIO_MEMERR_SIZE ,1}, 26 {NULL, 0, 0, 0 ,0} 27 /* {&ecc_va, OBIO_MEMERR, ALL, OBIO_MEMERR_SIZE }, */ 28 }; 29 30 extern void obioattach __P((struct device *, struct device *, void *)); 31 32 struct obio_softc { 33 struct device obio_dev; 34 }; 35 36 struct cfdriver obiocd = 37 { NULL, "obio", always_match, obioattach, DV_DULL, 38 sizeof(struct obio_softc), 0}; 39 40 void obio_print(addr, level) 41 caddr_t addr; 42 int level; 43 { 44 printf(" addr 0x%x", addr); 45 if (level >=0) 46 printf(" level %d", level); 47 } 48 49 void obioattach(parent, self, args) 50 struct device *parent; 51 struct device *self; 52 void *args; 53 { 54 struct cfdata *new_match; 55 56 printf("\n"); 57 while (1) { 58 new_match = config_search(NULL, self, NULL); 59 if (!new_match) break; 60 config_attach(self, new_match, NULL, NULL); 61 } 62 } 63 64 /* 65 * this routine "configures" any internal OBIO devices which must be 66 * accessible before the mainline OBIO autoconfiguration as part of 67 * configure(). 68 * 69 * In reality this maps in a few control registers. VA space is allocated 70 * out of the high_segment... 71 * 72 */ 73 void obio_internal_configure() 74 { 75 struct obio_internal *oip; 76 extern unsigned char cpu_machine_id; 77 vm_offset_t va, high_segment_alloc(), pte_proto,obio_pa; 78 int npages; 79 80 for (oip = obio_internal_dev; oip->obio_internal_va; oip++) { 81 if ((cpu_machine_id & oip->obio_cpu_mask) == 0) continue; 82 npages = PA_PGNUM(sun3_round_page(oip->obio_size)); 83 va = high_segment_alloc(npages); 84 if (!va) 85 mon_panic("obio_internal_configure: short pages for internal devs"); 86 *oip->obio_internal_va = va; 87 pte_proto = PG_VALID|PG_SYSTEM|PG_NC|MAKE_PGTYPE(PG_OBIO); 88 if (oip->obio_rw) 89 pte_proto |= PG_WRITE; 90 obio_pa = oip->obio_addr; 91 for (; npages != 0; npages--, va += NBPG, obio_pa += NBPG) 92 set_pte(va, pte_proto | PA_PGNUM(obio_pa)); 93 } 94 } 95 96 caddr_t obio_alloc(obio_addr, obio_size, obio_flags) 97 caddr_t obio_addr; 98 int obio_size; 99 int obio_flags; 100 { 101 int npages; 102 vm_offset_t va, high_segment_alloc(), obio_pa, obio_va, pte_proto; 103 104 npages = PA_PGNUM(sun3_round_page(obio_size)); 105 if (!npages) 106 panic("obio_alloc: attempt to allocate 0 pages for obio"); 107 va = high_segment_alloc(npages); 108 if (!va) 109 va = (vm_offset_t) obio_vm_alloc(npages); 110 if (!va) 111 panic("obio_alloc: unable to allocate va for obio mapping"); 112 pte_proto = PG_VALID|PG_SYSTEM|MAKE_PGTYPE(PG_OBIO); 113 if ((obio_flags & OBIO_CACHE) == 0) 114 pte_proto |= PG_NC; 115 if (obio_flags & OBIO_WRITE) 116 pte_proto |= PG_WRITE; 117 obio_va = va; 118 obio_pa = (vm_offset_t) obio_addr; 119 for (; npages ; npages--, obio_va += NBPG, obio_pa += NBPG) 120 set_pte(obio_va, pte_proto | PA_PGNUM(obio_pa)); 121 return (caddr_t) va; 122 } 123 124