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

Last change on this file since 625 was 625, checked in by alain, 5 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 10.3 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
[610]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
[1]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
[407]56
[1]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      */
[87]64        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]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      */
[87]79        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]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
[610]89#if DEBUG_HAL_USPACE
90printk("\n[%s] thread[%x,%x] exit\n", 
91__FUNCTION__, this->process->pid, this->trdid );
92#endif
93
[87]94}  // end hal_copy_from_uspace()
95
[1]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;
[87]103        uint32_t wsize;                   // number of words if aligned
[1]104    uint32_t src = (uint32_t)k_src;
105    uint32_t dst = (uint32_t)u_dst;
106
[610]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
[87]113        if( (dst & 0x3) || (src & 0x3) ) wsize = 0;          // not aligned
[1]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       */
[87]126        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]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                */
[610]137        "lb         $13,   0(%0)        \n"   /* read data from kernel space    */
[1]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       */
[87]141        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
[1]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
[610]150#if DEBUG_HAL_USPACE
151printk("\n[%s] thread[%x,%x] exit\n", 
152__FUNCTION__, this->process->pid, this->trdid );
153#endif
154
[87]155}  // end hal_copy_to_uspace()
156
[407]157//////////////////////////////////////////////
158void hal_strcpy_from_uspace( char     * k_dst,
159                             char     * u_src,
160                             uint32_t   size )
[87]161{
[407]162    uint32_t save_sr;
[87]163    uint32_t src = (uint32_t)u_src;
164    uint32_t dst = (uint32_t)k_dst;
165
166    hal_disable_irq( &save_sr );
167
[425]168    // loop on characters while ( (character != NUL) and (count < size ) )
[87]169    asm volatile(
[407]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                   */
[425]174        "mfc2   $15,   $1           \n"   /* $15 <= mode DTLB and ITLB off  */
175        "ori    $14,   $15,  0x4    \n"   /* $14 <= mode DTLB on            */
[407]176        "1:                         \n"
[87]177        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
[407]178        "lb     $10,   0($12)       \n"   /* read char from user space      */
[425]179        "mtc2   $15,   $1                       \n"   /* restore DTLB and ITLB off      */
[407]180            "sb     $10,   0($13)       \n"   /* store char to kernel space     */
[425]181        "beq    $10,   $0,   2f     \n"   /* exit if char = 0               */
[407]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"
[87]188        "nop                        \n"
[407]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 ); 
[87]195
196} // hal_strcpy_from_uspace()
197
[121]198////////////////////////////////////////////
[407]199void hal_strcpy_to_uspace( char     * u_dst,
200                           char     * k_src,
201                           uint32_t   size )
[121]202{
[407]203    uint32_t save_sr;
[87]204    uint32_t src = (uint32_t)k_src;
205    uint32_t dst = (uint32_t)u_dst;
206
207    hal_disable_irq( &save_sr );
208
[407]209    // loop on characters while ( (character != NUL) and (count < size) )
[87]210    asm volatile(
[407]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                   */
[425]215        "mfc2   $15,   $1           \n"   /* $15 <= mode DTLB and ITLB off  */
216        "ori    $14,   $15,  0x4    \n"   /* $14 <= mode DTLB on            */
[407]217        "1:                         \n"
218        "lb     $10,   0($12)       \n"   /* read char from kernel space    */
[87]219        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
[407]220            "sb     $10,   0($13)       \n"   /* store char to user space       */
[425]221        "mtc2   $15,   $1                       \n"   /* restore DTLB and ITLB off      */
222        "beq    $10,   $0,   2f     \n"   /* exit if char == 0              */
[407]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"
[87]229        "nop                        \n"
[407]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 ); 
[87]236
[299]237} // hal_strcpy_to_uspace()
[87]238
[1]239///////////////////////////////////////////////
240uint32_t hal_strlen_from_uspace( char * u_str )
241{
242    uint32_t save_sr;
[407]243    uint32_t count = 0;
[425]244    uint32_t str   = (uint32_t)u_str;
[1]245
246    hal_disable_irq( &save_sr ); 
247
248        asm volatile(
[407]249        ".set noreorder             \n"
[425]250        "move   $13,   %1           \n"   /* $13 <= str                     */
[625]251        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE (DTLB off)     */
[425]252        "ori    $14,   $15,  0x4    \n"   /* $14 <= mode DTLB on            */
[1]253        "1:                         \n"
[425]254        "mtc2   $14,   $1                       \n"   /* set DTLB on                    */
[625]255        "lb         $12,   0($13)       \n"   /* $12 <= one byte from u_space   */
[425]256        "mtc2   $15,   $1                       \n"   /* set DTLB off                   */
[1]257        "addi   $13,   $13,  1      \n"   /* increment address              */
[407]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" );
[1]264
265    hal_restore_irq( save_sr );
266
267    return count;
268}
269
Note: See TracBrowser for help on using the repository browser.