source: soft/giet_vm/sys/common.c @ 165

Last change on this file since 165 was 165, checked in by alain, 12 years ago

Introducing various modifications in kernel initialisation

File size: 9.8 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : common.c
3// Date     : 01/04/2012
4// Author   : alain greiner and joel porquet
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The common.c and common.h files are part of the GIET nano-kernel.
8// They contains various utilities functions.
9///////////////////////////////////////////////////////////////////////////////////
10
11#include <sys_handler.h>
12#include <common.h>
13#include <drivers.h>
14#include <stdarg.h>
15
16////////////////////////////////////////////////////////////////////////////
17// _get_lock()
18////////////////////////////////////////////////////////////////////////////
19inline void _get_lock( unsigned int* plock )
20{
21    register unsigned int  delay = (_proctime() & 0xF) << 4;
22
23    asm volatile (
24            "_lock_llsc:             \n"
25            "ll   $2,    0(%0)       \n" /* $2 <= _ioc_lock current value */
26            "bnez $2,    _lock_delay \n" /* delay if _ioc_lock already taken */
27            "li   $3,    1           \n" /* $3 <= argument for sc */
28            "sc   $3,    0(%0)       \n" /* try to set _ioc_lock */
29            "bnez $3,    _lock_ok    \n" /* exit if atomic */
30            "_lock_delay:            \n"
31            "move $4,    %1          \n" /* $4 <= delay */
32            "_lock_loop:             \n"
33            "addi $4,    $4,    -1   \n" /* $4 <= $4 - 1 */
34            "beqz $4,    _lock_loop  \n" /* test end delay */
35            "j           _lock_llsc  \n" /* retry */
36            "_lock_ok:               \n"
37            :
38            :"r"(plock), "r"(delay)
39            :"$2", "$3", "$4");
40}
41
42////////////////////////////////////////////////////////////////////////////
43// _release_lock()
44////////////////////////////////////////////////////////////////////////////
45inline void _release_lock( unsigned int* plock )
46{
47    *plock = 0;
48}
49
50////////////////////////////////////////////////////////////////////////////
51// _puts()
52// used for system code debug / it uses TTY0
53////////////////////////////////////////////////////////////////////////////
54void _puts(char *buffer) 
55{
56    unsigned int* tty_address = (unsigned int*)&seg_tty_base;
57    unsigned int n;
58
59    for ( n=0; n<100; n++)
60    {
61        if (buffer[n] == 0) break;
62        tty_address[0] = (unsigned int)buffer[n];
63    }
64}
65////////////////////////////////////////////////////////////////////////////
66// _putw()
67// used for system code debug / it uses TTY0
68////////////////////////////////////////////////////////////////////////////
69void _putw(unsigned int val)
70{
71    static const char   HexaTab[] = "0123456789ABCDEF";
72    char                buf[11];
73    unsigned int        c;
74
75    buf[0]  = '0';
76    buf[1]  = 'x';
77    buf[10] = 0;
78
79    for ( c = 0 ; c < 8 ; c++ )
80    { 
81        buf[9-c] = HexaTab[val&0xF];
82        val = val >> 4;
83    }
84    _puts(buf);
85}
86////////////////////////////////////////////////////////////////////////////
87// _strncmp()
88// compare two strings s1 & s2 (no more than n characters)
89////////////////////////////////////////////////////////////////////////////
90unsigned int _strncmp(const char* s1, 
91                      const char* s2, 
92                      unsigned int n)
93{
94    unsigned int i;
95    for ( i=0 ; i<n ; i++)
96    {
97        if ( s1[i] != s2[i] ) return 1;
98        if ( s1[i] == 0 )     break;
99    }
100    return 0;
101}
102////////////////////////////////////////////////////////////////////////////
103//      _dcache_buf_invalidate()
104// Invalidate all data cache lines corresponding to a memory
105// buffer (identified by an address and a size).
106////////////////////////////////////////////////////////////////////////////
107void _dcache_buf_invalidate(const void *buffer, 
108                            unsigned int size)
109{
110    unsigned int i;
111    unsigned int tmp;
112    unsigned int line_size;
113
114    /*
115     * compute data cache line size based on config register (bits 12:10)
116     */
117    asm volatile("mfc0 %0, $16, 1" : "=r"(tmp));
118    tmp = ((tmp>>10) & 0x7);
119    line_size = 2 << tmp;
120
121    /* iterate on cache lines to invalidate each one of them */
122    for (i = 0; i < size; i += line_size)
123    {
124        asm volatile(
125                " cache %0, %1"
126                ::"i" (0x11), "R" (*((unsigned char*)buffer+i))
127                );
128    }
129}
130///////////////////////////////////////////////////////////////////////////////////
131//      _itoa_dec()
132// Convert a 32-bit unsigned integer to a string of ten decimal characters.
133///////////////////////////////////////////////////////////////////////////////////
134void _itoa_dec(unsigned int val, char *buf)
135{
136    const static char dectab[] = "0123456789";
137    unsigned int i;
138
139    for (i = 0; i < 10; i++)
140    {
141        if ((val != 0) || (i == 0))
142            buf[9-i] = dectab[val % 10];
143        else
144            buf[9-i] = 0x20;
145        val /= 10;
146    }
147}
148///////////////////////////////////////////////////////////////////////////////////
149//      _itoa_hex()
150// Convert a 32-bit unsigned integer to a string of eight hexadecimal characters.
151///////////////////////////////////////////////////////////////////////////////////
152void _itoa_hex(unsigned int val, char *buf)
153{
154    const static char hexatab[] = "0123456789ABCD";
155    unsigned int i;
156
157    for (i = 0; i < 8; i++)
158    {
159        buf[7-i] = hexatab[val % 16];
160        val /= 16;
161    }
162}
163///////////////////////////////////////////////////////////////////////////////////
164//      _get_epc()
165// Access CP0 and returns EPC register.
166///////////////////////////////////////////////////////////////////////////////////
167inline unsigned int _get_epc()
168{
169    unsigned int ret;
170    asm volatile("mfc0 %0, $14" : "=r"(ret));
171    return ret;
172}
173///////////////////////////////////////////////////////////////////////////////////
174//      _get_bar()
175// Access CP0 and returns BAR register.
176///////////////////////////////////////////////////////////////////////////////////
177inline unsigned int _get_bar()
178{
179    unsigned int ret;
180    asm volatile("mfc0 %0, $8" : "=r"(ret));
181    return ret;
182}
183///////////////////////////////////////////////////////////////////////////////////
184//      _get_cr()
185// Access CP0 and returns CR register.
186///////////////////////////////////////////////////////////////////////////////////
187inline unsigned int _get_cause()
188{
189    unsigned int ret;
190    asm volatile("mfc0 %0, $13" : "=r"(ret));
191    return ret;
192}
193
194///////////////////////////////////////////////////////////////////////////////////
195//      _it_mask()
196// Access CP0 and mask IRQs
197///////////////////////////////////////////////////////////////////////////////////
198inline void _it_mask()
199{
200    asm volatile(
201            "lui   $27,      0xFFFF   \n"
202            "ori   $27, $27, 0xFFFE   \n"
203            "mfc0  $26, $12           \n"
204            "and   $26, $26, $27      \n"
205            "mtc0  $26, $12           \n"
206            ::: "$26", "$27"
207            );
208}
209///////////////////////////////////////////////////////////////////////////////////
210//      _it_enable()
211// Access CP0 and enable IRQs
212///////////////////////////////////////////////////////////////////////////////////
213inline void _it_enable()
214{
215    asm volatile(
216            "mfc0  $26, $12      \n"
217            "ori   $26, $26, 1   \n"
218            "mtc0  $26, $12      \n"
219            ::: "$26"
220            );
221}
222
223/////////////////////////////////////////////////////////////////////////////
224//      access functions to mapping_info data structure
225/////////////////////////////////////////////////////////////////////////////
226mapping_cluster_t* _get_cluster_base( mapping_header_t* header )
227{
228    return   (mapping_cluster_t*) ((char*)header +
229                                  MAPPING_HEADER_SIZE);
230}
231/////////////////////////////////////////////////////////////////////////////
232mapping_pseg_t* _get_pseg_base( mapping_header_t* header )
233{
234    return   (mapping_pseg_t*)    ((char*)header +
235                                  MAPPING_HEADER_SIZE +
236                                  MAPPING_CLUSTER_SIZE*header->clusters);
237}
238/////////////////////////////////////////////////////////////////////////////
239mapping_vspace_t* _get_vspace_base( mapping_header_t* header )
240{
241    return   (mapping_vspace_t*)  ((char*)header +
242                                  MAPPING_HEADER_SIZE +
243                                  MAPPING_CLUSTER_SIZE*header->clusters +
244                                  MAPPING_PSEG_SIZE*header->psegs);
245}
246/////////////////////////////////////////////////////////////////////////////
247mapping_vseg_t* _get_vseg_base( mapping_header_t* header )
248{
249    return   (mapping_vseg_t*)    ((char*)header +
250                                  MAPPING_HEADER_SIZE +
251                                  MAPPING_CLUSTER_SIZE*header->clusters +
252                                  MAPPING_PSEG_SIZE*header->psegs +
253                                  MAPPING_VSPACE_SIZE*header->vspaces);
254}
255/////////////////////////////////////////////////////////////////////////////
256mapping_vobj_t* _get_vobj_base( mapping_header_t* header )
257{
258    return   (mapping_vobj_t*)   ((char*)header +
259                                  MAPPING_HEADER_SIZE +
260                                  MAPPING_CLUSTER_SIZE*header->clusters +
261                                  MAPPING_PSEG_SIZE*header->psegs +
262                                  MAPPING_VSPACE_SIZE*header->vspaces +
263                                  MAPPING_VSEG_SIZE*header->vsegs );
264}
265/////////////////////////////////////////////////////////////////////////////
266mapping_task_t* _get_task_base( mapping_header_t* header )
267{
268    return   (mapping_task_t*)    ((char*)header +
269                                  MAPPING_HEADER_SIZE +
270                                  MAPPING_CLUSTER_SIZE*header->clusters +
271                                  MAPPING_PSEG_SIZE*header->psegs +
272                                  MAPPING_VSPACE_SIZE*header->vspaces +
273                                  MAPPING_VOBJ_SIZE*header->vobjs +
274                                  MAPPING_VSEG_SIZE*header->vsegs);
275}
276
277
Note: See TracBrowser for help on using the repository browser.