OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [pci/] [current/] [src/] [pci.c] - Blame information for rev 825

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//=============================================================================
2
//
3
//      pci.c
4
//
5
//      PCI library
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, 2004 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):    jskov, from design by nickg
43
// Contributors: jskov
44
// Date:         1999-08-09
45
// Purpose:      PCI configuration
46
// Description: 
47
//               PCI bus support library.
48
//               Handles simple resource allocation for devices.
49
//               Can configure 64bit devices, but drivers may need special
50
//               magic to access all of this memory space - this is platform
51
//               specific and the driver must know how to handle it on its own.
52
//####DESCRIPTIONEND####
53
//
54
//=============================================================================
55
 
56
#include <pkgconf/hal.h>
57
#include <pkgconf/io_pci.h>
58
#include <cyg/io/pci_hw.h>
59
 
60
// CYG_PCI_PRESENT only gets defined for targets that provide PCI HAL support.
61
// See pci_hw.h for details.
62
#ifdef CYG_PCI_PRESENT
63
 
64
#include <cyg/io/pci.h>
65
#include <cyg/infra/cyg_ass.h>
66
#include <cyg/infra/diag.h>
67
 
68
static cyg_bool cyg_pci_lib_initialized = false;
69
static CYG_PCI_ADDRESS64 cyg_pci_memory_base;
70
static CYG_PCI_ADDRESS32 cyg_pci_io_base;
71
 
72
void
73
cyg_pci_init( void )
74
{
75
    if (!cyg_pci_lib_initialized) {
76
 
77
        cyg_pci_set_memory_base(HAL_PCI_ALLOC_BASE_MEMORY);
78
        cyg_pci_set_io_base(HAL_PCI_ALLOC_BASE_IO);
79
 
80
        // Initialize the PCI bus, preparing it for general access.
81
        cyg_pcihw_init();
82
 
83
        cyg_pci_lib_initialized = true;
84
    }
85
}
86
 
87
//---------------------------------------------------------------------------
88
// Common device configuration access functions
89
 
90
void
91
cyg_pci_get_device_info ( cyg_pci_device_id devid, cyg_pci_device *dev_info )
92
{
93
    int i;
94
    unsigned char bar_count;
95
    cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(devid);
96
    cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(devid);
97
    cyg_uint8 header_type;
98
 
99
    dev_info->devid = devid;
100
 
101
    cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_VENDOR,
102
                                 &dev_info->vendor);
103
    cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_DEVICE,
104
                                 &dev_info->device);
105
    cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_COMMAND,
106
                                 &dev_info->command);
107
    cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_STATUS,
108
                                 &dev_info->status);
109
    cyg_pcihw_read_config_uint32(bus, devfn, CYG_PCI_CFG_CLASS_REV,
110
                                 &dev_info->class_rev);
111
    cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_CACHE_LINE_SIZE,
112
                                &dev_info->cache_line_size);
113
    cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_LATENCY_TIMER,
114
                                &dev_info->latency_timer);
115
    cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_HEADER_TYPE,
116
                                &header_type);
117
    dev_info->header_type = (cyg_pci_header_type) header_type;
118
    cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_BIST,
119
                                &dev_info->bist);
120
 
121
    if ((dev_info->header_type & CYG_PCI_CFG_HEADER_TYPE_MASK) == CYG_PCI_HEADER_BRIDGE)
122
        dev_info->num_bars = 2;
123
    else
124
        dev_info->num_bars = 6;
125
 
126
    // Clear out all address info (the code below stops short)
127
    for (i = 0; i < CYG_PCI_MAX_BAR; i++) {
128
        dev_info->base_map[i] = 0xffffffff;
129
        dev_info->base_address[i] = 0;
130
        dev_info->base_size[i] = 0;
131
    }
132
 
133
    for (i = 0; i < dev_info->num_bars; i++) {
134
        if (CYG_PCI_IGNORE_BAR(dev_info, i))
135
            continue;
136
 
137
        cyg_pcihw_read_config_uint32(bus, devfn,
138
                                     CYG_PCI_CFG_BAR_BASE + 4*i,
139
                                     &dev_info->base_address[i]);
140
    }
141
 
142
    // If device is disabled, probe BARs for sizes.
