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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [io/] [pci/] [v2_0/] [src/] [pci.c] - Blame information for rev 573

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

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

powered by: WebSVN 2.1.0

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