source: trunk/hal/tsar_mips32/hal_remote.c @ 6

Last change on this file since 6 was 1, checked in by alain, 8 years ago

First import

File size: 13.4 KB
Line 
1/*
2 * hal_remote.c - implementation of Generic Remote Access API for TSAR-MIPS32
3 *
4 * Authors : Mohammed Karaoui (2015)
5 *           Alain Greiner    (2016)
6 *
7 * Copyright (c) UPMC Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH..
10 *
11 * ALMOS-MKH. is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH. is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#include <hal_types.h>
26
27////////////////////////////////
28void hal_remote_sb( xptr_t   xp,
29                    char     data )
30{
31    uint32_t ptr = (uint32_t)GET_PTR( xp );
32    uint32_t cxy = (uint32_t)GET_CXY( xp );
33
34    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT */   
35                  "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy */   
36                  "sb     %0,     0(%1)        \n"  /* *paddr <= value  */
37                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15 */   
38                  "sync                        \n"
39                  :
40                  : "r" (data), "r" (ptr), "r" (cxy)
41                  : "$15" );
42}
43
44/////////////////////////////////
45void hal_remote_sw( xptr_t    xp,
46                    uint32_t  data )
47{
48    uint32_t ptr = (uint32_t)GET_PTR( xp );
49    uint32_t cxy = (uint32_t)GET_CXY( xp );
50
51    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT */   
52                  "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy */   
53                  "sw     %0,     0(%1)        \n"  /* *paddr <= value  */
54                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15 */   
55                  "sync                        \n"
56                  :
57                  : "r" (data), "r" (ptr), "r" (cxy)
58                  : "$15" );
59}
60
61//////////////////////////////////
62void hal_remote_swd( xptr_t    xp,
63                     uint64_t  data )
64{
65    uint32_t ptr = (uint32_t)GET_PTR( xp );
66    uint32_t cxy = (uint32_t)GET_CXY( xp );
67
68    uint32_t data_lsb = (uint32_t)data;
69    uint32_t data_msb = (uint32_t)(data>>32);
70
71    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT  */   
72                  "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy  */   
73                  "sw     %0,     0(%2)        \n"  /* *paddr <= lsb     */
74                  "sw     %1,     4(%2)        \n"  /* *(paddr+4) <= msb */
75                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15  */   
76                  "sync                        \n"
77                  :
78                  : "r" (data_lsb), "r" (data_msb), "r" (ptr), "r" (cxy)
79                  : "$15" );
80}
81
82////////////////////////////////////
83void hal_remote_spt( xptr_t      xp,
84                     void *      pt )
85{
86    hal_remote_sw ( xp , (uint32_t)pt );
87}
88
89////////////////////////////////
90char hal_remote_lb( xptr_t  xp )
91{
92        char     data;
93    uint32_t ptr = (uint32_t)GET_PTR( xp );
94    uint32_t cxy = (uint32_t)GET_CXY( xp );
95
96    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
97                  "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
98                  "lb     %0,     0(%1)        \n"  /* data <= *paddr     */
99                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
100                  : "=r" (data)
101                  : "r" (ptr), "r" (cxy)
102                  : "$15" );
103
104        return ( data );
105}
106
107////////////////////////////////////
108uint32_t hal_remote_lw( xptr_t  xp )
109{
110        uint32_t data;
111    uint32_t ptr = (uint32_t)GET_PTR( xp );
112    uint32_t cxy = (uint32_t)GET_CXY( xp );
113
114    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
115                  "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
116                  "lw     %0,     0(%1)        \n"  /* data <= *paddr     */
117                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
118                  : "=r" (data)
119                  : "r" (ptr), "r" (cxy)
120                  : "$15" );
121
122    return ( data );
123}
124
125/////////////////////////////////////
126uint64_t hal_remote_lwd( xptr_t  xp )
127{
128    uint32_t data_lsb;
129    uint32_t data_msb;
130    uint32_t ptr = (uint32_t)GET_PTR( xp );
131    uint32_t cxy = (uint32_t)GET_CXY( xp );
132
133    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
134                  "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
135                  "lw     %0,     0(%2)        \n"  /* data_lsb <= *paddr   */
136                  "lw     %1,     4(%2)        \n"  /* data_msb <= *paddr+4 */
137                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
138                  : "=r" (data_lsb), "=r"(data_msb)
139                  : "r" (ptr), "r" (cxy)
140                  : "$15" );
141
142    return ( (((uint64_t)data_msb)<<32) + (((uint64_t)data_lsb)) );
143}
144
145////////////////////////////////////
146void * hal_remote_lpt( xptr_t    xp,
147                       void *    pt )
148{
149    return (void *)hal_remote_lw ( xp );
150}
151
152////////////////////////////////////////
153uint32_t hal_remote_lw_unc( xptr_t  xp )
154{
155        uint32_t data;
156    uint32_t ptr = (uint32_t)GET_PTR( xp );
157    uint32_t cxy = (uint32_t)GET_CXY( xp );
158
159    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
160                  "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
161                  "ll     %0,     0(%1)        \n"  /* data <= *paddr     */
162                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
163                  : "=r" (data)
164                  : "r" (ptr), "r" (cxy)
165                  : "$15" );
166
167        return ( data );
168}
169
170///////////////////////////////////////////
171bool_t hal_remote_atomic_cas( xptr_t    xp,
172                              uint32_t  old,
173                              uint32_t  new )
174{
175        bool_t   isAtomic;
176    uint32_t ptr = (uint32_t)GET_PTR( xp );
177    uint32_t cxy = (uint32_t)GET_CXY( xp );
178
179    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
180                  "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy   */   
181                  "or     $8,     $0,    %3    \n"  /* $8 <= new          */
182                  "ll     $3,    0(%1)         \n"  /* $3 <= *paddr       */
183                  "bne    $3,     %2,    1f    \n"  /* if (new != old)    */
184                  "li     $7,     0            \n"  /* $7 <= 0            */
185                  "sc     $8,     (%1)         \n"  /* *paddr <= new      */
186                  "or     $7,     $8,    $0    \n"  /* $7 <= new          */
187                  "sync                        \n"
188                  "1:                          \n"
189                  "or     %0,     $7,    $0    \n"  /* isAtomic <= $7     */
190                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
191                  : "=&r" (isAtomic)
192                  : "r" (ptr), "r" (old) , "r" (new), "r" (cxy) 
193                          : "$3", "$7", "$8", "$15" );
194
195        return isAtomic;
196}
197
198////////////////////////////////////////////
199uint32_t hal_remote_atomic_add( xptr_t   xp, 
200                                uint32_t incr )
201{       
202        uint32_t current;
203    uint32_t ptr = (uint32_t)GET_PTR( xp );
204    uint32_t cxy = (uint32_t)GET_CXY( xp );
205
206    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
207                  "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
208                  "1:                          \n"
209                  "ll     %0,     (%1)         \n"  /* current <= *paddr    */
210                  "addu   $3,     %0,     %2   \n"  /* $3 <= current + incr */
211                  "sc     $3,     (%1)         \n"  /* *paddr <= $3         */
212                  "beq    $3,     $0,     1b   \n"  /* retry if failure     */
213                  "nop                         \n"
214                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
215                          : "=&r" (current)
216                          : "r" (ptr), "r" (incr), "r" (cxy)
217                          : "$3", "$15" );
218
219        return current;
220}
221
222////////////////////////////////////////////
223uint32_t hal_remote_atomic_and( xptr_t   xp, 
224                                uint32_t mask )
225{       
226        uint32_t current;
227    uint32_t ptr = (uint32_t)GET_PTR( xp );
228    uint32_t cxy = (uint32_t)GET_CXY( xp );
229
230    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
231                  "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
232                  "1:                          \n"
233                  "ll     %0,     (%1)         \n"  /* current <= *paddr    */
234                  "and    $3,     %0,     %2   \n"  /* $3 <= current & mask */
235                  "sc     $3,     (%1)         \n"  /* *paddr <= $3         */
236                  "beq    $3,     $0,     1b   \n"  /* retry if failure     */
237                  "nop                         \n"
238                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
239                          : "=&r" (current)
240                          : "r" (ptr), "r" (mask), "r" (cxy)
241                          : "$3", "$15" );
242
243        return current;
244}
245
246////////////////////////////////////////////
247uint32_t hal_remote_atomic_or( xptr_t   xp, 
248                               uint32_t mask )
249{       
250        uint32_t current;
251    uint32_t ptr = (uint32_t)GET_PTR( xp );
252    uint32_t cxy = (uint32_t)GET_CXY( xp );
253
254    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
255                  "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
256                  "1:                          \n"
257                  "ll     %0,     (%1)         \n"  /* current <= *paddr    */
258                  "or     $3,     %0,     %2   \n"  /* $3 <= current | mask */
259                  "sc     $3,     (%1)         \n"  /* *paddr <= $3         */
260                  "beq    $3,     $0,     1b   \n"  /* retry if failure     */
261                  "nop                         \n"
262                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
263                          : "=&r" (current)
264                          : "r" (ptr), "r" (mask), "r" (cxy)
265                          : "$3", "$15" );
266
267        return current;
268}
269
270/////////////////////////////////////////////////
271error_t hal_remote_atomic_try_add( xptr_t     xp,
272                                   uint32_t   incr,
273                                   uint32_t * old )
274{
275        uint32_t current;
276        error_t  error;
277    uint32_t ptr = (uint32_t)GET_PTR( xp );
278    uint32_t cxy = (uint32_t)GET_CXY( xp );
279
280    asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
281                  "mtc2   %4,     $24          \n"  /* PADDR_EXT <= cxy     */   
282                  "ll     %0,     (%2)         \n"  /* current <= *paddr    */
283                  "addu   $3,     %0,     %3   \n"  /* $3 <= current + incr */
284                  "sc     $3,     (%2)         \n"  /* *paddr <= $3         */
285                  "beq    $3,     $0,     1f   \n"  /* exit if failure      */
286                  "ori    %1,     $0,      1   \n"      /* fail: ret <= 1       */
287                  "and    %1,     $0,     $0   \n"      /* success: ret <= 0    */
288                  "1:                          \n"
289                  "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
290                          : "=&r" (current), "=&r" (error)
291                          : "r" (ptr), "r" (incr), "r" (cxy)
292                  : "$3", "$15" );
293               
294    *old = current;
295               
296        return error;
297}
298
299/////////////////////////////////////
300void hal_remote_memcpy( xptr_t   dst,
301                        xptr_t   src,
302                        uint32_t size )
303{
304        uint32_t i;
305        uint32_t wsize;
306    uint32_t dptr = (uint32_t)GET_PTR( dst );
307    uint32_t dcxy = (uint32_t)GET_CXY( dst );
308    uint32_t sptr = (uint32_t)GET_PTR( src );
309    uint32_t scxy = (uint32_t)GET_CXY( src );
310
311        if( (dptr & 0x3) || (sptr & 0x3) ) wsize = 0;  // do it all in bytes
312    else                               wsize = size >> 2;
313
314        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
315        {
316        asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
317                      "mtc2   %0,     $24          \n"  /* PADDR_EXT <= scxy    */   
318                              "lw         $3,     0(%1)            \n"  /* $3 <= *src           */                             
319                      "mtc2   %2,     $24          \n"  /* PADDR_EXT <= dcxy    */     
320                      "sw     $3,     0(%3)        \n"  /* *dst <= $3           */
321                      "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
322                              :
323                      : "r"(scxy), "r" (sptr+(i<<2)), "r"(dcxy), "r" (dptr+(i<<2))
324                              : "$3", "$15" );         
325        }
326
327        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
328        {
329        asm volatile( "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
330                      "mtc2   %0,     $24          \n"  /* PADDR_EXT <= scxy    */   
331                              "lb         $3,     0(%1)            \n"  /* $3 <= *src           */                             
332                      "mtc2   %2,     $24          \n"  /* PADDR_EXT <= dcxy    */     
333                      "sb     $3,     0(%3)        \n"  /* *dst <= $3           */
334                      "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
335                              :
336                      : "r"(scxy), "r" (sptr+i), "r"(dcxy), "r" (dptr+i)
337                              : "$3", "$15" );         
338        }
339}
340
341
Note: See TracBrowser for help on using the repository browser.