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

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [soft/] [linux/] [common/] [pex/] [pex_board.cpp] - Blame information for rev 54

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dsmv
 
2
#ifndef __PEX_BOARD_H__
3
#include "pex_board.h"
4
#endif
5
 
6
//-----------------------------------------------------------------------------
7
 
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <fcntl.h>
11
#include <errno.h>
12 35 v.karak
#include <unistd.h>
13 2 dsmv
#include <sys/mman.h>
14
#include <sys/ioctl.h>
15
 
16
#include <cassert>
17
#include <cstdlib>
18
#include <cstring>
19
#include <iostream>
20
#include <iomanip>
21
#include <climits>
22
 
23
//-----------------------------------------------------------------------------
24
 
25
using namespace std;
26
 
27
//-----------------------------------------------------------------------------
28
 
29
pex_board::pex_board()
30
{
31
    fd = -1;
32
    bar0 = bar1 = NULL;
33
    memset(&bi, 0, sizeof(bi));
34 6 v.karak
    //m_dma = new dma_memory();
35 2 dsmv
}
36
 
37
//-----------------------------------------------------------------------------
38
 
39
pex_board::~pex_board()
40
{
41 6 v.karak
    //if(m_dma) delete m_dma;
42 2 dsmv
    core_close();
43
}
44
 
45
//-----------------------------------------------------------------------------
46
 
47
int pex_board::core_open(const char *name)
48
{
49
    int error = 0;
50
 
51
    if(fd > 0)
52
        return 0;
53
 
54 54 v.karak
    //fd = open(name, S_IROTH | S_IWOTH );
55
    fd = open(name, 0666 );
56 2 dsmv
    if(fd < 0) {
57
        std::cerr << __FUNCTION__ << "(): " << " error open device: " << name << endl;
58
        goto do_out;
59
    }
60
 
61
    error = core_board_info();
62
    if(error < 0) {
63
        std::cerr << __FUNCTION__ << "(): " << " error get board info" << endl;
64
        goto do_close;
65
    }
66
 
67
    bar0 = (u32*)mmap(NULL, bi.Size[0], PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)bi.PhysAddress[0]);
68
    if( bar0 == MAP_FAILED ) {
69
        std::cerr << __FUNCTION__ << "(): " << " error map bar0 address" << endl;
70
        error = -EINVAL;
71
        goto do_close;
72
    }
73
 
74
    bar1 = (u32*)mmap(NULL, bi.Size[1], PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)bi.PhysAddress[1]);
75
    if( bar1== MAP_FAILED ) {
76
        std::cerr << __FUNCTION__ << "(): " << " error map bar1 address" << endl;
77
        error = -EINVAL;
78
        goto do_unmap_bar0;
79
    }
80
 
81
    std::cout << "Map BAR0: 0x" << hex << bi.PhysAddress[0] << " -> " << bar0 << dec << endl;
82
    std::cout << "Map BAR1: 0x" << hex << bi.PhysAddress[1] << " -> " << bar1 << dec << endl;
83
 
84
    return 0;
85
 
86
do_unmap_bar0:
87
    munmap(bar0, bi.Size[0]);
88
 
89
do_close:
90
    close(fd);
91
 
92
do_out:
93
    return error;
94
}
95
 
96
//-----------------------------------------------------------------------------
97
 
