source: trunk/hal/tsar_mips32/core/hal_uspace.c @ 408

Last change on this file since 408 was 407, checked in by alain, 6 years ago

First implementation of fork/exec.

File size: 9.5 KB
Line 
1/*
2 * hal_uspace.c - implementation of Generic User Space Access API for MIPS32
3 *
4 * Author  Mohamed 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 <errno.h>
26#include <vmm.h>
27#include <hal_types.h>
28#include <hal_uspace.h>
29#include <hal_irqmask.h>
30
31///////////////////////////////////////////
32void hal_copy_from_uspace( void     * k_dst,
33                           void     * u_src,
34                           uint32_t   size )
35{
36    uint32_t save_sr;
37        uint32_t i;
38        uint32_t wsize;                        // number of words
39    uint32_t src = (uint32_t)u_src;
40    uint32_t dst = (uint32_t)k_dst;
41
42        if( (dst & 0x3) || (src & 0x3) ) wsize = 0;          // do it all in bytes
43    else                             wsize = size >> 2;
44
45    hal_disable_irq( &save_sr );
46
47
48        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
49        {
50        asm volatile(
51        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
52        "ori    $14,   $0,  0x7     \n" 
53        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
54        "lw         $13,   0(%0)        \n"   /* read data from user space      */
55        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
56            "sw     $13,   0(%1)        \n"   /* store data to kernel space     */
57        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
58
59        src += 4;
60        dst += 4;
61    }
62
63        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
64        {
65        asm volatile(
66        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
67        "ori    $14,   $0,  0x7     \n" 
68        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
69        "lb         $13,   0(%0)        \n"   /* read data from user space      */
70        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
71            "sb     $13,   0(%1)        \n"   /* store data to kernel space     */
72        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
73
74        src += 1;
75        dst += 1;
76    }
77
78    hal_restore_irq( save_sr );
79
80}  // end hal_copy_from_uspace()
81
82///////////////////////////////////////////
83void hal_copy_to_uspace( void     * u_dst,
84                         void     * k_src,
85                         uint32_t   size )
86{
87    uint32_t save_sr;
88        uint32_t i;
89        uint32_t wsize;                   // number of words if aligned
90    uint32_t src = (uint32_t)k_src;
91    uint32_t dst = (uint32_t)u_dst;
92
93        if( (dst & 0x3) || (src & 0x3) ) wsize = 0;          // not aligned
94    else                             wsize = size >> 2;
95
96    hal_disable_irq( &save_sr );
97
98        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
99        {
100        asm volatile(
101        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
102        "lw         $13,   0(%0)        \n"   /* read data from kernel space    */
103        "ori    $14,   $0,  0x7     \n" 
104        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
105            "sw     $13,   0(%1)        \n"   /* store data to user space       */
106        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
107        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
108
109        src += 4;
110        dst += 4;
111    }
112
113        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
114        {
115        asm volatile(
116        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
117        "lw         $13,   0(%0)        \n"   /* read data from kernel space    */
118        "ori    $14,   $0,  0x7     \n" 
119        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
120            "sb     $13,   0(%1)        \n"   /* store data to user space       */
121        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
122        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
123
124        src += 1;
125        dst += 1;
126    }
127
128    hal_restore_irq( save_sr );
129
130}  // end hal_copy_to_uspace()
131
132//////////////////////////////////////////////
133void hal_strcpy_from_uspace( char     * k_dst,
134                             char     * u_src,
135                             uint32_t   size )
136{
137    uint32_t save_sr;
138
139    uint32_t src = (uint32_t)u_src;
140    uint32_t dst = (uint32_t)k_dst;
141
142    hal_disable_irq( &save_sr );
143
144    // loop on characters while ( (character != NUL) and (count < size )
145    asm volatile(
146        ".set noreorder             \n"
147        "move   $11,   %0           \n"   /* $11 <= count == size           */
148        "move   $12,   %1           \n"   /* $12 <= u_src                   */
149        "move   $13,   %2           \n"   /* $13 <= k_dst                   */
150        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE                */
151        "ori    $14,   $15,  0x7    \n"   /* $14 <= mode DTLB on            */
152        "1:                         \n"
153        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
154        "lb     $10,   0($12)       \n"   /* read char from user space      */
155        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
156            "sb     $10,   0($13)       \n"   /* store char to kernel space     */
157        "beq    $13,   $0,   2f     \n"   /* exit if char = 0               */
158        "addi   $11,   $11, -1      \n"   /* decrement count                */
159        "addi   $12,   $12,  1      \n"   /* increment u_src pointer        */
160        "beq    $11,   $0,   2f     \n"   /* exit if count == 0             */
161        "addi   $13,   $13,  1      \n"   /* increment k_src pointer        */
162        "j                   1b     \n"   /* jump to next iteration         */
163        "2:                         \n"
164        "nop                        \n"
165        ".set reorder               \n"
166        : 
167        : "r"(size),"r"(src),"r"(dst)
168        : "$10","$11","$12","$13","$14","$15" );
169       
170    hal_restore_irq( save_sr ); 
171
172} // hal_strcpy_from_uspace()
173
174////////////////////////////////////////////
175void hal_strcpy_to_uspace( char     * u_dst,
176                           char     * k_src,
177                           uint32_t   size )
178{
179    uint32_t save_sr;
180
181    uint32_t src = (uint32_t)k_src;
182    uint32_t dst = (uint32_t)u_dst;
183
184    hal_disable_irq( &save_sr );
185
186    // loop on characters while ( (character != NUL) and (count < size) )
187    asm volatile(
188        ".set noreorder             \n"
189        "move   $11,   %0           \n"   /* $11 <= count == size           */
190        "move   $12,   %1           \n"   /* $12 <= k_src                   */
191        "move   $13,   %2           \n"   /* $13 <= u_dst                   */
192        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE                */
193        "ori    $14,   $15,  0x7    \n"   /* $14 <= mode DTLB on            */
194        "1:                         \n"
195        "lb     $10,   0($12)       \n"   /* read char from kernel space    */
196        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
197            "sb     $10,   0($13)       \n"   /* store char to user space       */
198        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
199        "beq    $13,   $0,   2f     \n"   /* exit if char == 0              */
200        "addi   $11,   $11, -1      \n"   /* decrement count                */
201        "addi   $12,   $12,  1      \n"   /* increment k_src pointer        */
202        "beq    $11,   $0,   2f     \n"   /* exit if count == size          */
203        "addi   $13,   $13,  1      \n"   /* increment u_src pointer        */
204        "j                   1b     \n"   /* jump to next iteration         */
205        "2:                         \n"
206        "nop                        \n"
207        ".set reorder               \n"
208        :
209        : "r"(size),"r"(src),"r"(dst)
210        : "$10","$11","$12","$13","$14","$15" );
211       
212    hal_restore_irq( save_sr ); 
213
214} // hal_strcpy_to_uspace()
215
216///////////////////////////////////////////////
217uint32_t hal_strlen_from_uspace( char * u_str )
218{
219    uint32_t save_sr;
220    uint32_t count = 0;
221
222    uint32_t str = (uint32_t)u_str;
223
224    hal_disable_irq( &save_sr ); 
225
226        asm volatile(
227        ".set noreorder             \n"
228        "ori    $13,   %1,   0      \n"   /* $13 <= str                     */
229        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE                */
230        "ori    $14,   $15,  0x7    \n"   /* $14 <= mode DTLB on            */
231        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
232        "1:                         \n"
233        "lb         $12,   0($13)       \n"   /* read char from user space      */
234        "addi   $13,   $13,  1      \n"   /* increment address              */
235        "bne    $12,   $0,   1b     \n"   /* loop until NUL found           */
236        "addi   %0,    %0,   1      \n"   /* increment count                */
237        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
238        ".set reorder               \n"
239        : "+r"(count) 
240        : "r"(str) 
241        : "$12","$13","$14","$15" );
242
243    hal_restore_irq( save_sr );
244
245    return count;
246}
247
Note: See TracBrowser for help on using the repository browser.