📄 arch164.c
字号:
/* * EB164 and similar * CPU: 21164 * Core Logic: 21172 CIA or 21174 PYXIS */#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "ureg.h"static ulong *core;static ulong *wind;static ulong windsave[16];static ulong coresave[1];ulong iobase0;ulong iobase1;#define iobase(p) (iobase0+(p))static intident(void){ return 0; /* bug! */}static uvlong* sgmap;static voidsginit(void){ ulong pa; uvlong *pte; sgmap = xspanalloc(BY2PG, BY2PG, 0); memset(sgmap, 0, BY2PG); /* * Prepare scatter-gather map for 0-8MB. */ pte = sgmap; for(pa = 0; pa < 8*1024*1024; pa += BY2PG) *pte++ = ((pa>>PGSHIFT)<<1)|1; /* * Set up a map for ISA DMA accesses to physical memory. * Addresses presented by an ISA device between ISAWINDOW * and ISAWINDOW+8MB will be translated to between 0 and * 0+8MB of physical memory. */ wind[0x400/4] = ISAWINDOW|2|1; /* window base */ wind[0x440/4] = 0x00700000; /* window mask */ wind[0x480/4] = PADDR(sgmap)>>2; /* <33:10> of sg map */ wind[0x100/4] = 3; /* invalidate tlb cache */}static void *kmapio(ulong space, ulong offset, int size){ return kmapv(((uvlong)space<<32LL)|offset, size);}static voidcoreinit(void){ int i; core = kmapio(0x87, 0x40000000, 0x10000); wind = kmapio(0x87, 0x60000000, 0x1000); iobase0 = (ulong)kmapio(0x89, 0, 0x20000); /* hae_io = core[0x440/4]; iobase1 = (ulong)kmapio(0x89, hae_io, 0x10000); */ /* save critical parts of hardware memory mapping */ for (i = 4; i < 8; i++) { windsave[4*(i-4)+0] = wind[(i*0x100+0x00)/4]; windsave[4*(i-4)+1] = wind[(i*0x100+0x40)/4]; windsave[4*(i-4)+2] = wind[(i*0x100+0x80)/4]; } coresave[0] = core[0x140/4]; /* disable windows */ wind[0x400/4] = 0; wind[0x500/4] = 0; wind[0x600/4] = 0; wind[0x700/4] = 0; sginit(); /* * Set up a map for PCI DMA accesses to physical memory. * Addresses presented by a PCI device between PCIWINDOW * and PCIWINDOW+1GB will be translated to between 0 and * 0+1GB of physical memory. */ wind[0x500/4] = PCIWINDOW|1; wind[0x540/4] = 0x3ff00000; wind[0x580/4] = 0; /* clear error state */ core[0x8200/4] = 0x7ff; /* set config: byte/word enable, no monster window, etc. */ core[0x140/4] = 0x21; /* turn off mcheck on master abort. now we can probe PCI space. */ core[0x8280/4] &= ~(1<<7); /* set up interrupts. */ i8259init(); cserve(52, 4); /* enable SIO interrupt */}voidciaerror(void){ print("cia error 0x%luX\n", core[0x8200/4]);}static voidcorehello(void){ print("cpu%d: CIA revision %ld; cnfg %lux cntrl %lux\n", 0, /* BUG */ core[0x80/4] & 0x7f, core[0x140/4], core[0x100/4]); print("cpu%d: HAE_IO %lux\n", 0, core[0x440/4]); print("\n");}static voidcoredetach(void){ int i; for (i = 4; i < 8; i++) { wind[(i*0x100+0x00)/4] = windsave[4*(i-4)+0]; wind[(i*0x100+0x40)/4] = windsave[4*(i-4)+1]; wind[(i*0x100+0x80)/4] = windsave[4*(i-4)+2]; } core[0x140/4] = coresave[0];/* for (i = 0; i < 4; i++) if (i != 4) cserve(53, i); /* disable interrupts */}static Lock pcicfgl;static ulong pcimap[256];static void*pcicfg2117x(int tbdf, int rno){ int space, bus; ulong base; bus = BUSBNO(tbdf); lock(&pcicfgl); base = pcimap[bus]; if (base == 0) { if(bus) space = 0x8B; else space = 0x8A; pcimap[bus] = base = (ulong)kmapio(space, MKBUS(0, bus, 0, 0), (1<<16)); } unlock(&pcicfgl); return (void*)(base + BUSDF(tbdf) + rno);}static void*pcimem2117x(int addr, int len){ return kmapio(0x88, addr, len);}static intintrenable164(Vctl *v){ int vec, irq; irq = v->irq; if(irq > MaxIrqPIC) { print("intrenable: irq %d out of range\n", v->irq); return -1; } if(BUSTYPE(v->tbdf) == BusPCI) { vec = irq+VectorPCI; cserve(52, irq); } else { vec = irq+VectorPIC; if(i8259enable(irq, v->tbdf, v) == -1) return -1; } return vec;}/* * I have a function pointer in PCArch for every one of these, because on * some Alphas we have to use sparse mode, but on others we can use * MOVB et al. Additionally, the PC164 documentation threatened us * with the lie that the SIO is in region B, but everything else in region A. * This turned out not to be the case. Given the cost of this solution, it * may be better just to use sparse mode for I/O space on all platforms. */intinb2117x(int port){ mb(); return *(uchar*)(iobase(port));}ushortins2117x(int port){ mb(); return *(ushort*)(iobase(port));}ulonginl2117x(int port){ mb(); return *(ulong*)(iobase(port));}voidoutb2117x(int port, int val){ mb(); *(uchar*)(iobase(port)) = val; mb();}voidouts2117x(int port, ushort val){ mb(); *(ushort*)(iobase(port)) = val; mb();}voidoutl2117x(int port, ulong val){ mb(); *(ulong*)(iobase(port)) = val; mb();}voidinsb2117x(int port, void *buf, int len){ int i; uchar *p, *q; p = (uchar*)iobase(port); q = buf; for(i = 0; i < len; i++){ mb(); *q++ = *p; }}voidinss2117x(int port, void *buf, int len){ int i; ushort *p, *q; p = (ushort*)iobase(port); q = buf; for(i = 0; i < len; i++){ mb(); *q++ = *p; }}voidinsl2117x(int port, void *buf, int len){ int i; ulong *p, *q; p = (ulong*)iobase(port); q = buf; for(i = 0; i < len; i++){ mb(); *q++ = *p; }}voidoutsb2117x(int port, void *buf, int len){ int i; uchar *p, *q; p = (uchar*)iobase(port); q = buf; for(i = 0; i < len; i++){ mb(); *p = *q++; }}voidoutss2117x(int port, void *buf, int len){ int i; ushort *p, *q; p = (ushort*)iobase(port); q = buf; for(i = 0; i < len; i++){ mb(); *p = *q++; }}voidoutsl2117x(int port, void *buf, int len){ int i; ulong *p, *q; p = (ulong*)iobase(port); q = buf; for(i = 0; i < len; i++){ mb(); *p = *q++; }}PCArch arch164 = { "EB164", ident, coreinit, corehello, coredetach, pcicfg2117x, pcimem2117x, intrenable164, nil, nil, inb2117x, ins2117x, inl2117x, outb2117x, outs2117x, outl2117x, insb2117x, inss2117x, insl2117x, outsb2117x, outss2117x, outsl2117x,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -