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

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

Fix bugs in hal_remote, hal uspace, hal_special

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