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

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

This version modifies the exec syscall and fixes a large number of small bugs.
The version number has been updated (0.1)

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