The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/alphapc/arch164.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *      EB164 and similar
    3  *      CPU:    21164
    4  *      Core Logic: 21172 CIA or 21174 PYXIS
    5   */
    6 #include        "u.h"
    7 #include        "../port/lib.h"
    8 #include        "mem.h"
    9 #include        "dat.h"
   10 #include        "fns.h"
   11 #include        "io.h"
   12 
   13 static ulong *core;
   14 static ulong *wind;
   15 
   16 static ulong windsave[16];
   17 static ulong coresave[1];
   18 
   19 ulong   iobase0;
   20 ulong   iobase1;
   21 #define iobase(p)       (iobase0+(p))
   22 
   23 static int
   24 ident(void)
   25 {
   26         return 0;       /* bug! */
   27 }
   28 
   29 static uvlong* sgmap;
   30 
   31 static void
   32 sginit(void)
   33 {
   34         ulong pa;
   35         uvlong *pte;
   36 
   37         sgmap = xspanalloc(BY2PG, BY2PG, 0);
   38         memset(sgmap, 0, BY2PG);
   39 
   40         /*
   41          * Prepare scatter-gather map for 0-8MB.
   42          */
   43         pte = sgmap;
   44         for(pa = 0; pa < 8*1024*1024; pa += BY2PG)
   45                 *pte++ = ((pa>>PGSHIFT)<<1)|1;
   46 
   47         /*
   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.
   52          */
   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 */
   56 
   57         wind[0x100/4] = 3;                      /* invalidate tlb cache */
   58 }
   59 
   60 static void *
   61 kmapio(ulong space, ulong offset, int size)
   62 {
   63         return kmapv(((uvlong)space<<32LL)|offset, size);
   64 }
   65 
   66 static void
   67 coreinit(void)
   68 {
   69         int i;
   70 
   71         core = kmapio(0x87, 0x40000000, 0x10000);
   72         wind = kmapio(0x87, 0x60000000, 0x1000);
   73 
   74         iobase0 = (ulong)kmapio(0x89, 0, 0x20000);
   75 
   76         /* hae_io = core[0x440/4];
   77         iobase1 = (ulong)kmapio(0x89, hae_io, 0x10000); */
   78 
   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];
   84         }
   85         coresave[0] = core[0x140/4];
   86 
   87         /* disable windows */
   88         wind[0x400/4] = 0;
   89         wind[0x500/4] = 0;
   90         wind[0x600/4] = 0;
   91         wind[0x700/4] = 0;
   92 
   93         sginit();
   94 
   95         /*
   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.
  100          */
  101         wind[0x500/4] = PCIWINDOW|1;
  102         wind[0x540/4] = 0x3ff00000;
  103         wind[0x580/4] = 0;
  104 
  105         /* clear error state */
  106         core[0x8200/4] = 0x7ff;
  107 
  108         /* set config: byte/word enable, no monster window, etc. */
  109         core[0x140/4] = 0x21;
  110 
  111         /* turn off mcheck on master abort.  now we can probe PCI space. */
  112         core[0x8280/4] &= ~(1<<7);
  113 
  114         /* set up interrupts. */
  115         i8259init();
  116         cserve(52, 4);          /* enable SIO interrupt */
  117 }
  118 
  119 void
  120 ciaerror(void)
  121 {
  122         print("cia error 0x%luX\n", core[0x8200/4]);
  123 }
  124 
  125 static void
  126 corehello(void)
  127 {
  128         print("cpu%d: CIA revision %ld; cnfg %lux cntrl %lux\n",
  129                         0,      /* BUG */
  130                         core[0x80/4] & 0x7f, core[0x140/4], core[0x100/4]);
  131         print("cpu%d: HAE_IO %lux\n", 0, core[0x440/4]);
  132         print("\n");
  133 }
  134 
  135 static void
  136 coredetach(void)
  137 {
  138         int i;
  139 
  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];
  144         }
  145         core[0x140/4] = coresave[0];
  146 /*      for (i = 0; i < 4; i++)
  147                 if (i != 4)
  148                         cserve(53, i);          /* disable interrupts */
  149 }
  150 
  151 static Lock     pcicfgl;
  152 static ulong    pcimap[256];
  153 
  154 static void*
  155 pcicfg2117x(int tbdf, int rno)
  156 {
  157         int space, bus;
  158         ulong base;
  159 
  160         bus = BUSBNO(tbdf);
  161         lock(&pcicfgl);
  162         base = pcimap[bus];
  163         if (base == 0) {
  164                 if(bus)
  165                         space = 0x8B;
  166                 else
  167                         space = 0x8A;
  168                 pcimap[bus] = base = (ulong)kmapio(space, MKBUS(0, bus, 0, 0), (1<<16));
  169         }
  170         unlock(&pcicfgl);
  171         return (void*)(base + BUSDF(tbdf) + rno);
  172 }
  173 
  174 static void*
  175 pcimem2117x(int addr, int len)
  176 {
  177         return kmapio(0x88, addr, len);
  178 }
  179 
  180 static int
  181 intrenable164(Vctl *v)
  182 {
  183         int vec, irq;
  184 
  185         irq = v->irq;
  186         if(irq > MaxIrqPIC) {
  187                 print("intrenable: irq %d out of range\n", v->irq);
  188                 return -1;
  189         }
  190         if(BUSTYPE(v->tbdf) == BusPCI) {
  191                 vec = irq+VectorPCI;
  192                 cserve(52, irq);
  193         }
  194         else {
  195                 vec = irq+VectorPIC;
  196                 if(i8259enable(irq, v->tbdf, v) == -1)
  197                         return -1;
  198         }
  199         return vec;
  200 }
  201 
  202 /*
  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.
  209  */
  210 int
  211 inb2117x(int port)
  212 {
  213         mb();
  214         return *(uchar*)(iobase(port));
  215 }
  216 
  217 ushort
  218 ins2117x(int port)
  219 {
  220         mb();
  221         return *(ushort*)(iobase(port));
  222 }
  223 
  224 ulong
  225 inl2117x(int port)
  226 {
  227         mb();
  228         return *(ulong*)(iobase(port));
  229 }
  230 
  231 void
  232 outb2117x(int port, int val)
  233 {
  234         mb();
  235         *(uchar*)(iobase(port)) = val;
  236         mb();
  237 }
  238 
  239 void
  240 outs2117x(int port, ushort val)
  241 {
  242         mb();
  243         *(ushort*)(iobase(port)) = val;
  244         mb();
  245 }
  246 
  247 void
  248 outl2117x(int port, ulong val)
  249 {
  250         mb();
  251         *(ulong*)(iobase(port)) = val;
  252         mb();
  253 }
  254 
  255 void
  256 insb2117x(int port, void *buf, int len)
  257 {
  258         int i;
  259         uchar *p, *q;
  260 
  261         p = (uchar*)iobase(port);
  262         q = buf;
  263         for(i = 0; i < len; i++){
  264                 mb();
  265                 *q++ = *p;
  266         }
  267 }
  268 
  269 void
  270 inss2117x(int port, void *buf, int len)
  271 {
  272         int i;
  273         ushort *p, *q;
  274 
  275         p = (ushort*)iobase(port);
  276         q = buf;
  277         for(i = 0; i < len; i++){
  278                 mb();
  279                 *q++ = *p;
  280         }
  281 }
  282 
  283 void
  284 insl2117x(int port, void *buf, int len)
  285 {
  286         int i;
  287         ulong *p, *q;
  288 
  289         p = (ulong*)iobase(port);
  290         q = buf;
  291         for(i = 0; i < len; i++){
  292                 mb();
  293                 *q++ = *p;
  294         }
  295 }
  296 
  297 void
  298 outsb2117x(int port, void *buf, int len)
  299 {
  300         int i;
  301         uchar *p, *q;
  302 
  303         p = (uchar*)iobase(port);
  304         q = buf;
  305         for(i = 0; i < len; i++){
  306                 mb();
  307                 *p = *q++;
  308         }
  309 }
  310 
  311 void
  312 outss2117x(int port, void *buf, int len)
  313 {
  314         int i;
  315         ushort *p, *q;
  316 
  317         p = (ushort*)iobase(port);
  318         q = buf;
  319         for(i = 0; i < len; i++){
  320                 mb();
  321                 *p = *q++;
  322         }
  323 }
  324 
  325 void
  326 outsl2117x(int port, void *buf, int len)
  327 {
  328         int i;
  329         ulong *p, *q;
  330 
  331         p = (ulong*)iobase(port);
  332         q = buf;
  333         for(i = 0; i < len; i++){
  334                 mb();
  335                 *p = *q++;
  336         }
  337 }
  338 
  339 PCArch arch164 = {
  340         "EB164",
  341         ident,
  342         coreinit,
  343         corehello,
  344         coredetach,
  345         pcicfg2117x,
  346         pcimem2117x,
  347         intrenable164,
  348         nil,
  349         nil,
  350 
  351         inb2117x,
  352         ins2117x,
  353         inl2117x,
  354         outb2117x,
  355         outs2117x,
  356         outl2117x,
  357         insb2117x,
  358         inss2117x,
  359         insl2117x,
  360         outsb2117x,
  361         outss2117x,
  362         outsl2117x,
  363 };

Cache object: 17f5682c287379ff66313402c045b815


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.