source: soft/giet_vm/giet_drivers/icu_driver.c @ 333

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

Cosmetic

File size: 4.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : icu_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The icu_driver.c and icu_driver.h files are part ot the GIET-VM nano-kernel.
8// This driver supports the SoCLib vci_icu component, That is a vectorised
9// interrupt controler.
10//
11// It can exist several interrupt controller unit in the architecture
12// (one per cluster), and each one can contain several channels.
13// The number of ICU channels is equal to NB_PROCS_MAX, because there is
14// one private ICU channel per processor in a cluster.
15////////////////////////////////////////////////////////////////////////////////
16// The virtual base address of the segment associated to the component is:
17//      SEG_ICU_BASE + cluster_xy * PERI_CLUSTER_INCREMENT
18//
19// SEG_ICU_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h
20////////////////////////////////////////////////////////////////////////////////
21
22#include <giet_config.h>
23#include <icu_driver.h>
24#include <tty_driver.h>
25#include <utils.h>
26
27#if !defined(X_SIZE)
28# error: You must define X_SIZE in the hard_config.h file
29#endif
30
31#if !defined(Y_SIZE)
32# error: You must define X_SIZE in the hard_config.h file
33#endif
34
35#if !defined(X_WIDTH)
36# error: You must define X_WIDTH in the hard_config.h file
37#endif
38
39#if !defined(Y_WIDTH)
40# error: You must define X_WIDTH in the hard_config.h file
41#endif
42
43#if !defined(NB_PROCS_MAX)
44# error: You must define NB_PROCS_MAX in the hard_config.h file
45#endif
46
47#if !defined( USE_XCU )
48# error: You must define USE_XCU in the hard_config.h file
49#endif
50
51#if !defined(SEG_ICU_BASE)
52# error: You must define SEG_ICU_BASE in the hard_config.h file
53#endif
54
55#if !defined(PERI_CLUSTER_INCREMENT)
56# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
57#endif
58
59////////////////////////////////////////////////////////////////////////////////
60//     _icu_set_mask()
61// This function set the mask register for the ICU channel identified
62// by the cluster index and the processor index.
63// All '1' bits are set / all '0' bits are not modified.
64// Returns 0 if success, > 0 if error.
65////////////////////////////////////////////////////////////////////////////////
66unsigned int _icu_set_mask( unsigned int cluster_xy,
67                            unsigned int proc_id,
68                            unsigned int value )
69{
70    // parameters checking
71    unsigned int x = cluster_xy >> Y_WIDTH;
72    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
73    if (x >= X_SIZE)             return 1; 
74    if (y >= Y_SIZE)             return 1; 
75    if (proc_id >= NB_PROCS_MAX) return 1; 
76
77#if USE_XCU
78    _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
79    return 1;
80#else
81    unsigned int * icu_address = (unsigned int *) ( SEG_ICU_BASE + 
82                                 (cluster_xy * PERI_CLUSTER_INCREMENT) );
83    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 
84    return 0;
85#endif
86}
87
88////////////////////////////////////////////////////////////////////////////////
89//     _icu_get_index()
90// This function returns the index of the highest priority (smaller index) IRQ.
91// The ICU channel is identified by the cluster index and the processor index.
92// Returns 0 if success, > 0 if error.
93////////////////////////////////////////////////////////////////////////////////
94unsigned int _icu_get_index( unsigned int cluster_xy, 
95                             unsigned int proc_id, 
96                             unsigned int * buffer) 
97{
98    // parameters checking
99    unsigned int x = cluster_xy >> Y_WIDTH;
100    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
101    if (x >= X_SIZE)             return 1; 
102    if (y >= Y_SIZE)             return 1; 
103    if (proc_id >= NB_PROCS_MAX) return 1;
104
105#if USE_XCU
106    _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
107    return 1;
108#else
109    unsigned int * icu_address = (unsigned int *) ( SEG_ICU_BASE + 
110                                 (cluster_xy * PERI_CLUSTER_INCREMENT) );
111    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 
112    return 0;
113#endif
114}
115
116
117// Local Variables:
118// tab-width: 4
119// c-basic-offset: 4
120// c-file-offsets:((innamespace . 0)(inline-open . 0))
121// indent-tabs-mode: nil
122// End:
123// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
124
Note: See TracBrowser for help on using the repository browser.