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/mips/rmi/pcibus.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  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Exp $");
   29 
   30 #include "opt_isa.h"
   31 
   32 #define __RMAN_RESOURCE_VISIBLE
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/lock.h>
   37 #include <sys/mutex.h>
   38 #include <sys/module.h>
   39 #include <sys/proc.h>
   40 #include <sys/bus.h>
   41 
   42 #include <vm/vm.h>
   43 #include <vm/vm_param.h>
   44 #include <vm/pmap.h>
   45 
   46 #include <machine/bus.h>
   47 #include <machine/pmap.h>
   48 #include <sys/interrupt.h>
   49 #include <sys/sysctl.h>
   50 #include <mips/rmi/iomap.h>
   51 #include <mips/rmi/pic.h>
   52 #include <mips/rmi/shared_structs.h>
   53 #include <mips/rmi/board.h>
   54 #include <sys/rman.h>
   55 
   56 #include <dev/pci/pcivar.h>
   57 #include <machine/resource.h>
   58 #include <machine/md_var.h>
   59 #include <machine/intr_machdep.h>
   60 #include <mips/rmi/pcibus.h>
   61 /*
   62 static void bridge_pcix_ack(void *);
   63 static void bridge_pcie_ack(void *);
   64 static void pic_pcix_ack(void *);
   65 static void pic_pcie_ack(void *);
   66 */
   67 
   68 extern vm_map_t kernel_map;
   69 vm_offset_t kmem_alloc_nofault(vm_map_t map, vm_size_t size);
   70 
   71 
   72 int
   73 mips_pci_route_interrupt(device_t bus, device_t dev, int pin)
   74 {
   75         /*
   76          * Validate requested pin number.
   77          */
   78         if ((pin < 1) || (pin > 4))
   79                 return (255);
   80 
   81         if (xlr_board_info.is_xls) {
   82                 switch (pin) {
   83                 case 1:
   84                         return PIC_PCIE_LINK0_IRQ;
   85                 case 2:
   86                         return PIC_PCIE_LINK1_IRQ;
   87                 case 3:
   88                         return PIC_PCIE_LINK2_IRQ;
   89                 case 4:
   90                         return PIC_PCIE_LINK3_IRQ;
   91                 }
   92         } else {
   93                 if (pin == 1) {
   94                         return (16);
   95                 }
   96         }
   97 
   98         return (255);
   99 }
  100 
  101 static struct rman irq_rman, port_rman, mem_rman;
  102 
  103 /*
  104 static void bridge_pcix_ack(void *arg)
  105 {
  106         xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2);
  107         }
  108 */
  109 /*
  110 static void bridge_pcie_ack(void *arg)
  111 {
  112         int irq = (int)arg;
  113         uint32_t reg;
  114         xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
  115 
  116         switch (irq) {
  117         case PIC_PCIE_LINK0_IRQ : reg = PCIE_LINK0_MSI_STATUS; break;
  118         case PIC_PCIE_LINK1_IRQ : reg = PCIE_LINK1_MSI_STATUS; break;
  119         case PIC_PCIE_LINK2_IRQ : reg = PCIE_LINK2_MSI_STATUS; break;
  120         case PIC_PCIE_LINK3_IRQ : reg = PCIE_LINK3_MSI_STATUS; break;
  121         default:
  122                 return;
  123         }
  124 
  125         xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff);
  126 }
  127 */
  128 /*
  129 static void pic_pcix_ack(void *none)
  130 {
  131         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
  132         
  133         mtx_lock_spin(&xlr_pic_lock);
  134         xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX));
  135         mtx_unlock_spin(&xlr_pic_lock);
  136 }
  137 */
  138 /*
  139 static void pic_pcie_ack(void *arg)
  140 {
  141         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
  142         int irq = (int) arg;
  143 
  144         mtx_lock_spin(&xlr_pic_lock);
  145         xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
  146         mtx_unlock_spin(&xlr_pic_lock);
  147 }
  148 
  149 */
  150 
  151 int
  152 mips_platform_pci_setup_intr(device_t dev, device_t child,
  153     struct resource *irq, int flags,
  154     driver_filter_t * filt,
  155     driver_intr_t * intr, void *arg,
  156     void **cookiep)
  157 {
  158         int level;
  159         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
  160         int error = 0;
  161         int xlrirq;
  162 
  163         error = rman_activate_resource(irq);
  164         if (error)
  165                 return error;
  166         if (rman_get_start(irq) != rman_get_end(irq)) {
  167                 device_printf(dev, "Interrupt allocation %lu != %lu\n",
  168                     rman_get_start(irq), rman_get_end(irq));
  169                 return EINVAL;
  170         }
  171         xlrirq = rman_get_start(irq);
  172         if (strcmp(device_get_name(dev), "pcib") != 0)
  173                 return 0;
  174 
  175         if (xlr_board_info.is_xls == 0) {
  176         
  177                 if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock);
  178                 level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX);
  179                 xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01);
  180                 xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level << 30) |
  181                     (1 << 6) | (PIC_PCIX_IRQ)));
  182                 if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock);
  183                 cpu_establish_hardintr(device_get_name(child), filt,
  184                     (driver_intr_t *) intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep);
  185 
  186         } else {
  187                 if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock);
  188                 xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01);
  189                 xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE,
  190                     ((1 << 31) | (1 << 30) | (1 << 6) | xlrirq));
  191                 if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock);
  192 
  193                 if (flags & INTR_FAST)
  194                         cpu_establish_hardintr(device_get_name(child), filt,
  195                             (driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep);
  196                 else
  197                         cpu_establish_hardintr(device_get_name(child), filt,
  198                             (driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep);
  199 
  200 
  201         }
  202         return bus_generic_setup_intr(dev, child, irq, flags, filt, intr,
  203             arg, cookiep);
  204 }
  205 
  206 
  207 int
  208 mips_platform_pci_teardown_intr(device_t dev, device_t child,
  209     struct resource *irq, void *cookie);
  210 int
  211 mips_platform_pci_teardown_intr(device_t dev, device_t child,
  212     struct resource *irq, void *cookie)
  213 {
  214         if (strcmp(device_get_name(child), "pci") == 0) {
  215                 /* if needed reprogram the pic to clear pcix related entry */
  216         }
  217         return bus_generic_teardown_intr(dev, child, irq, cookie);
  218 }
  219 
  220 void
  221 pci_init_resources(void)
  222 {
  223         irq_rman.rm_start = 0;
  224         irq_rman.rm_end = 255;
  225         irq_rman.rm_type = RMAN_ARRAY;
  226         irq_rman.rm_descr = "PCI Mapped Interrupts";
  227         if (rman_init(&irq_rman)
  228             || rman_manage_region(&irq_rman, 0, 255))
  229                 panic("pci_init_resources irq_rman");
  230 
  231         port_rman.rm_start = 0;
  232         port_rman.rm_end = ~0u;
  233         port_rman.rm_type = RMAN_ARRAY;
  234         port_rman.rm_descr = "I/O ports";
  235         if (rman_init(&port_rman)
  236             || rman_manage_region(&port_rman, 0x10000000, 0x1fffffff))
  237                 panic("pci_init_resources port_rman");
  238 
  239         mem_rman.rm_start = 0;
  240         mem_rman.rm_end = ~0u;
  241         mem_rman.rm_type = RMAN_ARRAY;
  242         mem_rman.rm_descr = "I/O memory";
  243         if (rman_init(&mem_rman)
  244             || rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff))
  245                 panic("pci_init_resources mem_rman");
  246 }
  247 
  248 /* hack from bus.h in mips/include/bus.h */
  249 #ifndef MIPS_BUS_SPACE_PCI
  250 #define MIPS_BUS_SPACE_PCI 10
  251 #endif
  252 
  253 struct resource *
  254 xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
  255     u_long start, u_long end, u_long count, u_int flags)
  256 {
  257         struct rman *rm;
  258         struct resource *rv;
  259         vm_offset_t va;
  260         int needactivate = flags & RF_ACTIVE;
  261 
  262 #if 0
  263         device_printf(bus, "xlr_pci_alloc_resource : child %s, type %d, start %lx end %lx, count %lx, flags %x\n",
  264             device_get_nameunit(child), type, start, end, count, flags);
  265 #endif
  266 
  267         switch (type) {
  268         case SYS_RES_IRQ:
  269                 rm = &irq_rman;
  270                 break;
  271 
  272         case SYS_RES_IOPORT:
  273                 rm = &port_rman;
  274                 break;
  275 
  276         case SYS_RES_MEMORY:
  277                 rm = &mem_rman;
  278                 break;
  279 
  280         default:
  281                 return 0;
  282         }
  283 
  284         rv = rman_reserve_resource(rm, start, end, count, flags, child);
  285         if (rv == 0)
  286                 return 0;
  287 
  288         rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI);
  289         rman_set_rid(rv, *rid);
  290 
  291         if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
  292                 /*
  293                  * if ((start + count) > (2 << 28)) { va_start =
  294                  * kmem_alloc_nofault(kernel_map, count); }
  295                  */
  296                 /*
  297                  * This called for pmap_map_uncached, but the pmap_map calls
  298                  * pmap_kenter which does a is_cacheable_mem() check and
  299                  * thus sets the PTE_UNCACHED bit. Hopefully this will work
  300                  * for this guy... RRS
  301                  */
  302                 /* va = pmap_map(&va_start, start, start + count, 0); */
  303                 va = (vm_offset_t)pmap_mapdev(start, start + count);
  304                 rman_set_bushandle(rv, va);
  305                 /* bushandle is same as virtual addr */
  306                 rman_set_virtual(rv, (void *)va);
  307                 rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI);
  308         }
  309         if (needactivate) {
  310                 if (bus_activate_resource(child, type, *rid, rv)) {
  311                         rman_release_resource(rv);
  312                         return (NULL);
  313                 }
  314         }
  315         return rv;
  316 }
  317 
  318 
  319 int
  320 pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
  321     struct resource *r)
  322 {
  323         return (rman_deactivate_resource(r));
  324 }
  325 
  326 /* now in pci.c
  327 int
  328 pci_activate_resource(device_t bus, device_t child, int type, int rid,
  329                       struct resource *r)
  330 {
  331         return (rman_activate_resource(r));
  332 }
  333 
  334 int
  335 pci_release_resource(device_t bus, device_t child, int type, int rid,
  336                        struct resource *r)
  337 {
  338         return (rman_release_resource(r));
  339 }
  340 */
  341 
  342 struct rman *
  343 pci_get_rman(device_t dev, int type)
  344 {
  345         switch (type) {
  346                 case SYS_RES_IOPORT:
  347                 return &port_rman;
  348 
  349         case SYS_RES_MEMORY:
  350                 return &mem_rman;
  351 
  352         case SYS_RES_IRQ:
  353                 return &irq_rman;
  354         }
  355 
  356         return 0;
  357 }

Cache object: e05a98fcb4f61edc6650f5b19fdaba5b


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