Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:52

0001 /* remap the zero-based PCI IO spaces of both hoses to a single
0002  * address space
0003  *
0004  * This must be called AFTER to BSP_pci_initialize()
0005  */
0006 
0007 /* 
0008  * Authorship
0009  * ----------
0010  * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
0011  *     created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
0012  *     Stanford Linear Accelerator Center, Stanford University.
0013  * 
0014  * Acknowledgement of sponsorship
0015  * ------------------------------
0016  * The 'beatnik' BSP was produced by
0017  *     the Stanford Linear Accelerator Center, Stanford University,
0018  *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
0019  * 
0020  * Government disclaimer of liability
0021  * ----------------------------------
0022  * Neither the United States nor the United States Department of Energy,
0023  * nor any of their employees, makes any warranty, express or implied, or
0024  * assumes any legal liability or responsibility for the accuracy,
0025  * completeness, or usefulness of any data, apparatus, product, or process
0026  * disclosed, or represents that its use would not infringe privately owned
0027  * rights.
0028  * 
0029  * Stanford disclaimer of liability
0030  * --------------------------------
0031  * Stanford University makes no representations or warranties, express or
0032  * implied, nor assumes any liability for the use of this software.
0033  * 
0034  * Stanford disclaimer of copyright
0035  * --------------------------------
0036  * Stanford University, owner of the copyright, hereby disclaims its
0037  * copyright and all other rights in this software.  Hence, anyone may
0038  * freely use it for any purpose without restriction.  
0039  * 
0040  * Maintenance of notices
0041  * ----------------------
0042  * In the interest of clarity regarding the origin and status of this
0043  * SLAC software, this and all the preceding Stanford University notices
0044  * are to remain affixed to any copy or derivative of this software made
0045  * or distributed by the recipient and are to be affixed to any copy of
0046  * software made or distributed by the recipient that contains a copy or
0047  * derivative of this software.
0048  * 
0049  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
0050  */ 
0051 #include <rtems.h>
0052 #include <bsp.h>
0053 #include <libcpu/io.h>
0054 #include <bsp/pci.h>
0055 #include <bsp/irq.h>
0056 #include <rtems/bspIo.h>
0057 #include <bsp/gtreg.h>
0058 #include "pci_io_remap.h"
0059 
0060 static int
0061 fixup_irq_line(int bus, int slot, int fun, void *uarg)
0062 {
0063 unsigned char line;
0064     pci_read_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, &line);
0065     if ( line < BSP_IRQ_GPP_0 ) {
0066         pci_write_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, line + BSP_IRQ_GPP_0 );
0067     }
0068 
0069     return 0;
0070 }
0071 
0072 void BSP_motload_pci_fixup(void)
0073 {
0074 uint32_t    b0,b1,r0,r1,lim,dis;
0075 
0076     /* MotLoad on the mvme5500 and mvme6100 configures the PCI
0077      * busses nicely, i.e., the values read from the memory address
0078      * space BARs by means of PCI config cycles directly reflect the
0079      * CPU memory map. Thus, the presence of two hoses is already hidden.
0080      *
0081      * Unfortunately, all PCI I/O addresses are 'zero-based' i.e.,
0082      * a hose-specific base address would have to be added to
0083      * the values read from config space.
0084      *
0085      * We fix this here so I/O BARs also reflect the CPU memory map.
0086      *
0087      * Furthermore, the mvme5500 uses
0088      *    f000.0000
0089      *  ..f07f.ffff  for PCI-0 / hose0
0090      *
0091      *  and
0092      *
0093      *    f080.0000
0094      *  ..f0ff.0000  for PCI-1 / hose 0
0095      *
0096      *  whereas the mvme6100 does it the other way round...
0097      */
0098 
0099     b0 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Low_Decode) );
0100     b1 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Low_Decode) );
0101 
0102     r0 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap) );
0103     r1 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap) );
0104 
0105     switch ( BSP_getDiscoveryVersion(0) ) {
0106         case MV_64360:
0107             /* In case of the MV64360 the 'limit' is actually a 'size'!
0108              * Disable by setting special bits in the 'BAR disable reg'.
0109              */
0110             dis = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL) );
0111             /* disable PCI0 I/O and PCI1 I/O */
0112             out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis | (1<<9) | (1<<14) );
0113             /* remap busses on hose 0; if the remap register was already set, assume
0114              * that someone else [such as the bootloader] already performed the fixup
0115              */
0116             if ( (b0 & 0xffff) && 0 == (r0 & 0xffff) ) {
0117                 rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xffff)<<16 );
0118                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xffff) );
0119             }
0120 
0121             /* remap busses on hose 1 */
0122             if ( (b1 & 0xffff) && 0 == (r1 & 0xffff) ) {
0123                 rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xffff)<<16 );
0124                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xffff) );
0125             }
0126 
0127             /* re-enable */
0128             out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis );
0129         break;
0130 
0131         case GT_64260_A:
0132         case GT_64260_B:
0133             
0134             if ( (b0 & 0xfff) && 0 == (r0 & 0xfff) ) { /* base are only 12 bits */
0135                 /* switch window off by setting the limit < base */
0136                 lim = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode) );
0137                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), 0 );
0138                 /* remap busses on hose 0 */
0139                 rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xfff)<<20 );
0140 
0141                 /* BTW: it seems that writing the base register also copies the
0142                  * value into the 'remap' register automatically (??)
0143                  */
0144                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xfff) );
0145 
0146                 /* re-enable */
0147                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), lim );
0148             }
0149 
0150             if ( (b1 & 0xfff) && 0 == (r1 & 0xfff) ) { /* base are only 12 bits */
0151                 /* switch window off by setting the limit < base */
0152                 lim = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode) );
0153                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), 0 );
0154 
0155                 /* remap busses on hose 1 */
0156                 rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xfff)<<20 );
0157 
0158                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xfff) );
0159 
0160                 /* re-enable */
0161                 out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), lim );
0162             }
0163         break;
0164 
0165         default:
0166             rtems_panic("Unknown discovery version; switch in file: "__FILE__" not implemented (yet)");
0167         break; /* never get here */
0168     }
0169 
0170     /* Fixup the IRQ lines; the mvme6100 maps them nicely into our scheme, i.e., GPP
0171      * interrupts start at 64 upwards
0172      *
0173      * The mvme5500 is apparently initialized differently :-(. GPP interrupts start at 0
0174      * Since all PCI interrupts are wired to GPP we simply check for a value < 64 and
0175      * reprogram the interrupt line register.
0176      */
0177     BSP_pciScan(0, fixup_irq_line, 0);
0178 }
0179 
0180