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/chips/lance_mapped.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  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        lance_mapped.c,v $
   29  * Revision 2.21  93/05/15  19:36:50  mrt
   30  *      machparam.h -> machspl.h
   31  * 
   32  * Revision 2.20  93/05/10  20:08:11  rvb
   33  *      No more sys/types.h.
   34  *      [93/05/06  09:52:53  af]
   35  * 
   36  * Revision 2.19  93/03/26  17:58:07  mrt
   37  *      Removed dev_t, minor();
   38  *      [93/03/17            af]
   39  * 
   40  * Revision 2.18  93/03/11  14:06:09  danner
   41  *      eliminate u_long.
   42  *      [93/03/09            danner]
   43  * 
   44  * Revision 2.17  93/02/05  08:18:50  danner
   45  *      Include fixes.
   46  *      [93/02/04            danner]
   47  * 
   48  * Revision 2.16  93/02/01  09:55:15  danner
   49  *      Put return types on some functions to quiet warnings.
   50  *      [93/01/25            jfriedl]
   51  * 
   52  * Revision 2.15  93/01/14  17:16:46  danner
   53  *      corrected typo.
   54  *      [93/01/12            danner]
   55  *      Added LUNA88K and portability support.
   56  *      [92/12/02            jfriedl]
   57  *      Proper spl typing.
   58  *      [92/11/30            af]
   59  * 
   60  * Revision 2.14  92/01/03  20:39:03  dbg
   61  *      No need to destroy/init the eventcounter all the time.
   62  *      [91/12/27            af]
   63  * 
   64  *      Since we are actually using this, made user-safe.
   65  *      [91/12/27            af]
   66  * 
   67  * Revision 2.13  91/12/13  14:54:23  jsb
   68  *      Use eventcounters.
   69  *      [91/12/12  17:43:08  af]
   70  * 
   71  * Revision 2.12  91/08/24  11:52:17  af
   72  *      Bugfix: typos, spl for 3min.
   73  *      [91/08/02  01:52:26  af]
   74  * 
   75  * Revision 2.11  91/06/25  20:54:03  rpd
   76  *      Tweaks to make gcc happy.
   77  * 
   78  * Revision 2.10  91/06/19  15:19:40  rvb
   79  *      mips->DECSTATION; vax->VAXSTATION
   80  *      [91/06/12  14:01:45  rvb]
   81  * 
   82  *      File moved here from mips/PMAX since it tries to be generic;
   83  *      it is used on the PMAX and could be used on the Vax3100.
   84  *      [91/06/04            rvb]
   85  * 
   86  * Revision 2.9  91/05/14  17:22:24  mrt
   87  *      Correcting copyright
   88  * 
   89  * Revision 2.8  91/03/16  14:54:00  rpd
   90  *      Picked up a further spl fix from Sandro.
   91  *      [91/03/09            rpd]
   92  *      Updated for new kmem_alloc interface.
   93  *      [91/03/03            rpd]
   94  *      Removed thread_swappable.
   95  *      [91/01/18            rpd]
   96  * 
   97  * Revision 2.7  91/02/14  14:34:16  mrt
   98  *      In interrupt routine, drop priority as now required.
   99  *      Also sanity check for spurious interrupts anyways.
  100  *      [91/02/12  12:41:46  af]
  101  * 
  102  * Revision 2.6  91/02/05  17:41:22  mrt
  103  *      Added author notices
  104  *      [91/02/04  11:13:58  mrt]
  105  * 
  106  *      Changed to use new Mach copyright
  107  *      [91/02/02  12:12:01  mrt]
  108  * 
  109  * Revision 2.5  90/12/05  23:31:33  af
  110  *      Cleanups.
  111  *      [90/12/03  23:20:13  af]
  112  * 
  113  * Revision 2.3.1.1  90/10/03  12:06:02  af
  114  *      Made it work with multiple ether boards (e.g. thick ether
  115  *      on 3maxen).  This is the first time a mapped device does
  116  *      something before the un-mapped one..
  117  * 
  118  * Revision 2.3  90/09/09  23:52:11  rpd
  119  *      Changed thread_resume_from_kernel to thread_resume.
  120  * 
  121  * Revision 2.2  90/09/09  23:20:35  rpd
  122  *      Correctly return the ram size for the givem machine: 3maxen
  123  *      have twice as much ram as pmaxen.
  124  *      [90/09/09  18:59:41  af]
  125  * 
  126  *      Created.
  127  *      [90/08/22            af]
  128  */
  129 /*
  130  *      File: if_se_mapped.c
  131  *      Author: Alessandro Forin, Carnegie Mellon University
  132  *      Date:   8/90
  133  *
  134  *      In-kernel side of the user-mapped ethernet driver.
  135  */
  136 
  137 #include <ln.h>
  138 #if     NLN > 0
  139 #include <platforms.h>
  140 
  141 #include <mach/machine/vm_types.h>
  142 #include <machine/machspl.h>            /* spl definitions */
  143 #include <chips/lance.h>
  144 #include <chips/busses.h>
  145 
  146 #include <device/device_types.h>
  147 #include <device/errno.h>
  148 #include <device/io_req.h>
  149 #include <device/net_status.h>
  150 #include <device/net_io.h>
  151 #include <device/if_hdr.h>
  152 #include <device/if_ether.h>
  153 
  154 #include <vm/vm_kern.h>
  155 #include <kern/eventcount.h>
  156 
  157 #include <machine/machspl.h>
  158 
  159 #ifdef  DECSTATION
  160 
  161 #define machine_btop    mips_btop
  162 
  163 #define kvctophys(v)    K0SEG_TO_PHYS((v))      /* kernel virtual cached */
  164 #define phystokvc(p)    PHYS_TO_K0SEG((p))      /* and back */
  165 #define kvutophys(v)    K1SEG_TO_PHYS((v))      /* kernel virtual uncached */
  166 #define phystokvu(p)    PHYS_TO_K1SEG((p))      /* and back */
  167         /* remap from k2 to k0 */
  168 #define kvirt(v)        ((phystokvc(pmap_extract(pmap_kernel(),v))))
  169 
  170 #include <mips/mips_cpu.h>
  171 /*
  172  * Wired addresses and sizes
  173  */
  174 #define SE0_REG_EMRG    (se_reg_t)(0xb8000000)
  175 
  176 #define REGBASE(unit)   (((u_int)SE_statii[unit].registers) - se_sw->regspace)
  177 
  178 #define SE_REG_PHYS(unit)       kvutophys(REGBASE(unit)+se_sw->regspace)
  179 #define SE_REG_SIZE             PAGE_SIZE
  180 
  181 #define SE_BUF_PHYS(unit)       kvutophys(REGBASE(unit)+se_sw->bufspace)
  182 #define SE_BUF_SIZE             (128*1024)
  183 
  184 #define SE_ADR_PHYS(unit)       kvutophys(REGBASE(unit)+se_sw->romspace)
  185 #define SE_ADR_SIZE             PAGE_SIZE
  186 #endif  /*DECSTATION*/
  187 
  188 #ifdef  VAXSTATION
  189 #define machine_btop    vax_btop
  190 #endif  /*VAXSTATION*/
  191 
  192 #ifdef LUNA88K
  193 #  define machine_btop          m88k_btop
  194 #  define kvirt(v)              (v)
  195 #  define kvctophys(v)          pmap_extract(pmap_kernel(),(v))
  196 #  define SE0_REG_EMRG          ((se_reg_t)0xF1000000U)
  197 #  define REGBASE(unit) (((u_int)SE_statii[unit].registers) - se_sw->regspace)
  198 #  define SE_REG_PHYS(unit)     (REGBASE(unit) + se_sw->regspace)
  199 #  define SE_REG_SIZE           PAGE_SIZE
  200 #  define SE_BUF_PHYS(unit)     (REGBASE(unit) + se_sw->bufspace)
  201 #  define SE_BUF_SIZE           (64*1024)
  202 #  define SE_ADR_PHYS(unit)     kvctophys(REGBASE(unit) + se_sw->romspace)
  203 #  define SE_ADR_SIZE           PAGE_SIZE
  204 #  define wbflush()     /*empty*/
  205 #endif /*LUNA88K*/
  206 
  207 /*
  208  * Autoconf info
  209  */
  210 
  211 static  vm_offset_t SEstd[NLN] = { 0 };
  212 static  struct bus_device *SEinfo[NLN];
  213         void SE_attach();
  214         int SE_probe();
  215 
  216 struct bus_driver SEdriver =
  217        { SE_probe, 0, SE_attach, 0, SEstd, "SE", SEinfo, };
  218 
  219 /*
  220  * Externally visible functions
  221  */
  222 int             SE_probe();             /* Kernel */
  223 void            SE_intr(), SE_portdeath();
  224                                                 /* User */
  225 int             SE_open(), SE_close();
  226 vm_offset_t     SE_mmap();
  227 
  228 
  229 /* forward declarations */
  230 
  231 static void SE_stop(unsigned int unit);
  232 
  233 /*
  234  * Status information for all interfaces
  235  */
  236 /*static*/ struct SE_status {
  237         se_reg_t                         registers;
  238         mapped_ether_info_t              info;
  239         struct evc                       eventcounter;
  240 } SE_statii[NLN];
  241 
  242 
  243 /*
  244  * Probe the Lance to see (if) that it's there
  245  */
  246 int
  247 SE_probe(regbase, ui)
  248         vm_offset_t regbase;
  249         register struct bus_device *ui;
  250 {
  251         int                     unit = ui->unit;
  252         se_reg_t                regs;
  253         vm_offset_t             addr;
  254         mapped_ether_info_t     info;
  255         struct SE_status        *self;
  256 
  257 
  258         if (unit >= NLN)
  259                 return 0;
  260 
  261         self = &SE_statii[unit];
  262 
  263         printf("[mappable] ");
  264 
  265         regs = (se_reg_t) (regbase + se_sw->regspace);
  266         self->registers = regs;
  267 
  268         /*
  269          * Reset the interface 
  270          */
  271         SE_stop(unit);
  272 
  273         /*
  274          * Grab a page to be mapped later to users 
  275          */
  276         (void) kmem_alloc_wired(kernel_map, &addr, PAGE_SIZE);  
  277         /* 
  278           on the decstation, kmem_alloc_wired returns virtual addresses
  279           in the k2 seg. Since this page is going to get mapped in
  280           user space, we need to transform it to a better understood
  281           virtual address. The kvirt function does this.
  282         */
  283         bzero(addr, PAGE_SIZE);
  284         info = (mapped_ether_info_t) kvirt(addr);
  285         self->info = info;
  286 
  287         /*
  288          * Set permanent info
  289          */
  290         info->rom_stride = se_sw->romstride;
  291         info->ram_stride = se_sw->ramstride;
  292         info->buffer_size = se_sw->ramsize;
  293         info->buffer_physaddr = se_sw->ln_bufspace;
  294 
  295         /*
  296          * Synch setup
  297          */
  298         evc_init(&self->eventcounter);
  299         info->wait_event = self->eventcounter.ev_id;
  300 
  301         return 1;
  302 }
  303 
  304 void
  305 SE_attach(ui)
  306         register struct bus_device *ui;
  307 {
  308 }
  309  
  310 
  311 /*
  312  * Shut off the lance
  313  */
  314 static void SE_stop(unsigned int unit)
  315 {
  316         register se_reg_t       regs = SE_statii[unit].registers;
  317 
  318         if (regs == 0)
  319                 /* Stray interrupt */
  320                 regs = SE0_REG_EMRG;
  321 
  322         regs[2] = CSR0_SELECT;  /* XXXX rap XXXX */
  323         wbflush();
  324         regs[0] = LN_CSR0_STOP;
  325         wbflush();
  326 }
  327 
  328 
  329 /*
  330  * Ethernet interface interrupt routine
  331  */
  332 void SE_intr(unit,spllevel)
  333         int     unit;
  334         spl_t   spllevel;
  335 {
  336         register struct SE_status *self = &SE_statii[unit];
  337         register se_reg_t          regs = self->registers;
  338         register                   csr;
  339 
  340         if (regs == 0) {        /* stray */
  341                 SE_stop(unit);
  342                 return;
  343         }
  344 
  345         /* Acknowledge interrupt request, drop spurious intr */
  346         csr = regs[0];
  347         if ((csr & LN_CSR0_INTR) == 0)
  348                 return;
  349         regs[0] = csr & LN_CSR0_WTC;            /* silence it */
  350 
  351         splx(spllevel); /* drop priority now */
  352 
  353         /* Pass csr state up to user thread */
  354         if (self->info) {
  355                 self->info->interrupt_count++;  /* total interrupts */
  356                 self->info->saved_csr0 = csr;
  357         }
  358 
  359         /* Awake user thread */
  360         evc_signal(&self->eventcounter);
  361 }
  362  
  363 
  364 extern boolean_t se_use_mapped_interface[NLN];
  365 
  366 /*
  367  * Device open procedure
  368  */
  369 int SE_open(dev, flag, ior)
  370         io_req_t ior;
  371 {
  372         int             unit = dev;
  373         register struct SE_status *self = &SE_statii[unit];
  374 
  375         if (unit >= NLN)
  376                 return EINVAL;
  377 
  378         /*
  379          * Silence interface, just in case 
  380          */
  381         SE_stop(unit);
  382 
  383         /*
  384          * Reset eventcounter
  385          */
  386         evc_signal(&self->eventcounter);
  387 
  388         se_use_mapped_interface[unit] = 1;
  389 
  390         /*
  391          * Do not turn Ether interrupts on.  The user can do it when ready
  392          * to take them. 
  393          */
  394 
  395         return 0;
  396 }
  397 
  398 /*
  399  * Device close procedure
  400  */
  401 int SE_close(dev, flag)
  402 {
  403         int             unit = dev;
  404         register struct SE_status *self = &SE_statii[unit];
  405 
  406         if (unit >= NLN)
  407                 return EINVAL;
  408 
  409         /*
  410          * Silence interface, in case user forgot
  411          */
  412         SE_stop(unit);
  413         evc_signal(&self->eventcounter);
  414 
  415         se_normal(unit);
  416 
  417         return 0;
  418 }
  419 
  420 
  421 /*
  422  * Get status procedure.
  423  * We need to tell that we are mappable.
  424  */
  425 io_return_t
  426 SE_get_status(ifp, flavor, status, status_count)
  427 /*      struct ifnet    *ifp; not really..*/
  428         int             flavor;
  429         dev_status_t    status;         /* pointer to OUT array */
  430         unsigned int    *status_count;          /* OUT */
  431 {
  432         switch (flavor) {
  433             case NET_STATUS:
  434             {
  435                 register struct net_status *ns = (struct net_status *)status;
  436 
  437                 ns->min_packet_size = sizeof(struct ether_header);
  438                 ns->max_packet_size = sizeof(struct ether_header) + ETHERMTU;
  439                 ns->header_format   = HDR_ETHERNET;
  440                 ns->header_size     = sizeof(struct ether_header);
  441                 ns->address_size    = 6;
  442                 ns->flags           = IFF_BROADCAST;
  443                 ns->mapped_size     = SE_BUF_SIZE + (3 * PAGE_SIZE);
  444 
  445                 *status_count = NET_STATUS_COUNT;
  446                 break;
  447             }
  448 /*          case NET_ADDRESS:   find it yourself */
  449             default:
  450                 return (D_INVALID_OPERATION);
  451         }
  452         return (D_SUCCESS);
  453 }
  454 
  455 /*
  456  * Should not refuse this either
  457  */
  458 int SE_set_status(dev, flavor, status, status_count)
  459         int             dev;
  460         int             flavor;
  461         dev_status_t    status;
  462         unsigned int    status_count;
  463 {
  464         return (D_SUCCESS);
  465 }
  466 
  467 /*
  468  * Port death notification routine
  469  */
  470 void SE_portdeath(dev, dead_port)
  471 {
  472 }
  473 
  474 
  475 /*
  476  * Virtual->physical mapping routine.
  477  */
  478 vm_offset_t
  479 SE_mmap(dev, off, prot)
  480         int             dev;
  481         vm_offset_t     off;
  482         vm_prot_t       prot;
  483 {
  484         vm_offset_t     page;
  485         vm_offset_t     addr;
  486         int             unit = dev;
  487 
  488         /*
  489          * The offset (into the VM object) defines the following layout
  490          *
  491          *      off     size    what
  492          *      0       1pg     mapping information (csr & #interrupts)
  493          *      1pg     1pg     lance registers
  494          *      2pg     1pg     lance station address (ROM)
  495          *      3pg     128k    lance buffers 
  496          */
  497 #define S0      PAGE_SIZE
  498 #define S1      (S0+SE_REG_SIZE)
  499 #define S2      (S1+SE_ADR_SIZE)
  500 #define S3      (S2+SE_BUF_SIZE)
  501 
  502         if (off < S0) {
  503                 addr = kvctophys (SE_statii[unit].info);
  504         } else if (off < S1) {
  505                 addr = (vm_offset_t) SE_REG_PHYS(unit);
  506                 off -= S0;
  507         } else if (off < S2) {
  508                 addr = (vm_offset_t) SE_ADR_PHYS(unit);
  509                 off -= S1;
  510         } else if (off < S3) {
  511                 addr = (vm_offset_t) SE_BUF_PHYS(unit);
  512                 off -= S2;
  513         } else
  514                 return (EINVAL);
  515 
  516         page = machine_btop(addr + off);
  517         return (page);
  518 }
  519 
  520 #endif  NLN > 0

Cache object: 181ff8ddd4506f81c2ad9602b930b98e


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