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/dev/vme/if_ie_vme.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 /*      $NetBSD: if_ie_vme.c,v 1.18 2004/03/15 23:51:12 pk Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 1995 Charles D. Cranor
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Charles D. Cranor.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Converted to SUN ie driver by Charles D. Cranor,
   35  *              October 1994, January 1995.
   36  */
   37 
   38 /*
   39  * The i82586 is a very painful chip, found in sun3's, sun-4/100's
   40  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
   41  * SUN, making life difficult.  Programming this chip is mostly the same,
   42  * but certain details differ from system to system.  This driver is
   43  * written so that different "ie" interfaces can be controled by the same
   44  * driver.
   45  */
   46 
   47 /*
   48  * programming notes:
   49  *
   50  * the ie chip operates in a 24 bit address space.
   51  *
   52  * most ie interfaces appear to be divided into two parts:
   53  *       - generic 586 stuff
   54  *       - board specific
   55  *
   56  * generic:
   57  *      the generic stuff of the ie chip is all done with data structures
   58  *      that live in the chip's memory address space.   the chip expects
   59  *      its main data structure (the sys conf ptr -- SCP) to be at a fixed
   60  *      address in its 24 bit space: 0xfffff4
   61  *
   62  *      the SCP points to another structure called the ISCP.
   63  *      the ISCP points to another structure called the SCB.
   64  *      the SCB has a status field, a linked list of "commands", and
   65  *      a linked list of "receive buffers".   these are data structures that
   66  *      live in memory, not registers.
   67  *
   68  * board:
   69  *      to get the chip to do anything, you first put a command in the
   70  *      command data structure list.   then you have to signal "attention"
   71  *      to the chip to get it to look at the command.   how you
   72  *      signal attention depends on what board you have... on PC's
   73  *      there is an i/o port number to do this, on sun's there is a
   74  *      register bit you toggle.
   75  *
   76  *      to get data from the chip you program it to interrupt...
   77  *
   78  *
   79  * sun issues:
   80  *
   81  *      there are 3 kinds of sun "ie" interfaces:
   82  *        1 - a VME/multibus card
   83  *        2 - an on-board interface (sun3's, sun-4/100's, and sun-4/200's)
   84  *        3 - another VME board called the 3E
   85  *
   86  *      the VME boards lives in vme16 space.   only 16 and 8 bit accesses
   87  *      are allowed, so functions that copy data must be aware of this.
   88  *
   89  *      the chip is an intel chip.  this means that the byte order
   90  *      on all the "short"s in the chip's data structures is wrong.
   91  *      so, constants described in the intel docs are swapped for the sun.
   92  *      that means that any buffer pointers you give the chip must be
   93  *      swapped to intel format.   yuck.
   94  *
   95  *   VME/multibus interface:
   96  *      for the multibus interface the board ignores the top 4 bits
   97  *      of the chip address.   the multibus interface has its own
   98  *      MMU like page map (without protections or valid bits, etc).
   99  *      there are 256 pages of physical memory on the board (each page
  100  *      is 1024 bytes).   There are 1024 slots in the page map.  so,
  101  *      a 1024 byte page takes up 10 bits of address for the offset,
  102  *      and if there are 1024 slots in the page that is another 10 bits
  103  *      of the address.   That makes a 20 bit address, and as stated
  104  *      earlier the board ignores the top 4 bits, so that accounts
  105  *      for all 24 bits of address.
  106  *
  107  *      Note that the last entry of the page map maps the top of the
  108  *      24 bit address space and that the SCP is supposed to be at
  109  *      0xfffff4 (taking into account allignment).   so,
  110  *      for multibus, that entry in the page map has to be used for the SCP.
  111  *
  112  *      The page map effects BOTH how the ie chip sees the
  113  *      memory, and how the host sees it.
  114  *
  115  *      The page map is part of the "register" area of the board
  116  *
  117  *      The page map to control where ram appears in the address space.
  118  *      We choose to have RAM start at 0 in the 24 bit address space.
  119  * 
  120  *      to get the phyiscal address of the board's RAM you must take the
  121  *      top 12 bits of the physical address of the register address and
  122  *      or in the 4 bits from the status word as bits 17-20 (remember that
  123  *      the board ignores the chip's top 4 address lines). For example:
  124  *      if the register is @ 0xffe88000, then the top 12 bits are 0xffe00000.
  125  *      to get the 4 bits from the status word just do status & IEVME_HADDR.
  126  *      suppose the value is "4".   Then just shift it left 16 bits to get
  127  *      it into bits 17-20 (e.g. 0x40000).    Then or it to get the
  128  *      address of RAM (in our example: 0xffe40000).   see the attach routine!
  129  *
  130  *
  131  *   on-board interface:
  132  *
  133  *      on the onboard ie interface the 24 bit address space is hardwired
  134  *      to be 0xff000000 -> 0xffffffff of KVA.   this means that sc_iobase
  135  *      will be 0xff000000.   sc_maddr will be where ever we allocate RAM
  136  *      in KVA.    note that since the SCP is at a fixed address it means
  137  *      that we have to allocate a fixed KVA for the SCP.
  138  *      <fill in useful info later>
  139  *
  140  *
  141  *   VME3E interface:
  142  *
  143  *      <fill in useful info later>
  144  *
  145  */
  146 
  147 #include <sys/cdefs.h>
  148 __KERNEL_RCSID(0, "$NetBSD: if_ie_vme.c,v 1.18 2004/03/15 23:51:12 pk Exp $");
  149 
  150 #include <sys/param.h>
  151 #include <sys/systm.h>
  152 #include <sys/errno.h>
  153 #include <sys/device.h>
  154 #include <sys/protosw.h>
  155 #include <sys/socket.h>
  156 
  157 #include <net/if.h>
  158 #include <net/if_types.h>
  159 #include <net/if_dl.h>
  160 #include <net/if_media.h>
  161 #include <net/if_ether.h>
  162 
  163 #include <machine/bus.h>
  164 #include <machine/intr.h>
  165 #ifdef __sparc__
  166 #include <machine/autoconf.h>
  167 #endif
  168 #include <dev/vme/vmevar.h>
  169 
  170 #include <dev/ic/i82586reg.h>
  171 #include <dev/ic/i82586var.h>
  172 
  173 #include "locators.h"
  174 
  175 /*
  176  * VME/multibus definitions
  177  */
  178 #define IEVME_PAGESIZE 1024     /* bytes */
  179 #define IEVME_PAGSHIFT 10       /* bits */
  180 #define IEVME_NPAGES   256      /* number of pages on chip */
  181 #define IEVME_MAPSZ    1024     /* number of entries in the map */
  182 
  183 /*
  184  * PTE for the page map
  185  */
  186 #define IEVME_SBORDR 0x8000     /* sun byte order */
  187 #define IEVME_IBORDR 0x0000     /* intel byte ordr */
  188 
  189 #define IEVME_P2MEM  0x2000     /* memory is on P2 */
  190 #define IEVME_OBMEM  0x0000     /* memory is on board */
  191 
  192 #define IEVME_PGMASK 0x0fff     /* gives the physical page frame number */
  193 
  194 struct ievme {
  195         u_int16_t       pgmap[IEVME_MAPSZ];
  196         u_int16_t       xxx[32];        /* prom */
  197         u_int16_t       status;         /* see below for bits */
  198         u_int16_t       xxx2;           /* filler */
  199         u_int16_t       pectrl;         /* parity control (see below) */
  200         u_int16_t       peaddr;         /* low 16 bits of address */
  201 };
  202 
  203 /*
  204  * status bits
  205  */
  206 #define IEVME_RESET 0x8000      /* reset board */
  207 #define IEVME_ONAIR 0x4000      /* go out of loopback 'on-air' */
  208 #define IEVME_ATTEN 0x2000      /* attention */
  209 #define IEVME_IENAB 0x1000      /* interrupt enable */
  210 #define IEVME_PEINT 0x0800      /* parity error interrupt enable */
  211 #define IEVME_PERR  0x0200      /* parity error flag */
  212 #define IEVME_INT   0x0100      /* interrupt flag */
  213 #define IEVME_P2EN  0x0020      /* enable p2 bus */
  214 #define IEVME_256K  0x0010      /* 256kb rams */
  215 #define IEVME_HADDR 0x000f      /* mask for bits 17-20 of address */
  216 
  217 /*
  218  * parity control
  219  */
  220 #define IEVME_PARACK 0x0100     /* parity error ack */
  221 #define IEVME_PARSRC 0x0080     /* parity error source */
  222 #define IEVME_PAREND 0x0040     /* which end of the data got the error */
  223 #define IEVME_PARADR 0x000f     /* mask to get bits 17-20 of parity address */
  224 
  225 /* Supported media */
  226 static int media[] = {
  227         IFM_ETHER | IFM_10_2,
  228 };      
  229 #define NMEDIA  (sizeof(media) / sizeof(media[0]))
  230 
  231 /*
  232  * the 3E board not supported (yet?)
  233  */
  234 
  235 
  236 static void ie_vmereset __P((struct ie_softc *, int));
  237 static void ie_vmeattend __P((struct ie_softc *, int));
  238 static void ie_vmerun __P((struct ie_softc *));
  239 static int  ie_vmeintr __P((struct ie_softc *, int));
  240 
  241 int ie_vme_match __P((struct device *, struct cfdata *, void *));
  242 void ie_vme_attach __P((struct device *, struct device *, void *));
  243 
  244 struct ie_vme_softc {
  245         struct ie_softc ie;
  246         bus_space_tag_t ievt;
  247         bus_space_handle_t ievh;
  248 };
  249 
  250 CFATTACH_DECL(ie_vme, sizeof(struct ie_vme_softc),
  251     ie_vme_match, ie_vme_attach, NULL, NULL);
  252 
  253 #define read_iev(sc, reg) \
  254   bus_space_read_2(sc->ievt, sc->ievh, offsetof(struct ievme, reg))
  255 #define write_iev(sc, reg, val) \
  256   bus_space_write_2(sc->ievt, sc->ievh, offsetof(struct ievme, reg), val)
  257 
  258 /*
  259  * MULTIBUS/VME support routines
  260  */
  261 void
  262 ie_vmereset(sc, what)
  263         struct ie_softc *sc;
  264         int what;
  265 {
  266         struct ie_vme_softc *vsc = (struct ie_vme_softc *)sc;
  267         write_iev(vsc, status, IEVME_RESET);
  268         delay(100);             /* XXX could be shorter? */
  269         write_iev(vsc, status, 0);
  270 }
  271 
  272 void
  273 ie_vmeattend(sc, why)
  274         struct ie_softc *sc;
  275         int why;
  276 {
  277         struct ie_vme_softc *vsc = (struct ie_vme_softc *)sc;
  278 
  279         /* flag! */
  280         write_iev(vsc, status, read_iev(vsc, status) | IEVME_ATTEN);
  281         /* down. */
  282         write_iev(vsc, status, read_iev(vsc, status) & ~IEVME_ATTEN);
  283 }
  284 
  285 void
  286 ie_vmerun(sc)
  287         struct ie_softc *sc;
  288 {
  289         struct ie_vme_softc *vsc = (struct ie_vme_softc *)sc;
  290 
  291         write_iev(vsc, status, read_iev(vsc, status)
  292                   | IEVME_ONAIR | IEVME_IENAB | IEVME_PEINT);
  293 }
  294 
  295 int
  296 ie_vmeintr(sc, where)
  297         struct ie_softc *sc;
  298         int where;
  299 {
  300         struct ie_vme_softc *vsc = (struct ie_vme_softc *)sc;
  301 
  302         if (where != INTR_ENTER)
  303                 return (0);
  304 
  305         /*
  306          * check for parity error
  307          */
  308         if (read_iev(vsc, status) & IEVME_PERR) {
  309                 printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
  310                        sc->sc_dev.dv_xname, read_iev(vsc, pectrl),
  311                        read_iev(vsc, pectrl) & IEVME_HADDR,
  312                        read_iev(vsc, peaddr));
  313                 write_iev(vsc, pectrl, read_iev(vsc, pectrl) | IEVME_PARACK);
  314         }
  315         return (0);
  316 }
  317 
  318 void ie_memcopyin __P((struct ie_softc *, void *, int, size_t));
  319 void ie_memcopyout __P((struct ie_softc *, const void *, int, size_t));
  320 
  321 /*
  322  * Copy board memory to kernel.
  323  */
  324 void
  325 ie_memcopyin(sc, p, offset, size)
  326         struct ie_softc *sc;
  327         void *p;
  328         int offset;
  329         size_t size;
  330 {
  331         size_t help;
  332 
  333         if ((offset & 1) && ((u_long)p & 1) && size > 0) {
  334                 *(u_int8_t *)p = bus_space_read_1(sc->bt, sc->bh, offset);
  335                 offset++;
  336                 p = (u_int8_t *)p + 1;
  337                 size--;
  338         }
  339 
  340         if ((offset & 1) || ((u_long)p & 1)) {
  341                 bus_space_read_region_1(sc->bt, sc->bh, offset, p, size);
  342                 return;
  343         }
  344 
  345         help = size / 2;
  346         bus_space_read_region_2(sc->bt, sc->bh, offset, p, help);
  347         if (2 * help == size)
  348                 return;
  349 
  350         offset += 2 * help;
  351         p = (u_int16_t *)p + help;
  352         *(u_int8_t *)p = bus_space_read_1(sc->bt, sc->bh, offset);
  353 }
  354 
  355 /*
  356  * Copy from kernel space to board memory.
  357  */
  358 void
  359 ie_memcopyout(sc, p, offset, size)
  360         struct ie_softc *sc;
  361         const void *p;
  362         int offset;
  363         size_t size;
  364 {
  365         size_t help;
  366 
  367         if ((offset & 1) && ((u_long)p & 1) && size > 0) {
  368                 bus_space_write_1(sc->bt, sc->bh, offset, *(u_int8_t *)p);
  369                 offset++;
  370                 p = (u_int8_t *)p + 1;
  371                 size--;
  372         }
  373 
  374         if ((offset & 1) || ((u_long)p & 1)) {
  375                 bus_space_write_region_1(sc->bt, sc->bh, offset, p, size);
  376                 return;
  377         }
  378 
  379         help = size / 2;
  380         bus_space_write_region_2(sc->bt, sc->bh, offset, p, help);
  381         if (2 * help == size)
  382                 return;
  383 
  384         offset += 2 * help;
  385         p = (u_int16_t *)p + help;
  386         bus_space_write_1(sc->bt, sc->bh, offset, *(u_int8_t *)p);
  387 }
  388 
  389 /* read a 16-bit value at BH offset */
  390 u_int16_t ie_vme_read16 __P((struct ie_softc *, int offset));
  391 /* write a 16-bit value at BH offset */
  392 void ie_vme_write16 __P((struct ie_softc *, int offset, u_int16_t value));
  393 void ie_vme_write24 __P((struct ie_softc *, int offset, int addr));
  394 
  395 u_int16_t
  396 ie_vme_read16(sc, offset)
  397         struct ie_softc *sc;
  398         int offset;
  399 {
  400         u_int16_t v;
  401 
  402         bus_space_barrier(sc->bt, sc->bh, offset, 2, BUS_SPACE_BARRIER_READ);
  403         v = bus_space_read_2(sc->bt, sc->bh, offset);
  404         return (((v&0xff)<<8) | ((v>>8)&0xff));
  405 }
  406 
  407 void
  408 ie_vme_write16(sc, offset, v)
  409         struct ie_softc *sc;    
  410         int offset;
  411         u_int16_t v;
  412 {
  413         int v0 = ((((v)&0xff)<<8) | (((v)>>8)&0xff));
  414         bus_space_write_2(sc->bt, sc->bh, offset, v0);
  415         bus_space_barrier(sc->bt, sc->bh, offset, 2, BUS_SPACE_BARRIER_WRITE);
  416 }
  417 
  418 void
  419 ie_vme_write24(sc, offset, addr)
  420         struct ie_softc *sc;    
  421         int offset;
  422         int addr;
  423 {
  424         u_char *f = (u_char *)&addr;
  425         u_int16_t v0, v1;
  426         u_char *t;
  427 
  428         t = (u_char *)&v0;
  429         t[0] = f[3]; t[1] = f[2];
  430         bus_space_write_2(sc->bt, sc->bh, offset, v0);
  431 
  432         t = (u_char *)&v1;
  433         t[0] = f[1]; t[1] = 0;
  434         bus_space_write_2(sc->bt, sc->bh, offset+2, v1);
  435 
  436         bus_space_barrier(sc->bt, sc->bh, offset, 4, BUS_SPACE_BARRIER_WRITE);
  437 }
  438 
  439 int
  440 ie_vme_match(parent, cf, aux)
  441         struct device *parent;
  442         struct cfdata *cf;
  443         void *aux;
  444 {
  445         struct vme_attach_args *va = aux;
  446         vme_chipset_tag_t ct = va->va_vct;
  447         vme_am_t mod;
  448         int error;
  449 
  450         if (va->numcfranges < 2) {
  451                 printf("ie_vme_match: need 2 ranges\n");
  452                 return (0);
  453         }
  454         if ((va->r[1].offset & 0xff0fffff) ||
  455             ((va->r[0].offset & 0xfff00000)
  456              != (va->r[1].offset & 0xfff00000))) {
  457                 printf("ie_vme_match: base address mismatch\n");
  458                 return (0);
  459         }
  460         if (va->r[0].size != VMECF_LEN_DEFAULT &&
  461             va->r[0].size != sizeof(sizeof(struct ievme))) {
  462                 printf("ie_vme_match: bad csr size\n");
  463                 return (0);
  464         }
  465         if (va->r[1].size == VMECF_LEN_DEFAULT) {
  466                 printf("ie_vme_match: must specify memory size\n");
  467                 return (0);
  468         }
  469 
  470         mod = 0x3d; /* VME_AM_A24|VME_AM_MBO|VME_AM_SUPER|VME_AM_DATA */
  471 
  472         if (va->r[0].am != VMECF_AM_DEFAULT &&
  473             va->r[0].am != mod)
  474                 return (0);
  475 
  476         if (vme_space_alloc(va->va_vct, va->r[0].offset,
  477                             sizeof(struct ievme), mod))
  478                 return (0);
  479         if (vme_space_alloc(va->va_vct, va->r[1].offset,
  480                             va->r[1].size, mod)) {
  481                 vme_space_free(va->va_vct, va->r[0].offset,
  482                                sizeof(struct ievme), mod);
  483                 return (0);
  484         }
  485         error = vme_probe(ct, va->r[0].offset, 2, mod, VME_D16, 0, 0);
  486         vme_space_free(va->va_vct, va->r[0].offset, sizeof(struct ievme), mod);
  487         vme_space_free(va->va_vct, va->r[1].offset, va->r[1].size, mod);
  488 
  489         return (error == 0);
  490 }
  491 
  492 void
  493 ie_vme_attach(parent, self, aux)
  494         struct device *parent;
  495         struct device *self;
  496         void   *aux;
  497 {
  498         u_int8_t myaddr[ETHER_ADDR_LEN];
  499         struct ie_vme_softc *vsc = (void *) self;
  500         struct vme_attach_args *va = aux;
  501         vme_chipset_tag_t ct = va->va_vct;
  502         struct ie_softc *sc;
  503         vme_intr_handle_t ih;
  504         vme_addr_t rampaddr;
  505         vme_size_t memsize;
  506         vme_mapresc_t resc;
  507         int lcv;
  508 
  509         vme_am_t mod;
  510 
  511         /*
  512          * *note*: we don't detect the difference between a VME3E and
  513          * a multibus/vme card.   if you want to use a 3E you'll have
  514          * to fix this.
  515          */
  516         mod = 0x3d; /* VME_AM_A24|VME_AM_MBO|VME_AM_SUPER|VME_AM_DATA */
  517         if (vme_space_alloc(va->va_vct, va->r[0].offset,
  518                             sizeof(struct ievme), mod) ||
  519             vme_space_alloc(va->va_vct, va->r[1].offset,
  520                             va->r[1].size, mod))
  521                 panic("if_ie: vme alloc");
  522 
  523         sc = &vsc->ie;
  524 
  525         sc->hwreset = ie_vmereset;
  526         sc->hwinit = ie_vmerun;
  527         sc->chan_attn = ie_vmeattend;
  528         sc->intrhook = ie_vmeintr;
  529         sc->memcopyout = ie_memcopyout;
  530         sc->memcopyin = ie_memcopyin;
  531 
  532         sc->ie_bus_barrier = NULL;
  533         sc->ie_bus_read16 = ie_vme_read16;
  534         sc->ie_bus_write16 = ie_vme_write16;
  535         sc->ie_bus_write24 = ie_vme_write24;
  536 
  537         memsize = va->r[1].size;
  538 
  539         if (vme_space_map(ct, va->r[0].offset, sizeof(struct ievme), mod,
  540                           VME_D16 | VME_D8, 0,
  541                           &vsc->ievt, &vsc->ievh, &resc) != 0)
  542                 panic("if_ie: vme map csr");
  543 
  544         rampaddr = va->r[1].offset;
  545 
  546         /* 4 more */
  547         rampaddr = rampaddr | ((read_iev(vsc, status) & IEVME_HADDR) << 16);
  548         if (vme_space_map(ct, rampaddr, memsize, mod, VME_D16 | VME_D8, 0,
  549                           &sc->bt, &sc->bh, &resc) != 0)
  550                 panic("if_ie: vme map mem");
  551 
  552         write_iev(vsc, pectrl, read_iev(vsc, pectrl) | IEVME_PARACK);
  553 
  554         /*
  555          * Set up mappings, direct map except for last page
  556          * which is mapped at zero and at high address (for scp)
  557          */
  558         for (lcv = 0; lcv < IEVME_MAPSZ - 1; lcv++)
  559                 write_iev(vsc, pgmap[lcv], IEVME_SBORDR | IEVME_OBMEM | lcv);
  560         write_iev(vsc, pgmap[IEVME_MAPSZ - 1], IEVME_SBORDR | IEVME_OBMEM | 0);
  561 
  562         /* Clear all ram */
  563         bus_space_set_region_2(sc->bt, sc->bh, 0, 0, memsize/2);
  564 
  565         /*
  566          * We use the first page to set up SCP, ICSP and SCB data
  567          * structures. The remaining pages become the buffer area
  568          * (managed in i82586.c).
  569          * SCP is in double-mapped page, so the 586 can see it at
  570          * the mandatory magic address (IE_SCP_ADDR).
  571          */
  572         sc->scp = (IE_SCP_ADDR & (IEVME_PAGESIZE - 1));
  573 
  574         /* iscp at location zero */
  575         sc->iscp = 0;
  576 
  577         /* scb follows iscp */
  578         sc->scb = IE_ISCP_SZ;
  579 
  580         ie_vme_write16(sc, IE_ISCP_SCB((long)sc->iscp), sc->scb);
  581         ie_vme_write16(sc, IE_ISCP_BASE((u_long)sc->iscp), 0);
  582         ie_vme_write24(sc, IE_SCP_ISCP((u_long)sc->scp), 0);
  583 
  584         if (i82586_proberam(sc) == 0) {
  585                 printf(": memory probe failed\n");
  586                 return;
  587         }
  588 
  589         /*
  590          * Rest of first page is unused; rest of ram for buffers.
  591          */
  592         sc->buf_area = IEVME_PAGESIZE;
  593         sc->buf_area_sz = memsize - IEVME_PAGESIZE;
  594 
  595         sc->do_xmitnopchain = 0;
  596 
  597         printf("\n%s:", self->dv_xname);
  598 
  599 #ifdef __sparc__
  600         prom_getether(0, myaddr);
  601 #endif
  602         i82586_attach(sc, "multibus/vme", myaddr, media, NMEDIA, media[0]);
  603 
  604         vme_intr_map(ct, va->ilevel, va->ivector, &ih);
  605         vme_intr_establish(ct, ih, IPL_NET, i82586_intr, sc);
  606 }

Cache object: fc2c4ee2720f7d96a22c4aa35aa4d6e7


[ 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.