98
int pex_board::core_init()
99
{
100
    uint16_t temp = 0;
101
    uint16_t blockId = 0;
102
    uint16_t blockVer = 0;
103
    uint16_t deviceID = 0;
104
    uint16_t deviceRev = 0;
105
    int i = 0;
106
 
107
    fprintf(stderr,"%s()\n", __FUNCTION__);
108
 
109
    blockId =  core_block_read( 0, 0 );
110
    blockVer = core_block_read( 0, 1 );
111
 
112
    fprintf(stderr,"%s(): BlockID = 0x%X, BlockVER = 0x%X.\n", __FUNCTION__, blockId, blockVer);
113
 
114
    deviceID = core_block_read(  0, 2 );
115
    deviceRev = core_block_read( 0, 3 );
116
 
117
    fprintf(stderr,"%s(): DeviceID = 0x%X, DeviceRev = 0x%X.\n", __FUNCTION__, deviceID, deviceRev);
118
 
119
    temp = core_block_read( 0, 4 );
120
    int m_BlockCnt = core_block_read( 0, 5 );
121
 
122
    if( m_BlockCnt>8 ) {
123
        m_BlockCnt=8;
124
    }
125
 
126
    fprintf(stderr,"%s(): PldVER = 0x%X.\n", __FUNCTION__, temp);
127
    fprintf(stderr,"%s(): Block count = %d.\n", __FUNCTION__, m_BlockCnt);
128
 
129
    // определим какие каналы ПДП присутствуют и их характеристики:
130
    // направление передачи данных, размер FIFO, максимальный размер блока ПДП
131
 
132
    FIFO_ID FifoId;
133
    int m_DmaFifoSize[4] = {0};
134
    int m_MaxDmaSize[4] = {0};
135
    int m_DmaDir[4] = {0};
136
    int m_DmaChanMask = 0;
137
 
138
    for(int iBlock = 0; iBlock < m_BlockCnt; iBlock++)
139
    {
140
        uint16_t block_id = 0;
141
 
142
        block_id=core_block_read( iBlock, 0 );
143
        block_id &=0xFFF;
144
 
145
        if(block_id == PE_EXT_FIFO_ID)
146
        {
147
            u32 resource_id = 0;
148
            uint16_t iChan = core_block_read( iBlock, 3 );
149
            m_DmaChanMask |= (1 << iChan);
150
            FifoId.AsWhole = core_block_read( iBlock, 2 );
151
            m_DmaFifoSize[iChan] = FifoId.ByBits.Size;
152
            m_DmaDir[iChan] = FifoId.ByBits.Dir;
153
            m_MaxDmaSize[iChan] = 0x40000000; // макс. размер ПДП пусть будет 1 Гбайт
154
            resource_id = core_block_read( iBlock, 4 ); // RESOURCE
155
            fprintf(stderr,"%s(): Channel(ID) = %d(0x%x), FIFO size = %d Bytes, DMA Dir = %d, Max DMA size = %d MBytes, resource = 0x%x.\n", __FUNCTION__,
156
                    iChan, block_id, m_DmaFifoSize[iChan] * 4, m_DmaDir[iChan], m_MaxDmaSize[iChan] / 1024 / 1024, resource_id);
157
        }
158
    }
159
 
160
    // подготовим к работе ПЛИС ADM
161
    fprintf(stderr,"%s(): Prepare ADM PLD.\n", __FUNCTION__);
162
    core_block_write( 0, 8, 0);
163 6 v.karak
    core_delay(100);    // pause ~ 100 msec
164 2 dsmv
    for(i = 0; i < 10; i++)
165
    {
166
        core_block_write( 0, 8, 1);
167 6 v.karak
        core_delay(100);        // pause ~ 100 msec
168 2 dsmv
        core_block_write( 0, 8, 3);
169 6 v.karak
        core_delay(100);        // pause ~ 100 msec
170 2 dsmv
        core_block_write( 0, 8, 7);
171 6 v.karak
        core_delay(100);        // pause ~ 100 msec
172 2 dsmv
        temp = core_block_read( 0, 010 ) & 0x01;
173
        if(temp)
174
            break;
175
    }
176
    core_block_write( 0, 8, 0xF );
177 6 v.karak
    core_delay(100);    // pause ~ 100 msec
178 2 dsmv
 
179
    return 0;
180
}
181
 
182
//-----------------------------------------------------------------------------
183
 
184
int pex_board::core_reset()
185
{
186 54 v.karak
/*  for test read() syscall in userspace DMA mode
187
    void *data = NULL;
188
    size_t size = sysconf(_SC_PAGESIZE)*16;
189
    size_t align = sysconf(_SC_PAGESIZE);
190
    int res = posix_memalign(&data, align, size);
191
    if(res < 0) {
192
        fprintf(stderr, "error in posix_memalign()\n");
193
        return -1;
194
    }
195
 
196
    res = read(fd, data, size);
197
    if(res < 0) {
198
        fprintf(stderr, "error in read()\n");
199
        return -1;
200
    }
201
 
202
    free(data);
203
*/
204 2 dsmv
    return 0;
205
}
206
 
207
//-----------------------------------------------------------------------------
208
 
209
int pex_board::core_close()
210
{
211
    if(bar0) {
212
        munmap(bar0, bi.Size[0]);
213
        bar0 = NULL;
214
    }
215
    if(bar1) {
216
        munmap(bar1, bi.Size[1]);
217
        bar1 = NULL;
218
    }
219
 
220
    close(fd);
221
    fd = -1;
222
 
223
 
224
    return 0;
225
}
226
 
227
//-----------------------------------------------------------------------------
228
 
229
int pex_board::core_load_dsp()
230
{
231
    return 0;
232
}
233
 
234
//-----------------------------------------------------------------------------
235
 
236
int pex_board::core_load_pld()
237
{
238
    return 0;
239
}
240
 
241
//-----------------------------------------------------------------------------
242
 
