source: soft/giet_vm/giet_drivers/mmc_driver.c @ 297

Last change on this file since 297 was 297, checked in by alain, 10 years ago

Bug fix in both _tty_rx_isr() and _bdv_isr():
The ISR must do nothing it the status indicates that
there is no pending ISR.

File size: 5.2 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : mmc_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The mmc_driver.c and mmc_driver.h files are part ot the GIET-VM nano-kernel.
8// This driver supports the vci_mem_cache component used in the TSAR architecture.
9//
10// This component is replicated in all clusters, and can be accessed through
11// a configuration interface as a set of uncached, memory mapped registers.
12///////////////////////////////////////////////////////////////////////////////////
13// The (virtual) base address of the associated segment is:
14//
15//       seg_mmc_base + cluster_id * vseg_cluster_increment
16//
17// The seg_mmc_base and vseg_cluster_increment values must be defined
18// in the giet_vsegs.ld file.
19////////////////////////////////////////////////////////////////////////////////
20
21#include <giet_config.h>
22#include <mmc_driver.h>
23#include <tty_driver.h>
24#include <utils.h>
25
26#if !defined(X_SIZE)
27# error: You must define X_SIZE in the hard_config.h file
28#endif
29
30#if !defined(Y_SIZE)
31# error: You must define X_SIZE in the hard_config.h file
32#endif
33
34#if !defined(X_WIDTH)
35# error: You must define X_WIDTH in the hard_config.h file
36#endif
37
38#if !defined(Y_WIDTH)
39# error: You must define X_WIDTH in the hard_config.h file
40#endif
41
42///////////////////////////////////////////////////////////////////////////////////
43// This function invalidates all cache lines covering a memory buffer defined
44// by the physical base address, and the length.
45// The buffer address MSB are used to compute the cluster index.
46///////////////////////////////////////////////////////////////////////////////////
47void _mmc_inval( paddr_t      buf_paddr,
48                 unsigned int buf_length )
49{
50    // compute cluster coordinates
51    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
52    unsigned int x          = cluster_xy >> Y_WIDTH;
53    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
54
55    // parameters checking
56    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
57    {
58        _printf("\n[GIET ERROR] in _memc_inval() : illegal cluster_xy for paddr %l\n",
59                 buf_paddr );
60        _exit();
61    }
62
63    unsigned int* mmc_address = (unsigned int*)((unsigned int)&seg_mmc_base + 
64                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
65
66    // get the hard lock protecting exclusive access to MEMC
67    while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); }
68
69    // write inval arguments
70    mmc_address[MEMC_ADDR_LO]    = (unsigned int)buf_paddr;
71    mmc_address[MEMC_ADDR_HI]    = (unsigned int)(buf_paddr>>32);
72    mmc_address[MEMC_BUF_LENGTH] = buf_length;
73    mmc_address[MEMC_CMD_TYPE]   = MEMC_CMD_INVAL;
74
75    // release the lock
76    mmc_address[MEMC_LOCK] = 0;
77}
78///////////////////////////////////////////////////////////////////////////////////
79// This function copies to external RAM all cache lines covering a memory buffer
80// defined by the physical base address, and the length, if they are dirty.
81// The buffer address MSB are used to compute the cluster index.
82///////////////////////////////////////////////////////////////////////////////////
83void _mmc_sync( paddr_t      buf_paddr,
84                unsigned int buf_length )
85{
86    // compute cluster coordinates
87    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
88    unsigned int x          = cluster_xy >> Y_WIDTH;
89    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
90
91    // parameters checking
92    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
93    {
94        _printf( "\n[GIET ERROR] in _memc_sync() : illegal cluster_xy for paddr %l\n",
95                 buf_paddr );
96        _exit();
97    }
98
99    unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base + 
100                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
101
102    // get the hard lock protecting exclusive access to MEMC
103    while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); }
104
105    // write inval arguments
106    mmc_address[MEMC_ADDR_LO]    = (unsigned int)buf_paddr;
107    mmc_address[MEMC_ADDR_HI]    = (unsigned int)(buf_paddr>>32);
108    mmc_address[MEMC_BUF_LENGTH] = buf_length;
109    mmc_address[MEMC_CMD_TYPE]   = MEMC_CMD_SYNC;
110
111    // release the lock protecting MEMC
112    mmc_address[MEMC_LOCK] = 0;
113}
114
115//////////////////////////////////////////////////////////////////////////////////
116// This ISR access the vci_mem_cache component to get the faulty physical
117// address and the associated SRCID. It must also acknowledge the IRQ.
118//
119// TODO implement...
120//////////////////////////////////////////////////////////////////////////////////
121void _mmc_isr( unsigned int irq_type,  // should be HWI
122               unsigned int irq_id,    // index returned by ICU
123               unsigned int channel )  // unused
124{
125    _printf("[GIET ERROR] MMC IRQ received, but _mmc_isr() not implemented...\n");
126}
127
128
129
130// Local Variables:
131// tab-width: 4
132// c-basic-offset: 4
133// c-file-offsets:((innamespace . 0)(inline-open . 0))
134// indent-tabs-mode: nil
135// End:
136// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
137
Note: See TracBrowser for help on using the repository browser.