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

Last change on this file since 269 was 263, checked in by alain, 11 years ago

Introducing support for TSAR fixed format cluster index (cluster_xy)
We have now 4 parameters defined in map.xml:

  • X_WIDTH, Y_WIDTH define the fixed format (typically X_WIDTH = 4 / Y_WIDTH = 4)
  • X_SIZE, Y_SIZE define the actual TSAR 2D mesh variable size (from 1 to 16)
File size: 5.0 KB
RevLine 
[258]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>
[263]23#include <tty_driver.h>
[258]24#include <utils.h>
25
[263]26#if !defined(X_SIZE)
27# error: You must define X_SIZE in the hard_config.h file
[258]28#endif
29
[263]30#if !defined(Y_SIZE)
31# error: You must define X_SIZE in the hard_config.h file
[258]32#endif
33
[263]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
[258]42///////////////////////////////////////////////////////////////////////////////////
43// _memc_inval()
44// This function invalidates all cache lines covering a memory buffer defined
45// by the physical base address, and the length.
46// The buffer address MSB are used to compute the cluster index.
47///////////////////////////////////////////////////////////////////////////////////
48void _memc_inval( paddr_t      buf_paddr,
49                  unsigned int buf_length )
50{
[263]51    // compute cluster coordinates
52    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
53    unsigned int x          = cluster_xy >> Y_WIDTH;
54    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[258]55
[263]56    // parameters checking
57    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
58    {
59        _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster index[");
60        _putd( x );
61        _puts(",");
62        _putd( y );
63        _puts("]\n");
64        _puts("   - paddr      = ");
65        _putl( buf_paddr );
66        _puts("\n   - cluster_xy = ");
67        _putx( cluster_xy );
68        _puts("\n");
69        _exit();
70    }
71
[258]72    unsigned int* mmc_address = (unsigned int*)((unsigned int)&seg_mmc_base + 
[263]73                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
[258]74
75    // get the hard lock protecting exclusive access to MEMC
76    while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); }
77
78    // write inval arguments
79    mmc_address[MEMC_ADDR_LO]    = (unsigned int)buf_paddr;
80    mmc_address[MEMC_ADDR_HI]    = (unsigned int)(buf_paddr>>32);
81    mmc_address[MEMC_BUF_LENGTH] = buf_length;
82    mmc_address[MEMC_CMD_TYPE]   = MEMC_CMD_INVAL;
83
84    // release the lock
85    mmc_address[MEMC_LOCK] = 0;
86}
87///////////////////////////////////////////////////////////////////////////////////
88// _memc_sync()
89// This function copies to external RAM all cache lines covering a memory buffer
90// defined by the physical base address, and the length, if they are dirty.
91// The buffer address MSB are used to compute the cluster index.
92///////////////////////////////////////////////////////////////////////////////////
93void _memc_sync( paddr_t      buf_paddr,
94                 unsigned int buf_length )
95{
[263]96    // compute cluster coordinates
97    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
98    unsigned int x          = cluster_xy >> Y_WIDTH;
99    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[258]100
[263]101    // parameters checking
102    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
103    {
104        _puts("\n[GIET ERROR] in _memc_sync() : illegal cluster index[");
105        _putd( x );
106        _puts(",");
107        _putd( y );
108        _puts("]\n");
109        _puts("   - paddr      = ");
110        _putl( buf_paddr );
111        _puts("\n   - cluster_xy = ");
112        _putx( cluster_xy );
113        _puts("\n");
114        _exit();
115    }
116
[258]117    unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base + 
[263]118                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
[258]119
120    // get the hard lock protecting exclusive access to MEMC
121    while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); }
122
123    // write inval arguments
124    mmc_address[MEMC_ADDR_LO]    = (unsigned int)buf_paddr;
125    mmc_address[MEMC_ADDR_HI]    = (unsigned int)(buf_paddr>>32);
126    mmc_address[MEMC_BUF_LENGTH] = buf_length;
127    mmc_address[MEMC_CMD_TYPE]   = MEMC_CMD_SYNC;
128
129    // release the lock protecting MEMC
130    mmc_address[MEMC_LOCK] = 0;
131}
132
133// Local Variables:
134// tab-width: 4
135// c-basic-offset: 4
136// c-file-offsets:((innamespace . 0)(inline-open . 0))
137// indent-tabs-mode: nil
138// End:
139// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
140
Note: See TracBrowser for help on using the repository browser.