243
int pex_board::core_board_info()
244
{
245
    int error = ioctl(fd, IOCTL_PEX_BOARD_INFO, &bi);
246
    if(error < 0) {
247
        std::cerr << __FUNCTION__ << "(): " << " error get board info" << endl;
248
        return -1;
249
    }
250
/*
251
    fprintf(stderr, "VENDOR ID: 0x%X\n", bi.vendor_id);
252
    fprintf(stderr, "DEVICE ID: 0x%X\n", bi.device_id);
253
    fprintf(stderr, "BAR0: 0x%zX\n", bi.PhysAddress[0]);
254
    fprintf(stderr, "SIZE: 0x%zX\n", bi.Size[0]);
255
    fprintf(stderr, "BAR1 0x%zX\n", bi.PhysAddress[1]);
256
    fprintf(stderr, "SIZE: 0x%zX\n", bi.Size[1]);
257
    fprintf(stderr, "IRQ: 0x%zX\n", bi.InterruptVector);
258
*/
259
    return 0;
260
}
261
 
262
//-----------------------------------------------------------------------------
263
 
264
int pex_board::core_pld_info()
265
{
266
    u32 d = 0;
267
    u32 d1 = 0;
268
    u32 d2 = 0;
269
    u32 d3 = 0;
270
    u32 d4 = 0;
271
    u32 d5 = 0;
272
    int ii = 0;
273
 
274
    if(!bar1)
275
        return -1;
276
 
277
    fprintf(stderr," Firmware PLD ADM\n" );
278
    core_reg_poke_dir(0, 1, 1);
279
    core_reg_poke_dir(0, 1, 1);
280
 
281
    d=core_reg_peek_ind( 0, 0x108 );
282
    if( d==0x4953 ) {
283
        fprintf(stderr, " SIG = 0x%.4X - Ok\n", d );
284
    } else {
285
        fprintf(stderr, " SIG = 0x%.4X - Error, waiting 0x4953\n", d );
286
        return -1;
287
    }
288
 
289
    d=core_reg_peek_ind(  0, 0x109 );  fprintf(stderr, " ADM interface version:  %d.%d\n", d>>8, d&0xFF );
290
    d=core_reg_peek_ind(  0, 0x110 ); d1=core_reg_peek_ind(  0, 0x111 );
291
    fprintf(stderr,  " Base module: 0x%.4X  v%d.%d\n", d, d1>>8, d1&0xFF );
292
 
293
    d=core_reg_peek_ind(  0, 0x112 ); d1=core_reg_peek_ind(  0, 0x113 );
294
    fprintf(stderr,  " Submodule: 0x%.4X  v%d.%d\n", d, d1>>8, d1&0xFF );
295
 
296
    d=core_reg_peek_ind(  0, 0x10B );  fprintf(stderr,  " Firmware modificaton:  %d \n", d );
297
    d=core_reg_peek_ind(  0, 0x10A );  fprintf(stderr,  " Firmware version:       %d.%d\n", d>>8, d&0xFF );
298
    d=core_reg_peek_ind(  0, 0x114 );  fprintf(stderr,  " Firmware build number: 0x%.4X\n", d );
299
 
300
    fprintf(stderr,  "\n Information about the tetrads:\n\n" );
301
    for( ii=0; ii<8; ii++ ) {
302
 
303
        const char *str;
304
 
305
        d=core_reg_peek_ind(  ii, 0x100 );
306
        d1=core_reg_peek_ind(  ii, 0x101 );
307
        d2=core_reg_peek_ind(  ii, 0x102 );
308
        d3=core_reg_peek_ind(  ii, 0x103 );
309
        d4=core_reg_peek_ind(  ii, 0x104 );
310
        d5=core_reg_peek_ind(  ii, 0x105 );
311
 
312
        switch( d ) {
313 6 v.karak
        case 1: str="TRD_MAIN         "; break;
314
        case 2: str="TRD_BASE_DAC     "; break;
315
        case 3: str="TRD_PIO_STD      "; break;
316 2 dsmv
        case 0:    str=" -            "; break;
317
        case 0x47: str="SBSRAM_IN     "; break;
318
        case 0x48: str="SBSRAM_OUT    "; break;
319
        case 0x12: str="DIO64_OUT     "; break;
320
        case 0x13: str="DIO64_IN      "; break;
321
        case 0x14: str="ADM212x200M   "; break;
322
        case 0x5D: str="ADM212x500M   "; break;
323
        case 0x41: str="DDS9956       "; break;
324
        case 0x4F: str="TEST_CTRL     "; break;
325
        case 0x3F: str="ADM214x200M   "; break;
326
        case 0x40: str="ADM216x100    "; break;
327
        case 0x2F: str="ADM28x1G      "; break;
328
        case 0x2D: str="TRD128_OUT    "; break;
329
        case 0x4C: str="TRD128_IN     "; break;
330
        case 0x30: str="ADMDDC5016    "; break;
331
        case 0x2E: str="ADMFOTR2G     "; break;
332
        case 0x49: str="ADMFOTR3G     "; break;
333
        case 0x67: str="DDS9912       "; break;
334
        case 0x70: str="AMBPEX5_SDRAM "; break;
335
        case 0x71: str="TRD_MSG       "; break;
336
        case 0x72: str="TRD_TS201     "; break;
337
        case 0x73: str="TRD_STREAM_IN "; break;
338
        case 0x74: str="TRD_STREAM_OUT"; break;
339 6 v.karak
        case 0xA0: str="TRD_ADC       "; break;
340
        case 0xA1: str="TRD_DAC       "; break;
341
        case 0x91: str="TRD_EMAC      "; break;
342 2 dsmv
 
343
 
344
        default: str="UNKNOWN"; break;
345
        }
346
        fprintf(stderr,  " %d  0x%.4X %s ", ii, d, str );
347
        if( d>0 ) {
348
            fprintf(stderr,  " MOD: %-2d VER: %d.%d ", d1, d2>>8, d2&0xFF );
349
            if( d3 & 0x10 ) {
350
                fprintf(stderr,  "FIFO IN   %dx%d\n", d4, d5 );
351
            } else if( d3 & 0x20 ) {
352
                fprintf(stderr,  "FIFO OUT  %dx%d\n", d4, d5 );
353
            } else {
354
                fprintf(stderr,  "\n" );
355
            }
356
        } else {
357
            fprintf(stderr,  "\n" );
358
        }
359
 
360
    }
361
 
362
    return 0;
363
}
364
 
