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

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

Introducing support for IOMMU

File size: 10.1 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    // compute data cache line size based on config register (bits 12:10)
115    asm volatile("mfc0 %0, $16, 1" : "=r"(tmp));
116    tmp = ((tmp>>10) & 0x7);
117    line_size = 2 << tmp;
118
119    // iterate on cache lines
120    for (i = 0; i < size; i += line_size)
121    {
122        asm volatile(
123                " cache %0, %1"
124                ::"i" (0x11), "R" (*((unsigned char*)buffer+i))
125                );
126    }
127}
128///////////////////////////////////////////////////////////////////////////////////
129//      _itoa_dec()
130// Convert a 32-bit unsigned integer to a string of ten decimal characters.
131///////////////////////////////////////////////////////////////////////////////////
132void _itoa_dec(unsigned int val, char *buf)
133{
134    const static char dectab[] = "0123456789";
135    unsigned int i;
136
137    for (i = 0; i < 10; i++)
138    {
139        if ((val != 0) || (i == 0))
140            buf[9-i] = dectab[val % 10];
141        else
142            buf[9-i] = 0x20;
143        val /= 10;
144    }
145}
146///////////////////////////////////////////////////////////////////////////////////
147//      _itoa_hex()
148// Convert a 32-bit unsigned integer to a string of eight hexadecimal characters.
149///////////////////////////////////////////////////////////////////////////////////
150void _itoa_hex(unsigned int val, char *buf)
151{
152    const static char hexatab[] = "0123456789ABCD";
153    unsigned int i;
154
155    for (i = 0; i < 8; i++)
156    {
157        buf[7-i] = hexatab[val % 16];
158        val /= 16;
159    }
160}
161///////////////////////////////////////////////////////////////////////////////////
162//      _get_ptpr()
163// Access CP2 and returns PTPR register.
164///////////////////////////////////////////////////////////////////////////////////
165inline unsigned int _get_ptpr()
166{
167    unsigned int ret;
168    asm volatile("mfc2 %0, $0" : "=r"(ret));
169    return ret;
170}
171///////////////////////////////////////////////////////////////////////////////////
172//      _get_epc()
173// Access CP0 and returns EPC register.
174///////////////////////////////////////////////////////////////////////////////////
175inline unsigned int _get_epc()
176{
177    unsigned int ret;
178    asm volatile("mfc0 %0, $14" : "=r"(ret));
179    return ret;
180}
181///////////////////////////////////////////////////////////////////////////////////
182//      _get_bar()
183// Access CP0 and returns BAR register.
184///////////////////////////////////////////////////////////////////////////////////
185inline unsigned int _get_bar()
186{
187    unsigned int ret;
188    asm volatile("mfc0 %0, $8" : "=r"(ret));
189    return ret;
190}
191///////////////////////////////////////////////////////////////////////////////////
192//      _get_cr()
193// Access CP0 and returns CR register.
194///////////////////////////////////////////////////////////////////////////////////
195inline unsigned int _get_cause()
196{
197    unsigned int ret;
198    asm volatile("mfc0 %0, $13" : "=r"(ret));
199    return ret;
200}
201
202///////////////////////////////////////////////////////////////////////////////////
203//      _it_mask()
204// Access CP0 and mask IRQs
205///////////////////////////////////////////////////////////////////////////////////
206inline void _it_mask()
207{
208    asm volatile(
209            "lui   $27,      0xFFFF   \n"
210            "ori   $27, $27, 0xFFFE   \n"
211            "mfc0  $26, $12           \n"
212            "and   $26, $26, $27      \n"
213            "mtc0  $26, $12           \n"
214            ::: "$26", "$27"
215            );
216}
217///////////////////////////////////////////////////////////////////////////////////
218//      _it_enable()
219// Access CP0 and enable IRQs
220///////////////////////////////////////////////////////////////////////////////////
221inline void _it_enable()
222{
223    asm volatile(
224            "mfc0  $26, $12      \n"
225            "ori   $26, $26, 1   \n"
226            "mtc0  $26, $12      \n"
227            ::: "$26"
228            );
229}
230
231/////////////////////////////////////////////////////////////////////////////
232//      access functions to mapping_info data structure
233/////////////////////////////////////////////////////////////////////////////
234mapping_cluster_t* _get_cluster_base( mapping_header_t* header )
235{
236    return   (mapping_cluster_t*) ((char*)header +
237                                  MAPPING_HEADER_SIZE);
238}
239/////////////////////////////////////////////////////////////////////////////
240mapping_pseg_t* _get_pseg_base( mapping_header_t* header )
241{
242    return   (mapping_pseg_t*)    ((char*)header +
243                                  MAPPING_HEADER_SIZE +
244                                  MAPPING_CLUSTER_SIZE*header->clusters);
245}
246/////////////////////////////////////////////////////////////////////////////
247mapping_vspace_t* _get_vspace_base( mapping_header_t* header )
248{
249    return   (mapping_vspace_t*)  ((char*)header +
250                                  MAPPING_HEADER_SIZE +
251                                  MAPPING_CLUSTER_SIZE*header->clusters +
252                                  MAPPING_PSEG_SIZE*header->psegs);
253}
254/////////////////////////////////////////////////////////////////////////////
255mapping_vseg_t* _get_vseg_base( mapping_header_t* header )
256{
257    return   (mapping_vseg_t*)    ((char*)header +
258                                  MAPPING_HEADER_SIZE +
259                                  MAPPING_CLUSTER_SIZE*header->clusters +
260                                  MAPPING_PSEG_SIZE*header->psegs +
261                                  MAPPING_VSPACE_SIZE*header->vspaces);
262}
263/////////////////////////////////////////////////////////////////////////////
264mapping_vobj_t* _get_vobj_base( mapping_header_t* header )
265{
266    return   (mapping_vobj_t*)   ((char*)header +
267                                  MAPPING_HEADER_SIZE +
268                                  MAPPING_CLUSTER_SIZE*header->clusters +
269                                  MAPPING_PSEG_SIZE*header->psegs +
270                                  MAPPING_VSPACE_SIZE*header->vspaces +
271                                  MAPPING_VSEG_SIZE*header->vsegs );
272}
273/////////////////////////////////////////////////////////////////////////////
274mapping_task_t* _get_task_base( mapping_header_t* header )
275{
276    return   (mapping_task_t*)    ((char*)header +
277                                  MAPPING_HEADER_SIZE +
278                                  MAPPING_CLUSTER_SIZE*header->clusters +
279                                  MAPPING_PSEG_SIZE*header->psegs +
280                                  MAPPING_VSPACE_SIZE*header->vspaces +
281                                  MAPPING_VOBJ_SIZE*header->vobjs +
282                                  MAPPING_VSEG_SIZE*header->vsegs);
283}
284
285
Note: See TracBrowser for help on using the repository browser.