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

Last change on this file since 1 was 1, checked in by alain, 7 years ago

First import

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