365
//-----------------------------------------------------------------------------
366
 
367
int pex_board::core_resource()
368
{
369
    return 0;
370
}
371
 
372
//-----------------------------------------------------------------------------
373
 
374 6 v.karak
void pex_board::core_delay(int ms)
375 2 dsmv
{
376
    struct timeval tv = {0, 0};
377
    tv.tv_usec = 1000*ms;
378
 
379
    select(0,NULL,NULL,NULL,&tv);
380
}
381
 
382
//-----------------------------------------------------------------------------
383
 
384
u32 pex_board::core_reg_peek_dir( u32 trd, u32 reg )
385
{
386 54 v.karak
    if( (trd>15) || (reg>3) ) {
387
        fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
388 2 dsmv
        return -1;
389 54 v.karak
    }
390 2 dsmv
 
391
    u32 offset = trd*0x4000 + reg*0x1000;
392
    u32 ret = *(bar1 + offset/4);
393
 
394
    return ret;
395
}
396
 
397
//-----------------------------------------------------------------------------
398
 
399
u32 pex_board::core_reg_peek_ind( u32 trd, u32 reg )
400
{
401 54 v.karak
    if( (trd>15) || (reg>0x3FF) ) {
402
        fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
403 2 dsmv
        return -1;
404 54 v.karak
    }
405 2 dsmv
 
406
    u32 status;
407
    u32 Status  = trd*0x4000;
408
    u32 CmdAdr  = trd*0x4000 + 0x2000;
409
    u32 CmdData = trd*0x4000 + 0x3000;
410
    u32 ret;
411
 
412
    bar1[CmdAdr/4] = reg;
413
 
414
    for( int ii=0; ; ii++ ) {
415
 
416
        status = bar1[Status/4];
417
        if( status & 1 )
418
            break;
419
 
420
        if( ii>10000 )
421 6 v.karak
            core_delay( 1 );
422 2 dsmv
        if( ii>20000 ) {
423
            return 0xFFFF;
424
        }
425
    }
426
 
427
    ret = bar1[CmdData/4];
428
    ret &= 0xFFFF;
429
 
430
    return ret;
431
}
432
 
433
//-----------------------------------------------------------------------------
434
 
435
void pex_board::core_reg_poke_dir( u32 trd, u32 reg, u32 val )
436
{
437 54 v.karak
    if( (trd>15) || (reg>3) ) {
438
        fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
439 2 dsmv
        return;
440 54 v.karak
    }
441 2 dsmv
 
442
    u32 offset = trd*0x4000+reg*0x1000;
443
 
444
    bar1[offset/4]=val;
445
}
446
 
447
//-----------------------------------------------------------------------------
448
 
449
void pex_board::core_reg_poke_ind( u32 trd, u32 reg, u32 val )
450
{
451 54 v.karak
    if( (trd>15) || (reg>0x3FF) ) {
452
        fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
453 2 dsmv
        return;
454 54 v.karak
    }
455 2 dsmv
 
456
    u32 status;
457
    u32 Status  = trd*0x4000;
458
    u32 CmdAdr  = trd*0x4000 + 0x2000;
459
    u32 CmdData = trd*0x4000 + 0x3000;
460
 
461
    bar1[CmdAdr/4] = reg;
462
 
463
    for( int ii=0; ; ii++ ) {
464
 
465
        status = bar1[Status/4];
466
        if( status & 1 )
467
            break;
468
 
469
        if( ii>10000 )
470 6 v.karak
            core_delay( 1 );
471 2 dsmv
        if( ii>20000 ) {
472
            return;
473
        }
474
    }
475
 
476
    bar1[CmdData/4] = val;
477
}
478
 
