| 1 | 786 | skrzyp | //==========================================================================
 | 
      
         | 2 |  |  | //
 | 
      
         | 3 |  |  | //      uE250_pci.c
 | 
      
         | 4 |  |  | //
 | 
      
         | 5 |  |  | //      HAL support code for NMI uEngine uE250 PCI
 | 
      
         | 6 |  |  | //
 | 
      
         | 7 |  |  | //==========================================================================
 | 
      
         | 8 |  |  | // ####ECOSGPLCOPYRIGHTBEGIN####                                            
 | 
      
         | 9 |  |  | // -------------------------------------------                              
 | 
      
         | 10 |  |  | // This file is part of eCos, the Embedded Configurable Operating System.   
 | 
      
         | 11 |  |  | // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 | 
      
         | 12 |  |  | //
 | 
      
         | 13 |  |  | // eCos is free software; you can redistribute it and/or modify it under    
 | 
      
         | 14 |  |  | // the terms of the GNU General Public License as published by the Free     
 | 
      
         | 15 |  |  | // Software Foundation; either version 2 or (at your option) any later      
 | 
      
         | 16 |  |  | // version.                                                                 
 | 
      
         | 17 |  |  | //
 | 
      
         | 18 |  |  | // eCos is distributed in the hope that it will be useful, but WITHOUT      
 | 
      
         | 19 |  |  | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
 | 
      
         | 20 |  |  | // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
 | 
      
         | 21 |  |  | // for more details.                                                        
 | 
      
         | 22 |  |  | //
 | 
      
         | 23 |  |  | // You should have received a copy of the GNU General Public License        
 | 
      
         | 24 |  |  | // along with eCos; if not, write to the Free Software Foundation, Inc.,    
 | 
      
         | 25 |  |  | // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
 | 
      
         | 26 |  |  | //
 | 
      
         | 27 |  |  | // As a special exception, if other files instantiate templates or use      
 | 
      
         | 28 |  |  | // macros or inline functions from this file, or you compile this file      
 | 
      
         | 29 |  |  | // and link it with other works to produce a work based on this file,       
 | 
      
         | 30 |  |  | // this file does not by itself cause the resulting work to be covered by   
 | 
      
         | 31 |  |  | // the GNU General Public License. However the source code for this file    
 | 
      
         | 32 |  |  | // must still be made available in accordance with section (3) of the GNU   
 | 
      
         | 33 |  |  | // General Public License v2.                                               
 | 
      
         | 34 |  |  | //
 | 
      
         | 35 |  |  | // This exception does not invalidate any other reasons why a work based    
 | 
      
         | 36 |  |  | // on this file might be covered by the GNU General Public License.         
 | 
      
         | 37 |  |  | // -------------------------------------------                              
 | 
      
         | 38 |  |  | // ####ECOSGPLCOPYRIGHTEND####                                              
 | 
      
         | 39 |  |  | //==========================================================================
 | 
      
         | 40 |  |  | //#####DESCRIPTIONBEGIN####
 | 
      
         | 41 |  |  | //
 | 
      
         | 42 |  |  | // Author(s):    msalter
 | 
      
         | 43 |  |  | // Contributors: msalter, gthomas, David Mazur <david@mind.be>
 | 
      
         | 44 |  |  | // Date:         2002-01-04
 | 
      
         | 45 |  |  | // Purpose:      PCI support
 | 
      
         | 46 |  |  | // Description:  Implementations of HAL PCI interfaces
 | 
      
         | 47 |  |  | //
 | 
      
         | 48 |  |  | //####DESCRIPTIONEND####
 | 
      
         | 49 |  |  | //
 | 
      
         | 50 |  |  | //========================================================================*/
 | 
      
         | 51 |  |  |  
 | 
      
         | 52 |  |  | #include <pkgconf/hal.h>
 | 
      
         | 53 |  |  | #include <pkgconf/system.h>
 | 
      
         | 54 |  |  | #include CYGBLD_HAL_PLATFORM_H
 | 
      
         | 55 |  |  | #include CYGHWR_MEMORY_LAYOUT_H
 | 
      
         | 56 |  |  |  
 | 
      
         | 57 |  |  | #include <cyg/infra/cyg_type.h>         // base types
 | 
      
         | 58 |  |  | #include <cyg/infra/cyg_trac.h>         // tracing macros
 | 
      
         | 59 |  |  | #include <cyg/infra/cyg_ass.h>          // assertion macros
 | 
      
         | 60 |  |  | #include <cyg/infra/diag.h>             // diag_printf()
 | 
      
         | 61 |  |  |  
 | 
      
         | 62 |  |  | #include <cyg/hal/hal_io.h>             // IO macros
 | 
      
         | 63 |  |  | #include <cyg/hal/hal_if.h>             // calling interface API
 | 
      
         | 64 |  |  | #include <cyg/hal/hal_arch.h>           // Register state info
 | 
      
         | 65 |  |  | #include <cyg/hal/hal_diag.h>
 | 
      
         | 66 |  |  | #include <cyg/hal/hal_intr.h>           // Interrupt names
 | 
      
         | 67 |  |  | #include <cyg/hal/hal_cache.h>
 | 
      
         | 68 |  |  | #include <cyg/hal/plf_io.h>
 | 
      
         | 69 |  |  | #include <cyg/io/pci_hw.h>
 | 
      
         | 70 |  |  | #include <cyg/io/pci.h>
 | 
      
         | 71 |  |  |  
 | 
      
         | 72 |  |  | #ifdef CYGPKG_IO_PCI
 | 
      
         | 73 |  |  |  
 | 
      
         | 74 |  |  | #ifdef CYGSEM_HAL_LOAD_PCI_FPGA
 | 
      
         | 75 |  |  | static unsigned char uE250_pci_bitstream[] = {
 | 
      
         | 76 |  |  | #include "uE250_pci_bitstream.h"   
 | 
      
         | 77 |  |  | };
 | 
      
         | 78 |  |  | externC void load_fpga(void *bitstream, int len);
 | 
      
         | 79 |  |  | #endif
 | 
      
         | 80 |  |  |  
 | 
      
         | 81 |  |  | void
 | 
      
         | 82 |  |  | cyg_hal_plf_pci_init(void)
 | 
      
         | 83 |  |  | {
 | 
      
         | 84 |  |  |     cyg_uint8 next_bus;
 | 
      
         | 85 |  |  |     static bool _done = false;
 | 
      
         | 86 |  |  |  
 | 
      
         | 87 |  |  |     if (_done) return;
 | 
      
         | 88 |  |  |     _done = true;
 | 
      
         | 89 |  |  |  
 | 
      
         | 90 |  |  | //    diag_printf("Initializing PCI.\n");
 | 
      
         | 91 |  |  |  
 | 
      
         | 92 |  |  | #ifdef CYGSEM_HAL_LOAD_PCI_FPGA
 | 
      
         | 93 |  |  |     // Set MSC0 for FPGA configuration
 | 
      
         | 94 |  |  |     *PXA2X0_MSC1 = (*PXA2X0_MSC1 & 0x0000FFFF);
 | 
      
         | 95 |  |  |  
 | 
      
         | 96 |  |  |     // Program FPGA
 | 
      
         | 97 |  |  |     load_fpga(uE250_pci_bitstream, sizeof(uE250_pci_bitstream));
 | 
      
         | 98 |  |  | #endif
 | 
      
         | 99 |  |  |  
 | 
      
         | 100 |  |  |     *PXA2X0_MSC0 = (*PXA2X0_MSC0 & 0x0000FFFF) | 0x7ff10000;
 | 
      
         | 101 |  |  |     *PXA2X0_MSC1 = (*PXA2X0_MSC1 & 0x0000FFFF) | 0x70e40000;
 | 
      
         | 102 |  |  |     *PXA2X0_MSC2 = 0x70e470e4;
 | 
      
         | 103 |  |  |  
 | 
      
         | 104 |  |  |     *PXA2X0_MDREFR = 0x0009c018;
 | 
      
         | 105 |  |  |     *PXA2X0_MDCNFG = 0x03001bc9;
 | 
      
         | 106 |  |  |  
 | 
      
         | 107 |  |  |     // FIXME: Change MSC values ??
 | 
      
         | 108 |  |  |     // Set FPGA to 110.6 MHz
 | 
      
         | 109 |  |  |     *PXA2X0_GPDR0 |= (0x01 << 7);
 | 
      
         | 110 |  |  |     *PXA2X0_GPSR0 |= (0x01 << 7);
 | 
      
         | 111 |  |  |     *PXA2X0_GPDR1 |= (0x01 << (45-32));
 | 
      
         | 112 |  |  |     *PXA2X0_GPCR1 |= (0x01 << (45-32));
 | 
      
         | 113 |  |  |  
 | 
      
         | 114 |  |  |     // Set busmastering
 | 
      
         | 115 |  |  |     _pxa2x0_set_GPIO_mode(13, PXA2X0_GPIO_AF2, PXA2X0_GPIO_OUT);
 | 
      
         | 116 |  |  |     _pxa2x0_set_GPIO_mode(14, PXA2X0_GPIO_AF1, PXA2X0_GPIO_IN);
 | 
      
         | 117 |  |  |  
 | 
      
         | 118 |  |  | //    diag_printf("Activating PCI bridge.\n");
 | 
      
         | 119 |  |  |     PCICTL_MISC |= (1 | PCI_SDRAM_256) | PCI_TIMER;
 | 
      
         | 120 |  |  |  
 | 
      
         | 121 |  |  |     // Set command master
 | 
      
         | 122 |  |  |     cyg_hal_plf_pci_cfg_write_word(0, 0, CYG_PCI_CFG_COMMAND,
 | 
      
         | 123 |  |  |                                    CYG_PCI_CFG_COMMAND_MEMORY|CYG_PCI_CFG_COMMAND_MASTER);
 | 
      
         | 124 |  |  |  
 | 
      
         | 125 |  |  | //    diag_printf("Scanning PCI bridge...\n");
 | 
      
         | 126 |  |  |  
 | 
      
         | 127 |  |  |     // Initialize PCI support
 | 
      
         | 128 |  |  |     cyg_pci_init();
 | 
      
         | 129 |  |  |  
 | 
      
         | 130 |  |  |     // Configure PCI bus.
 | 
      
         | 131 |  |  |     next_bus = 1;
 | 
      
         | 132 |  |  |     cyg_pci_configure_bus(0, &next_bus);
 | 
      
         | 133 |  |  |  
 | 
      
         | 134 |  |  |     // Set up to handle PCI interrupts
 | 
      
         | 135 |  |  |     HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_GPIO1, 0, 0);  // Falling edge
 | 
      
         | 136 |  |  |     HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_GPIO1);
 | 
      
         | 137 |  |  |     PCICTL_INT_RESET = 0xFF;  // Clear all pending interrupts
 | 
      
         | 138 |  |  |     PCICTL_INT_EDGE = 0xFF;   // Generate interrupts
 | 
      
         | 139 |  |  |     PCICTL_IRQ_MASK = 0x00;   // All masked
 | 
      
         | 140 |  |  |  
 | 
      
         | 141 |  |  |     if (0){
 | 
      
         | 142 |  |  |         cyg_uint8 devfn;
 | 
      
         | 143 |  |  |         cyg_pci_device_id devid;
 | 
      
         | 144 |  |  |         cyg_pci_device dev_info;
 | 
      
         | 145 |  |  |         int i;
 | 
      
         | 146 |  |  |  
 | 
      
         | 147 |  |  |         devid = CYG_PCI_DEV_MAKE_ID(next_bus-1, 0) | CYG_PCI_NULL_DEVFN;
 | 
      
         | 148 |  |  |         while (cyg_pci_find_next(devid, &devid)) {
 | 
      
         | 149 |  |  |             devfn = CYG_PCI_DEV_GET_DEVFN(devid);
 | 
      
         | 150 |  |  |             cyg_pci_get_device_info(devid, &dev_info);
 | 
      
         | 151 |  |  |  
 | 
      
         | 152 |  |  |             diag_printf("\n");
 | 
      
         | 153 |  |  |             diag_printf("Bus:        %d\n", CYG_PCI_DEV_GET_BUS(devid));
 | 
      
         | 154 |  |  |             diag_printf("PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 155 |  |  |             diag_printf("PCI Func  : %d\n", CYG_PCI_DEV_GET_FN(devfn));
 | 
      
         | 156 |  |  |             diag_printf("Vendor Id : 0x%08X\n", dev_info.vendor);
 | 
      
         | 157 |  |  |             diag_printf("Device Id : 0x%08X\n", dev_info.device);
 | 
      
         | 158 |  |  |             diag_printf("Command:    0x%04X\n", dev_info.command);
 | 
      
         | 159 |  |  |             for (i = 0; i < dev_info.num_bars; i++) {
 | 
      
         | 160 |  |  |                 diag_printf("  BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
 | 
      
         | 161 |  |  |                 diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
 | 
      
         | 162 |  |  |                             dev_info.base_size[i], dev_info.base_map[i]);
 | 
      
         | 163 |  |  |             }
 | 
      
         | 164 |  |  |         }
 | 
      
         | 165 |  |  |     }
 | 
      
         | 166 |  |  | }
 | 
      
         | 167 |  |  |  
 | 
      
         | 168 |  |  | void
 | 
      
         | 169 |  |  | _uE250_pci_translate_interrupt(int bus, int devfn, int *vector, int *valid)
 | 
      
         | 170 |  |  | {
 | 
      
         | 171 |  |  |     int dev = CYG_PCI_DEV_GET_DEV(devfn);
 | 
      
         | 172 |  |  |  
 | 
      
         | 173 |  |  |     if (dev <= 5) {
 | 
      
         | 174 |  |  |         *vector = _uPCI_BASE_INTERRUPT+(dev-1);
 | 
      
         | 175 |  |  |         valid = true;;
 | 
      
         | 176 |  |  |     } else {
 | 
      
         | 177 |  |  |         valid = false;
 | 
      
         | 178 |  |  |     }
 | 
      
         | 179 |  |  | }
 | 
      
         | 180 |  |  |  
 | 
      
         | 181 |  |  | static void
 | 
      
         | 182 |  |  | cyg_hal_plf_pci_clear_idsel(void)
 | 
      
         | 183 |  |  | {
 | 
      
         | 184 |  |  |     // Clear any active idsels
 | 
      
         | 185 |  |  |     PCICTL_MISC &= ~PCI_IDSEL_OFF;
 | 
      
         | 186 |  |  |     PCICTL_STATUS_REG = 0;
 | 
      
         | 187 |  |  | }
 | 
      
         | 188 |  |  |  
 | 
      
         | 189 |  |  | void
 | 
      
         | 190 |  |  | cyg_hal_plf_pci_select_idsel(cyg_uint32 dev)
 | 
      
         | 191 |  |  | {
 | 
      
         | 192 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 193 |  |  |     // PCICTL_STATUS_REG = 0x0;
 | 
      
         | 194 |  |  |     PCICTL_MISC |= 1 + (((dev + 1) << PCI_IDSEL_SHIFT));
 | 
      
         | 195 |  |  | }
 | 
      
         | 196 |  |  |  
 | 
      
         | 197 |  |  | #define _PCI_ADDR(bus, devfn) (PCI_CONFIG_BASE |                        \
 | 
      
         | 198 |  |  |                                (bus << 16) |                            \
 | 
      
         | 199 |  |  |                                (CYG_PCI_DEV_GET_DEV(devfn) << 11) |     \
 | 
      
         | 200 |  |  |                                (CYG_PCI_DEV_GET_FN(devfn) << 8))
 | 
      
         | 201 |  |  |  
 | 
      
         | 202 |  |  | cyg_uint32
 | 
      
         | 203 |  |  | cyg_hal_plf_pci_cfg_read_dword(cyg_uint32 bus, cyg_uint32 devfn,
 | 
      
         | 204 |  |  |                                cyg_uint32 offset)
 | 
      
         | 205 |  |  | {
 | 
      
         | 206 |  |  |     cyg_uint32 config_data;
 | 
      
         | 207 |  |  |     volatile cyg_uint32 *address = (cyg_uint32 *)_PCI_ADDR(bus, devfn);
 | 
      
         | 208 |  |  |  
 | 
      
         | 209 |  |  |     cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 210 |  |  |     config_data = address[offset >> 2];
 | 
      
         | 211 |  |  |     if ((PCICTL_STATUS_REG & 0x0020) == 0x0020) {
 | 
      
         | 212 |  |  |         // Configuration cycle failed
 | 
      
         | 213 |  |  |         config_data = 0xFFFFFFFF;
 | 
      
         | 214 |  |  |     }
 | 
      
         | 215 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 216 |  |  |  
 | 
      
         | 217 |  |  |     return config_data;
 | 
      
         | 218 |  |  | }
 | 
      
         | 219 |  |  |  
 | 
      
         | 220 |  |  | void
 | 
      
         | 221 |  |  | cyg_hal_plf_pci_cfg_write_dword(cyg_uint32 bus, cyg_uint32 devfn,
 | 
      
         | 222 |  |  |                                 cyg_uint32 offset, cyg_uint32 data)
 | 
      
         | 223 |  |  | {
 | 
      
         | 224 |  |  |     volatile cyg_uint32 *address = (cyg_uint32 *)_PCI_ADDR(bus, devfn);
 | 
      
         | 225 |  |  |  
 | 
      
         | 226 |  |  |     cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 227 |  |  |     address[offset >> 2] = data;
 | 
      
         | 228 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 229 |  |  | }
 | 
      
         | 230 |  |  |  
 | 
      
         | 231 |  |  |  
 | 
      
         | 232 |  |  |  
 | 
      
         | 233 |  |  | cyg_uint16
 | 
      
         | 234 |  |  | cyg_hal_plf_pci_cfg_read_word(cyg_uint32 bus, cyg_uint32 devfn,
 | 
      
         | 235 |  |  |                               cyg_uint32 offset)
 | 
      
         | 236 |  |  | {
 | 
      
         | 237 |  |  |     cyg_uint16 config_data;
 | 
      
         | 238 |  |  |     volatile cyg_uint16 *address = (cyg_uint16 *)_PCI_ADDR(bus, devfn);
 | 
      
         | 239 |  |  |  
 | 
      
         | 240 |  |  |     cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 241 |  |  |     config_data = address[offset >> 1];
 | 
      
         | 242 |  |  |     if ((PCICTL_STATUS_REG & 0x0020) == 0x0020) {
 | 
      
         | 243 |  |  |         // Configuration cycle failed
 | 
      
         | 244 |  |  |         config_data = 0xFFFF;
 | 
      
         | 245 |  |  |     }
 | 
      
         | 246 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 247 |  |  |  
 | 
      
         | 248 |  |  |     return config_data;
 | 
      
         | 249 |  |  | }
 | 
      
         | 250 |  |  |  
 | 
      
         | 251 |  |  | void
 | 
      
         | 252 |  |  | cyg_hal_plf_pci_cfg_write_word(cyg_uint32 bus, cyg_uint32 devfn,
 | 
      
         | 253 |  |  |                                cyg_uint32 offset, cyg_uint16 data)
 | 
      
         | 254 |  |  | {
 | 
      
         | 255 |  |  |     volatile cyg_uint16 *address = (cyg_uint16 *)_PCI_ADDR(bus, devfn);
 | 
      
         | 256 |  |  |  
 | 
      
         | 257 |  |  |     cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 258 |  |  |     address[offset >> 1] = data;
 | 
      
         | 259 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 260 |  |  | }
 | 
      
         | 261 |  |  |  
 | 
      
         | 262 |  |  | cyg_uint8
 | 
      
         | 263 |  |  | cyg_hal_plf_pci_cfg_read_byte(cyg_uint32 bus, cyg_uint32 devfn,
 | 
      
         | 264 |  |  |                               cyg_uint32 offset)
 | 
      
         | 265 |  |  | {
 | 
      
         | 266 |  |  |     cyg_uint8 config_data;
 | 
      
         | 267 |  |  |     volatile cyg_uint8 *address = (cyg_uint8 *)_PCI_ADDR(bus, devfn);
 | 
      
         | 268 |  |  |  
 | 
      
         | 269 |  |  |     cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 270 |  |  |     config_data = address[offset];
 | 
      
         | 271 |  |  |     if ((PCICTL_STATUS_REG & 0x0020) == 0x0020) {
 | 
      
         | 272 |  |  |         // Configuration cycle failed
 | 
      
         | 273 |  |  |         config_data = 0xFF;
 | 
      
         | 274 |  |  |     }
 | 
      
         | 275 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 276 |  |  |  
 | 
      
         | 277 |  |  |     return config_data;
 | 
      
         | 278 |  |  | }
 | 
      
         | 279 |  |  |  
 | 
      
         | 280 |  |  |  
 | 
      
         | 281 |  |  | void
 | 
      
         | 282 |  |  | cyg_hal_plf_pci_cfg_write_byte(cyg_uint32 bus, cyg_uint32 devfn,
 | 
      
         | 283 |  |  |                                cyg_uint32 offset, cyg_uint8 data)
 | 
      
         | 284 |  |  | {
 | 
      
         | 285 |  |  |     volatile cyg_uint8 *address = (cyg_uint8 *)_PCI_ADDR(bus, devfn);
 | 
      
         | 286 |  |  |  
 | 
      
         | 287 |  |  |     cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
 | 
      
         | 288 |  |  |     address[offset] = data;
 | 
      
         | 289 |  |  |     cyg_hal_plf_pci_clear_idsel();
 | 
      
         | 290 |  |  | }
 | 
      
         | 291 |  |  |  
 | 
      
         | 292 |  |  | //
 | 
      
         | 293 |  |  | // Note: PCI I/O space reads on this platform require additional 
 | 
      
         | 294 |  |  | // addressing gymnastics
 | 
      
         | 295 |  |  |  
 | 
      
         | 296 |  |  | /**
 | 
      
         | 297 |  |  |  * Reads an 8 bit value (byte) from the given address of the PCI
 | 
      
         | 298 |  |  |  * IO space.
 | 
      
         | 299 |  |  |  **/
 | 
      
         | 300 |  |  | cyg_uint8 pci_io_read_8(cyg_uint32 address)
 | 
      
         | 301 |  |  | {
 | 
      
         | 302 |  |  |     volatile cyg_uint8 *addr = (volatile cyg_uint8 *)(((address & 0x00000003) << 22) |
 | 
      
         | 303 |  |  |                                                       address | _PCI_READ_8);
 | 
      
         | 304 |  |  |     cyg_uint8 val = *addr;
 | 
      
         | 305 |  |  | #ifdef _PCI_DEBUG
 | 
      
         | 306 |  |  |     diag_printf("READ  PCI.8 [%p/%p] => %02x\n", address, addr, val);
 | 
      
         | 307 |  |  | #endif
 | 
      
         | 308 |  |  |     return val;
 | 
      
         | 309 |  |  | }
 | 
      
         | 310 |  |  |  
 | 
      
         | 311 |  |  | /**
 | 
      
         | 312 |  |  |  *  * Reads a 16 bit value (word) from the given address of the PCI
 | 
      
         | 313 |  |  |  *   * IO space.
 | 
      
         | 314 |  |  |  *    */
 | 
      
         | 315 |  |  | cyg_uint16 pci_io_read_16(cyg_uint32 address)
 | 
      
         | 316 |  |  | {
 | 
      
         | 317 |  |  |     volatile cyg_uint16 *addr = (volatile cyg_uint16 *)(((address & 0x00000002) << 21) |
 | 
      
         | 318 |  |  |                                                         address | _PCI_READ_16);
 | 
      
         | 319 |  |  |     cyg_uint16 val = *addr;
 | 
      
         | 320 |  |  | #ifdef _PCI_DEBUG
 | 
      
         | 321 |  |  |     diag_printf("READ  PCI.16 [%p/%p] => %04x\n", address, addr, val);
 | 
      
         | 322 |  |  | #endif
 | 
      
         | 323 |  |  |     return val;
 | 
      
         | 324 |  |  | }
 | 
      
         | 325 |  |  |  
 | 
      
         | 326 |  |  | /**
 | 
      
         | 327 |  |  |  *  * Reads a 32 bit value (double word) from the given address of the PCI
 | 
      
         | 328 |  |  |  *   * IO space.
 | 
      
         | 329 |  |  |  *    */
 | 
      
         | 330 |  |  | cyg_uint32 pci_io_read_32(cyg_uint32 address)
 | 
      
         | 331 |  |  | {
 | 
      
         | 332 |  |  |     volatile cyg_uint32 *addr = (volatile cyg_uint32 *)(address | _PCI_READ_32);
 | 
      
         | 333 |  |  |     cyg_uint32 val = *addr;
 | 
      
         | 334 |  |  | #ifdef _PCI_DEBUG
 | 
      
         | 335 |  |  |     diag_printf("READ PCI.32 [%p/%p] => %02x\n", address, addr, val);
 | 
      
         | 336 |  |  | #endif
 | 
      
         | 337 |  |  |     return val;
 | 
      
         | 338 |  |  | }
 | 
      
         | 339 |  |  |  
 | 
      
         | 340 |  |  | /**
 | 
      
         | 341 |  |  |  *  * Writes an 8 bit value (byte) into the given address of the PCI
 | 
      
         | 342 |  |  |  *   * IO space.
 | 
      
         | 343 |  |  |  *    */
 | 
      
         | 344 |  |  | void pci_io_write_8(cyg_uint32 address, cyg_uint8 value)
 | 
      
         | 345 |  |  | {
 | 
      
         | 346 |  |  |     *((volatile cyg_uint8 *)(address | _PCI_WRITE_X)) = value;
 | 
      
         | 347 |  |  | #ifdef _PCI_DEBUG
 | 
      
         | 348 |  |  |     diag_printf("WRITE PCI.8[%p] <= %02x\n", address | _PCI_WRITE_X, value);
 | 
      
         | 349 |  |  | #endif
 | 
      
         | 350 |  |  | }
 | 
      
         | 351 |  |  |  
 | 
      
         | 352 |  |  | /**
 | 
      
         | 353 |  |  |  *  * Writes a 16 bit value (single word) into the given address of the PCI
 | 
      
         | 354 |  |  |  *   * IO space.
 | 
      
         | 355 |  |  |  *    */
 | 
      
         | 356 |  |  | void pci_io_write_16(cyg_uint32 address, cyg_uint16 value)
 | 
      
         | 357 |  |  | {
 | 
      
         | 358 |  |  |     *((volatile cyg_uint16 *)(address | _PCI_WRITE_X)) = value;
 | 
      
         | 359 |  |  | #ifdef _PCI_DEBUG
 | 
      
         | 360 |  |  |     diag_printf("WRITE PCI.16[%p] <= %04x\n", address | _PCI_WRITE_X, value);
 | 
      
         | 361 |  |  | #endif
 | 
      
         | 362 |  |  | }
 | 
      
         | 363 |  |  |  
 | 
      
         | 364 |  |  | /**
 | 
      
         | 365 |  |  |  *  * Writes a 32 bit value (double word) into the given address of the PCI
 | 
      
         | 366 |  |  |  *   * IO space.
 | 
      
         | 367 |  |  |  *    */
 | 
      
         | 368 |  |  | void pci_io_write_32(cyg_uint32 address, cyg_uint32 value)
 | 
      
         | 369 |  |  | {
 | 
      
         | 370 |  |  |     *((volatile cyg_uint32 *)(address | _PCI_WRITE_X)) = value;
 | 
      
         | 371 |  |  | #ifdef _PCI_DEBUG
 | 
      
         | 372 |  |  |     diag_printf("WRITE PCI.32[%p] <= %08x\n", address | _PCI_WRITE_X, value);
 | 
      
         | 373 |  |  | #endif
 | 
      
         | 374 |  |  | }
 | 
      
         | 375 |  |  |  
 | 
      
         | 376 |  |  | #endif // CYGPKG_IO_PCI
 |