143
    if ((dev_info->command & CYG_PCI_CFG_COMMAND_ACTIVE) == 0) {
144
 
145
        bar_count = 0;
146
        for (i = 0; i < dev_info->num_bars; i++){
147
            cyg_uint32 size;
148
 
149
            if (CYG_PCI_IGNORE_BAR(dev_info, i))
150
                continue;
151
 
152
            cyg_pcihw_write_config_uint32(bus, devfn,
153
                                          CYG_PCI_CFG_BAR_BASE + 4*i,
154
                                          0xffffffff);
155
            cyg_pcihw_read_config_uint32(bus, devfn,
156
                                         CYG_PCI_CFG_BAR_BASE + 4*i,
157
                                         &size);
158
            dev_info->base_size[i] = size;
159
            dev_info->base_map[i] = 0xffffffff;
160
 
161
            // Increment BAR count only if it has valid entry. BARs may not
162
            // be in contiguous locations. 
163
            if (size != 0) {
164
                ++bar_count;
165
            }
166
 
167
            // Check for a 64bit memory region.
168
            if (CYG_PCI_CFG_BAR_SPACE_MEM ==
169
                (size & CYG_PCI_CFG_BAR_SPACE_MASK)) {
170
                if (size & CYG_PRI_CFG_BAR_MEM_TYPE_64) {
171
                    // Clear fields for next BAR - it's the upper 32 bits.
172
                    i++;
173
                    dev_info->base_size[i] = 0;
174
                    dev_info->base_map[i] = 0xffffffff;
175
                }
176
            }
177
 
178
            // Fix any IO devices that only implement the bottom 16
179
            // bits of the the BAR. Just fill in these bits so it
180
            // looks like a full 32 bit BAR.
181
            if ((CYG_PCI_CFG_BAR_SPACE_IO ==
182
                 (size & CYG_PCI_CFG_BAR_SPACE_MASK)) &&
183
                ((size & 0xFFFF0000) == 0)
184
                )
185
            {
186
                dev_info->base_size[i] |= 0xFFFF0000;
187
            }
188
        }
189
        dev_info->num_bars = bar_count;
190
    } else {
191
        // If the device is already configured. Fill in the base_map.
192
        CYG_PCI_ADDRESS64 tmp_addr;
193
        cyg_uint32 bar;
194
 
195
        bar_count = 0;
196
        for (i = 0; i < dev_info->num_bars; i++){
197
 
198
            dev_info->base_size[i] = 0;
199
 
200
            bar = dev_info->base_address[i];
201
 
202
            // Increment BAR count only if it has valid entry. BARs may not
203
            // be in contiguous locations. 
204
            if (bar != 0) {
205
                ++bar_count;
206
            }
207
 
208
            if ((bar & CYG_PCI_CFG_BAR_SPACE_MASK) == CYG_PCI_CFG_BAR_SPACE_IO) {
209
                dev_info->base_map[i] = (bar & CYG_PRI_CFG_BAR_IO_MASK) + HAL_PCI_PHYSICAL_IO_BASE;
210
                bar &= CYG_PRI_CFG_BAR_IO_MASK;
211
                if ((bar < 0xFF000000) && (bar >= cyg_pci_io_base)) {
212
                    // Assume that this device owns 512 'registers'
213
                    cyg_pci_io_base = bar + 0x200;
214
#ifdef CYGPKG_IO_PCI_DEBUG
215
                    diag_printf("Update I/O base to %x from bar: %d\n", cyg_pci_io_base, i);
216
#endif
217
                }
218
            } else {
219
                tmp_addr = bar & CYG_PRI_CFG_BAR_MEM_MASK;
220
 
221
                if ((bar & CYG_PRI_CFG_BAR_MEM_TYPE_MASK) == CYG_PRI_CFG_BAR_MEM_TYPE_64)
222
                    tmp_addr |= ((CYG_PCI_ADDRESS64)(dev_info->base_address[i+1] & CYG_PRI_CFG_BAR_MEM_MASK)) << 32;
223
 
224
                if ((tmp_addr < 0xFF000000) && (tmp_addr >= cyg_pci_memory_base)) {
225
                    // Assume that this device owns 1M
226
                    cyg_pci_memory_base = tmp_addr + 0x100000;
227
#ifdef CYGPKG_IO_PCI_DEBUG
228
                    diag_printf("Update memory base to %llx from bar: %d\n", cyg_pci_memory_base, i);
229
#endif
230
                }
231
 
232
                tmp_addr += HAL_PCI_PHYSICAL_MEMORY_BASE;
233
 
234
                dev_info->base_map[i] = tmp_addr;
235
                if ((bar & CYG_PRI_CFG_BAR_MEM_TYPE_MASK) == CYG_PRI_CFG_BAR_MEM_TYPE_64)
236
                    dev_info->base_map[++i] = tmp_addr >> 32;
237
            }
238
        }
239
        dev_info->num_bars = bar_count;
240
    }
241
 
242
 
243
    switch (dev_info->header_type & CYG_PCI_CFG_HEADER_TYPE_MASK) {
244
    case CYG_PCI_HEADER_NORMAL:
245
        cyg_pcihw_read_config_uint32(bus, devfn, CYG_PCI_CFG_CARDBUS_CIS,
246
                                     &dev_info->header.normal.cardbus_cis);
247
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_SUB_VENDOR,
248
                                     &dev_info->header.normal.sub_vendor);
249
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_SUB_ID,
250
                                     &dev_info->header.normal.sub_id);
251
        cyg_pcihw_read_config_uint32(bus, devfn, CYG_PCI_CFG_ROM_ADDRESS,
252
                                     &dev_info->header.normal.rom_address);
253
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_CAP_LIST,
254
                                    &dev_info->header.normal.cap_list);
255
 
256
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_INT_LINE,
257
                                    &dev_info->header.normal.int_line);
258
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_INT_PIN,
259
                                    &dev_info->header.normal.int_pin);
260
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_MIN_GNT,
261
                                    &dev_info->header.normal.min_gnt);
262
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_MAX_LAT,
263
                                    &dev_info->header.normal.max_lat);
264
        break;
265
    case CYG_PCI_HEADER_BRIDGE:
266
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_PRI_BUS,
267
                                    &dev_info->header.bridge.pri_bus);
268
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_SEC_BUS,
269
                                    &dev_info->header.bridge.sec_bus);
270
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_SUB_BUS,
271
                                    &dev_info->header.bridge.sub_bus);
272
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_SEC_LATENCY_TIMER,
273
                                    &dev_info->header.bridge.sec_latency_timer);
274
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_IO_BASE,
275
                                    &dev_info->header.bridge.io_base);
276
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_IO_LIMIT,
277
                                    &dev_info->header.bridge.io_limit);
278
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_SEC_STATUS,
279
                                    &dev_info->header.bridge.sec_status);
280
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_MEM_BASE,
281
                                    &dev_info->header.bridge.mem_base);
282
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_MEM_LIMIT,
283
                                    &dev_info->header.bridge.mem_limit);
284
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_PREFETCH_BASE,
285
                                    &dev_info->header.bridge.prefetch_base);
286
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_PREFETCH_LIMIT,
287
                                    &dev_info->header.bridge.prefetch_limit);
288
        cyg_pcihw_read_config_uint32(bus, devfn, CYG_PCI_CFG_PREFETCH_BASE_UPPER32,
289
                                    &dev_info->header.bridge.prefetch_base_upper32);
290
        cyg_pcihw_read_config_uint32(bus, devfn, CYG_PCI_CFG_PREFETCH_LIMIT_UPPER32,
291
                                    &dev_info->header.bridge.prefetch_limit_upper32);
292
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_IO_BASE_UPPER16,
293
                                    &dev_info->header.bridge.io_base_upper16);
294
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_IO_LIMIT_UPPER16,
295
                                    &dev_info->header.bridge.io_limit_upper16);
