openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

pci.c (4514B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * PCI memory and configuration space routines.
      8  *
      9  * Under Solaris, these routines call the verinet model PLI simulation.
     10  * All PCI operations are performed talking over a socket to the model.
     11  *
     12  * NOTE: the base address used in this file is opaque. This means that
     13  * the PCI device must first have its base-address programmed by
     14  * writing the start offset to PCI configuration offset 0x10.
     15  * Writes to the memory space afterwards requires the address to be
     16  * based on the base-address plus the offset to the desire register
     17  * to be accessed.
     18  */
     19 
     20 #ifdef LINUX_PLI_COMBO_BDE
     21 /* Avoid name clash when using two BDEs */
     22 #define pci_config_getw pli_pci_config_getw
     23 #endif
     24 
     25 #include <shared/bsl.h>
     26 
     27 #include <assert.h>
     28 
     29 #include <sal/appl/io.h>
     30 #include <sal/appl/pci.h>
     31 
     32 #include "verinet.h"
     33 
     34 #ifdef SINGLE_MODE
     35 #define _SOCKLEN_T
     36 #define __socklen_t_defined
     37 #include <sim/pcid/pli.h>
     38 extern pcid_info_t pcid_info;
     39 #endif
     40 
     41 /*
     42  * NOTE:  Assume dev->devNo is the verinet unit (for now always zero).
     43  */
     44 
     45 /* In the DV model for the RTL, bit 12 selects Orion */
     46 #define IDSEL 0x1000
     47 
     48 #define VALID_DEV(dev) \
     49 	((dev)->busNo == 0 && \
     50          (dev)->devNo < pli_client_count() && \
     51          (dev)->funcNo == 0)
     52 
     53 /*
     54  * Initialize the package if not already done
     55  */
     56 
     57 int pci_init_check(void)
     58 {
     59     static int	 	pli_connected;
     60     int			client;
     61 
     62     if (! pli_connected) {
     63 	/*
     64 	 * Initialize each PLI client.
     65 	 */
     66 
     67 	for (client = 0; client < pli_client_count(); client++) {
     68 	    if (pli_client_attach(client) < 0) {
     69 		cli_out("pci_init_check: error attaching PLI client %d\n",
     70                         client);
     71 		return -1;
     72 	    }
     73 	}
     74 
     75 	pli_connected = 1;
     76     }
     77 
     78     return 0;
     79 }
     80 
     81 
     82 /*
     83  * Write a DWORD (32 bits) of data to PCI configuration space
     84  * at the specified offset.
     85  */
     86 
     87 int pci_config_putw(pci_dev_t *dev, uint32 addr, uint32 data)
     88 {
     89     if(pci_init_check() < 0)
     90         return -1;
     91 
     92     assert(! (addr & 3));
     93 
     94     if (VALID_DEV(dev))
     95 	return pli_setreg(dev->devNo, PCI_CONFIG, addr | IDSEL, data);
     96     else
     97 	return -1;
     98 }
     99 
    100 /*
    101  * Read a DWORD (32 bits) of data from PCI configuration space
    102  * at the specified offset.
    103  */
    104 
    105 uint32 pci_config_getw(pci_dev_t *dev, uint32 addr)
    106 {
    107     if (pci_init_check() < 0)
    108 	return 0xffffffff;
    109 
    110     assert(! (addr & 3));
    111 
    112     if (VALID_DEV(dev))
    113 	return pli_getreg(dev->devNo, PCI_CONFIG, addr | IDSEL);
    114     else
    115 	return 0xffffffff;
    116 }
    117 
    118 /*
    119  * Write a DWORD (32 bits) of data to PCI memory space
    120  * at the specified offset. Return last value at address.
    121  */
    122 
    123 int pci_memory_putw(pci_dev_t *dev, uint32 addr, uint32 data)
    124 {
    125     if (pci_init_check() < 0)
    126 	return -1;
    127 
    128     return pli_setreg(dev->devNo, PCI_MEMORY, addr, data);
    129 }
    130 
    131 /*
    132  * Read a DWORD (32 bits) of data from PCI memory space.
    133  */
    134 
    135 uint32 pci_memory_getw(pci_dev_t *dev, uint32 addr)
    136 {
    137     if (pci_init_check() < 0)
    138 	return 0xffffffff;
    139 
    140     return pli_getreg(dev->devNo, PCI_MEMORY, addr);
    141 }
    142 
    143 /*
    144  * pci_int_connect
    145  *
    146  *    For PLI simulation, the ISR has already been attached.
    147  */
    148 
    149 int pci_int_connect(int intLine,
    150 		    pci_isr_t isr,
    151 		    void *isr_data)
    152 {
    153     if (pci_init_check() < 0)
    154 	return -1;
    155 
    156     return pli_register_isr(intLine, isr, isr_data);
    157 }
    158 
    159 #ifdef SINGLE_MODE
    160 /********************************
    161 ***** SINGLE MODE FUNCTIONS
    162  */
    163 /*
    164  * The following function are equivalent to the above function. 
    165  * They used when using single mode (not going through the net). 
    166  */
    167 
    168 int local_config_putw(pci_dev_t *dev, uint32 addr, uint32 data)
    169 {
    170     assert(!(addr & 3)); 
    171 
    172     if (VALID_DEV(dev))
    173         return pli_setreg_service(&pcid_info, pcid_info.unit, PCI_CONFIG, addr | IDSEL, data);
    174     else
    175         return -1;
    176 }
    177 
    178 uint32 local_config_getw(pci_dev_t *dev, uint32 addr)
    179 {
    180     assert(! (addr & 3));
    181 
    182     if (VALID_DEV(dev))
    183         return pli_getreg_service(&pcid_info, pcid_info.unit, PCI_CONFIG, addr | IDSEL);
    184     else
    185         return 0xffffffff;
    186 }
    187 
    188 int local_memory_putw(pci_dev_t *dev, uint32 addr, uint32 data)
    189 {
    190     return pli_setreg_service(&pcid_info, pcid_info.unit, PCI_MEMORY, addr, data);
    191 }
    192 
    193 uint32 local_memory_getw(pci_dev_t *dev, uint32 addr)
    194 {
    195     return pli_getreg_service(&pcid_info, pcid_info.unit, PCI_MEMORY, addr);
    196 }
    197 
    198 int local_int_connect(int intLine,
    199 		    pci_isr_t isr,
    200 		    void *isr_data)
    201 {
    202     return pli_register_isr(intLine, isr, isr_data);
    203 }
    204 #endif /* !SINGLE_MODE*/