source: trunk/hal/tsar_mips32/core/hal_remote.c @ 446

Last change on this file since 446 was 313, checked in by alain, 7 years ago

RSeveral modifs in the page-fault handling.

File size: 18.5 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#include <hal_irqmask.h>
27
28////////////////////////////////
29void hal_remote_sb( xptr_t   xp,
30                    uint8_t  data )
31{
32    uint32_t ptr = (uint32_t)GET_PTR( xp );
33    uint32_t cxy = (uint32_t)GET_CXY( xp );
34
35    asm volatile( 
36        ".set noreorder              \n"
37        "mfc0   $14,    $12          \n"  /* $14 <= CP0_SR      */
38        "srl    $13,    $14,    1    \n" 
39        "sll    $13,    $13,    1    \n"  /* $13 <= SR masked   */
40        "mtc0   $13,    $12          \n"  /* IRQ disabled       */
41       
42        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */   
43        "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
44        "sb     %0,     0(%1)        \n"  /* *paddr <= value    */
45        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
46
47        "mtc0   $14,    $12          \n"  /* SR restored        */
48
49        "sync                        \n"
50        ".set reorder                \n"
51        : : "r" (data), "r" (ptr), "r" (cxy) : "$13", "$14", "$15" );
52}
53
54/////////////////////////////////
55void hal_remote_sw( xptr_t    xp,
56                    uint32_t  data )
57{
58    uint32_t ptr = (uint32_t)GET_PTR( xp );
59    uint32_t cxy = (uint32_t)GET_CXY( xp );
60
61    asm volatile( 
62        ".set noreorder              \n"
63        "mfc0   $14,    $12          \n"  /* $14 <= CP0_SR      */
64        "srl    $13,    $14,    1    \n" 
65        "sll    $13,    $13,    1    \n"  /* $13 <= SR masked   */
66        "mtc0   $13,    $12          \n"  /* IRQ disabled       */
67
68        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */   
69        "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
70        "sw     %0,     0(%1)        \n"  /* *paddr <= value    */
71        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
72
73        "mtc0   $14,    $12          \n"  /* SR restored        */
74
75        "sync                        \n"
76        ".set reorder                \n"
77        : : "r" (data), "r" (ptr), "r" (cxy) : "$13", "$14", "$15" );
78}
79
80//////////////////////////////////
81void hal_remote_swd( xptr_t    xp,
82                     uint64_t  data )
83{
84    uint32_t ptr = (uint32_t)GET_PTR( xp );
85    uint32_t cxy = (uint32_t)GET_CXY( xp );
86
87    uint32_t data_lsb = (uint32_t)data;
88    uint32_t data_msb = (uint32_t)(data>>32);
89
90    asm volatile( 
91        ".set noreorder              \n"
92        "mfc0   $14,    $12          \n"  /* $14 <= CP0_SR      */
93        "srl    $13,    $14,    1    \n" 
94        "sll    $13,    $13,    1    \n"  /* $13 <= SR masked   */
95        "mtc0   $13,    $12          \n"  /* IRQ disabled       */
96
97        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */   
98        "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy   */   
99        "sw     %0,     0(%2)        \n"  /* *paddr <= lsb      */
100        "sw     %1,     4(%2)        \n"  /* *(paddr+4) <= msb  */
101        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
102
103        "mtc0   $14,    $12          \n"  /* SR restored        */
104
105        "sync                        \n"
106        ".set reorder                \n"
107        : : "r" (data_lsb), "r" (data_msb), "r" (ptr), "r" (cxy) : "$13", "$14", "$15" );
108}
109
110////////////////////////////////////
111void hal_remote_spt( xptr_t      xp,
112                     void *      pt )
113{
114    hal_remote_sw ( xp , (uint32_t)pt );
115}
116
117////////////////////////////////
118uint8_t hal_remote_lb( xptr_t  xp )
119{
120        char     data;
121    uint32_t ptr = (uint32_t)GET_PTR( xp );
122    uint32_t cxy = (uint32_t)GET_CXY( xp );
123
124    asm volatile( 
125        ".set noreorder              \n"
126        "mfc0   $14,    $12          \n"  /* $14 <= CP0_SR      */
127        "srl    $13,    $14,    1    \n" 
128        "sll    $13,    $13,    1    \n"  /* $13 <= SR masked   */
129        "mtc0   $13,    $12          \n"  /* IRQ disabled       */
130
131        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
132        "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
133        "lb     %0,     0(%1)        \n"  /* data <= *paddr     */
134        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
135
136        "mtc0   $14,    $12          \n"  /* SR restored        */
137        ".set reorder                \n"
138        : "=r" (data) : "r" (ptr), "r" (cxy) : "$13", "$14", "$15" );
139
140        return ( data );
141}
142
143////////////////////////////////////
144uint32_t hal_remote_lw( xptr_t  xp )
145{
146        uint32_t data;
147    uint32_t ptr = (uint32_t)GET_PTR( xp );
148    uint32_t cxy = (uint32_t)GET_CXY( xp );
149
150    asm volatile( 
151        ".set noreorder              \n"
152        "mfc0   $14,    $12          \n"  /* $14 <= CP0_SR      */
153        "srl    $13,    $14,    1    \n" 
154        "sll    $13,    $13,    1    \n"  /* $13 <= SR masked   */
155        "mtc0   $13,    $12          \n"  /* IRQ disabled       */
156
157        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
158        "mtc2   %2,     $24          \n"  /* PADDR_EXT <= cxy   */   
159        "lw     %0,     0(%1)        \n"  /* data <= *paddr     */
160        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
161
162        "mtc0   $14,    $12          \n"  /* SR restored        */
163        ".set reorder                \n"
164        : "=r" (data) : "r" (ptr), "r" (cxy) : "$13", "$14", "$15" );
165
166    return ( data );
167}
168
169/////////////////////////////////////
170uint64_t hal_remote_lwd( xptr_t  xp )
171{
172    uint32_t data_lsb;
173    uint32_t data_msb;
174    uint32_t ptr = (uint32_t)GET_PTR( xp );
175    uint32_t cxy = (uint32_t)GET_CXY( xp );
176
177    asm volatile( 
178        ".set noreorder              \n"
179        "mfc0   $14,    $12          \n"  /* $14 <= CP0_SR        */
180        "srl    $13,    $14,    1    \n" 
181        "sll    $13,    $13,    1    \n"  /* $13 <= SR masked     */
182        "mtc0   $13,    $12          \n"  /* IRQ disabled         */
183
184        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
185        "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
186        "lw     %0,     0(%2)        \n"  /* data_lsb <= *paddr   */
187        "lw     %1,     4(%2)        \n"  /* data_msb <= *paddr+4 */
188        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
189
190        "mtc0   $14,    $12          \n"  /* SR restored          */
191        ".set reorder                \n"
192        : "=r" (data_lsb), "=r"(data_msb) : "r" (ptr), "r" (cxy) : "$13", "$14", "$15" );
193
194    return ( (((uint64_t)data_msb)<<32) + (((uint64_t)data_lsb)) );
195
196}
197
198////////////////////////////////////
199void * hal_remote_lpt( xptr_t    xp )
200{
201    return (void *)hal_remote_lw ( xp );
202}
203
204///////////////////////////////////////////
205bool_t hal_remote_atomic_cas( xptr_t    xp,
206                              uint32_t  old,
207                              uint32_t  new )
208{
209    uint32_t save_sr;
210        bool_t   isAtomic;
211    uint32_t ptr = (uint32_t)GET_PTR( xp );
212    uint32_t cxy = (uint32_t)GET_CXY( xp );
213
214    hal_disable_irq( &save_sr );
215
216    asm volatile( 
217        ".set noreorder              \n"
218        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT   */ 
219        "mtc2   %4,     $24          \n"  /* PADDR_EXT <= cxy   */   
220        "or     $8,     $0,    %3    \n"  /* $8 <= new          */
221        "ll     $3,    0(%1)         \n"  /* $3 <= *paddr       */
222        "bne    $3,     %2,    1f    \n"  /* if ($3 != old)     */
223        "li     $7,     0            \n"  /* $7 <= 0            */
224        "sc     $8,     (%1)         \n"  /* *paddr <= new      */
225        "or     $7,     $8,    $0    \n"  /* $7 <= atomic       */
226        "sync                        \n"
227        "1:                          \n"
228        "or     %0,     $7,    $0    \n"  /* isAtomic <= $7     */
229        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15   */   
230        ".set reorder                \n"
231        : "=&r" (isAtomic) : "r" (ptr), "r" (old) , "r" (new), "r" (cxy) 
232                : "$3", "$7", "$8", "$15" );
233
234    hal_restore_irq( save_sr );
235
236        return isAtomic;
237
238}  // end hal_remote_atomic_cas()
239
240////////////////////////////////////////////
241uint32_t hal_remote_atomic_add( xptr_t   xp, 
242                                uint32_t incr )
243{       
244    uint32_t save_sr;
245        uint32_t current;
246    uint32_t ptr = (uint32_t)GET_PTR( xp );
247    uint32_t cxy = (uint32_t)GET_CXY( xp );
248
249    hal_disable_irq( &save_sr );
250
251    asm volatile( 
252        ".set noreorder              \n"
253        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
254        "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
255        "1:                          \n"
256        "ll     %0,     (%1)         \n"  /* current <= *paddr    */
257        "addu   $3,     %0,     %2   \n"  /* $3 <= current + incr */
258        "sc     $3,     (%1)         \n"  /* *paddr <= $3         */
259        "beq    $3,     $0,     1b   \n"  /* retry if failure     */
260        "nop                         \n"
261        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
262        ".set reorder                \n"
263                : "=&r" (current) : "r" (ptr), "r" (incr), "r" (cxy) : "$3", "$15" );
264
265    hal_restore_irq( save_sr );
266
267        return current;
268
269}  // end hal_remote_atomic_add()
270
271////////////////////////////////////////////
272uint32_t hal_remote_atomic_and( xptr_t   xp, 
273                                uint32_t mask )
274{       
275    uint32_t save_sr;
276        uint32_t current;
277    uint32_t ptr = (uint32_t)GET_PTR( xp );
278    uint32_t cxy = (uint32_t)GET_CXY( xp );
279
280    hal_disable_irq( &save_sr );
281
282    asm volatile( 
283        ".set noreorder              \n"
284        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
285        "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
286        "1:                          \n"
287        "ll     %0,     (%1)         \n"  /* current <= *paddr    */
288        "and    $3,     %0,     %2   \n"  /* $3 <= current & mask */
289        "sc     $3,     (%1)         \n"  /* *paddr <= $3         */
290        "beq    $3,     $0,     1b   \n"  /* retry if failure     */
291        "nop                         \n"
292        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
293        ".set reorder                \n"
294            : "=&r" (current) : "r" (ptr), "r" (mask), "r" (cxy) : "$3", "$15" );
295
296    hal_restore_irq( save_sr );
297
298        return current;
299
300}  // end hal_remote_atomic_and()
301
302////////////////////////////////////////////
303uint32_t hal_remote_atomic_or( xptr_t   xp, 
304                               uint32_t mask )
305{       
306    uint32_t save_sr;
307        uint32_t current;
308    uint32_t ptr = (uint32_t)GET_PTR( xp );
309    uint32_t cxy = (uint32_t)GET_CXY( xp );
310
311    hal_disable_irq( &save_sr );
312
313    asm volatile( 
314        ".set noreorder              \n"
315        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
316        "mtc2   %3,     $24          \n"  /* PADDR_EXT <= cxy     */   
317        "1:                          \n"
318        "ll     %0,     (%1)         \n"  /* current <= *paddr    */
319        "or     $3,     %0,     %2   \n"  /* $3 <= current | mask */
320        "sc     $3,     (%1)         \n"  /* *paddr <= $3         */
321        "beq    $3,     $0,     1b   \n"  /* retry if failure     */
322        "nop                         \n"
323        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
324        ".set reorder                \n"
325            : "=&r" (current) : "r" (ptr), "r" (mask), "r" (cxy) : "$3", "$15" );
326
327    hal_restore_irq( save_sr );
328
329        return current;
330
331}  // end hal_remote_atomic_or()
332
333/////////////////////////////////////////////////
334error_t hal_remote_atomic_try_add( xptr_t     xp,
335                                   uint32_t   incr,
336                                   uint32_t * old )
337{
338    uint32_t save_sr;
339        uint32_t current;
340        error_t  error;
341    uint32_t ptr = (uint32_t)GET_PTR( xp );
342    uint32_t cxy = (uint32_t)GET_CXY( xp );
343
344    hal_disable_irq( &save_sr );
345
346    asm volatile( 
347        ".set noreorder              \n"
348        "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
349        "mtc2   %4,     $24          \n"  /* PADDR_EXT <= cxy     */   
350        "ll     %0,     (%2)         \n"  /* current <= *paddr    */
351        "addu   $3,     %0,     %3   \n"  /* $3 <= current + incr */
352        "sc     $3,     (%2)         \n"  /* *paddr <= $3         */
353        "beq    $3,     $0,     1f   \n"  /* exit if failure      */
354        "ori    %1,     $0,      1   \n"  /* fail: ret <= 1       */
355        "and    %1,     $0,     $0   \n"  /* success: ret <= 0    */
356        "1:                          \n"
357        "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
358        ".set reorder                \n"
359                : "=&r" (current), "=&r" (error) : "r" (ptr), "r" (incr), "r" (cxy) : "$3", "$15" );
360               
361    hal_restore_irq( save_sr );
362
363    *old = current;
364               
365        return error;
366
367}  // end hal_remote_atomic_try_add()
368
369/////////////////////////////////////
370void hal_remote_memcpy( xptr_t   dst,
371                        xptr_t   src,
372                        uint32_t size )
373{
374    uint32_t save_sr;
375        uint32_t i;
376        uint32_t wsize;
377    uint32_t dptr = (uint32_t)GET_PTR( dst );
378    uint32_t dcxy = (uint32_t)GET_CXY( dst );
379    uint32_t sptr = (uint32_t)GET_PTR( src );
380    uint32_t scxy = (uint32_t)GET_CXY( src );
381
382    hal_disable_irq( &save_sr );
383
384        if( (dptr & 0x3) || (sptr & 0x3) ) wsize = 0;  // do it all in bytes
385    else                               wsize = size >> 2;
386
387        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
388        {
389        asm volatile( 
390            ".set noreorder              \n"
391            "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
392            "mtc2   %0,     $24          \n"  /* PADDR_EXT <= scxy    */   
393                    "lw     $3,     0(%1)            \n"  /* $3 <= *src           */                           
394            "mtc2   %2,     $24          \n"  /* PADDR_EXT <= dcxy    */       
395            "sw     $3,     0(%3)        \n"  /* *dst <= $3           */
396            "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
397            ".set reorder                \n"
398                    : : "r"(scxy), "r" (sptr+(i<<2)), "r"(dcxy), "r" (dptr+(i<<2)) : "$3", "$15" );             
399        }
400
401        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
402        {
403        asm volatile( 
404            ".set noreorder              \n"
405            "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
406            "mtc2   %0,     $24          \n"  /* PADDR_EXT <= scxy    */   
407                    "lb         $3,     0(%1)        \n"  /* $3 <= *src           */                           
408            "mtc2   %2,     $24          \n"  /* PADDR_EXT <= dcxy    */       
409            "sb     $3,     0(%3)        \n"  /* *dst <= $3           */
410            "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
411            ".set reorder                \n"
412                    : : "r"(scxy), "r" (sptr+i), "r"(dcxy), "r" (dptr+i) : "$3", "$15" );               
413        }
414
415    hal_restore_irq( save_sr );
416
417}  // end hal_remote_memcpy()
418
419///////////////////////////////////
420void hal_remote_strcpy( xptr_t dst,
421                        xptr_t src )
422{
423    uint32_t save_sr;
424    uint32_t dptr = (uint32_t)GET_PTR( dst );
425    uint32_t dcxy = (uint32_t)GET_CXY( dst );
426    uint32_t sptr = (uint32_t)GET_PTR( src );
427    uint32_t scxy = (uint32_t)GET_CXY( src );
428
429    hal_disable_irq( &save_sr );
430
431    // loop on characters while non NUL
432    asm volatile(
433        "mfc2   $15,   $24          \n"   /* $15 <= PADDR_EXT               */
434        "1:                         \n"   /* loop entry                     */
435        "mtc2   %0,    $24          \n"   /* PADDR_EXT <= scxy              */   
436        "lb         $13,   0(%1)        \n"   /* read char from src string      */
437        "mtc2   %2,    $24          \n"   /* PADDR_EXT <= dcxy              */   
438            "sb     $13,   0(%3)        \n"   /* store char to dst string       */
439        "addi   %1,    %1,  1       \n"   /* increment sptr pointer         */
440        "addi   %3,    %3,  1       \n"   /* increment dptr pointer         */
441        "bne    $13,   $0,  1b      \n"   /* test NUL                       */
442        "nop                        \n"
443        "mtc2   $15,   $24          \n"   /* PADDR_EXT <= $15               */   
444        : : "r"(scxy), "r"(sptr), "r"(dcxy), "r"(dptr) : "$13","$15", "memory" );
445
446    hal_restore_irq( save_sr );
447
448} // end hal_remote_strcpy()
449
450////////////////////////////////////////
451void hal_remote_memset( xptr_t   buf_xp,
452                        uint8_t  byte,
453                        uint32_t size )
454{
455    uint32_t save_sr;
456        uint32_t i;
457        uint32_t wsize;
458    uint32_t buf_ptr = (uint32_t)GET_PTR( buf_xp );
459    uint32_t buf_cxy = (uint32_t)GET_CXY( buf_xp );
460    uint32_t word    = ((uint32_t)byte)<<24 |
461                       ((uint32_t)byte)<<16 |
462                       ((uint32_t)byte)<<8  |
463                       ((uint32_t)byte)     ;
464
465    hal_disable_irq( &save_sr );
466
467        if( (buf_ptr & 0x3) ) wsize = 0;  // do it all in bytes
468    else                  wsize = size >> 2;
469
470        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
471        {
472        asm volatile( 
473            ".set noreorder              \n"
474            "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
475            "mtc2   %0,     $24          \n"  /* PADDR_EXT <= buf_cxy */   
476            "sw     %2,     0(%1)        \n"  /* set one word         */
477            "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
478            ".set reorder                \n"
479                    : : "r"(buf_cxy), "r" (buf_ptr+(i<<2)), "r"(byte) : "$15" );               
480        }
481
482        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
483        {
484        asm volatile( 
485            ".set noreorder              \n"
486            "mfc2   $15,    $24          \n"  /* $15 <= PADDR_EXT     */ 
487            "mtc2   %0,     $24          \n"  /* PADDR_EXT <= buf_cxy */   
488            "sb     %2,     0(%1)        \n"  /* set one byte         */
489            "mtc2   $15,    $24          \n"  /* PADDR_EXT <= $15     */   
490            ".set reorder                \n"
491                    : : "r"(buf_cxy), "r"(buf_ptr+i), "r"(word) : "$15" );             
492        }
493
494    hal_restore_irq( save_sr );
495
496}  // end hal_remote_memset()
497
Note: See TracBrowser for help on using the repository browser.