296
        cyg_pcihw_read_config_uint32(bus, devfn, CYG_PCI_CFG_BRIDGE_ROM_ADDRESS,
297
                                    &dev_info->header.bridge.rom_address);
298
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_INT_LINE,
299
                                    &dev_info->header.bridge.int_line);
300
        cyg_pcihw_read_config_uint8(bus, devfn, CYG_PCI_CFG_INT_PIN,
301
                                    &dev_info->header.bridge.int_pin);
302
        cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_BRIDGE_CONTROL,
303
                                    &dev_info->header.bridge.control);
304
        break;
305
    case CYG_PCI_HEADER_CARDBUS_BRIDGE:
306
        CYG_FAIL("PCI device header 'cardbus bridge' support not implemented");
307
        break;
308
    default:
309
        CYG_FAIL("Unknown PCI device header type");
310
        break;
311
    }
312
}
313
 
314
void
315
cyg_pci_set_device_info ( cyg_pci_device_id devid, cyg_pci_device *dev_info )
316
{
317
    cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(devid);
318
    cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(devid);
319
    int i;
320
 
321
    // Only writable entries are updated.
322
    cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_COMMAND,
323
                                  dev_info->command);
324
    cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_STATUS,
325
                                  dev_info->status);
326
    cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_CACHE_LINE_SIZE,
327
                                 dev_info->cache_line_size);
328
    cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_LATENCY_TIMER,
329
                                 dev_info->latency_timer);
330
    cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_BIST,
331
                                 dev_info->bist);
332
 
333
    // Check for all possible BARs because they may be non-contiguous
334
    for (i = 0; i < CYG_PCI_MAX_BAR; i++) {
335
        if (dev_info->base_address[i]) {
336
            cyg_pcihw_write_config_uint32 (bus, devfn,
337
                                           CYG_PCI_CFG_BAR_BASE+4*i,
338
                                           dev_info->base_address[i]);
339
        }
340
    }
341
 
342
    switch (dev_info->header_type & CYG_PCI_CFG_HEADER_TYPE_MASK) {
343
    case CYG_PCI_HEADER_NORMAL:
344
        cyg_pcihw_write_config_uint32(bus, devfn, CYG_PCI_CFG_CARDBUS_CIS,
345
                                      dev_info->header.normal.cardbus_cis);
346
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_SUB_VENDOR,
347
                                      dev_info->header.normal.sub_vendor);
348
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_SUB_ID,
349
                                      dev_info->header.normal.sub_id);
350
        cyg_pcihw_write_config_uint32(bus, devfn, CYG_PCI_CFG_ROM_ADDRESS,
351
                                      dev_info->header.normal.rom_address);
352
 
353
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_INT_LINE,
354
                                     dev_info->header.normal.int_line);
355
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_INT_PIN,
356
                                     dev_info->header.normal.int_pin);
357
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_MIN_GNT,
358
                                     dev_info->header.normal.min_gnt);
359
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_MAX_LAT,
360
                                     dev_info->header.normal.max_lat);
361
        break;
362
    case CYG_PCI_HEADER_BRIDGE:
363
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_PRI_BUS,
364
                                     dev_info->header.bridge.pri_bus);
365
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_SEC_BUS,
366
                                     dev_info->header.bridge.sec_bus);
367
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_SUB_BUS,
368
                                     dev_info->header.bridge.sub_bus);
369
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_SEC_LATENCY_TIMER,
370
                                     dev_info->header.bridge.sec_latency_timer);
371
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_IO_BASE,
372
                                     dev_info->header.bridge.io_base);
373
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_IO_LIMIT,
374
                                     dev_info->header.bridge.io_limit);
375
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_SEC_STATUS,
376
                                      dev_info->header.bridge.sec_status);
377
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_MEM_BASE,
378
                                      dev_info->header.bridge.mem_base);
379
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_MEM_LIMIT,
380
                                      dev_info->header.bridge.mem_limit);
381
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_PREFETCH_BASE,
382
                                      dev_info->header.bridge.prefetch_base);
383
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_PREFETCH_LIMIT,
384
                                      dev_info->header.bridge.prefetch_limit);
385
        cyg_pcihw_write_config_uint32(bus, devfn, CYG_PCI_CFG_PREFETCH_BASE_UPPER32,
386
                                      dev_info->header.bridge.prefetch_base_upper32);
387
        cyg_pcihw_write_config_uint32(bus, devfn, CYG_PCI_CFG_PREFETCH_LIMIT_UPPER32,
388
                                      dev_info->header.bridge.prefetch_limit_upper32);
389
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_IO_BASE_UPPER16,
390
                                      dev_info->header.bridge.io_base_upper16);
391
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_IO_LIMIT_UPPER16,
392
                                      dev_info->header.bridge.io_limit_upper16);
393
        cyg_pcihw_write_config_uint32(bus, devfn, CYG_PCI_CFG_BRIDGE_ROM_ADDRESS,
394
                                      dev_info->header.bridge.rom_address);
395
        cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_INT_LINE,
396
                                     dev_info->header.bridge.int_line);
397
        cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_BRIDGE_CONTROL,
398
                                      dev_info->header.bridge.control);
399
        break;
400
    case CYG_PCI_HEADER_CARDBUS_BRIDGE:
401
        CYG_FAIL("PCI device header 'cardbus bridge' support not implemented");
402
        break;
403
    default:
404
        CYG_FAIL("Unknown PCI device header type");
405
        break;
406
    }
407
 
408
    // Update values in dev_info.
409
    cyg_pci_get_device_info(devid, dev_info);
410
}
411
 
412
 
413
//---------------------------------------------------------------------------
414
// Specific device configuration access functions
415
void
416
cyg_pci_read_config_uint8( cyg_pci_device_id devid,
417
                           cyg_uint8 offset, cyg_uint8 *val)
418
{
419
    cyg_pcihw_read_config_uint8(CYG_PCI_DEV_GET_BUS(devid),
420
                                CYG_PCI_DEV_GET_DEVFN(devid),
421
                                offset, val);
422
}
423
 
