source: trunk/tools/bootloader_tsar/boot_bdv_driver.c @ 418

Last change on this file since 418 was 6, checked in by alain, 8 years ago

Modify the boot_info_t struct to describe external peripherals in all clusters.

File size: 4.9 KB
RevLine 
[1]1///////////////////////////////////////////////////////////////////////////////////
2// File     : boot_bdv_driver.c
3// Date     : 18/01/2017
4// Author   : Alain Greiner / Vu Son
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <boot_config.h>
9#include <boot_bdv_driver.h>
10#include <boot_mmc_driver.h>
11#include <boot_utils.h>
12
13#ifndef SEG_IOC_BASE
[6]14# error "The SEG_IOC_BASE value should be defined in the 'hard_config.h' file"
[1]15#endif
16
[6]17#ifndef X_IO
18# error "The X_IO value should be defined in the 'hard_config.h' file"
[1]19#endif
20
[6]21#ifndef Y_IO
22# error "The Y_IO value should be defined in the 'hard_config.h' file"
23#endif
[1]24
[6]25#ifndef Y_WIDTH
26# error "The Y_WIDTH value should be defined in the 'hard_config.h' file"
27#endif
28
29
[1]30/****************************************************************************
31 *                           Internal functions.                            *
32 ****************************************************************************/
33
34/****************************************************************************
35 * This function returns the value of a BDV register.                       *
36 * @ reg    : BDV register to be read.                                      *
37 * @ returns the value stored in 'reg'.                                     *
38 ****************************************************************************/
39static uint32_t boot_bdv_get_register( uint32_t reg )
40{
[6]41    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
[1]42    uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
43   
44    return boot_remote_lw( XPTR( cxy , ptr ) ); 
45
46} // boot_bdv_get_register()
47
48/****************************************************************************
49 * This function set a new value to a BDV register.                         *
50 * @ reg    : BDV register to be configured.                                *
51 * @ val    : new value to be written.                                      *
52 ****************************************************************************/
53static void boot_bdv_set_register( uint32_t reg,
54                                   uint32_t val )
55{
[6]56    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
[1]57    uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
58
59    boot_remote_sw( XPTR( cxy , ptr ) , val ); 
60
61} // boot_bdv_set_register()
62
63/****************************************************************************
64 *                              Driver API functions.                       *
65 ****************************************************************************/
66
67///////////////////
68int boot_bdv_init()
69{
70    // Check block size
71    if (boot_bdv_get_register(BDV_BLOCK_SIZE) != 512)
72    {
73        boot_puts("\n[BOOT ERROR] boot_bdv_init(): "
74                  "Block size must be 512 bytes\n");
75        return -1;
76    }
77       
78    // Disable  IRQq
79    boot_bdv_set_register(BDV_IRQ_ENABLE, 0);
80
81    return 0;
82
83} // boot_bdv_init()
84
85////////////////////////////////////
86int boot_bdv_access( uint32_t  lba,
87                     xptr_t    buf_paddr,
88                     uint32_t  count)
89{
90    uint32_t error;
91    uint32_t status;
92
93    // get target buffer cluster and pointer
94    cxy_t      buf_cxy = GET_CXY( buf_paddr );
95    uint32_t   buf_ptr = (uint32_t)GET_PTR( buf_paddr );
96
97    // Check buffer address alignment
98    if (buf_ptr & 0x3F)
99    {
100        boot_puts("\n[BOOT ERROR] boot_bdv_access(): "
101                  "Buffer address is not cache-line-size-aligned\n");
102        return -1;
103    }
104
105    // Set BDV device registers
106    boot_bdv_set_register(BDV_BUFFER    , buf_ptr );
107    boot_bdv_set_register(BDV_BUFFER_EXT, buf_cxy );
108    boot_bdv_set_register(BDV_COUNT     , count );
109    boot_bdv_set_register(BDV_LBA       , lba );
110
111#if USE_IOB    // software L2/L3 cache coherence
112    if( boot_mmc_inval( buf_paddr, count<<9 ) ) return -1;
113#endif
114
115    // Launch data transfer
116    boot_bdv_set_register(BDV_OPERATION, BDV_READ);
117
118#if DEBUG_BOOT_IOC
119boot_printf("\n[BOOT] boot_bdv_access(): Transfer launched at cycle %d\n"
120            "       lba = %d / buf = %l / nblocks = %d\n",
121            boot_get_proctime() , lba , buf_paddr , count );
122#endif
123
124    // Wait transfer completion
125    do
126    {
127        status = boot_bdv_get_register(BDV_STATUS);
128
129    } while ((status != BDV_READ_SUCC ) &&
130             (status != BDV_READ_ERR  ) &&
131             (status != BDV_WRITE_SUCC) &&
132             (status != BDV_WRITE_ERR ));
133
134#if DEBUG_BOOT_IOC
135boot_printf("\n[BOOT] boot_bdv_access(): Transfer terminated at cycle %d\n",
136            boot_get_proctime() );
137
138// uint32_t * data = (uint32_t *)(uint32_t)buf_paddr;
139// uint32_t   line;
140// uint32_t   word;
141// boot_printf("\n");
142// for( line = 0 ; line < 16 ; line++ )
143// {
144//    for( word = 0 ; word < 8 ; word++ )
145//    {
146//        boot_printf(" | %x", data[line*8+word] );
147//    }
148//    boot_printf(" |\n");
149// }
150
151#endif
152
153    // Check error
154    error = ((status == BDV_READ_ERR) ||
155             (status == BDV_WRITE_ERR));
156
157    return error;
158
159} // boot_bdv_access()
Note: See TracBrowser for help on using the repository browser.