479
//-----------------------------------------------------------------------------
480
 
481
u32  pex_board::core_bar0_read( u32 offset )
482
{
483 6 v.karak
    return bar0[2*offset];
484 2 dsmv
}
485
 
486
//-----------------------------------------------------------------------------
487
 
488
void pex_board::core_bar0_write( u32 offset, u32 val )
489
{
490 6 v.karak
    bar0[2*offset] = val;
491 2 dsmv
}
492
 
493
//-----------------------------------------------------------------------------
494
 
495
u32  pex_board::core_bar1_read( u32 offset )
496
{
497 6 v.karak
    return bar1[2*offset];
498 2 dsmv
}
499
 
500
//-----------------------------------------------------------------------------
501
 
502
void pex_board::core_bar1_write( u32 offset, u32 val )
503
{
504 19 dsmv
    bar1[2*offset] = val;
505 2 dsmv
}
506
 
507
//-----------------------------------------------------------------------------
508
 
509
void pex_board::core_block_write( u32 nb, u32 reg, u32 val )
510
{
511
    if( (nb>7) || (reg>31) )
512
        return;
513
 
514
    *(bar0+nb*64+reg*2)=val;
515
}
516
 
517
//-----------------------------------------------------------------------------
518
 
519
u32  pex_board::core_block_read( u32 nb, u32 reg )
520
{
521 54 v.karak
    if( (nb>7) || (reg>31) ) {
522
        fprintf(stderr, "%s(): Invalid arguments.\n", __FUNCTION__);
523 2 dsmv
        return -1;
524 54 v.karak
    }
525 2 dsmv
 
526
    u32 ret = 0;
527
 
528
    ret=*(bar0+nb*64+reg*2);
529
    if( reg<8 )
530
        ret&=0xFFFF;
531
 
532
    return ret;
533
}
534
 
535
//-----------------------------------------------------------------------------
536
 
537 54 v.karak
u32 pex_board::core_allocate_memory(int DmaChan, BRDctrl_StreamCBufAlloc* sSCA)
538 2 dsmv
{
539
    m_DescrSize[DmaChan] = sizeof(AMB_MEM_DMA_CHANNEL) + (sSCA->blkNum - 1) * sizeof(void*);
540
    m_Descr[DmaChan] = (AMB_MEM_DMA_CHANNEL*) new u8[m_DescrSize[DmaChan]];
541
 
542
    m_Descr[DmaChan]->DmaChanNum = DmaChan;
543
    m_Descr[DmaChan]->Direction = sSCA->dir;
544
    m_Descr[DmaChan]->LocalAddr = 0;
545
    m_Descr[DmaChan]->MemType = sSCA->isCont;
546
    m_Descr[DmaChan]->BlockCnt = sSCA->blkNum;
547
    m_Descr[DmaChan]->BlockSize = sSCA->blkSize;
548
    m_Descr[DmaChan]->pStub = NULL;
549
 
550
    for(u32 iBlk = 0; iBlk < sSCA->blkNum; iBlk++) {
551
            m_Descr[DmaChan]->pBlock[iBlk] = NULL;
552
    }
553
 
554
    if( ioctl(fd, IOCTL_AMB_SET_MEMIO, m_Descr[DmaChan]) < 0 ) {
555
        fprintf(stderr, "%s(): Error allocate memory\n", __FUNCTION__ );
556
        return -1;
557
    }
558
 
559
    for(u32 iBlk = 0; iBlk < m_Descr[DmaChan]->BlockCnt; iBlk++) {
560
 
561
        void *MappedAddress = mmap( NULL,
562
                                    m_Descr[DmaChan]->BlockSize,
563
                                    PROT_READ | PROT_WRITE,
564
                                    MAP_SHARED,
565
                                    fd,
566
                                    (off_t)m_Descr[DmaChan]->pBlock[iBlk] );
567
 
568
        if(MappedAddress == MAP_FAILED) {
569
            fprintf(stderr, "%s(): Error map memory\n", __FUNCTION__ );
570
            return -1;
571
        }
572
 
573
        fprintf(stderr,"%d: %p -> %p\n", iBlk, (void*)m_Descr[DmaChan]->pBlock[iBlk], MappedAddress);
574
 
575
        //сохраним отображенный в процесс физический адрес текущего блока
576
        m_Descr[DmaChan]->pBlock[iBlk] = MappedAddress;
577
        sSCA->ppBlk[iBlk] = MappedAddress;
578
/*
579
        u32 *buffer = (u32*)MappedAddress;
580
        for(u32 jj=0; jj<m_Descr[DmaChan]->BlockSize/4; jj+=0x100) {
581
            fprintf(stdout,"%x ", buffer[jj]);
582
        }
583
        fprintf(stdout,"\n");
584
*/
585
    }
586
 
587
    if(m_Descr[DmaChan]->pStub) {
588
 
589
        void *StubAddress = mmap( NULL,
590
                                  sizeof(AMB_STUB),
591
                                  PROT_READ | PROT_WRITE,
592
                                  MAP_SHARED,
593
                                  fd,
594
                                  (off_t)m_Descr[DmaChan]->pStub );
595
 
596
        if(StubAddress == MAP_FAILED) {
597
            fprintf(stderr, "%s(): Error map stub\n", __FUNCTION__ );
598
            return -1;
599
        }
600
 
601
        fprintf(stderr,"Stub: %p -> %p\n", (void*)m_Descr[DmaChan]->pStub, StubAddress);
602
 
603
        m_Descr[DmaChan]->pStub = StubAddress;
604
        sSCA->pStub = (BRDstrm_Stub*)m_Descr[DmaChan]->pStub;
605
    }
606
 
607
    //сохраним информацию в буфере пользователя
608
    sSCA->blkNum = m_Descr[DmaChan]->BlockCnt;
609
 
610
    return 0;
611
}
612
 