424
void
425
cyg_pci_read_config_uint16( cyg_pci_device_id devid,
426
                            cyg_uint8 offset, cyg_uint16 *val)
427
{
428
    cyg_pcihw_read_config_uint16(CYG_PCI_DEV_GET_BUS(devid),
429
                                 CYG_PCI_DEV_GET_DEVFN(devid),
430
                                 offset, val);
431
}
432
 
433
void
434
cyg_pci_read_config_uint32( cyg_pci_device_id devid,
435
                            cyg_uint8 offset, cyg_uint32 *val)
436
{
437
    cyg_pcihw_read_config_uint32(CYG_PCI_DEV_GET_BUS(devid),
438
                                 CYG_PCI_DEV_GET_DEVFN(devid),
439
                                 offset, val);
440
}
441
 
442
 
443
// Write functions
444
void
445
cyg_pci_write_config_uint8( cyg_pci_device_id devid,
446
                            cyg_uint8 offset, cyg_uint8 val)
447
{
448
    cyg_pcihw_write_config_uint8(CYG_PCI_DEV_GET_BUS(devid),
449
                                 CYG_PCI_DEV_GET_DEVFN(devid),
450
                                 offset, val);
451
}
452
 
453
void
454
cyg_pci_write_config_uint16( cyg_pci_device_id devid,
455
                             cyg_uint8 offset, cyg_uint16 val)
456
{
457
    cyg_pcihw_write_config_uint16(CYG_PCI_DEV_GET_BUS(devid),
458
                                  CYG_PCI_DEV_GET_DEVFN(devid),
459
                                  offset, val);
460
}
461
 
462
void
463
cyg_pci_write_config_uint32( cyg_pci_device_id devid,
464
                             cyg_uint8 offset, cyg_uint32 val)
465
{
466
    cyg_pcihw_write_config_uint32(CYG_PCI_DEV_GET_BUS(devid),
467
                                  CYG_PCI_DEV_GET_DEVFN(devid),
468
                                  offset, val);
469
}
470
 
471
//------------------------------------------------------------------------
472
// Device find functions
473
 
474
cyg_bool
475
cyg_pci_find_next( cyg_pci_device_id cur_devid,
476
                   cyg_pci_device_id *next_devid )
477
{
478
    cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(cur_devid);
479
    cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(cur_devid);
480
    cyg_uint8 dev = CYG_PCI_DEV_GET_DEV(devfn);
481
    cyg_uint8 fn = CYG_PCI_DEV_GET_FN(devfn);
482
 
483
#ifdef CYGPKG_IO_PCI_DEBUG
484
    diag_printf("cyg_pci_find_next: start[%x] ...\n",(unsigned)cur_devid);
485
#endif
486
 
487
    // If this is the initializer, start with 0/0/0
488
    if (CYG_PCI_NULL_DEVID == cur_devid) {
489
        bus = dev = fn = 0;
490
        dev = CYG_PCI_MIN_DEV;
491
    } else if (CYG_PCI_NULL_DEVFN == (cur_devid & CYG_PCI_NULL_DEVFN)) {
492
        dev = fn = 0;
493
        dev = CYG_PCI_MIN_DEV;
494
    } else {
495
        // Otherwise, check multi-function bit of device's first function
496
        cyg_uint8 header;
497
 
498
        devfn = CYG_PCI_DEV_MAKE_DEVFN(dev, 0);
499
        cyg_pcihw_read_config_uint8(bus, devfn,
500
                                    CYG_PCI_CFG_HEADER_TYPE, &header);
501
        if (header & CYG_PCI_CFG_HEADER_TYPE_MF) {
502
            // Multi-function device. Increase fn.
503
            fn++;
504
            if (fn >= CYG_PCI_MAX_FN) {
505
                fn = 0;
506
                dev++;
507
            }
508
        } else {
509
            // Single-function device. Skip to next.
510
            dev++;
511
        }
512
    }
513
 
514
    // Note: Reset iterators in enclosing statement's "next" part.
515
    //       Allows resuming scan with given input values. 
516
    for (;bus < CYG_PCI_MAX_BUS; bus++, dev=CYG_PCI_MIN_DEV) {
517
        for (;dev < CYG_PCI_MAX_DEV; dev++, fn=0) {
518
            for (;fn < CYG_PCI_MAX_FN; fn++) {
519
                cyg_uint16 vendor;
520
 
521
                if (CYG_PCI_IGNORE_DEVICE(bus, dev, fn))
522
                    continue;
523
 
524
                devfn = CYG_PCI_DEV_MAKE_DEVFN(dev, fn);
525
                cyg_pcihw_read_config_uint16(bus, devfn,
526
                                             CYG_PCI_CFG_VENDOR, &vendor);
527
                if (CYG_PCI_VENDOR_UNDEFINED != vendor) {
528
#ifdef CYGPKG_IO_PCI_DEBUG
529
                diag_printf("   Bus: %d, Dev: %d, Fn: %d, Vendor: %x\n", bus, dev, fn, vendor);
530
#endif
531
                    *next_devid = CYG_PCI_DEV_MAKE_ID(bus, devfn);
532
                    return true;
533
                }
534
            }
535
        }
536
    }
537
 
538
#ifdef CYGPKG_IO_PCI_DEBUG
539
    diag_printf("nothing.\n");
540
#endif
541
 
542
    return false;
543
}
544
 
545
//
546
// Scan for a particular device, starting with 'devid'
547
// 'devid' is updated with the next device if found.
548
//         is not changed if no suitable device is found.
549
cyg_bool
550
cyg_pci_find_device( cyg_uint16 vendor, cyg_uint16 device,
551
                     cyg_pci_device_id *devid )
