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

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

Redefine the fuctions ppm_base2page() / ppm_page2base() / ppm_page2ppn() / ppm_ppn2page() / ppm_base2ppn() / ppm_ppn2base(),
to use explicitely extended pointers.

File size: 8.7 KB
RevLine 
[1]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
[315]25#include <errno.h>
26#include <vmm.h>
[1]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        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
48        {
49        asm volatile(
50        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
51        "ori    $14,   $0,  0x7     \n" 
52        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
53        "lw         $13,   0(%0)        \n"   /* read data from user space      */
[87]54        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]55            "sw     $13,   0(%1)        \n"   /* store data to kernel space     */
56        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
57
58        src += 4;
59        dst += 4;
60    }
61
62        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
63        {
64        asm volatile(
65        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
66        "ori    $14,   $0,  0x7     \n" 
67        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
68        "lb         $13,   0(%0)        \n"   /* read data from user space      */
[87]69        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]70            "sb     $13,   0(%1)        \n"   /* store data to kernel space     */
71        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
72
73        src += 1;
74        dst += 1;
75    }
76
77    hal_restore_irq( save_sr );
78
[87]79}  // end hal_copy_from_uspace()
80
[1]81///////////////////////////////////////////
82void hal_copy_to_uspace( void     * u_dst,
83                         void     * k_src,
84                         uint32_t   size )
85{
86    uint32_t save_sr;
87        uint32_t i;
[87]88        uint32_t wsize;                   // number of words if aligned
[1]89    uint32_t src = (uint32_t)k_src;
90    uint32_t dst = (uint32_t)u_dst;
91
[87]92        if( (dst & 0x3) || (src & 0x3) ) wsize = 0;          // not aligned
[1]93    else                             wsize = size >> 2;
94
95    hal_disable_irq( &save_sr );
96
97        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
98        {
99        asm volatile(
100        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
101        "lw         $13,   0(%0)        \n"   /* read data from kernel space    */
102        "ori    $14,   $0,  0x7     \n" 
103        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
104            "sw     $13,   0(%1)        \n"   /* store data to user space       */
[87]105        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]106        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
107
108        src += 4;
109        dst += 4;
110    }
111
112        for( i = wsize << 2 ; i < size ; i++ )  // transfer one byte per iteration
113        {
114        asm volatile(
115        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
116        "lw         $13,   0(%0)        \n"   /* read data from kernel space    */
117        "ori    $14,   $0,  0x7     \n" 
118        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
119            "sb     $13,   0(%1)        \n"   /* store data to user space       */
[87]120        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]121        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
122
123        src += 1;
124        dst += 1;
125    }
126
127    hal_restore_irq( save_sr );
128
[87]129}  // end hal_copy_to_uspace()
130
131//////////////////////////////////////////
[299]132error_t hal_strcpy_from_uspace( char     * k_dst,
133                                char     * u_src,
134                                uint32_t   max_size )
[87]135
136{
[121]137
[299]138// TODO implement the max_size handling, and error handling
[121]139
[87]140    uint32_t save_sr;
141    uint32_t src = (uint32_t)u_src;
142    uint32_t dst = (uint32_t)k_dst;
[300]143    uint32_t length;
144    error_t error;
145    paddr_t paddr;
[87]146
[300]147    // XXX XXX XXX: must be converted, to handle faults
148    error = vmm_v2p_translate( false , u_src , &paddr );
149    if( error )
150    {
151        return EFAULT;
152    }
[315]153
[300]154    length = hal_strlen_from_uspace( u_src );
155    if( length >= max_size )
156    {
157        return EFAULT;
158    }
159
[87]160    hal_disable_irq( &save_sr );
161
162    // loop on characters while non NUL
163    asm volatile(
164        "mfc2   $15,   $1           \n"   /* save current MMU_MODE          */
165        "1:                         \n"   /* loop entry                     */
166        "ori    $14,   $0,  0x7     \n" 
167        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
168        "lb         $13,   0(%0)        \n"   /* read char from user space      */
169        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
170            "sb     $13,   0(%1)        \n"   /* store char to kernel space     */
171        "addi   %0,    %0,  1       \n"   /* increment SRC pointer          */
172        "addi   %1,    %1,  1       \n"   /* increment DST pointer          */
173        "bne    $13,   $0,  1b      \n"   /* test NUL                       */
174        "nop                        \n"
175        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
176
177    hal_restore_irq( save_sr );
178
[299]179    return 0;
[87]180} // hal_strcpy_from_uspace()
181
[121]182////////////////////////////////////////////
[299]183error_t hal_strcpy_to_uspace( char     * u_dst,
184                              char     * k_src,
185                              uint32_t   max_size )
[121]186{
[87]187
[299]188// TODO implement the max_size handling, and error handling
[121]189
[87]190    uint32_t save_sr;
191    uint32_t src = (uint32_t)k_src;
192    uint32_t dst = (uint32_t)u_dst;
193
194    hal_disable_irq( &save_sr );
195
196    // loop on characters while non NUL
197    asm volatile(
198        "mfc2   $15,   $1           \n"   /* save current MMU_MODE          */
199        "1:                         \n"   /* loop entry                     */
200        "lb         $13,   0(%0)        \n"   /* read char from kernel space    */
201        "ori    $14,   $0,  0x7     \n" 
202        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
203            "sb     $13,   0(%1)        \n"   /* store char to user space       */
204        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
205        "addi   %0,    %0,  1       \n"   /* increment SRC pointer          */
206        "addi   %1,    %1,  1       \n"   /* increment DST pointer          */
207        "bne    $13,   $0,  1b      \n"   /* test NUL                       */
208        "nop                        \n"
209        : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
210
211    hal_restore_irq( save_sr );
212
[299]213    return 0;
214} // hal_strcpy_to_uspace()
[87]215
[1]216///////////////////////////////////////////////
217uint32_t hal_strlen_from_uspace( char * u_str )
218{
219    uint32_t save_sr;
220    uint32_t str      = (uint32_t)u_str;
221    uint32_t count    = 0;
222
223    hal_disable_irq( &save_sr ); 
224
225        asm volatile(
226        "ori    $15,   %0,   0      \n"   /* $15 <= count                   */
227        "ori    $13,   %1,   0      \n"   /* $13 <= str                     */
228   
229        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
230        "ori    $14,   $0,   0x7    \n"   /* $14 <= mode DTLB on            */
231        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
232
233        "1:                         \n"
[87]234        "lb         $13,   0(%0)        \n"   /* read char from kernel space    */
[1]235        "addi   $13,   $13,  1      \n"   /* increment address              */
236        "bne    $13,   $0,   1b     \n"   /* loop until NUL found           */
237        "addi   $15,   $15,  1      \n"   /* increment counter              */
238
239        "mtc2   $14,   $1                       \n"   /* restore MMU_MODE               */
240        : "+r"(count) : "r"(str) : "$13","$14","$15" );
241
242    hal_restore_irq( save_sr );
243
244    return count;
245}
246
Note: See TracBrowser for help on using the repository browser.