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*/