552
{
553
    cyg_pci_device_id new_devid = *devid;
554
 
555
#ifdef CYGPKG_IO_PCI_DEBUG
556
    diag_printf("cyg_pci_find_device - vendor: %x, device: %x\n", vendor, device);
557
#endif
558
    // Scan entire bus, check for matches on valid devices.
559
    while (cyg_pci_find_next(new_devid, &new_devid)) {
560
        cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(new_devid);
561
        cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(new_devid);
562
        cyg_uint16 v, d;
563
 
564
        // Check that vendor matches.
565
        cyg_pcihw_read_config_uint16(bus, devfn,
566
                                     CYG_PCI_CFG_VENDOR, &v);
567
        cyg_pcihw_read_config_uint16(bus, devfn,
568
                                     CYG_PCI_CFG_DEVICE, &d);
569
#ifdef CYGPKG_IO_PCI_DEBUG
570
        diag_printf("... PCI vendor = %x, device = %x\n", v, d);
571
#endif
572
 
573
        if (v != vendor) continue;
574
 
575
        // Check that device matches.
576
        if (d == device) {
577
#ifdef CYGPKG_IO_PCI_DEBUG
578
            diag_printf("Found it!\n");
579
#endif
580
            *devid = new_devid;
581
            return true;
582
        }
583
    }
584
 
585
    return false;
586
}
587
 
588
cyg_bool
589
cyg_pci_find_class( cyg_uint32 dev_class, cyg_pci_device_id *devid )
590
{
591
    // Scan entire bus, check for matches on valid devices.
592
    while (cyg_pci_find_next(*devid, devid)) {
593
        cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(*devid);
594
        cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(*devid);
595
        cyg_uint32 c;
596
 
597
        // Check that class code matches.
598
        cyg_pcihw_read_config_uint32(bus, devfn,
599
                                     CYG_PCI_CFG_CLASS_REV, &c);
600
        c >>= 8;
601
        if (c == dev_class)
602
            return true;
603
    }
604
 
605
    return false;
606
}
607
 
608
cyg_bool
609
cyg_pci_find_matching( cyg_pci_match_func *matchp,
610
                       void * match_callback_data,
611
                       cyg_pci_device_id *devid )
612
{
613
    cyg_pci_device_id new_devid = *devid;
614
 
615
#ifdef CYGPKG_IO_PCI_DEBUG
616
    diag_printf("cyg_pci_find_matching - func is at %x\n", (unsigned int)matchp);
617
#endif
618
    // Scan entire bus, check for matches on valid devices.
619
    while (cyg_pci_find_next(new_devid, &new_devid)) {
620
        cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(new_devid);
621
        cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(new_devid);
622
        cyg_uint16 v, d;
623
        cyg_uint32 c;
624
 
625
        // Check that vendor, device and class match.
626
        cyg_pcihw_read_config_uint16(bus, devfn,
627
                                     CYG_PCI_CFG_VENDOR, &v);
628
        cyg_pcihw_read_config_uint16(bus, devfn,
629
                                     CYG_PCI_CFG_DEVICE, &d);
630
        cyg_pcihw_read_config_uint32(bus, devfn,
631
                                     CYG_PCI_CFG_CLASS_REV, &c);
632
        c >>= 8;
633
#ifdef CYGPKG_IO_PCI_DEBUG
634
        diag_printf("... PCI vendor = %x, device = %x, class %x\n", v, d, c);
635
#endif
636
        // Check that device matches as the caller desires:
637
        if ( (*matchp)(v, d, c, match_callback_data) ) {
638
            *devid = new_devid;
639
            return true;
640
        }
641
    }
642
 
643
    return false;
644
}
645
 
646
//------------------------------------------------------------------------
647
// Resource Allocation
648
 
649
void
650
cyg_pci_set_memory_base(CYG_PCI_ADDRESS64 base)
651
{
652
    cyg_pci_memory_base = base;
653
}
654
 
655
void
656
cyg_pci_set_io_base(CYG_PCI_ADDRESS32 base)
657
{
658
    cyg_pci_io_base = base;
659
}
660
 
661
cyg_bool
662
cyg_pci_configure_device( cyg_pci_device *dev_info )
663
{
664
    int bar;
665
    cyg_uint32 flags;
666
    cyg_bool ret = true;
667
 
668
    // If device is already active, just return true as
669
    // cyg_pci_get_device_info has presumably filled in
670
    // the base_map already.
671
    if ((dev_info->command & CYG_PCI_CFG_COMMAND_ACTIVE) != 0)
672
        return true;
673
 
674
    if (dev_info->num_bars > 0) {
675
        for (bar = 0; bar < CYG_PCI_MAX_BAR; bar++) {
676
            if (!dev_info->base_size[bar]) {
677
                continue;
678
            }
679
            flags = dev_info->base_size[bar];
680
 
681
            ret = false;
682
 
683
            if ((flags & CYG_PCI_CFG_BAR_SPACE_MASK) == CYG_PCI_CFG_BAR_SPACE_MEM){
684
                ret |= cyg_pci_allocate_memory(dev_info, bar,
685
                                               &cyg_pci_memory_base);
686
 
687
                // If this is a 64bit memory region, skip the next bar
688
                // since it will contain the top 32 bits.
689
                if (flags & CYG_PRI_CFG_BAR_MEM_TYPE_64)
690
                    bar++;
691
            } else
692
                ret |= cyg_pci_allocate_io(dev_info, bar, &cyg_pci_io_base);
693
 
694
            if (!ret)
695
                return ret;
696
        }
697
    }
698
 
699
    cyg_pci_translate_interrupt(dev_info, &dev_info->hal_vector);
700
 
701
    return ret;
702
}
703
 
704
// This is the function that handles resource allocation. It doesn't
705
// affect the device state.
706
// Should not be called with top32bit-bar of a 64bit pair.
707
inline cyg_bool
708
cyg_pci_allocate_memory_priv( cyg_pci_device *dev_info, cyg_uint32 bar,
709
                              CYG_PCI_ADDRESS64 *base,
710
                              CYG_PCI_ADDRESS64 *assigned_addr)
