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

Last change on this file since 610 was 610, checked in by alain, 3 years ago

Fix several bugs in VFS to support the following
ksh commandis : cp, mv, rm, mkdir, cd, pwd

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