123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /*
- * 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"
- static ulong *core;
- static ulong *wind;
- static ulong windsave[16];
- static ulong coresave[1];
- ulong iobase0;
- ulong iobase1;
- #define iobase(p) (iobase0+(p))
- static int
- ident(void)
- {
- return 0; /* bug! */
- }
- static uvlong* sgmap;
- static void
- sginit(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 void
- coreinit(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 */
- }
- void
- ciaerror(void)
- {
- print("cia error 0x%luX\n", core[0x8200/4]);
- }
- static void
- corehello(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 void
- coredetach(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 int
- intrenable164(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.
- */
- int
- inb2117x(int port)
- {
- mb();
- return *(uchar*)(iobase(port));
- }
- ushort
- ins2117x(int port)
- {
- mb();
- return *(ushort*)(iobase(port));
- }
- ulong
- inl2117x(int port)
- {
- mb();
- return *(ulong*)(iobase(port));
- }
- void
- outb2117x(int port, int val)
- {
- mb();
- *(uchar*)(iobase(port)) = val;
- mb();
- }
- void
- outs2117x(int port, ushort val)
- {
- mb();
- *(ushort*)(iobase(port)) = val;
- mb();
- }
- void
- outl2117x(int port, ulong val)
- {
- mb();
- *(ulong*)(iobase(port)) = val;
- mb();
- }
- void
- insb2117x(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;
- }
- }
- void
- inss2117x(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;
- }
- }
- void
- insl2117x(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;
- }
- }
- void
- outsb2117x(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++;
- }
- }
- void
- outss2117x(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++;
- }
- }
- void
- outsl2117x(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,
- };
|