711
{
712
    cyg_uint32 mem_type, flags;
713
    CYG_PCI_ADDRESS64 size, aligned_addr;
714
 
715
    // Get the probed size and flags
716
    flags = dev_info->base_size[bar];
717
 
718
    // Decode size
719
    size = (CYG_PCI_ADDRESS64) ((~(flags & CYG_PRI_CFG_BAR_MEM_MASK))+1);
720
 
721
    // Calculate address we will assign the device.
722
    // This can be made more clever, specifically:
723
    //  1) The lowest 1MB should be reserved for devices with 1M memory type.
724
    //     : Needs to be handled.
725
    //  2) The low 32bit space should be reserved for devices with 32bit type.
726
    //     : With the usual handful of devices it is unlikely that the
727
    //       low 4GB space will become full.
728
    //  3) A bitmap can be used to avoid fragmentation.
729
    //     : Again, unlikely to be necessary.
730
    //
731
    // For now, simply align to required size.
732
    aligned_addr = (*base+size-1) & ~(size-1);
733
 
734
    // Is the request for memory space?
735
    if (CYG_PCI_CFG_BAR_SPACE_MEM != (flags & CYG_PCI_CFG_BAR_SPACE_MASK))
736
        return false;
737
 
738
    // Check type of memory requested...
739
    mem_type = CYG_PRI_CFG_BAR_MEM_TYPE_MASK & flags;
740
 
741
    // We don't handle <1MB devices optimally yet.
742
    if (CYG_PRI_CFG_BAR_MEM_TYPE_1M == mem_type
743
        && (aligned_addr + size) > 1024*1024)
744
        return false;
745
 
746
    // Update the resource pointer and return values.
747
    *base = aligned_addr+size;
748
    *assigned_addr = aligned_addr;
749
 
750
    dev_info->base_map[bar] = (cyg_uint32)
751
        (aligned_addr+HAL_PCI_PHYSICAL_MEMORY_BASE) & 0xffffffff;
752
 
753
    // If a 64bit region, store upper 32 bits in the next bar.
754
    // Note: The CPU is not necessarily able to access the region
755
    // linearly - it may have to do it in segments. Driver must handle that.
756
    if (CYG_PRI_CFG_BAR_MEM_TYPE_64 == mem_type) {
757
        dev_info->base_map[bar+1] = (cyg_uint32)
758
            ((aligned_addr+HAL_PCI_PHYSICAL_MEMORY_BASE) >> 32) & 0xffffffff;
759
    }
760
 
761
    return true;
762
}
763
 
764
cyg_bool
765
cyg_pci_allocate_memory( cyg_pci_device *dev_info, cyg_uint32 bar,
766
                         CYG_PCI_ADDRESS64 *base)
767
{
768
    cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(dev_info->devid);
769
    cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(dev_info->devid);
770
    CYG_PCI_ADDRESS64 assigned_addr;
771
    cyg_bool ret;
772
 
773
    // Check that device is inactive.
774
    if ((dev_info->command & CYG_PCI_CFG_COMMAND_ACTIVE) != 0)
775
        return false;
776
 
777
    // Allocate memory space for the device.
778
    ret = cyg_pci_allocate_memory_priv(dev_info, bar, base, &assigned_addr);
779
 
780
    if (ret) {
781
        // Map the device and update the BAR in the dev_info structure.
782
        cyg_pcihw_write_config_uint32(bus, devfn,
783
                                      CYG_PCI_CFG_BAR_BASE+4*bar,
784
                                      (cyg_uint32)
785
                                      (assigned_addr & 0xffffffff));
786
        cyg_pcihw_read_config_uint32(bus, devfn,
787
                                     CYG_PCI_CFG_BAR_BASE+4*bar,
788
                                     &dev_info->base_address[bar]);
789
 
790
        // Handle upper 32 bits if necessary.
791
        if (dev_info->base_size[bar] & CYG_PRI_CFG_BAR_MEM_TYPE_64) {
792
            cyg_pcihw_write_config_uint32(bus, devfn,
793
                                          CYG_PCI_CFG_BAR_BASE+4*(bar+1),
794
                                          (cyg_uint32)
795
                                          ((assigned_addr >> 32)& 0xffffffff));
796
            cyg_pcihw_read_config_uint32(bus, devfn,
797
                                         CYG_PCI_CFG_BAR_BASE+4*(bar+1),
798
                                         &dev_info->base_address[bar+1]);
799
        }
800
    }
801
 
802
    return ret;
803
}
804
 
805
cyg_bool
806
cyg_pci_allocate_io_priv( cyg_pci_device *dev_info, cyg_uint32 bar,
807
                          CYG_PCI_ADDRESS32 *base,
808
                          CYG_PCI_ADDRESS32 *assigned_addr)
809
{
810
    cyg_uint32 flags, size;
811
    CYG_PCI_ADDRESS32 aligned_addr;
812
 
813
    // Get the probed size and flags
814
    flags = dev_info->base_size[bar];
815
 
816
    // Decode size
817
    size = (~(flags & CYG_PRI_CFG_BAR_IO_MASK))+1;
818
 
819
    // Calculate address we will assign the device.
820
    // This can be made more clever.
821
    // For now, simply align to required size.
822
    aligned_addr = (*base+size-1) & ~(size-1);
823
 
824
    // Is the request for IO space?
825
    if (CYG_PCI_CFG_BAR_SPACE_IO != (flags & CYG_PCI_CFG_BAR_SPACE_MASK))
826
        return false;
827
 
828
    // Update the resource pointer and return values.
829
    *base = aligned_addr+size;
830
    dev_info->base_map[bar] = aligned_addr+HAL_PCI_PHYSICAL_IO_BASE;
831
    *assigned_addr = aligned_addr;
832
 
833
    return true;
834
}
835
 
836
 
837
cyg_bool
838
cyg_pci_allocate_io( cyg_pci_device *dev_info, cyg_uint32 bar,
839
                     CYG_PCI_ADDRESS32 *base)