613
//-----------------------------------------------------------------------------
614
 
615 6 v.karak
u32 pex_board::core_allocate_memory(int DmaChan,
616
                                    void** pBuf,
617
                                    u32 blkSize,
618
                                    u32 blkNum,
619
                                    u32 isSysMem,
620
                                    u32 dir,
621
                                    u32 addr,
622
                                    BRDstrm_Stub **pStub )
623 2 dsmv
{
624
    m_DescrSize[DmaChan] = sizeof(AMB_MEM_DMA_CHANNEL) + (blkNum - 1) * sizeof(void*);
625
    m_Descr[DmaChan] = (AMB_MEM_DMA_CHANNEL*) new u8[m_DescrSize[DmaChan]];
626
 
627
    m_Descr[DmaChan]->DmaChanNum = DmaChan;
628
    m_Descr[DmaChan]->Direction = dir;
629
    m_Descr[DmaChan]->LocalAddr = addr;
630
    m_Descr[DmaChan]->MemType = isSysMem;
631
    m_Descr[DmaChan]->BlockCnt = blkNum;
632
    m_Descr[DmaChan]->BlockSize = blkSize;
633
    m_Descr[DmaChan]->pStub = NULL;
634
 
635
    for(u32 iBlk = 0; iBlk < blkNum; iBlk++) {
636
            m_Descr[DmaChan]->pBlock[iBlk] = NULL;
637
    }
638
 
639
    if( ioctl(fd, IOCTL_AMB_SET_MEMIO, m_Descr[DmaChan]) < 0 ) {
640
        fprintf(stderr, "%s(): Error allocate memory\n", __FUNCTION__ );
641
        return -1;
642
    }
643
 
644
    for(u32 iBlk = 0; iBlk < blkNum; iBlk++) {
645
 
646
        void *MappedAddress = mmap( NULL,
647
                                    m_Descr[DmaChan]->BlockSize,
648
                                    PROT_READ | PROT_WRITE,
649
                                    MAP_SHARED,
650
                                    fd,
651
                                    (off_t)m_Descr[DmaChan]->pBlock[iBlk] );
652
 
653
        if(MappedAddress == MAP_FAILED) {
654
            fprintf(stderr, "%s(): Error map memory\n", __FUNCTION__ );
655
            return -1;
656
        }
657
 
658
        fprintf(stderr,"%d: %p -> %p\n", iBlk, (void*)m_Descr[DmaChan]->pBlock[iBlk], MappedAddress);
659
 
660
        //сохраним отображенный в процесс физический адрес текущего блока
661
        m_Descr[DmaChan]->pBlock[iBlk] = MappedAddress;
662
    }
663
 
664
    if(m_Descr[DmaChan]->pStub) {
665
 
666
        void *StubAddress = mmap( NULL,
667
                                  sizeof(AMB_STUB),
668
                                  PROT_READ | PROT_WRITE,
669
                                  MAP_SHARED,
670
                                  fd,
671
                                  (off_t)m_Descr[DmaChan]->pStub );
672
 
673
        if(StubAddress == MAP_FAILED) {
674
            fprintf(stderr, "%s(): Error map stub\n", __FUNCTION__ );
675
            return -1;
676
        }
677
 
678
        fprintf(stderr,"Stub: %p -> %p\n", (void*)m_Descr[DmaChan]->pStub, StubAddress);
679
 
680
        m_Descr[DmaChan]->pStub = StubAddress;
681
    }
682
 
683
    *pBuf = &m_Descr[DmaChan]->pBlock[0];
684 6 v.karak
    *pStub = (BRDstrm_Stub*)m_Descr[DmaChan]->pStub;
685 2 dsmv
 
686
    return 0;
687
}
688
 
