4 * Core Logic: 21172 CIA or 21174 PYXIS
7 #include "../port/lib.h"
16 static ulong windsave[16];
17 static ulong coresave[1];
21 #define iobase(p) (iobase0+(p))
37 sgmap = xspanalloc(BY2PG, BY2PG, 0);
38 memset(sgmap, 0, BY2PG);
41 * Prepare scatter-gather map for 0-8MB.
44 for(pa = 0; pa < 8*1024*1024; pa += BY2PG)
45 *pte++ = ((pa>>PGSHIFT)<<1)|1;
48 * Set up a map for ISA DMA accesses to physical memory.
49 * Addresses presented by an ISA device between ISAWINDOW
50 * and ISAWINDOW+8MB will be translated to between 0 and
51 * 0+8MB of physical memory.
53 wind[0x400/4] = ISAWINDOW|2|1; /* window base */
54 wind[0x440/4] = 0x00700000; /* window mask */
55 wind[0x480/4] = PADDR(sgmap)>>2; /* <33:10> of sg map */
57 wind[0x100/4] = 3; /* invalidate tlb cache */
61 kmapio(ulong space, ulong offset, int size)
63 return kmapv(((uvlong)space<<32LL)|offset, size);
71 core = kmapio(0x87, 0x40000000, 0x10000);
72 wind = kmapio(0x87, 0x60000000, 0x1000);
74 iobase0 = (ulong)kmapio(0x89, 0, 0x20000);
76 /* hae_io = core[0x440/4];
77 iobase1 = (ulong)kmapio(0x89, hae_io, 0x10000); */
79 /* save critical parts of hardware memory mapping */
80 for (i = 4; i < 8; i++) {
81 windsave[4*(i-4)+0] = wind[(i*0x100+0x00)/4];
82 windsave[4*(i-4)+1] = wind[(i*0x100+0x40)/4];
83 windsave[4*(i-4)+2] = wind[(i*0x100+0x80)/4];
85 coresave[0] = core[0x140/4];
96 * Set up a map for PCI DMA accesses to physical memory.
97 * Addresses presented by a PCI device between PCIWINDOW
98 * and PCIWINDOW+1GB will be translated to between 0 and
99 * 0+1GB of physical memory.
101 wind[0x500/4] = PCIWINDOW|1;
102 wind[0x540/4] = 0x3ff00000;
105 /* clear error state */
106 core[0x8200/4] = 0x7ff;
108 /* set config: byte/word enable, no monster window, etc. */
109 core[0x140/4] = 0x21;
111 /* turn off mcheck on master abort. now we can probe PCI space. */
112 core[0x8280/4] &= ~(1<<7);
114 /* set up interrupts. */
116 cserve(52, 4); /* enable SIO interrupt */
122 print("cia error 0x%luX\n", core[0x8200/4]);
128 print("cpu%d: CIA revision %ld; cnfg %lux cntrl %lux\n",
130 core[0x80/4] & 0x7f, core[0x140/4], core[0x100/4]);
131 print("cpu%d: HAE_IO %lux\n", 0, core[0x440/4]);
140 for (i = 4; i < 8; i++) {
141 wind[(i*0x100+0x00)/4] = windsave[4*(i-4)+0];
142 wind[(i*0x100+0x40)/4] = windsave[4*(i-4)+1];
143 wind[(i*0x100+0x80)/4] = windsave[4*(i-4)+2];
145 core[0x140/4] = coresave[0];
146 /* for (i = 0; i < 4; i++)
148 cserve(53, i); /* disable interrupts */
152 static ulong pcimap[256];
155 pcicfg2117x(int tbdf, int rno)
168 pcimap[bus] = base = (ulong)kmapio(space, MKBUS(0, bus, 0, 0), (1<<16));
171 return (void*)(base + BUSDF(tbdf) + rno);
175 pcimem2117x(int addr, int len)
177 return kmapio(0x88, addr, len);
181 intrenable164(Vctl *v)
186 if(irq > MaxIrqPIC) {
187 print("intrenable: irq %d out of range\n", v->irq);
190 if(BUSTYPE(v->tbdf) == BusPCI) {
196 if(i8259enable(irq, v->tbdf, v) == -1)
203 * I have a function pointer in PCArch for every one of these, because on
204 * some Alphas we have to use sparse mode, but on others we can use
205 * MOVB et al. Additionally, the PC164 documentation threatened us
206 * with the lie that the SIO is in region B, but everything else in region A.
207 * This turned out not to be the case. Given the cost of this solution, it
208 * may be better just to use sparse mode for I/O space on all platforms.
214 return *(uchar*)(iobase(port));
221 return *(ushort*)(iobase(port));
228 return *(ulong*)(iobase(port));
232 outb2117x(int port, int val)
235 *(uchar*)(iobase(port)) = val;
240 outs2117x(int port, ushort val)
243 *(ushort*)(iobase(port)) = val;
248 outl2117x(int port, ulong val)
251 *(ulong*)(iobase(port)) = val;
256 insb2117x(int port, void *buf, int len)
261 p = (uchar*)iobase(port);
263 for(i = 0; i < len; i++){
270 inss2117x(int port, void *buf, int len)
275 p = (ushort*)iobase(port);
277 for(i = 0; i < len; i++){
284 insl2117x(int port, void *buf, int len)
289 p = (ulong*)iobase(port);
291 for(i = 0; i < len; i++){
298 outsb2117x(int port, void *buf, int len)
303 p = (uchar*)iobase(port);
305 for(i = 0; i < len; i++){
312 outss2117x(int port, void *buf, int len)
317 p = (ushort*)iobase(port);
319 for(i = 0; i < len; i++){
326 outsl2117x(int port, void *buf, int len)
331 p = (ulong*)iobase(port);
333 for(i = 0; i < len; i++){