840
{
841
    cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(dev_info->devid);
842
    cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(dev_info->devid);
843
    CYG_PCI_ADDRESS32 assigned_addr;
844
    cyg_bool ret;
845
 
846
    // Check that device is inactive.
847
    if ((dev_info->command & CYG_PCI_CFG_COMMAND_ACTIVE) != 0)
848
        return false;
849
 
850
    // Allocate IO space for the device.
851
    ret = cyg_pci_allocate_io_priv(dev_info, bar, base, &assigned_addr);
852
 
853
    if (ret) {
854
        // Map the device and update the BAR in the dev_info structure.
855
        cyg_pcihw_write_config_uint32(bus, devfn,
856
                                      CYG_PCI_CFG_BAR_BASE+4*bar,
857
                                      assigned_addr);
858
        cyg_pcihw_read_config_uint32(bus, devfn,
859
                                     CYG_PCI_CFG_BAR_BASE+4*bar,
860
                                     &dev_info->base_address[bar]);
861
    }
862
 
863
    return ret;
864
}
865
 
866
cyg_bool
867
cyg_pci_translate_interrupt( cyg_pci_device *dev_info,
868
                             CYG_ADDRWORD *vec )
869
{
870
    cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(dev_info->devid);
871
    cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(dev_info->devid);
872
 
873
    if (cyg_pcihw_translate_interrupt(bus, devfn, vec)) {
874
#ifdef CYGPKG_IO_PCI_CONFIGURE_INTLINE
875
        // Fill in interrupt line info. This only really works for
876
        // platforms where assigned PCI irq numbers are less than 255.
877
        cyg_pcihw_write_config_uint8(bus, devfn,
878
                                     CYG_PCI_CFG_INT_LINE,
879
                                     *vec & 0xff);
880
#endif
881
        return true;
882
    }
883
    return false;
884
}
885
 
886
 
887
// Initialize devices on a given bus and all subordinate busses.
888
cyg_bool
889
cyg_pci_configure_bus( cyg_uint8 bus,
890
                       cyg_uint8 *next_bus )
891
{
892
    cyg_uint8 devfn, header_type;
893
    cyg_pci_device_id devid;
894
    cyg_pci_device dev_info;
895
 
896
    CYG_PCI_ADDRESS64 mem_start, mem_limit, mem_base;
897
    CYG_PCI_ADDRESS32 io_start, io_limit, io_base;
898
 
899
    // Scan only this bus for valid devices.
900
    devid = CYG_PCI_DEV_MAKE_ID(bus, 0) | CYG_PCI_NULL_DEVFN;
901
 
902
#ifdef CYGPKG_IO_PCI_DEBUG
903
    diag_printf("Configuring bus %d.\n", bus);
904
#endif
905
 
906
    while (cyg_pci_find_next(devid, &devid) && bus == CYG_PCI_DEV_GET_BUS(devid)) {
907
 
908
        devfn = CYG_PCI_DEV_GET_DEVFN(devid);
909
 
910
        // Get the device info
911
        cyg_pci_get_device_info(devid, &dev_info);
912
 
913
#ifdef CYGPKG_IO_PCI_DEBUG
914
        diag_printf("\n");
915
        diag_printf("Configuring PCI Bus   : %d\n", bus);
916
        diag_printf("            PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));
917
        diag_printf("            PCI Func  : %d\n", CYG_PCI_DEV_GET_FN(devfn));
918
        diag_printf("            Vendor Id : 0x%08X\n", dev_info.vendor);
919
        diag_printf("            Device Id : 0x%08X\n", dev_info.device);
920
#endif
921
 
922
        header_type = dev_info.header_type & CYG_PCI_CFG_HEADER_TYPE_MASK;
923
 
924
        // Check for supported header types.
925
        if (header_type != CYG_PCI_HEADER_NORMAL &&
926
            header_type != CYG_PCI_HEADER_BRIDGE) {
927
            CYG_FAIL("Unsupported PCI header type");
928
            continue;
929
        }
930
 
931
        // Only PCI-to-PCI bridges
932
        if (header_type == CYG_PCI_HEADER_BRIDGE &&
933
            (dev_info.class_rev >> 8) != CYG_PCI_CLASS_BRIDGE_PCI_PCI) {
934
            CYG_FAIL("Unsupported PCI bridge class");
935
            continue;
936
        }
937
 
938
        // Configure the base registers
939
        if (!cyg_pci_configure_device(&dev_info)) {
940
            // Apparently out of resources.
941
            CYG_FAIL("cyg_pci_configure_device failed");
942
            break;
943
        }
944
 
945
        // Activate non-bridge devices.
946
        if (header_type != CYG_PCI_HEADER_BRIDGE) {
947
            dev_info.command |= (CYG_PCI_CFG_COMMAND_IO         // enable I/O space
948
                              | CYG_PCI_CFG_COMMAND_MEMORY      // enable memory space
949
                              | CYG_PCI_CFG_COMMAND_MASTER);    // enable bus master
950
            cyg_pci_write_config_uint16(dev_info.devid, CYG_PCI_CFG_COMMAND, dev_info.command);
951
        } else {
952
            //  Bridge Configuration
953
 
954
            // Set up the bus numbers that define the bridge
955
            dev_info.header.bridge.pri_bus = bus;
956
            cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_PRI_BUS,
957
                                         dev_info.header.bridge.pri_bus);
958
 
959
            dev_info.header.bridge.sec_bus = *next_bus;
960
            cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_SEC_BUS,
961
                                         dev_info.header.bridge.sec_bus);
962
 
963
            // Temporarily set to maximum so config cycles get passed along.
964
            dev_info.header.bridge.sub_bus = CYG_PCI_MAX_BUS - 1;
965
            cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_SUB_BUS,
966
                                         dev_info.header.bridge.sub_bus);
967
 
968
            // increment bus counter
969
            *next_bus += 1;
970
 
971
            // To figure the sizes of the memory and I/O windows, save the
972
            // current base of memory and I/O before configuring the bus
973
            // or busses on the secondary side of the bridge. After the
974
            // secondary side is configured, the difference between the
975
            // current values and saved values will tell the size.
976
 
977
            // For bridges, the memory window must start and end on a 1M
978
            // boundary and the I/O window must start and end on a 4K
979
            // boundary. We round up the mem and I/O allocation bases
980
            // to appropriate boundaries before configuring the secondary
981
            // bus. Save the pre-rounded values in case no mem or I/O
982
            // is needed we can recover any space lost due to rounding.
983
 
984
            // round up start of PCI memory space to a 1M boundary
985
            mem_base = cyg_pci_memory_base;
986
            cyg_pci_memory_base += 0xfffff;
987
            cyg_pci_memory_base &= ~0xfffff;
988
            mem_start = cyg_pci_memory_base;
989
 
990
            // round up start of PCI I/O space to a 4 Kbyte start address
991
            io_base = cyg_pci_io_base;
992
            cyg_pci_io_base += 0xfff;
993
            cyg_pci_io_base &= ~0xfff;
994
            io_start = cyg_pci_io_base;
995
 
996
            // configure the subordinate PCI bus
997
            cyg_pci_configure_bus (dev_info.header.bridge.sec_bus, next_bus);
998
 
999
            // set subordinate bus number to last assigned bus number
1000
            dev_info.header.bridge.sub_bus = *next_bus - 1;
1001
            cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_SUB_BUS,
1002
                                         dev_info.header.bridge.sub_bus);
