Changeset 626 for trunk/hal/tsar_mips32
- Timestamp:
- Apr 29, 2019, 7:25:09 PM (6 years ago)
- Location:
- trunk/hal/tsar_mips32
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/core/hal_uspace.c
r625 r626 2 2 * hal_uspace.c - implementation of Generic User Space Access API for MIPS32 3 3 * 4 * Author Mohamed Karaoui (2015) 5 * Alain Greiner (2016) 4 * Author Alain Greiner (2016,2017,2018,2019) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 23 22 */ 24 23 25 #include <errno.h>26 #include <vmm.h>27 24 #include <hal_kernel_types.h> 28 25 #include <hal_uspace.h> 26 #include <hal_special.h> 29 27 #include <hal_irqmask.h> 30 28 … … 32 30 #include <thread.h> 33 31 34 /////////////////////////////////////////// 35 void hal_copy_from_uspace( void * k_dst, 32 /////////////////////////////////////////////////////////////////////////////////////// 33 // This function moves <size> bytes from a source buffer in user virtual space, 34 // defined by the <u_src> argument, to a destination kernel buffer, defined by the 35 // <k_cxy> and <k_dst> arguments. 36 // It works in a critical section, as it modifies briefly two CP2 registers: 37 // It activates briefly the DATA_MMU by writing into the CP2_MODE register to access the 38 // user buffer, and modifies the CP2_DATA_EXT register to access the kernel buffer. 39 // If the two buffers are aligned on a word boundary, it moves the data word per word 40 // in a first loop, and moves byte per byte the remaining bytes in a second loop. 41 // If the buffers are not aligned, it moves all data byte per byte. 42 /////////////////////////////////////////////////////////////////////////////////////// 43 // @ k_cxy : cluster of destination kernel buffer 44 // @ k_dst : pointer on destination kernel buffer 45 // @ u_src : pointer on source user buffer 46 // @ size : number of bytes to move 47 /////////////////////////////////////////////////////////////////////////////////////// 48 void hal_copy_from_uspace( cxy_t k_cxy, 49 void * k_dst, 36 50 void * u_src, 37 51 uint32_t size ) 38 52 { 39 53 uint32_t save_sr; 40 uint32_t i; 41 uint32_t wsize; // number of words 54 uint32_t words; // number of words (if buffers aligned) 42 55 uint32_t src = (uint32_t)u_src; 43 56 uint32_t dst = (uint32_t)k_dst; 44 57 45 58 #if DEBUG_HAL_USPACE 46 thread_t * this = CURRENT_THREAD; 47 printk("\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 ); 59 thread_t * this = CURRENT_THREAD; 60 uint32_t cycle = (uint32_t)hal_get_cycles(); 61 if( cycle > DEBUG_HAL_USPACE ) 62 printk("\n[%s] thread[%x,%x] enter / %d bytes / u_buf(%x,%x) -> k_buf(%x,%x) / cycle %d\n", 63 __FUNCTION__, this->process->pid, this->trdid, size, local_cxy, u_src, k_cxy, k_dst, cycle ); 49 64 #endif 50 65 51 if( (dst & 0x3) || (src & 0x3) ) wsize = 0; // do it all in bytes 52 else wsize = size >> 2; 53 66 if( (dst & 0x3) || (src & 0x3) ) words = 0; // do it all in bytes 67 else words = size >> 2; 68 69 // enter critical section 54 70 hal_disable_irq( &save_sr ); 55 71 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 72 asm volatile( ".set noreorder \n" 73 74 /* initialise registers */ 75 "move $8, %0 \n" /* $8 <= src */ 76 "move $9, %1 \n" /* $9 <= dst */ 77 "move $10, %2 \n" /* $10 <= words */ 78 "move $11, %3 \n" /* $11 <= size */ 79 "mfc2 $12, $1 \n" /* $12 <= old MMU_MODE */ 80 "ori $13, $12, 0x4 \n" /* $13 <= MMU_MODE with DTLB */ 81 82 /* save old MMU_DATA_EXT and set k_cxy in it */ 83 "mfc2 $16, $24 \n" /* $16 <= old MMU_DATA_EXT */ 84 "mtc2 %4, $24 \n" /* MMU_DATA_EXT <= k_cxy */ 85 86 /* transfer one word per iteration in first loop if aligned */ 87 "move $15, $10 \n" /* $15 <= words ($15 == i) */ 88 "1: \n" 89 "beq $15, $0, 2f \n" /* exit loop if (i==0) */ 90 "nop \n" 91 "mtc2 $13, $1 \n" /* MMU_MODE <= DTLB ON */ 92 "lw $14, 0($8) \n" /* word from user space */ 93 "mtc2 $12, $1 \n" /* restore old MMU_MODE */ 94 "sw $14, 0($9) \n" /* word to kernel space */ 95 "addi $15, $15, -1 \n" /* i-- */ 96 "addi $8, $8, 4 \n" /* src += 4 bytes */ 97 "j 1b \n" 98 "addi $9, $9, 4 \n" /* dst += 4 bytes */ 99 100 /* transfer one byte per iteration in this second loop */ 101 "2: \n" 102 "sll $15, $10, 2 \n" /* $15 <= words*4 ($15 == i) */ 103 "3: \n" 104 "beq $15, $11, 4f \n" /* exit loop if (i == size) */ 105 "nop \n" 106 "mtc2 $13, $1 \n" /* MMU_MODE <= DTLB ON */ 107 "lb $14, 0($8) \n" /* byte from user space */ 108 "mtc2 $12, $1 \n" /* restore omd MMU_MODE */ 109 "sb $14, 0($9) \n" /* byte to kernel space */ 110 "addi $15, $15, 1 \n" /* i++ */ 111 "addi $8, $8, 1 \n" /* src += 1 byte */ 112 "j 3b \n" 113 "addi $9, $9, 1 \n" /* dst += 1 byte */ 114 115 /* restore old MMU_DATA_EXT register */ 116 "4: \n" 117 "mtc2 $16, $24 \n" /* MMU__DATA_EXT <= $16 */ 118 ".set reorder \n" 119 : 120 : "r"(src) , "r"(dst) , "r"(words) , "r"(size) , "r"(k_cxy) 121 : "$8","$9","$10","$11","$12","$13","$14","$15","$16","memory" ); 122 123 // exit critical section 87 124 hal_restore_irq( save_sr ); 88 125 89 126 #if DEBUG_HAL_USPACE 90 printk("\n[%s] thread[%x,%x] exit\n", 91 __FUNCTION__, this->process->pid, this->trdid ); 127 cycle = (uint32_t)hal_get_cycles(); 128 if( cycle > DEBUG_HAL_USPACE ) 129 printk("\n[%s] thread[%x,%x] moved %d bytes / u_buf(%x,%x) -> k_buf(%x,%x) / cycle %d\n", 130 __FUNCTION__, this->process->pid, this->trdid, size, local_cxy, u_src, k_cxy, k_dst, cycle ); 92 131 #endif 93 132 94 133 } // end hal_copy_from_uspace() 95 134 96 /////////////////////////////////////////// 97 void hal_copy_to_uspace( void * u_dst, 135 /////////////////////////////////////////////////////////////////////////////////////// 136 // This function moves <size> bytes from a source kernel buffer, defined by the 137 // <k_cxy> and <k_src> arguments, to a destination buffer in user virtual space, 138 // defined by the <u_dst> argument. 139 // It works in a critical section, as it modifies briefly two CP2 registers: 140 // It activates briefly the DATA_MMU by writing into the CP2_MODE register to access the 141 // user buffer, and modifies the CP2_DATA_EXT register to access the kernel buffer. 142 // If the two buffers are aligned on a word boundary, it moves the data word per word 143 // in a first loop, and moves byte per byte the remaining bytes in a second loop. 144 // If the buffers are not aligned, it moves all data byte per byte. 145 /////////////////////////////////////////////////////////////////////////////////////// 146 // @ k_cxy : cluster of destination kernel buffer 147 // @ k_dst : pointer on destination kernel buffer 148 // @ u_src : pointer on source user buffer 149 // @ size : number of bytes to move 150 /////////////////////////////////////////////////////////////////////////////////////// 151 void hal_copy_to_uspace( cxy_t k_cxy, 98 152 void * k_src, 153 void * u_dst, 99 154 uint32_t size ) 100 155 { 101 156 uint32_t save_sr; 102 uint32_t i; 103 uint32_t wsize; // number of words if aligned 157 uint32_t words; // number of words (if buffers aligned) 104 158 uint32_t src = (uint32_t)k_src; 105 159 uint32_t dst = (uint32_t)u_dst; 106 160 107 161 #if DEBUG_HAL_USPACE 108 thread_t * this = CURRENT_THREAD; 109 printk("\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 ); 162 thread_t * this = CURRENT_THREAD; 163 uint32_t cycle = (uint32_t)hal_get_cycles(); 164 if( cycle > DEBUG_HAL_USPACE ) 165 printk("\n[%s] thread[%x,%x] enter / %d bytes / k_buf(%x,%x) -> u_buf(%x,%x) / cycle %d\n", 166 __FUNCTION__, this->process->pid, this->trdid, size, k_cxy, k_src, local_cxy, u_dst, cycle ); 111 167 #endif 112 168 113 if( (dst & 0x3) || (src & 0x3) ) wsize = 0; // not aligned 114 else wsize = size >> 2; 115 169 if( (dst & 0x3) || (src & 0x3) ) words = 0; // not aligned 170 else words = size >> 2; 171 172 // enter critical section 116 173 hal_disable_irq( &save_sr ); 117 174 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 175 asm volatile( ".set noreorder \n" 176 177 /* initialise registers */ 178 "move $8, %0 \n" /* $8 <= k_src */ 179 "move $9, %1 \n" /* $9 <= u_dst */ 180 "move $10, %2 \n" /* $10 <= words */ 181 "move $11, %3 \n" /* $11 <= size */ 182 "mfc2 $12, $1 \n" /* $12 <= old MMU_MODE */ 183 "ori $13, $12, 0x4 \n" /* $13 <= MMU_MODE with DTLB */ 184 185 /* save old MMU_DATA_EXT and set k_cxy in it */ 186 "mfc2 $16, $24 \n" /* $16 <= old MMU_DATA_EXT */ 187 "mtc2 %4, $24 \n" /* MMU_DATA_EXT <= k_cxy */ 188 189 /* transfer one word per iteration in first loop if aligned */ 190 "move $15, $10 \n" /* $15 <= words ($15 == i) */ 191 "1: \n" 192 "beq $15, $0, 2f \n" /* exit loop if (i==0) */ 193 "nop \n" 194 "lw $14, 0($8) \n" /* load from kernel space */ 195 "mtc2 $13, $1 \n" /* MMU_MODE <= DTLB ON */ 196 "sw $14, 0($9) \n" /* store to user space */ 197 "mtc2 $12, $1 \n" /* restore old MMU_MODE */ 198 "addi $15, $15, -1 \n" /* i-- */ 199 "addi $8, $8, 4 \n" /* src += 4 bytes */ 200 "j 1b \n" 201 "addi $9, $9, 4 \n" /* dst += 4 bytes */ 202 203 /* transfer one byte per iteration in this second loop */ 204 "2: \n" 205 "sll $15, $10, 2 \n" /* $15 <= words*4 ($15 == i) */ 206 "3: \n" 207 "beq $15, $11, 4f \n" /* exit loop if (i == size) */ 208 "nop \n" 209 "lb $14, 0($8) \n" /* byte from kernel space */ 210 "mtc2 $13, $1 \n" /* MMU_MODE <= DTLB ON */ 211 "sb $14, 0($9) \n" /* byte to user space */ 212 "mtc2 $12, $1 \n" /* restore omd MMU_MODE */ 213 "addi $15, $15, 1 \n" /* i++ */ 214 "addi $8, $8, 1 \n" /* src += 1 byte */ 215 "j 3b \n" 216 "addi $9, $9, 1 \n" /* dst += 1 byte */ 217 218 /* restore old MMU_DATA_EXT register */ 219 "4: \n" 220 "mtc2 $16, $24 \n" /* MMU__DATA_EXT <= $16 */ 221 ".set reorder \n" 222 : 223 : "r"(src) , "r"(dst) , "r"(words) , "r"(size) , "r"(k_cxy) 224 : "$8","$9","$10","$11","$12","$13","$14","$15","$16","memory" ); 225 226 // exit critical section 148 227 hal_restore_irq( save_sr ); 149 228 150 229 #if DEBUG_HAL_USPACE 151 printk("\n[%s] thread[%x,%x] exit\n", 152 __FUNCTION__, this->process->pid, this->trdid ); 230 cycle = (uint32_t)hal_get_cycles(); 231 if( cycle > DEBUG_HAL_USPACE ) 232 printk("\n[%s] thread[%x,%x] moved %d bytes / k_buf(%x,%x) -> u_buf(%x,%x) / cycle %d\n", 233 __FUNCTION__, this->process->pid, this->trdid, size, k_cxy, k_src, local_cxy, u_dst, cycle ); 153 234 #endif 154 235 -
trunk/hal/tsar_mips32/drivers/soclib_bdv.c
r622 r626 58 58 void __attribute__ ((noinline)) soclib_bdv_cmd( xptr_t th_xp ) 59 59 { 60 uint32_t cmd_type; // IOC_READ / IOC_WRITE / IOC_SYNC_READ 60 uint32_t cmd_type; // IOC_READ / IOC_WRITE / IOC_SYNC_READ / IOC_SYNC_WRITE 61 61 uint32_t lba; 62 62 uint32_t count; … … 86 86 ioc_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) ); 87 87 88 #if DEBUG_HAL_IOC_RX 89 if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) ) 90 printk("\n[%s] thread[%x,%x] enters for client thread[%x,%x] / RX / cycle %d\n", 91 __FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 92 #endif 93 94 #if DEBUG_HAL_IOC_TX 95 if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) ) 96 printk("\n[%s] thread[%x,%x] enters for client thread[%x,%x] / TX / cycle %d\n", 97 __FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 98 #endif 88 // decode command 89 if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) ) op = BDV_OP_READ; 90 else if( (cmd_type == IOC_WRITE) || (cmd_type == IOC_SYNC_WRITE) ) op = BDV_OP_WRITE; 91 else assert( false , "illegal command" ); 99 92 100 93 // get IOC device cluster and local pointer … … 110 103 uint32_t buf_lsb = (uint32_t)(buf_xp); 111 104 uint32_t buf_msb = (uint32_t)(buf_xp>>32); 105 106 #if DEBUG_HAL_IOC_RX 107 if( DEBUG_HAL_IOC_RX < cycle ) 108 printk("\n[%s] thread[%x,%x] enters / client[%x,%x] / cmd %d / lba %x / buf(%x,%x) / cycle %d\n", 109 __FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, 110 cmd_type, lba, buf_msb, buf_lsb, cycle ); 111 #endif 112 113 #if DEBUG_HAL_IOC_TX 114 if( DEBUG_HAL_IOC_TX < cycle ) 115 printk("\n[%s] thread[%x,%x] enters / client[%x,%x] / cmd %d / lba %x / buf(%x,%x) / cycle %d\n", 116 __FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, 117 cmd_type, lba, buf_msb, buf_lsb, cycle ); 118 #endif 112 119 113 120 // select operation … … 143 150 { 144 151 hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 0 ); 152 153 #if DEBUG_HAL_IOC_RX 154 cycle = (uint32_t)hal_get_cycles(); 155 if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type == IOC_SYNC_READ) ) 156 printk("\n[%s] thread[%x,%x] exit after SYNC_READ for client thread[%x,%x] / cycle %d\n", 157 __FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 158 #endif 159 160 #if DEBUG_HAL_IOC_TX 161 cycle = (uint32_t)hal_get_cycles(); 162 if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_SYNC_WRITE) ) 163 printk("\n[%s] thread[%x,%x] exit after SYNC_WRITE for client thread[%x,%x] / cycle %d\n", 164 __FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 165 #endif 145 166 break; 146 167 } 147 else if( status == BDV_BUSY ) // non completed168 else if( status == BDV_BUSY ) // non completed 148 169 { 149 170 continue; 150 171 } 151 else // error reported172 else // error reported 152 173 { 153 174 hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 1 ); … … 170 191 #if DEBUG_HAL_IOC_RX 171 192 if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) ) 172 printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching R Xtransfer\n",193 printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching READ transfer\n", 173 194 __FUNCTION__ , this->process->pid, this->trdid ); 174 195 #endif … … 176 197 #if DEBUG_HAL_IOC_TX 177 198 if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) ) 178 printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching TXtransfer\n",199 printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching WRITE transfer\n", 179 200 __FUNCTION__ , this->process->pid, this->trdid ); 180 201 #endif … … 184 205 // exit critical section 185 206 hal_restore_irq( save_sr ); 186 }187 207 188 208 #if DEBUG_HAL_IOC_RX 189 209 cycle = (uint32_t)hal_get_cycles(); 190 210 if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE) ) 191 printk("\n[%s] thread[%x,%x] exit after R Xfor client thread[%x,%x] / cycle %d\n",211 printk("\n[%s] thread[%x,%x] exit after READ for client thread[%x,%x] / cycle %d\n", 192 212 __FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 193 213 #endif … … 196 216 cycle = (uint32_t)hal_get_cycles(); 197 217 if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) ) 198 printk("\n[%s] thread[%x,%x] exit after TX for client thread[%x,%x] / cycle %d\n", 199 __FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 200 #endif 218 printk("\n[%s] thread[%x,%x] exit after WRITE for client thread[%x,%x] / cycle %d\n", 219 __FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle ); 220 #endif 221 222 } 201 223 202 224 } // end soclib_bdv_cmd() … … 263 285 else 264 286 { 265 assert( false , " IOC_SYNC_READ should not use IRQ");287 assert( false , "illegal command %d", cmd_type ); 266 288 } 267 289 -
trunk/hal/tsar_mips32/drivers/soclib_mmc.c
r570 r626 1 1 /* 2 * soclib_mmc.c - soclib L2 cache controllerdriver implementation.2 * soclib_mmc.c - soclib L2 cache driver implementation. 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 61 61 62 62 // get command type and extended pointer on MMC device 63 type = hal_remote_l32 63 type = hal_remote_l32( XPTR( th_cxy , &th_ptr->mmc_cmd.type ) ); 64 64 dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->mmc_cmd.dev_xp ) ); 65 65 -
trunk/hal/tsar_mips32/drivers/soclib_mmc.h
r451 r626 1 1 /* 2 * soclib_mmc.h - SOCLIB_MMC (TSAR L2 cache)driver definition.2 * soclib_mmc.h - TSAR L2 cache driver definition. 3 3 * 4 * Author Alain Greiner 4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites
Note: See TracChangeset
for help on using the changeset viewer.