689
//-----------------------------------------------------------------------------
690
 
691
u32  pex_board::core_free_memory(int DmaChan)
692
{
693
    for(u32 iBlk = 0; iBlk < m_Descr[DmaChan]->BlockCnt; iBlk++) {
694
        munmap( m_Descr[DmaChan]->pBlock[iBlk], m_Descr[DmaChan]->BlockSize );
695
    }
696
 
697 54 v.karak
    fprintf(stderr, "%s(): Unmap blocks - OK\n", __FUNCTION__ );
698
 
699 2 dsmv
    munmap( m_Descr[DmaChan]->pStub, sizeof(AMB_STUB) );
700
 
701 54 v.karak
    fprintf(stderr, "%s(): Unmap stub - OK\n", __FUNCTION__ );
702
 
703 2 dsmv
    if(ioctl(fd, IOCTL_AMB_FREE_MEMIO, m_Descr[DmaChan]) < 0) {
704
        fprintf(stderr, "%s(): Error free memory\n", __FUNCTION__ );
705
        return -1;
706
    }
707
 
708
    delete m_Descr[DmaChan];
709
    m_Descr[DmaChan] = NULL;
710
 
711
    return 0;
712
}
713
 
714
//-----------------------------------------------------------------------------
715
 
716
u32  pex_board::core_start_dma(int DmaChan, int IsCycling)
717
{
718 19 dsmv
 
719
fprintf(stderr, "%s(): DmaChan=%d IsCycling=%d \n", __FUNCTION__, DmaChan, IsCycling );
720 2 dsmv
    if(m_Descr[DmaChan])
721
    {
722
        AMB_START_DMA_CHANNEL StartDescrip;
723
        StartDescrip.DmaChanNum = DmaChan;
724
        StartDescrip.IsCycling = IsCycling;
725
 
726 19 dsmv
        fprintf(stderr, "%s(): IOCTL_AMB_START_MEMIO  ", __FUNCTION__ );
727
 
728 2 dsmv
        if (ioctl(fd,IOCTL_AMB_START_MEMIO,&StartDescrip) < 0) {
729
            fprintf(stderr, "%s(): Error start DMA\n", __FUNCTION__ );
730
            return -1;
731
        }
732 19 dsmv
        fprintf(stderr, " %s - OK \n", __FUNCTION__ );
733 2 dsmv
    }
734
    return 0;
735
}
736
 
737
//-----------------------------------------------------------------------------
738
 
739
u32  pex_board::core_stop_dma(int DmaChan)
740
{
741
    if(m_Descr[DmaChan])
742
    {
743
        AMB_STUB* pStub = (AMB_STUB*)m_Descr[DmaChan]->pStub;
744
        if(pStub->state == STATE_RUN)
745
        {
746
            AMB_STATE_DMA_CHANNEL StateDescrip;
747
            StateDescrip.DmaChanNum = DmaChan;
748
            StateDescrip.Timeout = 0;//pState->timeout; останавливает немедленно (в 0-кольце оставлю пока возможность ожидания)
749
 
750
            if (ioctl(fd, IOCTL_AMB_STOP_MEMIO, &StateDescrip) < 0) {
751
                fprintf(stderr, "%s(): Error stop DMA\n", __FUNCTION__ );
752
                return -1;
753
            }
754
        }
755
    }
756
    return 0;
757
}
758
 
759
//-----------------------------------------------------------------------------
760
 
761
u32  pex_board::core_state_dma(int DmaChan, u32 msTimeout, int& state, u32& blkNum)
762
{
763
    AMB_STATE_DMA_CHANNEL StateDescrip;
764
    StateDescrip.DmaChanNum = DmaChan;
765
    StateDescrip.Timeout = msTimeout;
766
 
767
    if (0 > ioctl(fd, IOCTL_AMB_STATE_MEMIO, &StateDescrip)) {
768
        fprintf(stderr, "%s(): Error state DMA\n", __FUNCTION__ );
769
        return -1;
770
    }
771
    blkNum = StateDescrip.BlockCntTotal;
772
    state = StateDescrip.DmaChanState;
773
 
774
    return 0;
775
}
776
 
777
//-----------------------------------------------------------------------------
778
 