1003
 
1004
            // Did sub bus configuration use any I/O?
1005
            if (cyg_pci_io_base > io_start) {
1006
 
1007
                // round up end of bridge's I/O space to a 4K boundary
1008
                cyg_pci_io_base += 0xfff;
1009
                cyg_pci_io_base &= ~0xfff;
1010
                io_limit = cyg_pci_io_base - 0x1000;
1011
 
1012
                // Enable I/O cycles across bridge
1013
                dev_info.command |= CYG_PCI_CFG_COMMAND_IO;
1014
 
1015
                // 32 Bit I/O?
1016
                if ((dev_info.header.bridge.io_base & 0x0f) == 0x01) {
1017
                    // I/O Base Upper 16 Bits Register
1018
                    dev_info.header.bridge.io_base_upper16 = io_start >> 16;
1019
                    cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_IO_BASE_UPPER16,
1020
                                                 dev_info.header.bridge.io_base_upper16);
1021
                    // I/O Limit Upper 16 Bits Register
1022
                    dev_info.header.bridge.io_limit_upper16 = io_limit >> 16;
1023
                    cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_IO_LIMIT_UPPER16,
1024
                                                 dev_info.header.bridge.io_limit_upper16);
1025
                }
1026
 
1027
                // I/O Base Register
1028
                dev_info.header.bridge.io_base = (io_start & 0xf000) >> 8;
1029
                cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_IO_BASE,
1030
                                             dev_info.header.bridge.io_base);
1031
                // I/O Limit Register
1032
                dev_info.header.bridge.io_limit = (io_limit & 0xf000) >> 8;
1033
                cyg_pcihw_write_config_uint8(bus, devfn, CYG_PCI_CFG_IO_LIMIT,
1034
                                             dev_info.header.bridge.io_limit);
1035
 
1036
            } else {
1037
                // No I/O space used on secondary bus.
1038
                // Recover any space lost on unnecessary rounding
1039
                cyg_pci_io_base = io_base;
1040
            }
1041
 
1042
            // Did sub bus configuration use any memory?
1043
            if (cyg_pci_memory_base > mem_start) {
1044
 
1045
                // round up end of bridge's PCI memory space to a 1M boundary
1046
                cyg_pci_memory_base += 0xfffff;
1047
                cyg_pci_memory_base &= ~0xfffff;
1048
                mem_limit = cyg_pci_memory_base - 0x100000;
1049
 
1050
                // Enable memory cycles across bridge
1051
                dev_info.command |= CYG_PCI_CFG_COMMAND_MEMORY;
1052
 
1053
                // Memory Base Register
1054
                dev_info.header.bridge.mem_base = (mem_start >> 16) & 0xfff0;
1055
                cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_MEM_BASE,
1056
                                                 dev_info.header.bridge.mem_base);
1057
 
1058
                // Memory Limit Register
1059
                dev_info.header.bridge.mem_limit = (mem_limit >> 16) & 0xfff0;
1060
                cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_MEM_LIMIT,
1061
                                                 dev_info.header.bridge.mem_limit);
1062
 
1063
                // Prefetchable memory not yet supported across bridges.
1064
                // Disable by making limit < base
1065
                {
1066
                    cyg_uint16 tmp_word;
1067
 
1068
                    tmp_word = 0;
1069
                    cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_PREFETCH_LIMIT,
1070
                                                 tmp_word);
1071
                    tmp_word = 0xfff0;
1072
                    cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_PREFETCH_BASE,
1073
                                                 tmp_word);
1074
                }
1075
            } else {
1076
                // No memory space used on secondary bus.
1077
                // Recover any space lost on unnecessary rounding
1078
                cyg_pci_memory_base = mem_base;
1079
            }
1080
 
1081
            // Setup the bridge command register
1082
            dev_info.command |= CYG_PCI_CFG_COMMAND_MASTER;
1083
            dev_info.command |= CYG_PCI_CFG_COMMAND_SERR;
1084
            cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_COMMAND,
1085
                                          dev_info.command);
1086
 
1087
            /* Setup the Bridge Control Register */
1088
            dev_info.header.bridge.control |= CYG_PCI_CFG_BRIDGE_CTL_PARITY;
1089
            dev_info.header.bridge.control |= CYG_PCI_CFG_BRIDGE_CTL_SERR;
1090
            dev_info.header.bridge.control |= CYG_PCI_CFG_BRIDGE_CTL_MASTER;
1091
            cyg_pcihw_write_config_uint16(bus, devfn, CYG_PCI_CFG_BRIDGE_CONTROL,
1092
                                          dev_info.header.bridge.control);
1093
        }
1094
    }
1095
#ifdef CYGPKG_IO_PCI_DEBUG
1096
    diag_printf("Finished configuring bus %d.\n", bus);
1097
#endif
1098
 
1099
    return true;
1100
}
1101
 
1102
 
1103
#endif // ifdef CYG_PCI_PRESENT
1104
 
1105
//-----------------------------------------------------------------------------
1106
// end of pci.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.