xref: /netbsd-src/sys/arch/sun3/sun3/obio.c (revision 5f7096188587a2c7c95fa3c69b78e1ec9c7923d0)
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