779
u32  pex_board::core_wait_buffer(int DmaChan, u32 msTimeout)
780
{
781
    AMB_STATE_DMA_CHANNEL WaitDmaDescr;
782
    WaitDmaDescr.DmaChanNum = DmaChan;
783
    WaitDmaDescr.Timeout = msTimeout;
784
 
785
    if(m_Descr[DmaChan])
786
    {
787
        if (0 > ioctl(fd, IOCTL_AMB_WAIT_DMA_BUFFER, &WaitDmaDescr)) {
788
            fprintf(stderr, "%s(): Error wait buffer DMA\n", __FUNCTION__ );
789
            return -1;
790
        }
791
    }
792
 
793
    return 0;
794
}
795
 
796
//-----------------------------------------------------------------------------
797
 
798
u32  pex_board::core_wait_block(int DmaChan, u32 msTimeout)
799
{
800
    AMB_STATE_DMA_CHANNEL WaitDmaDescr;
801
    WaitDmaDescr.DmaChanNum = DmaChan;
802
    WaitDmaDescr.Timeout = msTimeout;
803
 
804
    if(m_Descr[DmaChan])
805
    {
806
        if (0 > ioctl(fd, IOCTL_AMB_WAIT_DMA_BLOCK, &WaitDmaDescr)) {
807
            fprintf(stderr, "%s(): Error wait block DMA\n", __FUNCTION__ );
808
            return -1;
809
        }
810
    }
811
 
812
    return 0;
813
}
814
 
815
//-----------------------------------------------------------------------------
816
 
817
u32 pex_board::core_reset_fifo(int DmaChan)
818
{
819
    AMB_SET_DMA_CHANNEL DmaParam;
820
    DmaParam.DmaChanNum = DmaChan;
821
    DmaParam.Param = 0;
822
 
823
    if(m_Descr[DmaChan])
824
    {
825
        if (0 > ioctl(fd, IOCTL_AMB_RESET_FIFO, &DmaParam)) {
826
            fprintf(stderr, "%s(): Error reset FIFO\n", __FUNCTION__ );
827
            return -1;
828
        }
829
    }
830
 
831
    return 0;
832
}
833
 
834
//-----------------------------------------------------------------------------
835
 
836
u32 pex_board::core_set_local_addr(int DmaChan, u32 addr)
837
{
838
    AMB_SET_DMA_CHANNEL DmaParam;
839
    DmaParam.DmaChanNum = DmaChan;
840 5 v.karak
    DmaParam.Param = addr;
841 2 dsmv
 
842 19 dsmv
fprintf(stderr, "%s(): DmaChan=%d addr=0x%.8X \n", __FUNCTION__, DmaChan, addr );
843
 
844
 
845 2 dsmv
    if(m_Descr[DmaChan])
846
    {
847
        if (0 > ioctl(fd, IOCTL_AMB_SET_SRC_MEM, &DmaParam)) {
848
            fprintf(stderr, "%s(): Error set source for DMA\n", __FUNCTION__ );
849
            return -1;
850
        }
851 19 dsmv
 
852
 
853
       DmaParam.Param = m_Descr[DmaChan]->Direction;
854
 
855
          if (0 > ioctl(fd, IOCTL_AMB_SET_DIR_MEM, &DmaParam)) {
856
              fprintf(stderr, "%s(): Error set dir for DMA\n", __FUNCTION__ );
857
              return -1;
858
          }
859
 
860
 
861 2 dsmv
    }
862
 
863
    return 0;
864
}
865
 
866
//-----------------------------------------------------------------------------
867
 
868
u32 pex_board::core_adjust(int DmaChan, u32 mode)
869
{
870
    AMB_SET_DMA_CHANNEL DmaParam;
871
    DmaParam.DmaChanNum = DmaChan;
872
    DmaParam.Param = mode;
873
 
874
    if(m_Descr[DmaChan])
875
    {
876
        if (0 > ioctl(fd, IOCTL_AMB_ADJUST, &DmaParam)) {
877
            fprintf(stderr, "%s(): Error adjust DMA\n", __FUNCTION__ );
878
            return -1;
879
        }
880
    }
881
 
882
    return 0;
883
}
884
 
885
//-----------------------------------------------------------------------------
886
 
887
u32 pex_board::core_done(int DmaChan, u32 blockNumber)
888
{
889
    AMB_SET_DMA_CHANNEL DmaParam;
890
    DmaParam.DmaChanNum = DmaChan;
891
    DmaParam.Param = blockNumber;
892
 
893
    if(m_Descr[DmaChan])
894
    {
895
        if (0 > ioctl(fd, IOCTL_AMB_DONE, &DmaParam)) {
896
            fprintf(stderr, "%s(): Error done DMA\n", __FUNCTION__ );
897
            return -1;
898
        }
899
    }
900
 
901
    return 0;
902
}
903
 
904
//-----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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