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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [xscale/] [picasso/] [current/] [src/] [xilinx-load.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      xilinx-load.c
4
//
5
//      FPGA support for NMI uEngine picasso
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2003 Free Software Foundation, Inc.                        
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    David Mazur <david@mind.be>
43
// Contributors: gthomas
44
// Date:         2003-02-20
45
// Purpose:      FPGA support
46
// Description:  
47
//
48
//####DESCRIPTIONEND####
49
//
50
//========================================================================*/
51
 
52
#include <pkgconf/hal.h>
53
#include <pkgconf/system.h>
54
#include CYGBLD_HAL_PLATFORM_H
55
#include CYGHWR_MEMORY_LAYOUT_H
56
 
57
#include <cyg/infra/cyg_type.h>         // base types
58
#include <cyg/infra/cyg_trac.h>         // tracing macros
59
#include <cyg/infra/cyg_ass.h>          // assertion macros
60
#include <cyg/infra/diag.h>             // diagnostic printing
61
 
62
#include <cyg/hal/hal_io.h>             // IO macros
63
#include <cyg/hal/hal_if.h>             // calling interface API
64
#include <cyg/hal/hal_arch.h>           // Register state info
65
#include <cyg/hal/hal_diag.h>
66
#include <cyg/hal/hal_intr.h>           // Interrupt names
67
#include <cyg/hal/hal_cache.h>
68
#include <cyg/io/pci_hw.h>
69
#include <cyg/io/pci.h>
70
 
71
#include <cyg/hal/plx.h>
72
 
73
#define FPGA_PROG 0x00020000
74
#define FPGA_INIT 0x00000002
75
#define FPGA_DONE 0x00080000
76
 
77
#define _FPGA_PROG_BASE 0x0c000000
78
#define FPGA_PROG_BASE (*((volatile cyg_uint32 *)(_FPGA_PROG_BASE)))
79
 
80
#define FPGA_DONE_DRV   0x8
81
#define FPGA_INIT_DRV   0x10
82
#define FPGA_WRITE      0x20
83
 
84
#define VGA_PROG_CTRL  0x4008
85
#define VGA_PROG_DATA  0x400C
86
 
87
#define VGA_DONE       0x1
88
#define VGA_INIT       0x2
89
#define VGA_PROG       0x4
90
#define VGA_DONE_DRV   0x8
91
#define VGA_INIT_DRV   0x10
92
#define VGA_WRITE      0x20
93
 
94
 
95
#include <cyg/compress/zlib.h>
96
 
97
extern char _end;
98
 
99
static z_stream stream;
100
 
101
#define FEEDBACK_COUNT 16
102
#define ZCHAR_BUF_SIZE 256
103
struct _zchar_info {
104
    char  buf[ZCHAR_BUF_SIZE];
105
    char *ptr;
106
    int   avail;
107
    int   feedback;
108
    int   total;
109
};
110
 
111
// Internal allocator for decompression - just use bottom of heap
112
// which will be reclaimed by eCos once the system is initialized
113
static void *
114
_zcalloc(void *opaque, unsigned int items, unsigned int size)
115
{
116
    static char *ptr = (char *)&_end;
117
    char *res = ptr;
118
 
119
//    diag_printf("%s(%p,%d,%d) = %p\n", __FUNCTION__, opaque, items, size, res);
120
    ptr += (size*items);
121
    return res;
122
}
123
 
124
static void
125
_zcfree(void *opaque, void *ptr)
126
{
127
//    diag_printf("%s(%p,%p)\n", __FUNCTION__, opaque, ptr);    
128
}
129
 
130
static int
131
_zchar(void)
132
{
133
    int err;
134
    struct _zchar_info *info = (struct _zchar_info *)stream.opaque;
135
    static char spin[] = "|/-\\|-";
136
    static int tick = 0;
137
 
138
    if (info->avail == 0) {
139
        stream.next_out = info->buf;
140
        stream.avail_out = sizeof(info->buf);
141
        info->ptr = info->buf;
142
        err = inflate(&stream, Z_SYNC_FLUSH);
143
        info->avail = (char *)stream.next_out - info->buf;
144
        if (--info->feedback == 0) {
145
            diag_printf("%c\b", spin[tick++]);
146
            if (tick >= (sizeof(spin)-1)) {
147
                tick = 0;
148
            }
149
            info->feedback = FEEDBACK_COUNT;
150
        }
151
    }
152
    if (info->avail) {
153
        info->avail--;
154
        info->total++;
155
        return *(info->ptr)++;
156
    } else {
157
        // End of data stream
158
        return -1;
159
    }
160
}
161
 
162
/**
163
 * A little bit swapping function, necessary due to the xilinx bit file format.
164
 */
165
static const cyg_uint8 _swapped[] = {
166
    0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E,
167
    0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F
168
};
169
 
170
static cyg_uint8
171
bitswap(cyg_uint8 byte)
172
{
173
    cyg_uint8 _new = (_swapped[byte & 0x0F] << 4) | (_swapped[(byte >> 4) & 0x0F]);
174
    return _new;
175
}
176
 
177
typedef int _bitfile_fun(void);
178
typedef void _download_fun(_bitfile_fun *_bitfile);
179
 
180
/**
181
 * Gets the tag at given location in the bitfile.
182
 */
183
static cyg_uint8
184
bitfile_get_tag(_bitfile_fun *_bitfile)
185
{
186
    return (*_bitfile)();
187
}
188
 
189
static cyg_uint16
190
bitfile_get_len16(_bitfile_fun *_bitfile)
191
{
192
    cyg_uint16 length;
193
 
194
    length = (*_bitfile)() << 8;
195
    length |= (*_bitfile)();
196
 
197
    return length;
198
}
199
 
200
static int
201
bitfile_get_len32(_bitfile_fun *_bitfile)
202
{
203
    cyg_uint32 length;
204
 
205
    length = (*_bitfile)() << 24;
206
    length |= (*_bitfile)() << 16;
207
    length |= (*_bitfile)() << 8;
208
    length |= (*_bitfile)();
209
 
210
    return length;
211
}
212
 
213
/**
214
 * Process a string tag.
215
 */
216
static void
217
bitfile_process_string_tag(char *description, _bitfile_fun *_bitfile)
218
{
219
    int len,i;
220
 
221
    len = bitfile_get_len16(_bitfile);
222
    diag_printf(description);
223
    for (i = 0; i < len; i++) {
224
        diag_printf("%c", (*_bitfile)());
225
    }
226
}
227
 
228
/**
229
 * Process the 'e' tag in the bit file, which is the actual code that is to
230
 * be programmed on the fpga.
231
 */
232
static void
233
bitfile_process_tag_e(_bitfile_fun *_bitfile)
234
{
235
    int len,count,i;
236
    cyg_uint8 byte;
237
    cyg_uint32 word;
238
 
239
    len = bitfile_get_len32(_bitfile);
240
 
241
    *PXA2X0_GPCR0 = FPGA_PROG;
242
 
243
    for (count=0; count<10000; count++)
244
        if ((*PXA2X0_GPLR0 & FPGA_INIT) == 0)
245
            break;
246
    if ((*PXA2X0_GPLR0 & FPGA_INIT) != 0)
247
        diag_printf("INIT did not go low. FPGA programming failed\n");
248
 
249
    *PXA2X0_GPSR0 = FPGA_PROG;
250
 
251
    for (count=0; count<10000; count++)
252
        if ((*PXA2X0_GPLR0 & FPGA_INIT) != 0)
253
            break;
254
    if ((*PXA2X0_GPLR0 & FPGA_INIT) == 0)
255
        diag_printf("INIT did not go high. FPGA programming failed\n");
256
 
257
    for( i=0; i<len; i++) {
258
        if ((*PXA2X0_GPLR0 & FPGA_INIT) == 0) {
259
            diag_printf("CRC Error. FPGA programming failed\n");
260
        }
261
 
262
        byte = (*_bitfile)();
263
        word = 0;
264
 
265
        if (byte & (0x01 << 7)) word|=(0x01);
266
        if (byte & (0x01 << 6)) word|=(0x01 << 18);
267
        if (byte & (0x01 << 5)) word|=(0x01 << 14);
268
        if (byte & (0x01 << 4)) word|=(0x01 << 1);
269
        if (byte & (0x01 << 3)) word|=(0x01 << 4);
270
        if (byte & (0x01 << 2)) word|=(0x01 << 6);
271
        if (byte & (0x01 << 1)) word|=(0x01 << 9);
272
        if (byte & (0x01)) word|=(0x01 << 30);
273
 
274
        FPGA_PROG_BASE = word;
275
    }
276
 
277
    for (count=0; count<10000; count++)
278
        if ((*PXA2X0_GPLR0 & FPGA_DONE) != 0)
279
            break;
280
    if ((*PXA2X0_GPLR0 & FPGA_DONE) == 0)
281
        diag_printf("DONE did not go high. FPGA programming failed\n");
282
 
283
}
284
 
285
/**
286
 * Process the 'e' tag in the bit file, which is the actual code that is to
287
 * be programmed on the fpga.
288
 */
289
static void
290
vga_bitfile_process_tag_e(_bitfile_fun *_bitfile)
291
{
292
    int len,count,i;
293
    cyg_uint8 byte;
294
 
295
    len = bitfile_get_len32(_bitfile);
296
 
297
    localbus_writeb(VGA_WRITE,  VGA_PROG_CTRL);
298
    localbus_writeb(VGA_WRITE | VGA_PROG,  VGA_PROG_CTRL);
299
 
300
    for (count=0; count<10000; count++)
301
        if (localbus_readb(VGA_PROG_CTRL) & VGA_INIT)
302
            break;
303
    if (!(localbus_readb(VGA_PROG_CTRL) & VGA_INIT))
304
        diag_printf("INIT did not go high. VGA FPGA programming failed\n");
305
 
306
    localbus_writeb(VGA_PROG, VGA_PROG_CTRL);
307
 
308
    for (i=0; i<len; i++) {
309
        byte = (*_bitfile)();
310
        localbus_writeb(bitswap(byte),VGA_PROG_DATA);
311
    }
312
 
313
    for (count=0; count<10000; count++)
314
        if (localbus_readb(VGA_PROG_CTRL) & VGA_DONE)
315
            break;
316
    if (!(localbus_readb(VGA_PROG_CTRL) & VGA_DONE))
317
        diag_printf("DONE did not go high. VGA FPGA programming failed\n");
318
 
319
    localbus_writeb(VGA_PROG | VGA_WRITE,  VGA_PROG_CTRL);
320
}
321
 
322
//
323
// Download a bitstream
324
//
325
static void
326
download_bitstream(char *title, _bitfile_fun *_bitfile, _download_fun *_download)
327
{
328
    int len, tag;
329
 
330
    diag_printf("Load %s(", title);
331
 
332
    len = bitfile_get_len16(_bitfile);
333
    while (len-- > 0) {
334
        (*_bitfile)();  // Skip
335
    }
336
    len = bitfile_get_len16(_bitfile);
337
 
338
    tag = 0;
339
    while (tag != 'e') {
340
 
341
        tag = bitfile_get_tag(_bitfile);
342
        switch (tag) {
343
        case 'a':
344
            bitfile_process_string_tag("Design:", _bitfile);
345
            break;
346
 
347
        case 'b':
348
            bitfile_process_string_tag(", Part:", _bitfile);
349
            break;
350
 
351
        case 'c':
352
            bitfile_process_string_tag(", Date:", _bitfile);
353
            break;
354
 
355
        case 'd':
356
            bitfile_process_string_tag(" ", _bitfile);
357
            break;
358
 
359
        case 'e':
360
            (*_download)(_bitfile);
361
            break;
362
 
363
        default:
364
            diag_printf("Unknown tag. aborting...\n");
365
            return;
366
        }
367
    }
368
}
369
 
370
 
371
/**
372
 * Process a bitfile located at the given address.
373
 */
374
void
375
load_fpga(cyg_uint8 *compressed_bitfile, int len)
376
{
377
    int err;
378
    struct _zchar_info zchar_data;
379
 
380
    stream.zalloc = _zcalloc;
381
    stream.zfree = _zcfree;
382
    stream.next_in = compressed_bitfile;
383
    stream.avail_in = len;
384
    stream.next_out = 0;
385
    stream.avail_out = 0;
386
    stream.opaque = (void *)&zchar_data;
387
    zchar_data.avail = 0;
388
    zchar_data.feedback = FEEDBACK_COUNT;
389
    zchar_data.total = 0;
390
    err = inflateInit(&stream);
391
    if (err) {
392
        diag_printf("%s: Can't init stream\n", __FUNCTION__);
393
        return;
394
    }
395
    // Set up to download FPGA bitstreap
396
    *PXA2X0_GPSR0 = FPGA_PROG;
397
    download_bitstream("PCI ctlr", _zchar, bitfile_process_tag_e);
398
    inflateEnd(&stream);
399
    diag_printf(") %x bytes\n", zchar_data.total);
400
}
401
 
402
#if 0
403
/**
404
 * Process a bitfile located at the given address.
405
 */
406
void
407
load_vga(cyg_uint8 *compressed_bitfile, int len)
408
{
409
    int err;
410
    struct _zchar_info zchar_data;
411
 
412
    stream.zalloc = _zcalloc;
413
    stream.zfree = _zcfree;
414
    stream.next_in = compressed_bitfile;
415
    stream.avail_in = len;
416
    stream.next_out = 0;
417
    stream.avail_out = 0;
418
    stream.opaque = (void *)&zchar_data;
419
    zchar_data.avail = 0;
420
    zchar_data.feedback = FEEDBACK_COUNT;
421
    zchar_data.total = 0;
422
    err = inflateInit(&stream);
423
    if (err) {
424
        diag_printf("%s: Can't init stream\n", __FUNCTION__);
425
        return;
426
    }
427
    download_bitstream("VGA ctlr", _zchar, vga_bitfile_process_tag_e);
428
    inflateEnd(&stream);
429
    diag_printf(") %x bytes\n", zchar_data.total);
430
}
431
#endif
432
 

powered by: WebSVN 2.1.0

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