- Timestamp:
- Apr 29, 2019, 7:25:09 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 51 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Makefile
r625 r626 60 60 # Rule to generate boot.elf, kernel.elf, all user.elf files, and update the virtual disk 61 61 # when the corresponding sources files have been modified or destroyed. 62 # The /homedirectory on the virtual disk is not modified62 # The "home" directory on the virtual disk is not modified 63 63 compile: dirs \ 64 64 hard_config.h \ … … 123 123 mmd -o -i $(DISK_IMAGE) ::/bin/user || true 124 124 mmd -o -i $(DISK_IMAGE) ::/home || true 125 mcopy -o -i $(DISK_IMAGE) Makefile ::/home || true126 125 mdir -/ -b -i $(DISK_IMAGE) ::/ 127 126 -
trunk/hal/generic/hal_uspace.h
r570 r626 2 2 * hal_uspace.h - Generic User Space Access API definition 3 3 * 4 * Authors Alain Greiner (2016,2017 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 38 38 39 39 /***************************************************************************************** 40 * This function tranfers a data buffer from the user space to the kernel space.41 * If the kernel uses physical addresses, it activates the MMU to access the user buffer.40 * This function tranfers a data buffer in user space to a kernel buffer 41 * that can be located in any cluster. 42 42 ***************************************************************************************** 43 * @ k_dst : destination address in kernel space. 43 * @ k_cxy : cluster identifier for kernel destination buffer. 44 * @ k_dst : local pointer on kernel destination buffer. 44 45 * @ u_src : source buffer address in user space. 45 46 * @ size : size (number of bytes). 46 47 ****************************************************************************************/ 47 extern void hal_copy_from_uspace( void * k_dst, 48 extern void hal_copy_from_uspace( cxy_t k_cxy, 49 void * k_dst, 48 50 void * u_src, 49 51 uint32_t size ); 50 52 51 53 /***************************************************************************************** 52 * This function tranfers a data buffer from the kernel space to the user space.53 * If the kernel uses physical addresses, it activates the MMU to access the user buffer.54 * This function tranfers a kernel buffer that can be located in any cluster 55 * to a data buffer in the user space. 54 56 ***************************************************************************************** 57 * @ k_cxy : cluster identifier for kernel source buffer. 58 * @ k_src : local pointer on kernel source buffer. 55 59 * @ u_dst : destination buffer address in user space. 56 * @ k_src : source address in kernel space.57 60 * @ size : size (number of bytes). 58 61 ****************************************************************************************/ 59 extern void hal_copy_to_uspace( void * u_dst,62 extern void hal_copy_to_uspace( cxy_t k_cxy, 60 63 void * k_src, 64 void * u_dst, 61 65 uint32_t size ); 62 66 -
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 -
trunk/kernel/Makefile
r612 r626 185 185 build/syscalls/sys_is_fg.o 186 186 187 SYS_OBJS_5 = build/syscalls/sys_exit.o 187 SYS_OBJS_5 = build/syscalls/sys_exit.o \ 188 build/syscalls/sys_sync.o \ 189 build/syscalls/sys_fsync.o 188 190 189 191 VFS_OBJS = build/fs/vfs.o \ … … 194 196 # List of directories to be searched for included files 195 197 # when compiling for kernel.elf generation 196 KERNEL_INCLUDE = -I. \197 -Ikern \198 -Idevices \199 -Isyscalls \200 -I$(SHARED_INCLUDE) \198 KERNEL_INCLUDE = -I. \ 199 -Ikern \ 200 -Idevices \ 201 -Isyscalls \ 202 -I$(SHARED_INCLUDE) \ 201 203 -I$(HAL_ARCH)/drivers \ 202 204 -Isyscalls \ -
trunk/kernel/devices/dev_ioc.c
r619 r626 2 2 * dev_ioc.c - IOC (Block Device Controler) generic device API implementation. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 36 36 37 37 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 38 39 //////////////////////////////////////// 40 char * dev_ioc_cmd_str( cmd_type_t cmd ) 41 { 42 if ( cmd == IOC_READ ) return "READ"; 43 else if( cmd == IOC_WRITE ) return "WRITE"; 44 else if( cmd == IOC_SYNC_READ ) return "SYNC_READ"; 45 else if( cmd == IOC_SYNC_WRITE ) return "SYNC_WRITE"; 46 else return "undefined"; 47 } 38 48 39 49 ////////////////////////////////// … … 192 202 ////////////////////////////////////i///////////////////////////////////////////// 193 203 error_t dev_ioc_sync_access( uint32_t cmd_type, 194 uint8_t * buffer,204 xptr_t buffer_xp, 195 205 uint32_t lba, 196 206 uint32_t count ) … … 202 212 if( chdev_dir.iob ) 203 213 { 204 if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( XPTR(local_cxy,buffer), count<<9 );205 else dev_mmc_sync ( XPTR(local_cxy,buffer), count<<9 );214 if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( buffer_xp , count<<9 ); 215 else dev_mmc_sync ( buffer_xp , count<<9 ); 206 216 } 207 217 … … 215 225 this->ioc_cmd.dev_xp = ioc_xp; 216 226 this->ioc_cmd.type = cmd_type; 217 this->ioc_cmd.buf_xp = XPTR( local_cxy , buffer );227 this->ioc_cmd.buf_xp = buffer_xp; 218 228 this->ioc_cmd.lba = lba; 219 229 this->ioc_cmd.count = count; … … 241 251 return this->ioc_cmd.error; 242 252 243 } // end ioc_sync_access()244 245 ///////////////////////////////////////////// 246 error_t dev_ioc_sync_read( uint8_t * buffer,253 } // end dev_ioc_sync_access() 254 255 //////////////////////////////////////////////// 256 error_t dev_ioc_sync_read( xptr_t buffer_xp, 247 257 uint32_t lba, 248 258 uint32_t count ) … … 253 263 uint32_t cycle = (uint32_t)hal_get_cycles(); 254 264 if( DEBUG_DEV_IOC_RX < cycle ) 255 printk("\n[%s] thread[%x,%x] : lba %x / buffer %x / cycle %d\n", 256 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle ); 257 #endif 258 259 return dev_ioc_sync_access( IOC_SYNC_READ , buffer , lba , count ); 265 printk("\n[%s] thread[%x,%x] : lba %x / buffer(%x,%x) / count %d / cycle %d\n", 266 __FUNCTION__ , this->process->pid, this->trdid, 267 lba, GET_CXY(buffer_xp), GET_PTR(buffer_xp), count, cycle ); 268 #endif 269 270 return dev_ioc_sync_access( IOC_SYNC_READ , buffer_xp , lba , count ); 260 271 } 261 272 262 ////////////////////////////////////////////// 263 error_t dev_ioc_sync_write( uint8_t * buffer,273 ///////////////////////////////////////////////// 274 error_t dev_ioc_sync_write( xptr_t buffer_xp, 264 275 uint32_t lba, 265 276 uint32_t count ) 266 277 { 267 278 268 #if DEBUG_DEV_IOC_RX 269 thread_t * this = CURRENT_THREAD; 270 uint32_t cycle = (uint32_t)hal_get_cycles(); 271 if( DEBUG_DEV_IOC_RX < cycle ) 272 printk("\n[%s] thread[%x,%x] enters / lba %x / buffer %x / cycle %d\n", 273 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle ); 274 #endif 275 276 return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer , lba , count ); 279 #if DEBUG_DEV_IOC_TX 280 thread_t * this = CURRENT_THREAD; 281 uint32_t cycle = (uint32_t)hal_get_cycles(); 282 if( DEBUG_DEV_IOC_TX < cycle ) 283 printk("\n[%s] thread[%x,%x] : lba %x / buffer(%x,%x) / count %d / cycle %d\n", 284 __FUNCTION__ , this->process->pid, this->trdid, 285 lba, GET_CXY(buffer_xp), GET_PTR(buffer_xp), count, cycle ); 286 #endif 287 288 return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer_xp , lba , count ); 277 289 } 278 290 -
trunk/kernel/devices/dev_ioc.h
r614 r626 2 2 * dev_ioc.h - IOC (Block Device Controler) generic device API definition. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 44 44 * - SYNC_WRITE : move blocks from memory to device, with a busy waiting policy. 45 45 46 * A READ or WRITE operation requiresdynamic ressource allocation. The calling thread46 * The READ or WRITE operations require dynamic ressource allocation. The calling thread 47 47 * is descheduled, and the work is done by the server thread associated to IOC device. 48 48 * The general scenario is detailed below. … … 66 66 * 67 67 * The SYNC_READ and SYNC_WRITE operations are used by the kernel in the initialisation 68 * phase. These operations do not not use the IOC device waiting queue, the server thread, 69 * and the IOC IRQ, but implement a busy-waiting policy for the calling thread. 68 * phase, to update the FAT (both the FAT mapper and the FAT on IOC device), or to update 69 * a directory on IOC device when a new file is created. 70 * - These synchronous operations do not not use the IOC device waiting queue, 71 * the server thread, and the IOC IRQ, but implement a busy-waiting policy 72 * for the calling thread. 73 * - As the work 70 74 *****************************************************************************************/ 71 75 … … 119 123 } 120 124 ioc_command_t; 125 126 /****************************************************************************************** 127 * This function returns a printable string for a IOC command type. 128 ****************************************************************************************** 129 * @ cmd : command type. 130 * @ return pointer on string. 131 *****************************************************************************************/ 132 char * dev_ioc_cmd_str( cmd_type_t cmd ); 121 133 122 134 /****************************************************************************************** … … 138 150 * registered in the device pending request queue, and the calling thread is descheduled, 139 151 * waiting on transfer completion. It will be resumed by the IRQ signaling completion. 140 * It must be called in the client cluster.152 * It must be called by a local thread. 141 153 ****************************************************************************************** 142 154 * @ buffer : local pointer on target buffer in memory (must be block aligned). 143 155 * @ lba : first block index on device. 144 156 * @ count : number of blocks to transfer. 145 * @ returns 0 if success / returns EINVALif error.157 * @ returns 0 if success / returns -1 if error. 146 158 *****************************************************************************************/ 147 159 error_t dev_ioc_read( uint8_t * buffer, … … 154 166 * registered in the device pending request queue, and the calling thread is descheduled, 155 167 * waiting on transfer completion. It will be resumed by the IRQ signaling completion. 156 * It must be called in the client cluster.168 * It must be called by a local thread. 157 169 ****************************************************************************************** 158 170 * @ buffer : local pointer on source buffer in memory (must be block aligned). 159 171 * @ lba : first block index on device. 160 172 * @ count : number of blocks to transfer. 161 * @ returns 0 if success / returns EINVALif error.173 * @ returns 0 if success / returns -1 if error. 162 174 *****************************************************************************************/ 163 175 error_t dev_ioc_write( uint8_t * buffer, … … 167 179 /****************************************************************************************** 168 180 * This blocking function moves one or several contiguous blocks of data 169 * from the block device to a localmemory buffer.181 * from the block device to a - possibly remote - memory buffer. 170 182 * It does not uses the IOC device waiting queue and server thread, and does not use 171 183 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting 172 184 * policy for the calling thread. 173 * It must be called in the clientcluster.174 ****************************************************************************************** 175 * @ buffer : localpointer on target buffer in memory (must be block aligned).176 * @ lba : first block index on device. 177 * @ count : number of blocks to transfer. 178 * @ returns 0 if success / returns EINVALif error.179 *****************************************************************************************/ 180 error_t dev_ioc_sync_read( uint8_t * buffer,185 * It can be called by a thread running in any cluster. 186 ****************************************************************************************** 187 * @ buffer_xp : extended pointer on target buffer in memory (must be block aligned). 188 * @ lba : first block index on device. 189 * @ count : number of blocks to transfer. 190 * @ returns 0 if success / returns -1 if error. 191 *****************************************************************************************/ 192 error_t dev_ioc_sync_read( xptr_t buffer_xp, 181 193 uint32_t lba, 182 194 uint32_t count ); … … 184 196 /****************************************************************************************** 185 197 * This blocking function moves one or several contiguous blocks of data 186 * from a localmemory buffer to the block device.198 * from a - possibly remote - memory buffer to the block device. 187 199 * It does not uses the IOC device waiting queue and server thread, and does not use 188 200 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting 189 201 * policy for the calling thread. 190 * It must be called in the clientcluster.191 ****************************************************************************************** 192 * @ buffer : localpointer on source buffer in memory (must be block aligned).193 * @ lba : first block index on device. 194 * @ count : number of blocks to transfer. 195 * @ returns 0 if success / returns EINVALif error.196 *****************************************************************************************/ 197 error_t dev_ioc_sync_write( uint8_t * buffer,202 * It can be called by a thread running in any cluster. 203 ****************************************************************************************** 204 * @ buffer_xp : extended pointer on source buffer in memory (must be block aligned). 205 * @ lba : first block index on device. 206 * @ count : number of blocks to transfer. 207 * @ returns 0 if success / returns -1 if error. 208 *****************************************************************************************/ 209 error_t dev_ioc_sync_write( xptr_t buffer_xp, 198 210 uint32_t lba, 199 211 uint32_t count ); -
trunk/kernel/devices/dev_mmc.c
r605 r626 108 108 109 109 // get buffer cluster and local pointer 110 cxy_t buf_cxy = GET_CXY( buf_xp );111 void* buf_ptr = GET_PTR( buf_xp );110 cxy_t buf_cxy = GET_CXY( buf_xp ); 111 uint8_t * buf_ptr = GET_PTR( buf_xp ); 112 112 113 assert( (((intptr_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) , 114 "buffer not aligned on cache line" ); 113 // force buffer align 114 uint32_t delta = (uint32_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE - 1); 115 uint8_t * base = buf_ptr - delta; 116 uint32_t size = buf_size + delta; 115 117 116 118 // store command arguments in thread descriptor 117 119 this->mmc_cmd.dev_xp = chdev_dir.mmc[buf_cxy]; 118 120 this->mmc_cmd.type = MMC_CC_INVAL; 119 this->mmc_cmd.buf_ptr = b uf_ptr;120 this->mmc_cmd.buf_size = buf_size;121 this->mmc_cmd.buf_ptr = base; 122 this->mmc_cmd.buf_size = size; 121 123 122 124 // call MMC driver … … 152 154 void * buf_ptr = GET_PTR( buf_xp ); 153 155 154 assert( (((intptr_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) , 155 "buffer not aligned on cache line" ); 156 // force buffer align 157 uint32_t delta = (uint32_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE - 1); 158 uint8_t * base = buf_ptr - delta; 159 uint32_t size = buf_size + delta; 156 160 157 161 // store command arguments in thread descriptor 158 162 this->mmc_cmd.dev_xp = chdev_dir.mmc[buf_cxy]; 159 163 this->mmc_cmd.type = MMC_CC_SYNC; 160 this->mmc_cmd.buf_ptr = b uf_ptr;161 this->mmc_cmd.buf_size = buf_size;164 this->mmc_cmd.buf_ptr = base; 165 this->mmc_cmd.buf_size = size; 162 166 163 167 // call MMC driver -
trunk/kernel/devices/dev_txt.c
r619 r626 2 2 * dev_txt.c - TXT (Text Terminal) generic device API implementation. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites -
trunk/kernel/devices/dev_txt.h
r565 r626 2 2 * dev_txt.h - TXT (Text Terminal) generic device API definition. 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017,2018,2019)) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 106 106 const char * buffer; /*! local pointer on characters array */ 107 107 uint32_t count; /*! number of characters in buffer */ 108 uint32_t channel; /*! channel, aka which tty to write to*/108 uint32_t channel; /*! channel, aka which tty to write to */ 109 109 } 110 110 txt_sync_args_t; 111 111 112 112 /****************************************************************************************** 113 * This function returns a printable string for the comman type.113 * This function returns a printable string for the command type. 114 114 ****************************************************************************************** 115 115 * @ type : command type (TXT_READ / TXT_WRITE / TXT_SYNC_WRITE) … … 166 166 * interfering with another possible TXT access to another terminal. 167 167 * As it is used for debug, the command arguments <buffer> and <count> are registerd 168 * in a specific " dbg_cmd" field of the calling thread.168 * in a specific "txt_syc_args_t" structure passed to the driver "aux" function. 169 169 **************************************************************************************** 170 170 * @ buffer : local pointer on source buffer containing the string. -
trunk/kernel/fs/fatfs.c
r625 r626 37 37 #include <fatfs.h> 38 38 39 #define LITTLE_ENDIAN 1 39 40 40 41 ////////////////////////////////////////////////////////////////////////////////////////// … … 72 73 73 74 ////////////////////////////////////////////////////////////////////////////////////////// 74 // This function return an integer record value (one, two, or four bytes) 75 // from a memory buffer, taking into account endianness.76 // ////////////////////////////////////////////////////////////////////////////////////////77 // @ offset : first byte of record in buffer.78 // @ size : record length in bytes (1/2/4).79 // @ buffer : pointer on buffer base.80 // @ little endian : the most significant byte has the highest address when true.75 // This function return an integer record value (one, two, or four bytes) from a local 76 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 77 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 78 ////////////////////////////////////////////////////////////////////////////////////////// 79 // @ offset : first byte in array. 80 // @ nbytes : record length in bytes (1/2/4). 81 // @ buffer : local pointer on byte array. 81 82 // @ return the integer value in a 32 bits word. 82 83 ////////////////////////////////////////////////////////////////////////////////////////// 83 84 static uint32_t fatfs_get_record( uint32_t offset, 84 uint32_t size, 85 uint8_t * buffer, 86 uint32_t little_endian ) 87 { 88 uint32_t n; 89 uint32_t res = 0; 90 91 if ( little_endian ) 92 { 93 for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1]; 94 } 95 else // big_endian 96 { 97 for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n]; 85 uint32_t nbytes, 86 uint8_t * buffer ) 87 { 88 uint32_t i; 89 uint32_t res = 0; 90 91 if ( LITTLE_ENDIAN ) 92 { 93 for( i = nbytes ; i > 0 ; i-- ) res = (res<<8) | buffer[offset+i-1]; 94 } 95 else 96 { 97 for( i = 0 ; i < nbytes ; i++ ) res = (res<<8) | buffer[offset+i]; 98 98 } 99 99 return res; … … 102 102 103 103 ////////////////////////////////////////////////////////////////////////////////////////// 104 // This function writes one, two, or four bytes from a 32 bits integer to a memory buffer,105 // taking into account endianness.106 // ////////////////////////////////////////////////////////////////////////////////////////107 // @ offset : first byte of record in buffer.108 // @ size : record length in bytes (1/2/4).109 // @ buffer : pointer on buffer base.110 // @ little endian : the most significant byte has the highest address when true.104 // This function return an integer record value (one, two, or four bytes) from a remote 105 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 106 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 107 ////////////////////////////////////////////////////////////////////////////////////////// 108 // @ offset : first byte in array. 109 // @ nbytes : record length in bytes (1/2/4). 110 // @ buffer_xp : extended pointer on byte array. 111 111 // @ return the integer value in a 32 bits word. 112 112 ////////////////////////////////////////////////////////////////////////////////////////// 113 static uint32_t fatfs_get_remote_record( uint32_t offset, 114 uint32_t nbytes, 115 xptr_t buffer_xp ) 116 { 117 uint32_t i; 118 uint32_t res = 0; 119 120 if ( LITTLE_ENDIAN ) 121 { 122 for( i = nbytes ; i > 0 ; i-- ) 123 { 124 res = (res<<8) | hal_remote_lb( buffer_xp+offset+i-1 ); 125 } 126 } 127 else 128 { 129 for( i = 0 ; i < nbytes ; i++ ) 130 { 131 res = (res<<8) | hal_remote_lb( buffer_xp+offset+i ); 132 } 133 } 134 return res; 135 136 } // end fatfs_get_remote_record() 137 138 ////////////////////////////////////////////////////////////////////////////////////////// 139 // This function writes one, two, or four bytes from a 32 bits integer to a local 140 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 141 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 142 ////////////////////////////////////////////////////////////////////////////////////////// 143 // @ offset : first byte in array. 144 // @ nbytes : record length in bytes (1/2/4). 145 // @ buffer : local pointer on byte array. 146 // @ value : 32 bits integer value. 147 ////////////////////////////////////////////////////////////////////////////////////////// 113 148 static void fatfs_set_record( uint32_t offset, 114 uint32_t size,149 uint32_t nbytes, 115 150 uint8_t * buffer, 116 uint32_t little_endian,117 151 uint32_t value ) 118 152 { 119 uint32_t n; 120 121 if ( little_endian ) 122 { 123 for( n = size ; n > 0 ; n-- ) buffer[offset+n-1] = (uint8_t)(value>>((n-1)<<3)); 124 } 125 else // big_endian 126 { 127 for( n = 0 ; n < size ; n++ ) buffer[offset+n] = (uint8_t)(value>>((size-1-n)<<3)); 153 uint32_t i; 154 155 if ( LITTLE_ENDIAN ) 156 { 157 for( i = nbytes ; i > 0 ; i-- ) buffer[offset+i-1] = (uint8_t)(value>>((i-1)<<3)); 158 } 159 else 160 { 161 for( i = 0 ; i < nbytes ; i++ ) buffer[offset+i] = (uint8_t)(value>>((nbytes-1-i)<<3)); 162 } 163 164 } // end fatfs_set_record() 165 166 ////////////////////////////////////////////////////////////////////////////////////////// 167 // This function writes one, two, or four bytes from a 32 bits integer to a remote 168 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 169 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 170 ////////////////////////////////////////////////////////////////////////////////////////// 171 // @ offset : first byte in array. 172 // @ nbytes : record length in bytes (1/2/4). 173 // @ buffer_xp : extended pointer on byte array. 174 // @ value : 32 bits integer value. 175 ////////////////////////////////////////////////////////////////////////////////////////// 176 static void fatfs_set_remote_record( uint32_t offset, 177 uint32_t nbytes, 178 xptr_t buffer_xp, 179 uint32_t value ) 180 { 181 uint32_t i; 182 183 if ( LITTLE_ENDIAN ) 184 { 185 for( i = nbytes ; i > 0 ; i-- ) 186 { 187 hal_remote_sb( (buffer_xp+offset+i-1) , (uint8_t)(value>>((i-1)<<3)) ); 188 } 189 } 190 else 191 { 192 for( i = 0 ; i < nbytes ; i++ ) 193 { 194 hal_remote_sb( (buffer_xp+offset+i) , (uint8_t)(value>>((nbytes-1-i)<<3)) ); 195 } 128 196 } 129 197 … … 374 442 375 443 ////////////////////////////////////////////////////////////////////////////////////////// 444 // This static function is called by both the fatfs_free_clusters_increment(), 445 // and the fatfs_free_cluster_decrement() functions defined below. 446 // It synchronously updates the "free_clusters" and "free_cluster_hint" variables 447 // in FS_INFO sector on the IOC device, each times these variables are modified. 448 ////////////////////////////////////////////////////////////////////////////////////////// 449 // @ fatfs_ctx_xp : extended pointer on fatfs context in FAT cluster. 450 // @ free_clusters : new free_clusters value. 451 // @ free_cluster_hint : new free_cluster_hint value. 452 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 453 ////////////////////////////////////////////////////////////////////////////////////////// 454 static error_t fatfs_free_clusters_update_ioc( xptr_t fatfs_ctx_xp, 455 uint32_t free_clusters, 456 uint32_t free_cluster_hint ) 457 { 458 cxy_t fat_cxy; // FAT cluster identifier 459 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on fatfs context in FAT cluster 460 uint8_t * fs_info_buffer_ptr; // local pointer on FS_INFO buffer in FAT cluster 461 xptr_t fs_info_buffer_xp; // extended pointer on FS_INFO buffer in FAT cluster 462 uint32_t fs_info_lba; // FS_INFO sector lba on IOC device 463 464 // get cluster and local pointer on FAT cluster context 465 fat_cxy = GET_CXY( fatfs_ctx_xp ); 466 fatfs_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 467 468 // get pointers on FS_INFO buffer in FAT cluster 469 fs_info_buffer_ptr = hal_remote_lpt( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_buffer ) ); 470 fs_info_buffer_xp = XPTR( fat_cxy , fs_info_buffer_ptr ); 471 472 // get lba of FS_INFO sector on IOC device from fatfs context 473 fs_info_lba = hal_remote_l32( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_lba ) ); 474 475 // update the FS_INFO buffer in FAT cluster 476 fatfs_set_remote_record( FS_FREE_CLUSTERS , fs_info_buffer_xp , free_clusters ); 477 fatfs_set_remote_record( FS_FREE_CLUSTER_HINT , fs_info_buffer_xp , free_cluster_hint ); 478 479 // update the FS_INFO sector on IOC device 480 return dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 ); 481 482 } // fatfs_free_clusters_update_ioc() 483 484 ////////////////////////////////////////////////////////////////////////////////////////// 376 485 // This static function decrements the "free_clusters" variable, and updates the 377 // "free_cluster_hint" variable in the FATFS context , identified by the <fat_ctx_cxy>378 // and <fat_ctx_ptr> arguments (cluster containing the FAT mapper).486 // "free_cluster_hint" variable in the FATFS context in FAT cluster, identified 487 // by the <fat_ctx_xp> argument, when a new <cluster> has been allocated from FAT. 379 488 // It scan all slots in the FAT mapper seen as an array of 32 bits words, looking for the 380 489 // first free slot larger than the <cluster> argument, to update "free_cluster_hint". 490 // It calls the fatfs_free_clusters_update_ioc() function to synchronously update the 491 // FS_INFO sector on the IOC device. It can be called by a thead running in any cluster. 381 492 // 382 493 // WARNING : The free_lock protecting exclusive access to these variables 383 494 // must be taken by the calling function. 384 495 ////////////////////////////////////////////////////////////////////////////////////////// 385 // @ fat_ctx_cxy : FAT mapper cluster identifier. 386 // @ fat_ctx_ptr : local pointer on FATFS context. 387 // @ cluster : recently allocated cluster index in FAT. 388 ////////////////////////////////////////////////////////////////////////////////////////// 389 static error_t fatfs_free_clusters_decrement( cxy_t fat_ctx_cxy, 390 fatfs_ctx_t * fat_ctx_ptr, 391 uint32_t cluster ) 392 { 496 // @ fatfs_ctx_xp : extended pointer on FATFS context in FAT cluster. 497 // @ cluster : recently allocated cluster index in FAT. 498 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 499 ////////////////////////////////////////////////////////////////////////////////////////// 500 static error_t fatfs_free_clusters_decrement( xptr_t fatfs_ctx_xp, 501 uint32_t cluster ) 502 { 503 error_t error; 504 cxy_t fat_cxy; // FAT cluster identifier 505 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster 393 506 xptr_t mapper_xp; // extended pointer on FAT mapper 394 507 xptr_t hint_xp; // extended pointer on "free_cluster_hint" shared variable 395 508 xptr_t numb_xp; // extended pointer on "free_clusters" shared variable 396 509 uint32_t numb; // "free_clusters" variable current value 510 uint32_t hint; // "free_cluster_hint" variable current value 397 511 uint32_t page_id; // page index in FAT mapper 398 512 uint32_t slot_id; // slot index in one page of FAT (1024 slots per page) … … 405 519 uint32_t cycle = (uint32_t)hal_get_cycles(); 406 520 thread_t * this = CURRENT_THREAD; 407 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles())521 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 408 522 printk("\n[%s] thread[%x,%x] enter for allocated cluster %x / cycle %d\n", 409 523 __FUNCTION__, this->process->pid, this->trdid, cluster , cycle ); 410 524 #endif 411 525 412 // build extended pointers on free_clusters, and free_cluster_hint 413 hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint ); 414 numb_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_clusters ); 415 416 // update "free_clusters" 417 numb = hal_remote_l32( numb_xp ); 418 hal_remote_s32( numb_xp , numb - 1 ); 526 // get FAT cluster an local pointer on fatfs context in FAT cluster 527 fat_cxy = GET_CXY( fatfs_ctx_xp ); 528 fat_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 529 530 // build extended pointers on free_clusters, and free_cluster_hint in fatfs context 531 hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint ); 532 numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters ); 533 534 // update "free_clusters" value 535 numb = hal_remote_l32( numb_xp ) - 1; 536 hal_remote_s32( numb_xp , numb ); 419 537 420 538 // get extended pointer on FAT mapper 421 mapper_xp = hal_remote_l64( XPTR( fat_c tx_cxy , &fat_ctx_ptr->fat_mapper_xp ) );539 mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper_xp ) ); 422 540 423 541 // initialise variables to scan the FAT mapper … … 425 543 page_id = (cluster + 1) >> 10; 426 544 slot_id = (cluster + 1) & 0x3FF; 427 page_max = hal_remote_l32( XPTR( fat_c tx_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;545 page_max = hal_remote_l32( XPTR( fat_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3; 428 546 429 547 // scan FAT mapper / loop on pages … … 451 569 if ( hal_remote_l32( slot_xp ) == FREE_CLUSTER ) 452 570 { 453 // update "free_cluster_hint" 454 hal_remote_s32( hint_xp , (page_id << 10) + slot_id - 1 ); 571 // update "free_cluster_hint" value 572 hint = (page_id << 10) + slot_id - 1; 573 hal_remote_s32( hint_xp , hint ); 574 575 // update FS_INFO sector on IOC device 576 error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint ); 577 578 if( error ) 579 { 580 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ ); 581 return -1; 582 } 455 583 456 584 #if DEBUG_FATFS_FREE_CLUSTERS 457 585 cycle = (uint32_t)hal_get_cycles(); 458 586 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() ) 459 printk("\n[%s] thread[%x,%x] exit / hint %x / free_clusters %x / cycle %d\n",460 __FUNCTION__, this->process->pid, this->trdid, 461 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) , cycle);587 printk("\n[%s] thread[%x,%x] updated free cluster info / hint %x / number %x\n", 588 __FUNCTION__, this->process->pid, this->trdid, 589 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) ); 462 590 #endif 463 591 return 0; … … 469 597 } // end loop on slots 470 598 471 // update (page_id,slot_id)variables599 // update page_id & slot_id variables 472 600 page_id++; 473 601 slot_id = 0; … … 483 611 ////////////////////////////////////////////////////////////////////////////////////////// 484 612 // This static function increments the "free_clusters" variable, and updates the 485 // "free_cluster_hint" variables in the FATFS context , identified by the <fat_ctx_cxy>486 // and <fat_ctx_ptr> argument (cluster containing the FAT mapper).613 // "free_cluster_hint" variables in the FATFS context in FAT cluster, identified 614 // by the <fat_ctx_xp> argument, when a cluster is released to FAT. 487 615 // If the released cluster index is smaller than the current (hint) value, 488 616 // it set "free_cluster_hint" <= cluster. 617 // It calls the fatfs_free_clusters_update_ioc() function to synchronously update the 618 // FS_INFO sector on the IOC device. It can be called by a thead running in any cluster. 489 619 // 490 620 // WARNING : The free_lock protecting exclusive access to these variables 491 621 // must be taken by the calling function. 492 622 ////////////////////////////////////////////////////////////////////////////////////////// 493 // @ fat_ctx_cxy : FAT mapper cluster identifier. 494 // @ fat_ctx_ptr : local pointer on FATFS context. 495 // @ cluster : recently released cluster index in FAT. 496 ////////////////////////////////////////////////////////////////////////////////////////// 497 static void fatfs_free_clusters_increment( cxy_t fat_ctx_cxy, 498 fatfs_ctx_t * fat_ctx_ptr, 499 uint32_t cluster ) 500 { 623 // @ fatfs_ctx_xp : extended pointer on FATFS context in FAT cluster. 624 // @ cluster : recently released cluster index in FAT. 625 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 626 ////////////////////////////////////////////////////////////////////////////////////////// 627 static error_t fatfs_free_clusters_increment( xptr_t fatfs_ctx_xp, 628 uint32_t cluster ) 629 { 630 error_t error; 631 cxy_t fat_cxy; // FAT cluster identifier 632 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster 501 633 xptr_t hint_xp; // extended pointer on "free_cluster_hint" shared variable 502 634 xptr_t numb_xp; // extended pointer on "free_clusters" shared variable … … 504 636 uint32_t numb; // "free_clusters" variable current value 505 637 638 #if DEBUG_FATFS_FREE_CLUSTERS 639 uint32_t cycle = (uint32_t)hal_get_cycles(); 640 thread_t * this = CURRENT_THREAD; 641 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 642 printk("\n[%s] thread[%x,%x] enter for released cluster %x / cycle %d\n", 643 __FUNCTION__, this->process->pid, this->trdid, cluster , cycle ); 644 #endif 645 646 // get FAT cluster an local pointer on fatfs context in FAT cluster 647 fat_cxy = GET_CXY( fatfs_ctx_xp ); 648 fat_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 649 506 650 // build extended pointers on free_clusters, and free_cluster_hint 507 hint_xp = XPTR( fat_c tx_cxy , &fat_ctx_ptr->free_cluster_hint );508 numb_xp = XPTR( fat_c tx_cxy , &fat_ctx_ptr->free_clusters );651 hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint ); 652 numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters ); 509 653 510 654 // get current value of free_cluster_hint and free_clusters … … 512 656 numb = hal_remote_l32( numb_xp ); 513 657 514 // update free_cluster_hint if required 515 if ( (cluster - 1) < hint ) hal_remote_s32( hint_xp , (cluster - 1) ); 658 // update "numb" and "hint" variables as required 659 numb++; 660 if ( (cluster - 1) < hint ) hint = cluster - 1; 516 661 517 662 // update free_clusters 518 hal_remote_s32( numb_xp , numb + 1 ); 663 hal_remote_s32( numb_xp , numb ); 664 hal_remote_s32( hint_xp , hint ); 665 666 // update FS_INFO sector on IOC device 667 error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint ); 668 669 if( error ) 670 { 671 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ ); 672 return -1; 673 } 519 674 520 675 #if DEBUG_FATFS_FREE_CLUSTERS 521 676 thread_t * this = CURRENT_THREAD; 522 677 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() ) 523 printk("\n[%s] thread[%x,%x] update sfree cluster info : hint %x / number %x\n",678 printk("\n[%s] thread[%x,%x] updated free cluster info : hint %x / number %x\n", 524 679 __FUNCTION__, this->process->pid, this->trdid, 525 680 hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) ); 526 681 #endif 682 683 return 0; 527 684 528 685 } // end fatfs_free_clusters_increment() … … 576 733 FREE_CLUSTER ) ) return -1; 577 734 578 // Update free_cluster_hint and free_clusters in FAT context 579 fatfs_free_clusters_increment( mapper_cxy, 580 fatfs_ctx, 581 cluster ); 582 583 return 0; 735 // Update free_cluster info in FATFS context and in FS_INFO sector 736 return fatfs_free_clusters_increment( XPTR( mapper_cxy , fatfs_ctx ) , cluster ); 584 737 585 738 } // end fatfs_recursive_release() … … 590 743 ////////////////////////////////////////////////////////////////////////////////////////// 591 744 592 /////////////////////////////////////////// 593 void fatfs_ctx_display( fatfs_ctx_t * ctx ) 594 { 595 printk("\n*** FAT context ***\n" 745 /////////////////////////////////// 746 void fatfs_display_ctx( cxy_t cxy ) 747 { 748 // get pointer on local FATFS context 749 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 750 fatfs_ctx_t * ctx = hal_remote_lpt( XPTR( cxy , &vfs_ctx->extend ) ); 751 752 uint32_t fat_sectors = hal_remote_l32( XPTR( cxy , &ctx->fat_sectors_count ) ); 753 uint32_t sector_size = hal_remote_l32( XPTR( cxy , &ctx->bytes_per_sector ) ); 754 uint32_t sec_per_clus = hal_remote_l32( XPTR( cxy , &ctx->sectors_per_cluster ) ); 755 uint32_t fat_lba = hal_remote_l32( XPTR( cxy , &ctx->fat_begin_lba ) ); 756 uint32_t data_lba = hal_remote_l32( XPTR( cxy , &ctx->cluster_begin_lba ) ); 757 uint32_t fsinfo_lba = hal_remote_l32( XPTR( cxy , &ctx->fs_info_lba ) ); 758 uint32_t root_dir_clus = hal_remote_l32( XPTR( cxy , &ctx->root_dir_cluster ) ); 759 uint32_t free_clusters = hal_remote_l32( XPTR( cxy , &ctx->free_clusters ) ); 760 uint32_t free_cluster_hint = hal_remote_l32( XPTR( cxy , &ctx->free_cluster_hint ) ); 761 xptr_t mapper_xp = hal_remote_l64( XPTR( cxy , &ctx->fat_mapper_xp ) ); 762 void * fs_info_buffer = hal_remote_lpt( XPTR( cxy , &ctx->fs_info_buffer ) ); 763 764 printk("\n*** FAT context in cluster %x\n" 596 765 "- fat_sectors = %d\n" 597 766 "- sector size = %d\n" 598 767 "- cluster size = %d\n" 599 "- fat_first_lba = %d\n" 600 "- data_first_lba = %d\n" 601 "- root_dir_cluster = %d\n" 602 "- free_clusters = %d\n" 603 "- free_cluster_hint = %d\n" 604 "- fat_mapper_xp = %l\n", 605 ctx->fat_sectors_count, 606 ctx->bytes_per_sector, 607 ctx->sectors_per_cluster * ctx->bytes_per_sector, 608 ctx->fat_begin_lba, 609 ctx->cluster_begin_lba, 610 ctx->root_dir_cluster, 611 ctx->free_clusters, 612 ctx->free_cluster_hint, 613 ctx->fat_mapper_xp ); 614 615 } // end ctx_display() 768 "- fat_lba = %x\n" 769 "- data_lba = %x\n" 770 "- fsinfo_lba = %x\n" 771 "- root_dir_cluster = %x\n" 772 "- free_clusters = %x\n" 773 "- free_cluster_hint = %x\n" 774 "- fat_mapper_ptr = %x\n" 775 "- fs_info_buffer = %x\n", 776 cxy, 777 fat_sectors, 778 sector_size, 779 sector_size * sec_per_clus, 780 fat_lba, 781 data_lba, 782 fsinfo_lba, 783 root_dir_clus, 784 free_clusters, 785 free_cluster_hint, 786 GET_PTR( mapper_xp ), 787 fs_info_buffer ); 788 789 } // end fatfs_ctx_display() 616 790 617 791 ////////////////////////////////////////// … … 622 796 uint32_t maxline; 623 797 624 // co pute numner of lines to display798 // compute number of lines to display 625 799 maxline = nentries >> 3; 626 800 if( nentries & 0x7 ) maxline++; 627 801 628 802 // get pointer on local FATFS context 629 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];630 fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;803 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 804 fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend; 631 805 632 806 // get extended pointer on FAT mapper 633 xptr_t fat_mapper_xp = fatfs_ctx->fat_mapper_xp; 634 635 // get extended pointer and cluster of FAT mapper requested page 807 xptr_t fat_mapper_xp = loc_fatfs_ctx->fat_mapper_xp; 808 809 // get FAT cluster identifier 810 cxy_t fat_cxy = GET_CXY( fat_mapper_xp ); 811 812 // get pointer on FATFS context in FAT cluster 813 fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 814 815 // get current value of hint and free_clusters 816 uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) ); 817 uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) ); 818 819 // get extended pointer on requested page in FAT mapper 636 820 xptr_t page_xp = mapper_remote_get_page( fat_mapper_xp , page_id ); 637 821 638 822 // get extended pointer on requested page base 639 823 xptr_t base_xp = ppm_page2base( page_xp ); 640 641 printk("\n***** FAT content / page %d *****\n", page_id ); 824 void * base = GET_PTR( base_xp ); 825 826 printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n", 827 fat_cxy, page_id, base, free, hint ); 828 642 829 for( line = 0 ; line < maxline ; line++ ) 643 830 { … … 766 953 kmem_req_t req; 767 954 uint8_t * buffer; 955 xptr_t buffer_xp; 768 956 769 957 #if DEBUG_FATFS_CTX_INIT … … 778 966 assert( (fatfs_ctx != NULL) , "pointer on FATFS context is NULL" ); 779 967 780 // check only cluster 0 does FATFS init 968 // check only cluster 0 does FATFS initialization 781 969 assert( (local_cxy == 0) , "only cluster 0 can initialize FATFS"); 782 970 783 // allocate a 512 bytes buffer to store the boot record 971 // allocate a permanent 512 bytes buffer to store 972 // - temporarily the BOOT sector 973 // - permanently the FS_INFO sector 784 974 req.type = KMEM_512_BYTES; 785 975 req.flags = AF_KERNEL | AF_ZERO; 786 976 buffer = (uint8_t *)kmem_alloc( &req ); 977 buffer_xp = XPTR( local_cxy , buffer ); 787 978 788 979 if( buffer == NULL ) … … 793 984 794 985 // load the BOOT record from device 795 error = dev_ioc_sync_read( buffer , 0 , 1 );986 error = dev_ioc_sync_read( buffer_xp , 0 , 1 ); 796 987 797 988 if ( error ) … … 807 998 808 999 // get sector size from boot record 809 uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer , 1);1000 uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer ); 810 1001 if ( sector_size != 512 ) 811 1002 { … … 815 1006 816 1007 // get cluster size from boot record 817 uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer , 1);1008 uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer ); 818 1009 if ( nb_sectors != 8 ) 819 1010 { … … 823 1014 824 1015 // get number of FAT copies from boot record 825 uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer , 1);1016 uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer ); 826 1017 if ( nb_fats != 1 ) 827 1018 { … … 831 1022 832 1023 // get number of sectors in FAT from boot record 833 uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer , 1);1024 uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer ); 834 1025 if ( (fat_sectors & 0xF) != 0 ) 835 1026 { … … 839 1030 840 1031 // get root cluster from boot record 841 uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer , 1);1032 uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer ); 842 1033 if ( root_cluster != 2 ) 843 1034 { … … 847 1038 848 1039 // get FAT lba from boot record 849 uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer , 1);1040 uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer ); 850 1041 851 1042 // get FS_INFO sector lba from boot record 852 uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer , 1);1043 uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer ); 853 1044 854 1045 // load the FS_INFO record from device 855 error = dev_ioc_sync_read( buffer , fs_info_lba , 1 );1046 error = dev_ioc_sync_read( buffer_xp , fs_info_lba , 1 ); 856 1047 857 1048 if ( error ) … … 861 1052 } 862 1053 863 // get free 864 uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer , 1);1054 // get free_clusters number from FS_INFO record 1055 uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer ); 865 1056 if ( free_clusters >= fat_sectors << 7 ) 866 1057 { … … 869 1060 } 870 1061 871 // get cluster hint from FS_INFO record 872 uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer , 1 ); 1062 // get free_cluster_hint from FS_INFO record 1063 uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer ); 1064 873 1065 if ( free_cluster_hint >= fat_sectors << 7 ) 874 1066 { … … 876 1068 hal_core_sleep(); 877 1069 } 878 879 // release the 512 bytes buffer880 req.type = KMEM_512_BYTES;881 req.ptr = buffer;882 kmem_free( &req );883 1070 884 1071 // allocate a mapper for the FAT itself … … 890 1077 } 891 1078 892 // WARNING : the inode field MUST beNULL for the FAT mapper1079 // the inode field is NULL for the FAT mapper 893 1080 fat_mapper->inode = NULL; 894 895 1081 896 1082 // initialize the FATFS context … … 902 1088 fatfs_ctx->root_dir_cluster = 2; 903 1089 fatfs_ctx->fat_mapper_xp = XPTR( local_cxy , fat_mapper ); 1090 fatfs_ctx->fs_info_lba = fs_info_lba; 904 1091 fatfs_ctx->free_clusters = free_clusters; 905 1092 fatfs_ctx->free_cluster_hint = free_cluster_hint; 1093 fatfs_ctx->fs_info_buffer = buffer; 906 1094 907 1095 remote_queuelock_init( XPTR( local_cxy , &fatfs_ctx->free_lock ) , LOCK_FATFS_FREE ); … … 1019 1207 while ( (offset < 4096) && (found == 0) ) 1020 1208 { 1021 if ( fatfs_get_record( LDIR_ORD, (base + offset) , 0) == NO_MORE_ENTRY )1209 if ( fatfs_get_record( LDIR_ORD, (base + offset) ) == NO_MORE_ENTRY ) 1022 1210 { 1023 1211 found = 1; … … 1335 1523 1336 1524 // check for LFN entry 1337 assert( (fatfs_get_record( DIR_ATTR, base + offset , 0) == ATTR_LONG_NAME_MASK ),1525 assert( (fatfs_get_record( DIR_ATTR, base + offset ) == ATTR_LONG_NAME_MASK ), 1338 1526 "this directory entry must be a LFN\n"); 1339 1527 … … 1439 1627 while( (offset < 4096) && (found == 0) ) 1440 1628 { 1441 attr = fatfs_get_record( DIR_ATTR , base + offset , 0);1442 ord = fatfs_get_record( LDIR_ORD , base + offset , 0);1629 attr = fatfs_get_record( DIR_ATTR , base + offset ); 1630 ord = fatfs_get_record( LDIR_ORD , base + offset ); 1443 1631 1444 1632 if (ord == NO_MORE_ENTRY) // no more entry => break … … 1559 1747 1560 1748 // check arguments 1561 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1562 assert( (name != NULL) , "name is NULL\n" ); 1563 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is XPTR_NULL\n" ); 1749 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1750 assert( (name != NULL) , "name is NULL\n" ); 1751 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is NULL\n" ); 1752 1753 // get child inode cluster and local pointer 1754 child_inode_cxy = GET_CXY( child_inode_xp ); 1755 child_inode_ptr = GET_PTR( child_inode_xp ); 1756 1757 // build extended pointer on root of list of parent dentries 1758 root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents ); 1759 1760 // check child inode has at least one parent 1761 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n"); 1564 1762 1565 1763 #if DEBUG_FATFS_GET_DENTRY … … 1578 1776 error = fatfs_scan_directory( mapper, name , &entry , &index ); 1579 1777 1580 if( error ) 1581 { 1582 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name ); 1583 printk("\n[ERROR] in %s : cannot find <%s> in parent mapper <%s>\n", 1584 __FUNCTION__, name , dir_name ); 1585 return -1; 1586 } 1778 // return non fatal error if not found 1779 if( error ) return -1; 1587 1780 1588 1781 // get relevant infos from FAT32 directory entry 1589 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry , 1 ) << 16) | 1590 (fatfs_get_record( DIR_FST_CLUS_LO , entry , 1 ) ) ; 1591 is_dir = (fatfs_get_record( DIR_ATTR , entry , 1 ) & ATTR_DIRECTORY); 1592 size = fatfs_get_record( DIR_FILE_SIZE , entry , 1 ); 1593 1594 // get child inode cluster and local pointer 1595 child_inode_cxy = GET_CXY( child_inode_xp ); 1596 child_inode_ptr = GET_PTR( child_inode_xp ); 1597 1598 // build extended pointer on root of list of parent dentries 1599 root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents ); 1600 1601 // check child inode has at least one parent 1602 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n"); 1782 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry ) << 16) | 1783 (fatfs_get_record( DIR_FST_CLUS_LO , entry ) ) ; 1784 is_dir = (fatfs_get_record( DIR_ATTR , entry ) & ATTR_DIRECTORY); 1785 size = fatfs_get_record( DIR_FILE_SIZE , entry ); 1603 1786 1604 1787 // scan list of parent dentries to search the parent_inode … … 1692 1875 1693 1876 // set size in FAT32 directory entry 1694 fatfs_set_record( DIR_FILE_SIZE , entry , 1 ,size );1877 fatfs_set_record( DIR_FILE_SIZE , entry , size ); 1695 1878 1696 1879 // get local pointer on modified page base … … 1795 1978 bool_t valid = (dentry_id >= min_dentry) && (dirent_id < max_dirent ); 1796 1979 1797 attr = fatfs_get_record( DIR_ATTR , base + offset , 0);1798 ord = fatfs_get_record( LDIR_ORD , base + offset , 0);1980 attr = fatfs_get_record( DIR_ATTR , base + offset ); 1981 ord = fatfs_get_record( LDIR_ORD , base + offset ); 1799 1982 1800 1983 if (ord == NO_MORE_ENTRY) // no more entry => break … … 2033 2216 error_t fatfs_sync_free_info( void ) 2034 2217 { 2218 error_t error; 2219 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on fatfs context in cluster 0 2220 uint32_t ctx_free_clusters; // number of free clusters from fatfs context 2221 uint32_t ctx_free_cluster_hint; // free cluster hint from fatfs context 2222 uint32_t ioc_free_clusters; // number of free clusters from fatfs context 2223 uint32_t ioc_free_cluster_hint; // free cluster hint from fatfs context 2224 uint32_t fs_info_lba; // lba of FS_INFO sector on IOC device 2225 uint8_t * fs_info_buffer; // local pointer on FS_INFO buffer in cluster 0 2226 xptr_t fs_info_buffer_xp; // extended pointer on FS_INFO buffer in cluster 0 2227 uint8_t tmp_buf[512]; // 512 bytes temporary buffer 2228 xptr_t tmp_buf_xp; // extended pointer on temporary buffer 2035 2229 2036 2230 #if DEBUG_FATFS_SYNC_FSINFO … … 2042 2236 #endif 2043 2237 2044 uint8_t * buffer; // dynamically allocated aligned 512 bytes buffer 2045 kmem_req_t req; 2046 error_t error; 2047 2048 // get FS_INFO lba, free_ from FATFS context 2049 fatfs_ctx_t * fatfs_ctx = fs_context[FS_TYPE_FATFS].extend; 2050 uint32_t lba = fatfs_ctx->fs_info_lba; 2051 uint32_t hint = fatfs_ctx->free_cluster_hint; 2052 uint32_t number = fatfs_ctx->free_clusters; 2053 2054 // allocate buffer to store the FS_INFO sector 2055 req.type = KMEM_512_BYTES; 2056 req.flags = AF_KERNEL | AF_ZERO; 2057 buffer = (uint8_t *)kmem_alloc( &req ); 2058 if( buffer == NULL ) 2059 { 2060 printk("\n[PANIC] in %s : cannot allocate buffer\n", __FUNCTION__ ); 2061 return ENOMEM; 2062 } 2063 2064 // load the FS_INFO sector from device to buffer 2065 error = dev_ioc_read( buffer , lba , 1 ); 2238 // get pointer on fatfs context in cluster 0 2239 fatfs_ctx_ptr = hal_remote_lpt( XPTR( 0 , &fs_context[FS_TYPE_FATFS].extend ) ); 2240 2241 // get "free_clusters" and "free_cluster_hint" from fatfs context in cluster 0 2242 ctx_free_clusters = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_clusters ) ); 2243 ctx_free_cluster_hint = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_cluster_hint ) ); 2244 2245 // get fs_info_lba 2246 fs_info_lba = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->fs_info_lba ) ); 2247 2248 // build extended pointer on temporary buffer 2249 tmp_buf_xp = XPTR( local_cxy , tmp_buf ); 2250 2251 // copy FS_INFO sector from IOC to local buffer 2252 error = dev_ioc_sync_read( tmp_buf_xp , fs_info_lba , 1 ); 2253 2066 2254 if ( error ) 2067 2255 { 2068 printk("\n[PANIC] in %s : cannot read FS_INFO record\n", __FUNCTION__ ); 2069 return EIO; 2070 } 2071 2072 // update buffer 2073 fatfs_set_record( FS_FREE_CLUSTERS , buffer , 1 , number ); 2074 fatfs_set_record( FS_FREE_CLUSTER_HINT , buffer , 1 , hint ); 2075 2076 // write modified FS_INFO sector from buffer to device 2077 error = dev_ioc_write( buffer , lba , 1 ); 2078 if ( error ) 2079 { 2080 printk("\n[PANIC] in %s : cannot write FS_INFO record\n", __FUNCTION__ ); 2081 return EIO; 2082 } 2083 2084 // release the 512 bytes buffer 2085 req.type = KMEM_512_BYTES; 2086 req.ptr = buffer; 2087 kmem_free( &req ); 2256 printk("\n[ERROR] in %s : cannot access FS_INFO on IOC device\n", __FUNCTION__ ); 2257 return -1; 2258 } 2259 2260 // get current values of "free_clusters" and "free_cluster_hint" from FS_INFO on IOC 2261 ioc_free_clusters = fatfs_get_remote_record( FS_FREE_CLUSTERS , tmp_buf_xp ); 2262 ioc_free_cluster_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , tmp_buf_xp ); 2263 2264 // check values 2265 if( (ioc_free_clusters != ctx_free_clusters) || 2266 (ioc_free_cluster_hint != ctx_free_cluster_hint) ) 2267 { 2268 printk("\n[WARNING] in %s : unconsistent free clusters info\n" 2269 " ioc_free %x / ctx_free %x / ioc_hint %x / ctx_hint %x\n", 2270 __FUNCTION__, ioc_free_clusters, ctx_free_clusters, 2271 ioc_free_cluster_hint, ctx_free_cluster_hint ); 2272 2273 // get pointers on FS_INFO buffer in cluster 0 2274 fs_info_buffer = hal_remote_lpt( XPTR( 0 , &fatfs_ctx_ptr->fs_info_buffer ) ); 2275 fs_info_buffer_xp = XPTR( 0 , fs_info_buffer ); 2276 2277 // update FS_INFO buffer in cluster 0 2278 fatfs_set_remote_record(FS_FREE_CLUSTERS ,fs_info_buffer_xp,ctx_free_clusters ); 2279 fatfs_set_remote_record(FS_FREE_CLUSTER_HINT,fs_info_buffer_xp,ctx_free_cluster_hint); 2280 2281 // update the FS_INFO sector on IOC device 2282 error = dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 ); 2283 2284 if ( error ) 2285 { 2286 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC device\n", __FUNCTION__ ); 2287 return -1; 2288 } 2289 } 2088 2290 2089 2291 #if DEBUG_FATFS_SYNC_FSINFO … … 2096 2298 return 0; 2097 2299 2098 } // end fatfs_sync_f s_info()2300 } // end fatfs_sync_free_info() 2099 2301 2100 2302 ////////////////////////////////////////////////////////// 2101 2303 error_t fatfs_cluster_alloc( uint32_t * searched_cluster ) 2102 2304 { 2305 error_t error; 2103 2306 uint32_t page_id; // page index in FAT mapper 2104 2307 uint32_t slot_id; // slot index in page (1024 slots per page) … … 2109 2312 fatfs_ctx_t * fat_fatfs_ctx; // local pointer on FATFS context in FAT cluster 2110 2313 xptr_t mapper_xp; // extended pointer on FAT mapper 2111 cxy_t mapper_cxy;// Fat mapper cluster identifier2314 cxy_t fat_cxy; // Fat mapper cluster identifier 2112 2315 xptr_t page_xp; // extended pointer on current page descriptor in mapper 2113 2316 xptr_t slot_xp; // extended pointer on FAT slot defined by hint 2114 2317 xptr_t lock_xp; // extended pointer on lock protecting free clusters info 2115 2318 xptr_t hint_xp; // extended pointer on free_cluster_hint in FAT cluster 2116 xptr_t numb_xp; // extended pointer on free_clusters_number in FAT cluster2319 xptr_t free_xp; // extended pointer on free_clusters_number in FAT cluster 2117 2320 2118 2321 #if DEBUG_FATFS_CLUSTER_ALLOC … … 2130 2333 loc_fatfs_ctx = vfs_ctx->extend; 2131 2334 2132 // get extended pointer and clusteron FAT mapper2335 // get extended pointer on FAT mapper 2133 2336 mapper_xp = loc_fatfs_ctx->fat_mapper_xp; 2134 mapper_cxy = GET_CXY( mapper_xp ); 2337 2338 // get FAT cluster 2339 fat_cxy = GET_CXY( mapper_xp ); 2135 2340 2136 2341 // get local pointer on FATFS context in FAT cluster 2137 fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );2342 fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 2138 2343 2139 2344 // build relevant extended pointers on free clusters info in mapper cluster 2140 lock_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_lock );2141 hint_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_cluster_hint );2142 numb_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_clusters );2345 lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_lock ); 2346 hint_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ); 2347 free_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ); 2143 2348 2144 2349 // take the lock protecting free clusters 2145 2350 remote_queuelock_acquire( lock_xp ); 2146 2351 2147 // get hint and free_clusters values from FATFS context 2352 // get hint and free_clusters values from FATFS context in FAT cluster 2148 2353 cluster = hal_remote_l32( hint_xp ) + 1; 2149 free_clusters = hal_remote_l32( numb_xp );2354 free_clusters = hal_remote_l32( free_xp ); 2150 2355 2151 2356 #if (DEBUG_FATFS_CLUSTER_ALLOC & 1) … … 2168 2373 } 2169 2374 2170 2171 2172 2375 // get page index & slot index for selected cluster 2173 2376 page_id = cluster >> 10; 2174 2377 slot_id = cluster & 0x3FF; 2175 2378 2176 // get relevant page descriptor from mapper2379 // get relevant page descriptor from FAT mapper 2177 2380 page_xp = mapper_remote_get_page( mapper_xp , page_id ); 2178 2381 … … 2194 2397 } 2195 2398 2196 // update free cluster info in FATFS context 2197 fatfs_free_clusters_decrement( mapper_cxy , fat_fatfs_ctx , cluster ); 2399 // update free cluster info in FATFS context and in FS_INFO sector 2400 error = fatfs_free_clusters_decrement( XPTR( fat_cxy , fat_fatfs_ctx ) , cluster ); 2401 2402 if( error ) 2403 { 2404 printk("\n[ERROR] in %s : cannot update free cluster info\n", __FUNCTION__ ); 2405 remote_queuelock_acquire( lock_xp ); 2406 return -1; 2407 } 2408 2409 // update FAT mapper 2410 hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX ); 2411 2412 // synchronously update FAT on device 2413 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2414 2415 if( error ) 2416 { 2417 printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ ); 2418 remote_queuelock_acquire( lock_xp ); 2419 return -1; 2420 } 2198 2421 2199 2422 // release free clusters busylock 2200 2423 remote_queuelock_release( lock_xp ); 2201 2202 // update FAT mapper2203 hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );2204 2205 // synchronously update FAT on device2206 fatfs_move_page( page_xp , IOC_SYNC_WRITE );2207 2424 2208 2425 #if DEBUG_FATFS_CLUSTER_ALLOC 2209 2426 cycle = (uint32_t)hal_get_cycles(); 2210 2427 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle ) 2211 printk("\n[%s] thread[%x,%x] exit / updated cluster %x in FAT / cycle %d\n",2428 printk("\n[%s] thread[%x,%x] exit / allocated cluster %x in FAT / cycle %d\n", 2212 2429 __FUNCTION__, this->process->pid, this->trdid, cluster, cycle ); 2213 2430 #endif … … 2230 2447 xptr_t first_xp; // extended pointer on inode extension 2231 2448 uint32_t first_cluster; // first cluster index for released inode 2232 vfs_inode_t * inode_ptr; 2233 cxy_t inode_cxy; 2449 vfs_inode_t * inode_ptr; // local pointer on target inode 2450 cxy_t inode_cxy; // target inode cluster identifier 2234 2451 2235 2452 // check inode pointer … … 2357 2574 2358 2575 // get page base address 2359 xptr_t b ase_xp= ppm_page2base( page_xp );2360 uint8_t * buffer = (uint8_t *)GET_PTR( base_xp );2576 xptr_t buffer_xp = ppm_page2base( page_xp ); 2577 uint8_t * buffer_ptr = (uint8_t *)GET_PTR( buffer_xp ); 2361 2578 2362 2579 // get inode pointer from mapper 2363 2580 inode_ptr = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) ); 2364 2581 2365 ////////////////////////////// it is the FAT mapper 2582 #if DEBUG_FATFS_MOVE_PAGE 2583 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 2584 printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n", 2585 __FUNCTION__, this->process->pid, this->trdid, 2586 dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, buffer_ptr ); 2587 #endif 2588 2589 ////////////////////////////// FAT mapper 2366 2590 if( inode_ptr == NULL ) 2367 2591 { … … 2370 2594 2371 2595 // access device 2372 if ( cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer , lba , 8 ); 2373 else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 ); 2374 else if( cmd_type == IOC_READ ) error = dev_ioc_read ( buffer , lba , 8 ); 2375 else if( cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer , lba , 8 ); 2376 else error = -1; 2377 2378 if( error ) return EIO; 2596 if (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp , lba , 8 ); 2597 else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp , lba , 8 ); 2598 else if(cmd_type == IOC_READ ) error = dev_ioc_read ( buffer_ptr , lba , 8 ); 2599 else if(cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer_ptr , lba , 8 ); 2600 else error = -1; 2601 2602 if( error ) 2603 { 2604 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ ); 2605 return -1; 2606 } 2379 2607 2380 2608 #if DEBUG_FATFS_MOVE_PAGE … … 2382 2610 { 2383 2611 if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) ) 2384 printk("\n[%s] thread[%x,%x] load page %d of FAT/ cycle %d\n",2385 2612 printk("\n[%s] thread[%x,%x] load FAT mapper page %d from IOC / cycle %d\n", 2613 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 2386 2614 else 2387 printk("\n[%s] thread[%x,%x] sync page %d of FAT/ cycle %d\n",2615 printk("\n[%s] thread[%x,%x] sync FAT mapper page %d to IOC / cycle %d\n", 2388 2616 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 2389 2617 } … … 2391 2619 2392 2620 } 2393 ///////////////////////// it is aninode mapper2621 ///////////////////////// inode mapper 2394 2622 else 2395 2623 { … … 2425 2653 } 2426 2654 2427 // get lba f romsearched_cluster2655 // get lba for searched_cluster 2428 2656 uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster ); 2657 2658 // access device 2659 if (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp , lba , 8 ); 2660 else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp , lba , 8 ); 2661 else if(cmd_type == IOC_READ ) error = dev_ioc_read ( buffer_ptr , lba , 8 ); 2662 else if(cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer_ptr , lba , 8 ); 2663 else error = -1; 2664 2665 if( error ) 2666 { 2667 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ ); 2668 return -1; 2669 } 2429 2670 2430 2671 #if DEBUG_FATFS_MOVE_PAGE … … 2440 2681 #endif 2441 2682 2442 // access device2443 if ( cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer , lba , 8 );2444 else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 );2445 else if( cmd_type == IOC_READ ) error = dev_ioc_read ( buffer , lba , 8 );2446 else if( cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer , lba , 8 );2447 else error = -1;2448 2449 if( error )2450 {2451 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );2452 return -1;2453 }2454 2683 } 2455 2684 -
trunk/kernel/fs/fatfs.h
r625 r626 173 173 /***************************************************************************************** 174 174 * This structure defines a FATFS specific context (extension to VFS context). 175 * This extension is replicated in all clusters. 176 * 177 * WARNING : Almost all fields are constant values, but the <free_cluster_hint> and 178 * <free_clusters> are shared variables. All kernel instances use the variables 179 * in cluster 0, using the <free_lock> remote busy_lock for exclusive access. 175 * This fatfs context is replicated in all clusters. 176 * 177 * WARNING : Almost all fields are constant values, but the <free_cluster_hint>, 178 * <free_clusters> and <free_lock> are shared variables. Moreover, the <fs_info_buffer>, 179 * only allocated in cluster 0, contains a copy of the FS_INFO sector. It is used by all 180 * kernel instances to synchronously update the free clusters info on IOC device. 181 * For these four variables, all kernel instances must use the values in cluster 0, 182 * and take the <free_lock> stored in this cluster for exclusive access to FAT. 180 183 ****************************************************************************************/ 181 184 182 185 typedef struct fatfs_ctx_s 183 186 { 187 /* read-only constants replicated in all clusters */ 184 188 uint32_t fat_sectors_count; /*! number of sectors in FAT region */ 185 189 uint32_t bytes_per_sector; /*! number of bytes per sector */ … … 190 194 uint32_t root_dir_cluster; /*! cluster index for root directory */ 191 195 xptr_t fat_mapper_xp; /*! extended pointer on FAT mapper */ 196 197 /* shared variables (only the copy in FAT cluster must be used) */ 192 198 uint32_t free_cluster_hint; /*! cluster[hint+1] is the first free */ 193 199 uint32_t free_clusters; /*! free clusters number */ 194 remote_queuelock_t free_lock; /*! exclusive access to hint & number */ 200 remote_queuelock_t free_lock; /*! exclusive access to FAT */ 201 uint8_t * fs_info_buffer; /*! local pointer on FS_INFO buffer */ 195 202 } 196 203 fatfs_ctx_t; … … 224 231 225 232 /***************************************************************************************** 226 * This function display the content of the local FATFS context. 227 ***************************************************************************************** 228 * @ ctx : local pointer on the context. 229 ****************************************************************************************/ 230 void fatfs_ctx_display( fatfs_ctx_t * ctx ); 231 232 /***************************************************************************************** 233 * This function displays the content of a part of the File Allocation Table. 234 * It loads the requested page fom device to mapper if required. 235 ***************************************************************************************** 236 * @ page_id : page index in FAT mapper (one page is 4 Kbytes). 237 * @ nentries : number of entries (one entry is 4 bytes). 233 * This function display the content of the FATFS context copy in cluster identified 234 * by the <cxy> argument. 235 * This function can be called by a thread running in any cluster. 236 ***************************************************************************************** 237 * @ cxy : target cluster identifier. 238 ****************************************************************************************/ 239 void fatfs_display_ctx( cxy_t cxy ); 240 241 /***************************************************************************************** 242 * This function access the FAT mapper to display one page of the File Allocation Table. 243 * It loads the requested page fom IOC device to FAT mapper if required. 244 * This function can be called by a thread running in any cluster. 245 ***************************************************************************************** 246 * @ page_id : page index in FAT mapper (one page is 4 Kbytes). 247 * @ nb_entries : number of entries (one entry is 4 bytes). 238 248 ****************************************************************************************/ 239 249 void fatfs_display_fat( uint32_t page_id, 240 uint32_t n entries );250 uint32_t nb_entries ); 241 251 242 252 … … 254 264 255 265 /***************************************************************************************** 256 * This function access the boot device, and initialises the local FATFS context 257 * from informations contained in the boot record. 266 * This function access the boot device, and initialises the local FATFS context, 267 * from informations contained in the boot record. This initialisation includes the 268 * creation of the FAT mapper in cluster 0. 258 269 ***************************************************************************************** 259 270 * @ vfs_ctx : local pointer on VFS context for FATFS. … … 271 282 * This function implements the generic vfs_fs_add_dentry() function for the FATFS. 272 283 ***************************************************************************************** 273 * This function updates a directory identified by the <inode> argument284 * This function updates a directory mapper identified by the <inode> argument 274 285 * to add a new directory entry identified by the <dentry> argument. 275 * All modified pages in directory mapper are synchronously updated on IOC device.276 * It must be called by a thread running in the cluster containing the inode.286 * All modified pages in the directory mapper are synchronously updated on IOC device. 287 * It must be called by a thread running in the cluster containing the directory inode. 277 288 * 278 289 * Implementation note : this function works in two steps: … … 313 324 * This function implements the generic vfs_fs_new_dentry() function for the FATFS. 314 325 ***************************************************************************************** 315 * It initializes a new inode/dentry couple in Inode Tree, attached to the directory316 * identified by the <parent_inode> argument. The directory entry is identified317 * by the <name> argument. The child inode descriptor, identified by the <child_inode_xp>318 * argument, and the associated dentry descriptor must have been previously allocated.319 * It scan the parent mapper to find the <name> argument.320 * It set the "type", "size", and "extend" fields in the child inode descriptor.321 * It set the " extend" field in the dentry descriptor.326 * It scan a parent directory mapper, identified by the <parent_inode> argument to find 327 * a directory entry identified by the <name> argument. In case of success, it 328 * initializes the inode/dentry couple, identified by the <child_inode_xp> argument 329 * in the Inode Tree. The child inode descriptor, and the associated dentry descriptor 330 * must have been previously allocated by the caller. 331 * - It set the "type", "size", and "extend" fields in the child inode descriptor. 332 * - It set the " extend" field in the dentry descriptor. 322 333 * It must be called by a thread running in the cluster containing the parent inode. 323 334 ***************************************************************************************** … … 325 336 * @ name : child name. 326 337 * @ child_inode_xp : extended pointer on remote child inode (file or directory). 327 * @ return 0 if success / return ENOENTif child not found.338 * @ return 0 if success / return -1 if child not found. 328 339 ****************************************************************************************/ 329 340 error_t fatfs_new_dentry( struct vfs_inode_s * parent_inode, … … 392 403 ***************************************************************************************** 393 404 * @ inode : local pointer on inode. 394 * @ return 0 if success / return EIO if failure duringdevice access.405 * @ return 0 if success / return -1 if failure during IOC device access. 395 406 ****************************************************************************************/ 396 407 error_t fatfs_sync_inode( struct vfs_inode_s * inode ); … … 399 410 * This function implements the generic vfs_fs_sync_fat() function for the FATFS. 400 411 ***************************************************************************************** 401 * It updates the FAT FSon the IOC device for the FAT itself.412 * It updates the FAT on the IOC device for the FAT itself. 402 413 * It scan all clusters registered in the FAT mapper, and copies from mapper to device 403 414 * each page marked as dirty. … … 408 419 * variables defining the smallest/largest dirty page index in FAT mapper... 409 420 ***************************************************************************************** 410 * @ return 0 if success / return EIO if failure duringdevice access.421 * @ return 0 if success / return -1 if failure during IOC device access. 411 422 ****************************************************************************************/ 412 423 error_t fatfs_sync_fat( void ); … … 415 426 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS. 416 427 ***************************************************************************************** 417 * It updates the FS_INFO sector on the IOC device. 418 * It copies the <free_cluster_hint> and <free_clusters> variables from 419 * the FATFS context in cluster 0 to the FS_INFO sector on device. 420 ***************************************************************************************** 421 * @ return 0 if success / return EIO if failure during device access. 428 * It checks the current values of the "free_clusters" and "free_cluster_hint" variables 429 * in the FS_INFO sector on IOC, versus the values stored in the fatfs context. 430 * As these values are synchronously updated on IOC device at each modification, 431 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device, 432 * and displays a warning message on TXT0 if they are not equal. 433 * This function can be called by any thread running in any cluster. 434 ***************************************************************************************** 435 * @ return 0 if success / return -1 if failure during IOC device access. 422 436 ****************************************************************************************/ 423 437 error_t fatfs_sync_free_info( void ); … … 430 444 * It can be called by a thread running in any cluster, as it uses remote access 431 445 * primitives when the FAT mapper is remote. It takes the queuelock stored in the FATFS 432 * context (located in the same cluster as the FAT mapper itself), to get exclusive433 * access to the FAT. It uses the <free_cluster_hint> and <free_clusters> variables434 * stored in this FATFS context.446 * context located in the same cluster as the FAT mapper itself, to get exclusive 447 * access to the FAT. It uses and updates the <free_cluster_hint> and <free_clusters> 448 * variables stored in this FATFS context. 435 449 * - it updates the <free_cluster_hint> and <free_clusters> variables in FATFS context. 436 450 * - it updates the FAT mapper (handling miss from IOC device if required). … … 445 459 /***************************************************************************************** 446 460 * This function implements the generic vfs_fs_release_inode() function for the FATFS. 447 *****************************************************************************************461 ***************************************************************************************** 448 462 * It releases all clusters allocated to a file/directory identified by the <inode_xp> 449 463 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper. … … 466 480 * The pointer on the mapper and the page index in file are found in the page descriptor. 467 481 * It is used for both a regular file/directory mapper, and the FAT mapper. 468 * For the FAT mapper, it access the FATFS to get the location on IOC device.469 * For a regular file, it access the FAT mapper to get the cluster index on IOC device.482 * - For the FAT mapper, it updates the FAT region on IOC device. 483 * - For a regular file, it access the FAT mapper to get the cluster index on IOC device. 470 484 * It can be called by any thread running in any cluster. 471 485 * -
trunk/kernel/fs/vfs.c
r625 r626 423 423 } // end vfs_inode_load_all_pages() 424 424 425 ///////////////////////////////////////// 426 void vfs_inode_display( xptr_t inode_xp ) 427 { 428 assert( (inode_xp != XPTR_NULL), "inode pointer is NULL"); 429 430 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 431 432 vfs_inode_get_name( inode_xp , name ); 433 434 cxy_t inode_cxy = GET_CXY( inode_xp ); 435 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 436 437 vfs_inode_type_t type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 438 uint32_t attr = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->attr ) ); 439 uint32_t size = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->size ) ); 440 uint32_t parents = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->links ) ); 441 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 442 void * extend = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->extend ) ); 443 444 printk("\n**** inode <%s>\n" 445 " - type = %s\n" 446 " - attr = %x\n" 447 " - size = %d\n" 448 " - parents = %d\n" 449 " - cxy = %x\n" 450 " - inode = %x\n" 451 " - mapper = %x\n" 452 " - extend = %x\n", 453 name, 454 vfs_inode_type_str( type ), 455 attr, 456 size, 457 parents, 458 inode_cxy, 459 inode_ptr, 460 mapper, 461 extend ); 462 463 } // end vfs_inode_display() 464 465 425 466 //////////////////////////////////////////////////////////////////////////////////////////// 426 467 // VFS dentry descriptor related functions … … 737 778 cycle = (uint32_t)hal_get_cycles(); 738 779 if( DEBUG_VFS_OPEN < cycle ) 739 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / c luster%x / cycle %d\n",780 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cxy %x / cycle %d\n", 740 781 __FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle ); 741 782 #endif … … 773 814 // check inode type 774 815 assert( (inode_type == INODE_TYPE_FILE), "bad inode type" ); 816 817 #if DEBUG_VFS_USER_MOVE 818 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 819 uint32_t cycle = (uint32_t)hal_get_cycles(); 820 thread_t * this = CURRENT_THREAD; 821 vfs_inode_t * inode = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 822 vfs_inode_get_name( XPTR( file_cxy , inode ) , name ); 823 if( cycle > DEBUG_VFS_USER_MOVE ) 824 { 825 if( to_buffer ) 826 printk("\n[%s] thread[%x,%x] enter / %d bytes / mapper(%s) -> buffer(%x) / cycle %d\n", 827 __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, cycle ); 828 else 829 printk("\n[%s] thread[%x,%x] enter / %d bytes / buffer(%x) -> mapper(%s) / cycle %d\n", 830 __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, cycle ); 831 } 832 #endif 775 833 776 834 // get mapper pointer and file offset from file descriptor … … 794 852 795 853 #if DEBUG_VFS_USER_MOVE 796 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 797 uint32_t cycle = (uint32_t)hal_get_cycles(); 798 thread_t * this = CURRENT_THREAD; 799 vfs_inode_t * inode = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 800 vfs_inode_get_name( XPTR( file_cxy , inode ) , name ); 854 cycle = (uint32_t)hal_get_cycles(); 801 855 if( cycle > DEBUG_VFS_USER_MOVE ) 802 856 { 803 857 if( to_buffer ) 804 printk("\n[%s] thread[%x,%x] moves %d bytes from <%s> mapper to buffer(%x) / cycle %d\n",805 __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer );858 printk("\n[%s] thread[%x,%x] exit / %d bytes / mapper(%s) -> buffer(%x) / cycle %d\n", 859 __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, cycle ); 806 860 else 807 printk("\n[%s] thread[%x,%x] moves %d bytes from buffer (%x) to <%s> mapper/ cycle %d\n",808 __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name );861 printk("\n[%s] thread[%x,%x] exit / %d bytes / buffer(%x) -> mapper(%s) / cycle %d\n", 862 __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, cycle ); 809 863 } 810 864 #endif … … 1794 1848 xptr_t inode_children_xp = XPTR( inode_cxy , &inode_ptr->children.items ); 1795 1849 1796 printk("\n@@@ in %s : children_xp = (%x,%x)\n",1797 __FUNCTION__, inode_cxy, &inode_ptr->children.items );1798 1799 1850 // get target inode number of children 1800 1851 inode_children = hal_remote_l32( inode_children_xp ); … … 2166 2217 2167 2218 // display inode 2168 nolock_printk("%s<%s> : %s / extd % d/ %d bytes / dirty %d / cxy %x / inode %x / mapper %x\n",2219 nolock_printk("%s<%s> : %s / extd %x / %d bytes / dirty %d / cxy %x / inode %x / mapper %x\n", 2169 2220 indent_str[indent], name, vfs_inode_type_str( inode_type ), (uint32_t)inode_extd, 2170 2221 inode_size, inode_dirty, inode_cxy, inode_ptr, mapper_ptr ); … … 2301 2352 // This static function is used by the vfs_lookup() function. 2302 2353 // It takes an extended pointer on a remote parent directory inode, a directory 2303 // entry name, and returns an extended pointer on the child inode. 2354 // entry name, and and scan the XHTAB associated to the parent inode to find the 2355 // searched dentry. It does NOT modify the inode tree in case of miss. 2304 2356 // It can be used by any thread running in any cluster. 2305 2357 ////////////////////////////////////////////////////////////////////////////////////////// … … 2424 2476 bool_t create; // searched inode must be created if not found 2425 2477 bool_t excl; // searched inode must not exist 2426 bool_t par ;// searched inode is the parent2478 bool_t parent; // searched inode is the parent 2427 2479 thread_t * this; // pointer on calling thread descriptor 2428 2480 process_t * process; // pointer on calling process descriptor … … 2449 2501 create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE; 2450 2502 excl = (lookup_mode & VFS_LOOKUP_EXCL) == VFS_LOOKUP_EXCL; 2451 par 2503 parent = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT; 2452 2504 2453 2505 // initialise loop variables … … 2499 2551 child_cxy = GET_CXY( child_xp ); 2500 2552 2501 // analyse found & last, depending on lookup_mode2502 2553 if( found == false ) // not found in Inode Tree 2503 2554 { 2504 2555 // when a inode is not found in the Inode Tree: 2505 // - if (last and par ) the Inode Tree is not modified2556 // - if (last and parent) the Inode Tree is not modified 2506 2557 // - else we speculatively introduce a new (dentry/inode) in inode tree, 2507 2558 // and scan the parent directory mapper to initialise it. … … 2514 2565 // - if the child is a directory, the child mapper is loaded from device 2515 2566 2516 if( last && par ) // does nothing2567 if( last && parent ) // does nothing 2517 2568 { 2518 2569 … … 2577 2628 } 2578 2629 2579 if ( error ) // child not found in parent mapper 2630 // when the missing dentry is not in the parent mapper, 2631 // it is a new dentry that must be registered in parent directory mapper 2632 if ( error ) 2580 2633 { 2581 2634 if ( last && create ) // add a brand new dentry in parent directory … … 2594 2647 #if (DEBUG_VFS_LOOKUP & 1) 2595 2648 if( DEBUG_VFS_LOOKUP < cycle ) 2596 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => create it\n",2649 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => created it\n", 2597 2650 __FUNCTION__, process->pid, this->trdid, name ); 2598 #endif 2651 vfs_inode_display( child_xp ); 2652 #endif 2653 2654 2599 2655 } 2600 2656 else // not last or not create => error … … 2687 2743 if ( last ) // last inode in path => return relevant info 2688 2744 { 2689 if ( par ) // return parent inode and child name2745 if ( parent ) // return parent inode and child name 2690 2746 { 2691 2747 … … 2757 2813 vfs_inode_t * child_ptr = GET_PTR( child_xp ); 2758 2814 2759 // 1. allocate one free cluster to child inode 2760 // depending on the child inode FS type 2815 // 1. allocate one free cluster in file system to child inode, 2816 // and update the File Allocation Table in both the TAF mapper and IOC device. 2817 // It depends on the child inode FS type. 2761 2818 vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) ); 2762 2819 … … 2772 2829 #if( DEBUG_VFS_NEW_DENTRY_INIT & 1) 2773 2830 if( DEBUG_VFS_NEW_DENTRY_INIT < cycle ) 2774 printk("\n[%s] thread[%x,%x] allocated F ATcluster %x to <%s>\n",2831 printk("\n[%s] thread[%x,%x] allocated FS cluster %x to <%s>\n", 2775 2832 __FUNCTION__ , this->process->pid, this->trdid, cluster, child_name ); 2776 2833 #endif 2777 2834 2778 // 2. update the child inode descriptor 2835 // 2. update the child inode descriptor size and extend 2779 2836 child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) ); 2780 2837 child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0; … … 3301 3358 #endif 3302 3359 3303 // register new_dentry in parent_inode xhtab of children3360 // 4. register new_dentry in parent_inode xhtab of children 3304 3361 children_xhtab_xp = XPTR( parent_cxy , &parent_inode_ptr->children ); 3305 3362 children_entry_xp = XPTR( parent_cxy , &new_dentry_ptr->children ); … … 3313 3370 #endif 3314 3371 3315 // update "parent" and "child_xp" fields in new_dentry3372 // 5. update "parent" and "child_xp" fields in new_dentry 3316 3373 hal_remote_s64( XPTR( parent_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp ); 3317 3374 hal_remote_spt( XPTR( parent_cxy , &new_dentry_ptr->parent ) , parent_inode_ptr ); -
trunk/kernel/fs/vfs.h
r625 r626 376 376 * argument to a local buffer identified by the <name> argument. 377 377 * The local buffer size must be at least CONFIG_VFS_MAX_NAME_LENGTH. 378 ***************************************************************************************** 378 ****************************************************************************************** 379 379 * @ inode_xp : extended pointer on the remote inode. 380 380 * @ name : local buffer pointer. … … 396 396 error_t vfs_inode_load_all_pages( vfs_inode_t * inode ); 397 397 398 398 /****************************************************************************************** 399 * This debug function display the curren state of an inode descriptor identified by 400 * the <inode_xp> argument. 401 *****************************************************************************************/ 402 void vfs_inode_display( xptr_t inode_xp ); 399 403 400 404 /****************************************************************************************** … … 547 551 * It can be executed by any thread running in any cluster (can be different from both 548 552 * the child cluster and the parent cluster). 549 * 550 * [Implementation ]553 * The new child inode and the parent inode can have different FS types. 554 * [Implementation note] 551 555 * As there are cross-references between inode and dentry, this function implements 552 * a three steps scenario :556 * a five steps scenario : 553 557 * 1) The dentry descriptor is created in the cluster containing the existing <parent_xp> 554 558 * inode, and partially initialized, using the RPC_VFS_CREATE DENTRY if required. 555 559 * 2) The inode and its associated mapper are created in cluster identified by <child_cxy>, 556 560 * and partially initialised, using the RPC_VFS_CREATE_INODE if required. 557 * The new inode and the parent inode can have different FS types.558 * 3) The pointers between the parent inode, the new dentry, and the child inode559 * are updated, using remote accesses.560 ***************************************************************************************** *561 * 3) The pointers on dentry in parent inode are updated, using remote access. 562 * 4) The pointers on dentry in child inode are updated, using remotes access. 563 * 5) The pointers on parent and child inode in dentry are updated, using remotes access. 564 ***************************************************************************************** 561 565 * @ child_inode_cxy : [in] target cluster for child inode. 562 566 * @ fs_type : [in] child inode FS type. … … 591 595 592 596 /****************************************************************************************** 593 * This function is called by the vfs_lookup() function when a new dentry/inodemust594 * be created from scratch and introduced in both the Inode Treeand the IOC device.595 * The dentry and inode descriptors have beencreated by the caller.596 * - It allocates one cluster from the relevant FS, and updates the File Allocation597 * Table (both the FAT mapper, andthe IOC device).598 * -It set the "size", and "extend" fields in child inode descriptor.599 * - It updates the parent directory to introduce the new child in the parent directory600 * inode descriptor (radix tree), in theparent inode mapper, and onIOC device.601 * -It set the "extend" field in dentry descriptor.597 * This function is called by the vfs_lookup() function when a new (dentry/inode) must 598 * be created from scratch and introduced in both the parent mapper and the IOC device. 599 * The dentry and inode descriptors must have been previously created by the caller. 600 * 1. It allocates one cluster from the relevant FS, updates the FAT mapper, 601 * and synchronously update the IOC device). 602 * 2. It set the "size", and "extend" fields in child inode descriptor. 603 * 3. It updates the parent directory mapper to introduce the new child, 604 * and synchronously update the IOC device. 605 * 4. It set the "extend" field in dentry descriptor. 602 606 * It can be called by a thread running in any cluster. 603 607 ****************************************************************************************** -
trunk/kernel/kern/do_syscall.c
r610 r626 2 2 * do_syscall.c - architecture independant entry-point for system calls. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018, 2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 106 106 107 107 sys_exit, // 50 108 sys_sync, // 51 109 sys_fsync, // 52 108 110 }; 109 111 … … 169 171 170 172 case SYS_EXIT: return "EXIT"; // 50 173 case SYS_SYNC: return "SYNC"; // 51 174 case SYS_FSYNC: return "FSYNc"; // 52 171 175 172 176 default: return "undefined"; -
trunk/kernel/kern/kernel_init.c
r624 r626 898 898 } 899 899 900 901 902 903 904 ///////////////////////////////// 905 // kleenex debug function 906 ///////////////////////////////// 907 void display_fat( uint32_t step ) 908 { 909 fatfs_ctx_t * fatfs_ctx = fs_context[FS_TYPE_FATFS].extend; 910 if( fatfs_ctx != NULL ) 911 { 912 printk("\n[%s] step %d at cycle %d\n", __FUNCTION__, step, (uint32_t)hal_get_cycles() ); 913 xptr_t mapper_xp = fatfs_ctx->fat_mapper_xp; 914 mapper_display_page( mapper_xp , 0 , 128 ); 915 } 916 else 917 { 918 printk("\n[%s] step %d : fatfs context not initialized\n", __FUNCTION__, step ); 919 } 920 } 921 922 923 924 925 900 926 /////////////////////////////////////////////////////////////////////////////////////////// 901 927 // This function is the entry point for the kernel initialisation. … … 1143 1169 if( CONFIG_VFS_ROOT_IS_FATFS ) 1144 1170 { 1145 // 1. allocate memory for FATFS context extensionin cluster 01171 // 1. allocate memory for FATFS context in cluster 0 1146 1172 fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc(); 1147 1173 … … 1155 1181 // 2. access boot device to initialize FATFS context 1156 1182 fatfs_ctx_init( fatfs_ctx ); 1157 1183 1158 1184 // 3. get various informations from FATFS context 1159 1185 uint32_t root_dir_cluster = fatfs_ctx->root_dir_cluster; -
trunk/kernel/kern/process.c
r625 r626 1447 1447 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1448 1448 cycle = (uint32_t)hal_get_cycles(); 1449 if( DEBUG_PROCESS_MAKE_ EXEC< cycle )1449 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1450 1450 printk("\n[%s] thread[%x,%x] / child takes TXT ownership / cycle %d\n", 1451 1451 __FUNCTION__ , pid, trdid, cycle ); … … 1556 1556 #if DEBUG_PROCESS_MAKE_EXEC 1557 1557 uint32_t cycle = (uint32_t)hal_get_cycles(); 1558 if( DEBUG_PROCESS_MAKE_EXEC < cycle)1558 if( local_cxy == 0x11 ) 1559 1559 printk("\n[%s] thread[%x,%x] enters for %s / cycle %d\n", 1560 1560 __FUNCTION__, pid, thread->trdid, path, cycle ); … … 1579 1579 #if (DEBUG_PROCESS_MAKE_EXEC & 1) 1580 1580 cycle = (uint32_t)hal_get_cycles(); 1581 if( DEBUG_PROCESS_MAKE_EXEC < cycle)1581 if( local_cxy == 0x11 ) 1582 1582 printk("\n[%s] thread[%x,%x] opened file <%s> / cycle %d\n", 1583 1583 __FUNCTION__, pid, thread->trdid, path, cycle ); … … 1589 1589 #if (DEBUG_PROCESS_MAKE_EXEC & 1) 1590 1590 cycle = (uint32_t)hal_get_cycles(); 1591 if( DEBUG_PROCESS_MAKE_EXEC < cycle)1591 if( local_cxy == 0x11 ) 1592 1592 printk("\n[%s] thread[%x,%x] deleted existing threads / cycle %d\n", 1593 1593 __FUNCTION__, pid, thread->trdid, cycle ); … … 1599 1599 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1600 1600 cycle = (uint32_t)hal_get_cycles(); 1601 if( DEBUG_PROCESS_MAKE_EXEC < cycle)1601 if( local_cxy == 0x11 ) 1602 1602 printk("\n[%s] thread[%x,%x] completed VMM reset / cycle %d\n", 1603 1603 __FUNCTION__, pid, thread->trdid, cycle ); … … 1616 1616 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1617 1617 cycle = (uint32_t)hal_get_cycles(); 1618 if( DEBUG_PROCESS_MAKE_EXEC < cycle)1618 if( local_cxy == 0x11 ) 1619 1619 printk("\n[%s] thread[%x,%x] registered args/envs vsegs / cycle %d\n", 1620 1620 __FUNCTION__, pid, thread->trdid, cycle ); … … 1634 1634 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 1635 1635 cycle = (uint32_t)hal_get_cycles(); 1636 if( DEBUG_PROCESS_MAKE_EXEC < cycle)1636 if( local_cxy == 0x11 ) 1637 1637 printk("\n[%s] thread[%x,%x] registered code/data vsegs / cycle %d\n", 1638 1638 __FUNCTION__, pid, thread->trdid, cycle ); -
trunk/kernel/libk/grdxt.c
r610 r626 1 1 /* 2 * grdxt.c - Three-levels Generic Radix-tree implementation 2 * grdxt.c - Three-levels Generic Radix-tree implementation. 3 3 * 4 * authors Alain Greiner (2016 )4 * authors Alain Greiner (2016,2017,2018,2019)) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites -
trunk/kernel/libk/grdxt.h
r623 r626 1 1 /* 2 * grdxt.h - Three-levels Generic Radix-tree interface2 * grdxt.h - Three-levels Generic Radix-tree definition. 3 3 * 4 * Authors Alain Greiner (2016 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright UPMC Sorbonne Universites -
trunk/kernel/libk/remote_rwlock.c
r625 r626 251 251 thread_t * thread_ptr = GET_PTR( thread_xp ); 252 252 253 printk("\n@@@ in %s : release first waiting writer[%x,%x]\n",254 __FUNCTION__, thread_cxy, thread_ptr );255 256 253 // remove this waiting thread from waiting list 257 254 xlist_unlink( XPTR( thread_cxy , &thread_ptr->wait_xlist ) ); -
trunk/kernel/mm/mapper.c
r625 r626 280 280 printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cycle %d", 281 281 __FUNCTION__, this->process->pid, this->trdid, page_id, name, cycle ); 282 if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name );282 if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name ); 283 283 } 284 284 if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) ) … … 286 286 printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cycle %d", 287 287 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 288 if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" );288 if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" ); 289 289 } 290 290 #endif … … 324 324 } 325 325 326 // launch I/O operation to load page from device to mapper326 // launch I/O operation to load page from IOC device to mapper 327 327 error = vfs_fs_move_page( XPTR( local_cxy , page ) , IOC_SYNC_READ ); 328 328 … … 401 401 402 402 #if DEBUG_MAPPER_MOVE_USER 403 uint32_t cycle = (uint32_t)hal_get_cycles(); 404 thread_t * this = CURRENT_THREAD; 403 uint32_t cycle = (uint32_t)hal_get_cycles(); 404 thread_t * this = CURRENT_THREAD; 405 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 406 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 407 vfs_inode_t * inode_ptr = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) ); 408 xptr_t inode_xp = XPTR( mapper_cxy , inode_ptr ); 409 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 410 vfs_inode_get_name( inode_xp , name ); 405 411 if( DEBUG_MAPPER_MOVE_USER < cycle ) 406 printk("\n[%s] thread[%x,%x] : to_buf %d / buffer %x / size %d / offset %d / cycle %d\n", 407 __FUNCTION__, this->process->pid, this->trdid, 408 to_buffer, buffer, size, file_offset, cycle ); 412 { 413 if( to_buffer ) 414 printk("\n[%s] thread[%x,%x] : mapper(%s) -> buffer(%x) / bytes %d / cycle %d\n", 415 __FUNCTION__, this->process->pid, this->trdid, name, buffer, size, cycle ); 416 else 417 printk("\n[%s] thread[%x,%x] : buffer(%x) -> mapper(%s) / bytes %d / cycle %d\n", 418 __FUNCTION__, this->process->pid, this->trdid, buffer, name, size, cycle ); 419 } 409 420 #endif 410 421 … … 419 430 #if (DEBUG_MAPPER_MOVE_USER & 1) 420 431 if( DEBUG_MAPPER_MOVE_USER < cycle ) 421 printk("\n[%s] thread[%x,%x] : first_page %d / last_page %d\n",422 __FUNCTION__, this->process->pid, this->trdid, first, last );432 printk("\n[%s] thread[%x,%x] : mapper(%x,%x) / first_page %d / last_page %d\n", 433 __FUNCTION__, this->process->pid, this->trdid, mapper_cxy, mapper_ptr, first, last ); 423 434 #endif 424 435 … … 440 451 #if (DEBUG_MAPPER_MOVE_USER & 1) 441 452 if( DEBUG_MAPPER_MOVE_USER < cycle ) 442 printk("\n[%s] thread[%x,%x] : page_id = %d / page_offset = %d / page_count =%d\n",453 printk("\n[%s] thread[%x,%x] : page_id %d / page_offset %d / bytes %d\n", 443 454 __FUNCTION__, this->process->pid, this->trdid, page_id , page_offset , page_count ); 444 455 #endif … … 449 460 if ( page_xp == XPTR_NULL ) return -1; 450 461 462 // compute cluster and pointers on page in mapper 463 xptr_t map_xp = ppm_page2base( page_xp ); 464 uint8_t * map_ptr = GET_PTR( map_xp ); 465 cxy_t map_cxy = GET_CXY( map_xp ); 466 451 467 #if (DEBUG_MAPPER_MOVE_USER & 1) 452 468 if( DEBUG_MAPPER_MOVE_USER < cycle ) 453 printk("\n[%s] thread[%x,%x] : get page (%x,%x) from mapper\n", 454 __FUNCTION__, this->process->pid, this->trdid, GET_CXY(page_xp), GET_PTR(page_xp) ); 455 #endif 456 457 // compute pointer in mapper 458 xptr_t base_xp = ppm_page2base( page_xp ); 459 uint8_t * map_ptr = (uint8_t *)GET_PTR( base_xp ) + page_offset; 460 461 // compute pointer in buffer 469 printk("\n[%s] thread[%x,%x] : get buffer(%x,%x) in mapper\n", 470 __FUNCTION__, this->process->pid, this->trdid, map_cxy, map_ptr ); 471 #endif 472 // compute pointer in user buffer 462 473 uint8_t * buf_ptr = (uint8_t *)buffer + done; 463 474 … … 465 476 if( to_buffer ) 466 477 { 467 hal_copy_to_uspace( buf_ptr , map_ptr , page_count ); 478 hal_copy_to_uspace( map_cxy , map_ptr , buf_ptr , page_count ); 479 480 #if DEBUG_MAPPER_MOVE_USER & 1 481 if( DEBUG_MAPPER_MOVE_USER < cycle ) 482 printk("\n[%s] thread[%x,%x] moved %d bytes / mapper %s (%x,%x) -> user buffer(%x,%x)\n", 483 __FUNCTION__, this->process->pid, this->trdid, page_count, 484 name, map_cxy, map_ptr, local_cxy, buf_ptr ); 485 #endif 486 468 487 } 469 488 else 470 489 { 471 490 ppm_page_do_dirty( page_xp ); 472 hal_copy_from_uspace( map_ptr , buf_ptr , page_count ); 491 hal_copy_from_uspace( map_cxy , map_ptr , buf_ptr , page_count ); 492 493 #if DEBUG_MAPPER_MOVE_USER & 1 494 if( DEBUG_MAPPER_MOVE_USER < cycle ) 495 printk("\n[%s] thread[%x,%x] moved %d bytes / user buffer(%x,%x) -> mapper %s (%x,%x)\n", 496 __FUNCTION__, this->process->pid, this->trdid, page_count, 497 local_cxy, buf_ptr, name, map_cxy, map_ptr ); 498 mapper_display_page( mapper_xp , page_id, 128 ); 499 #endif 500 473 501 } 474 502 … … 477 505 478 506 #if DEBUG_MAPPER_MOVE_USER 479 cycle = (uint32_t)hal_get_cycles();507 cycle = (uint32_t)hal_get_cycles(); 480 508 if( DEBUG_MAPPER_MOVE_USER < cycle ) 481 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 482 __FUNCTION__, this->process->pid, this->trdid, cycle ); 509 { 510 if( to_buffer ) 511 printk("\n[%s] thread[%x,%x] completed mapper(%s) -> buffer(%x) / cycle %d\n", 512 __FUNCTION__, this->process->pid, this->trdid, name, buffer, cycle ); 513 else 514 printk("\n[%s] thread[%x,%x] completed buffer(%x) -> mapper(%s) / cycle %d\n", 515 __FUNCTION__, this->process->pid, this->trdid, buffer, name, cycle ); 516 } 483 517 #endif 484 518 … … 717 751 #if DEBUG_MAPPER_SYNC 718 752 if( cycle > DEBUG_MAPPER_SYNC ) 719 printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to device\n",753 printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to IOC device\n", 720 754 __FUNCTION__, this->process->pid, this->trdid, page->index, name ); 721 755 #endif … … 804 838 // display 8 words per line 805 839 tabi = (uint32_t *)buffer; 806 printk("\n***** <%s> first %d bytes of page %d *****\n", name, nbytes, page_id ); 840 printk("\n***** mapper <%s> / %d bytes in page %d (%x,%x)\n", 841 name, nbytes, page_id, GET_CXY(base_xp), GET_PTR(base_xp) ); 807 842 for( line = 0 ; line < (nbytes >> 5) ; line++ ) 808 843 { -
trunk/kernel/mm/mapper.h
r625 r626 62 62 * and the allocated memory is only released when the mapper/inode is destroyed. 63 63 * 64 * TODO : the mapper being only used to implement the VFS cache(s), the mapper.c 65 * and mapper.h file should be trandfered to the fs directory. 64 * TODO (1) the mapper being only used to implement the VFS cache(s), the mapper.c 65 * and mapper.h file should be trandfered to the fs directory. 66 * TODO (2) the "type" field is probably unused... 66 67 ******************************************************************************************/ 67 68 … … 230 231 231 232 /******************************************************************************************* 232 * This scansall pages present in the mapper identified by the <mapper> argument,233 * This function scan all pages present in the mapper identified by the <mapper> argument, 233 234 * and synchronize all pages maked as dirty" on disk. 234 235 * These pages are unmarked and removed from the local PPM dirty_list. -
trunk/kernel/syscalls/shared_include/shared_almos.h
r623 r626 54 54 DISPLAY_MAPPER = 9, 55 55 DISPLAY_BARRIER = 10, 56 DISPLAY_FAT = 11, 56 57 } 57 58 display_type_t; -
trunk/kernel/syscalls/shared_include/syscalls_numbers.h
r610 r626 2 2 * syscalls_numbers.c - Contains enum of the syscalls. 3 3 * 4 * Author Alain Greiner (201 8)4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 86 86 87 87 SYS_EXIT = 50, 88 SYS_SYNC = 51, 89 SYS_FSYNC = 52, 88 90 89 SYSCALLS_NR = 5 1,91 SYSCALLS_NR = 53, 90 92 91 93 } syscalls_t; -
trunk/kernel/syscalls/sys_barrier.c
r625 r626 104 104 105 105 // copy barrier attributes into kernel space 106 hal_copy_from_uspace( &k_attr , (void*)attr , sizeof(pthread_barrierattr_t) ); 106 hal_copy_from_uspace( local_cxy, 107 &k_attr, 108 (void*)attr, 109 sizeof(pthread_barrierattr_t) ); 107 110 108 111 if ( count != k_attr.x_size * k_attr.y_size *k_attr.nthreads ) -
trunk/kernel/syscalls/sys_display.c
r625 r626 56 56 else if( type == DISPLAY_MAPPER ) return "MAPPER"; 57 57 else if( type == DISPLAY_BARRIER ) return "BARRIER"; 58 else if( type == DISPLAY_FAT ) return "FAT"; 58 59 else return "undefined"; 59 60 } … … 436 437 break; 437 438 } 439 ///////////////// 440 case DISPLAY_FAT: 441 { 442 uint32_t entries = (uint32_t)arg1; 443 444 if( entries > 4096 ) 445 { 446 447 #if DEBUG_SYSCALLS_ERROR 448 printk("\n[ERROR] in %s for FAT : nb_entries larger than 4096\n", 449 __FUNCTION__ ); 450 #endif 451 this->errno = EINVAL; 452 return -1; 453 } 454 455 if( entries == 0 ) // display fat context in cluster cxy 456 { 457 uint32_t cxy = (uint32_t)arg0; 458 459 if( cluster_is_undefined( cxy ) ) 460 { 461 462 #if DEBUG_SYSCALLS_ERROR 463 printk("\n[ERROR] in %s for FAT : illegal cxy argument %x\n", 464 __FUNCTION__ , cxy ); 465 #endif 466 this->errno = EINVAL; 467 return -1; 468 } 469 470 fatfs_display_ctx( cxy ); 471 } 472 else // display nb_entries in page 473 { 474 uint32_t page = (uint32_t)arg0; 475 476 fatfs_display_fat( page , entries ); 477 } 478 479 break; 480 } 438 481 //////// 439 482 default: -
trunk/kernel/syscalls/sys_exec.c
r625 r626 96 96 97 97 // copy the array of pointers to kernel buffer 98 hal_copy_from_uspace( k_pointers, 98 hal_copy_from_uspace( local_cxy, 99 k_pointers, 99 100 u_pointers, 100 101 CONFIG_PPM_PAGE_SIZE ); … … 115 116 116 117 // copy the user string to kernel buffer 117 hal_copy_from_uspace( k_buf_ptr, 118 hal_copy_from_uspace( local_cxy, 119 k_buf_ptr, 118 120 k_pointers[index], 119 121 length ); -
trunk/kernel/syscalls/sys_fsync.c
r1 r626 1 1 /* 2 * sys_fsync : sync file2 * sys_fsync.c - copy all modified pages of a given file mapper to IOC device. 3 3 * 4 * Copyright (c) 2015 UPMC Sorbonne Universites4 * Author Alain Greiner (2016,1017) 5 5 * 6 * This file is part of ALMOS-kernel.6 * Copyright (c) UPMC Sorbonne Universites 7 7 * 8 * ALMOS-kernel is free software; you can redistribute it and/or modify it 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 9 11 * under the terms of the GNU General Public License as published by 10 12 * the Free Software Foundation; version 2.0 of the License. 11 13 * 12 * ALMOS- kernelis distributed in the hope that it will be useful, but14 * ALMOS-MKH is distributed in the hope that it will be useful, but 13 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 16 18 * 17 19 * You should have received a copy of the GNU General Public License 18 * along with ALMOS- kernel; if not, write to the Free Software Foundation,20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 19 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 22 */ 21 23 24 #include <hal_kernel_types.h> 25 #include <vfs.h> 26 #include <process.h> 27 #include <thread.h> 28 #include <printk.h> 22 29 23 #include < types.h>30 #include <syscalls.h> 24 31 25 int sys_fsync (uint_t fd) 32 ///////////////////////////////// 33 int sys_fsync( uint32_t file_id ) 26 34 { 27 //TODO 28 return 0;35 printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__, file_id ); 36 return ENOSYS; 29 37 } -
trunk/kernel/syscalls/sys_get_config.c
r625 r626 111 111 112 112 // copy to user space 113 hal_copy_to_uspace( x_size , &k_x_size, sizeof(uint32_t) );114 hal_copy_to_uspace( y_size , &k_y_size, sizeof(uint32_t) );115 hal_copy_to_uspace( ncores , &k_ncores, sizeof(uint32_t) );113 hal_copy_to_uspace( local_cxy, &k_x_size, x_size, sizeof(uint32_t) ); 114 hal_copy_to_uspace( local_cxy, &k_y_size, y_size, sizeof(uint32_t) ); 115 hal_copy_to_uspace( local_cxy, &k_ncores, ncores, sizeof(uint32_t) ); 116 116 117 117 hal_fence(); -
trunk/kernel/syscalls/sys_get_core.c
r625 r626 82 82 83 83 // copy to user space 84 hal_copy_to_uspace( cxy , &k_cxy, sizeof(uint32_t) );85 hal_copy_to_uspace( l id , &k_lid, sizeof(uint32_t) );84 hal_copy_to_uspace( local_cxy, &k_cxy, cxy, sizeof(uint32_t) ); 85 hal_copy_to_uspace( local_cxy, &k_lid, lid, sizeof(uint32_t) ); 86 86 87 87 return 0; -
trunk/kernel/syscalls/sys_get_cycle.c
r625 r626 64 64 65 65 // copy to user space 66 hal_copy_to_uspace( cycle , &k_cycle, sizeof(uint64_t) );66 hal_copy_to_uspace( local_cxy, &k_cycle, cycle, sizeof(uint64_t) ); 67 67 68 68 return 0; -
trunk/kernel/syscalls/sys_is_fg.c
r625 r626 91 91 92 92 // copy to user space 93 hal_copy_to_uspace( is_fg , &is_txt_owner, sizeof(uint32_t) );93 hal_copy_to_uspace( local_cxy, &is_txt_owner, is_fg, sizeof(uint32_t) ); 94 94 95 95 hal_fence(); -
trunk/kernel/syscalls/sys_mmap.c
r625 r626 77 77 78 78 // copy attributes from user space to kernel space 79 hal_copy_from_uspace( &k_attr , attr , sizeof(mmap_attr_t) ); 79 hal_copy_from_uspace( local_cxy, 80 &k_attr, 81 attr, 82 sizeof(mmap_attr_t) ); 80 83 81 84 // get addr, fdid, offset, and length attributes … … 305 308 306 309 // copy vseg base address to user space 307 hal_copy_to_uspace( &attr->addr , &vseg->min , sizeof(intptr_t) ); 308 310 hal_copy_to_uspace( local_cxy, 311 &vseg->min, 312 &attr->addr, 313 sizeof(intptr_t) ); 309 314 hal_fence(); 310 315 -
trunk/kernel/syscalls/sys_opendir.c
r625 r626 175 175 176 176 // set ident value in user buffer 177 hal_copy_to_uspace( dirp , &ident , sizeof(intptr_t) ); 177 hal_copy_to_uspace( local_cxy, 178 &ident, 179 dirp, 180 sizeof(intptr_t) ); 178 181 179 182 hal_fence(); -
trunk/kernel/syscalls/sys_readdir.c
r625 r626 2 2 * sys_readdir.c - Copy one entry from an open VFS directory to an user buffer. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 113 113 114 114 // copy dirent pointer to user buffer 115 hal_copy_to_uspace( buffer, &direntp , sizeof(void *) ); 115 hal_copy_to_uspace( local_cxy, 116 &direntp, 117 buffer, 118 sizeof(void *) ); 116 119 117 120 // update current index in user_dir structure -
trunk/kernel/syscalls/sys_sem.c
r624 r626 139 139 140 140 // return value to user 141 hal_copy_to_uspace( current_value , ¤t , sizeof(uint32_t) ); 141 hal_copy_to_uspace( local_cxy, 142 ¤t, 143 current_value, 144 sizeof(uint32_t) ); 142 145 } 143 146 break; -
trunk/kernel/syscalls/sys_stat.c
r624 r626 122 122 123 123 // copy k_stat to u_stat 124 hal_copy_to_uspace( u_stat , &k_stat , sizeof(struct stat) ); 124 hal_copy_to_uspace( local_cxy, 125 &k_stat, 126 u_stat, 127 sizeof(struct stat) ); 125 128 126 129 hal_fence(); -
trunk/kernel/syscalls/sys_thread_create.c
r624 r626 106 106 } 107 107 108 hal_copy_from_uspace( &kern_attr , user_attr , sizeof(pthread_attr_t) ); 108 hal_copy_from_uspace( local_cxy, 109 &kern_attr, 110 user_attr, 111 sizeof(pthread_attr_t) ); 109 112 } 110 113 … … 212 215 // returns trdid to user space 213 216 trdid = hal_remote_l32( XPTR( child_cxy , &child_ptr->trdid ) ); 214 hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) ); 217 hal_copy_to_uspace( local_cxy, 218 &trdid, 219 trdid_ptr, 220 sizeof(pthread_t) ); 215 221 216 222 // activate new thread -
trunk/kernel/syscalls/sys_timeofday.c
r624 r626 83 83 84 84 // copy values to user space 85 hal_copy_to_uspace( tv , &k_tv , sizeof(struct timeval) ); 85 hal_copy_to_uspace( local_cxy, 86 &k_tv, 87 tv, 88 sizeof(struct timeval) ); 86 89 87 90 hal_fence(); -
trunk/kernel/syscalls/sys_wait.c
r625 r626 154 154 #endif 155 155 // return child termination state to parent process 156 hal_copy_to_uspace( status , &child_state , sizeof(int) ); 156 hal_copy_to_uspace( local_cxy, 157 &child_state, 158 status, 159 sizeof(int) ); 157 160 return child_pid; 158 161 } -
trunk/kernel/syscalls/syscalls.h
r623 r626 2 2 * syscalls.h - Kernel side services for syscall handling. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 584 584 * [43] This debug function displays on the kernel terminal TXT0 an user defined string, 585 585 * or the current state of a kernel structure, identified by the <type> argument. 586 * The <arg0>, <arg1>, and <arg2> arguments depends on the structure type: 587 * - DISPLAY_STRING : an user defined string 588 * - DISPLAY_VMM : VSL and GPT for a process identified by <pid>. 589 * - DISPLAY_SCHED : all threads allocated to a scheduler <cxy> & <lid>. 590 * - DISPLAY_CLUSTER_PROCESS : all processes registered in a cluster identified by <cxy>. 591 * - DISPLAY_TXT_PROCESS : all processes registered in a cluster identified by <cxy>. 592 * - DISPLAY_VFS : all files registered in the VFS cache. 593 * - DISPLAY_CHDEV : all registered channel devices. 594 * - DISPLAY_DQDT : all DQDT nodes curren values. 595 * - DISPLAY_BUSYLOCKS : all busylocks taken by one thread. 596 * - DISPLAY_MAPPER : one page of a given mapper. 586 * The <arg0>, <arg1>, and <arg2> arguments depends on the structure type. 597 587 ****************************************************************************************** 598 588 * type : [in] type of display … … 671 661 672 662 /****************************************************************************************** 673 * [50] This function implements the exitsystem call terminating a POSIX process.663 * [50] This function implements the "exit" system call terminating a POSIX process. 674 664 * It can be called by any thread running in any cluster. 675 665 * It uses both remote accesses to access the owner process descriptor, and the 676 * RPC_PROCESS_SIGACTION to delete remote process and thread descriptors.666 * RPC_PROCESS_SIGACTION to delete remote process copies and thread descriptors. 677 667 * In the present implementation, this function implements actually the _exit(): 678 668 * - it does not flush open output streams. 679 669 * - it does not close open streams. 680 670 ****************************************************************************************** 681 * @ status : terminaison status. 671 * @ status : terminaison status returned to parent process. 672 * @ return 0 if success / return -1 if failure. 682 673 *****************************************************************************************/ 683 674 int sys_exit( uint32_t status ); 684 675 676 /****************************************************************************************** 677 * [51] This function implements the "sync" system call. 678 * It forces all modified pages in all kernel mappers to be copied to the IOC device. 679 * It can be called by any thread running in any cluster. 680 * TODO not implemented yet. 681 ****************************************************************************************** 682 * @ return 0 if success / return -1 if failure. 683 *****************************************************************************************/ 684 int sys_sync( void ); 685 686 /****************************************************************************************** 687 * [52] This function implements the "fsync" system call. 688 * It forces all modified pages of the file mapper identified by the <fd> argument 689 * to be copied to the IOC device. 690 * It can be called by any thread running in any cluster. 691 * TODO not implemented yet. 692 ****************************************************************************************** 693 * @ file_id : file descriptor index in fd_array. 694 * @ return 0 if success / return -1 if failure. 695 *****************************************************************************************/ 696 int sys_fsync( uint32_t file_id ); 697 685 698 #endif // _SYSCALLS_H_ -
trunk/libs/libalmosmkh/almosmkh.c
r623 r626 199 199 } // end get_uint32() 200 200 201 ////////////////////////////// 202 int get_string( char * string, 203 int maxlen ) 204 { 205 int c; 206 int done = 0; 207 int length = 0; 208 209 while( done == 0 ) 210 { 211 // check buffer overflow 212 if( length >= maxlen-1 ) 213 { 214 return -1; // return failure 215 } 216 217 // read one character 218 c = getchar(); 219 220 // analyse this character 221 if ( (c >= 0x20) && (c < 0x7F) ) // printable character 222 { 223 putchar( c ); // echo 224 string[length] = (char)c; // register character in string 225 length++; // update length 226 } 227 else if (c == 0x0A) // LF character marks end of string 228 { 229 done = 1; 230 } 231 else if ( (c == 0x7F) || // DEL character 232 (c == 0x08) ) // BS character 233 { 234 if ( length > 0 ) 235 { 236 length--; 237 printf("\b \b"); // BS / / BS 238 } 239 } 240 else if ( c == 0 ) // EOF character 241 { 242 return -1; // return failure 243 } 244 } 245 246 // set NUL character in string and return success 247 string[length] = 0; 248 return 0; 249 250 } // end get_string() 251 201 252 202 253 /////////////// non standard debug functions ////////////////////////// … … 298 349 } 299 350 351 /////////////////////////////////////// 352 int display_fat( unsigned int page_id, 353 unsigned int nb_entries ) 354 { 355 return hal_user_syscall( SYS_DISPLAY, 356 DISPLAY_FAT, 357 (reg_t)page_id, 358 (reg_t)nb_entries, 0 ); 359 } 360 300 361 /////////////////////////////// 301 362 int trace( unsigned int active, … … 313 374 { 314 375 char cmd; 315 unsigned int cxy;316 unsigned int lid;317 unsigned int txt;318 unsigned int pid;319 unsigned int trdid;320 unsigned int active;321 376 322 377 while( 1 ) 323 378 { 379 // display prompt 324 380 printf("\n[idbg] cmd = "); 381 382 // get a one character command 325 383 cmd = (char)getchar(); 326 384 327 if( cmd == 'h' ) 328 { 329 printf("h\n" 330 "p : display on TXT0 process descriptors in cluster[cxy]\n" 331 "s : display on TXT0 scheduler state for core[cxy,lid]\n" 332 "v : display on TXT0 VMM state for process[cxy,pid]\n" 333 "t : display on TXT0 process decriptors attached to TXT[tid]\n" 334 "b : display on TXT0 busylocks taken by thread[pid,trdid]\n" 335 "q : display on TXT0 DQDT state\n" 336 "y : activate/desactivate trace for core[cxy,lid]\n" 337 "x : force calling process to exit\n" 338 "c : resume calling process execution\n" 339 "h : list supported commands\n"); 340 } 385 // display all busylocks owned by thread(pid,trdid) 386 if( cmd == 'b' ) 387 { 388 printf("b / pid = "); 389 unsigned int pid = get_uint32(); 390 printf(" / trdid = "); 391 unsigned int trdid = get_uint32(); 392 display_busylocks( pid , trdid ); 393 } 394 // return to calling process 395 else if( cmd == 'c' ) 396 { 397 printf("c\n"); 398 break; 399 } 400 // display FAT mapper(page,entries) 401 else if( cmd == 'f' ) 402 { 403 printf("f / page = "); 404 unsigned int page = get_uint32(); 405 printf(" / entries = "); 406 unsigned int entries = get_uint32(); 407 display_fat( page , entries ); 408 } 409 // list all supported commands 410 else if( cmd == 'h' ) 411 { 412 printf("h\n" 413 "- b : display on TXT0 busylocks taken by thread[pid,trdid]\n" 414 "- c : resume calling process execution\n" 415 "- f : display on TXT0 FAT mapper[page,entries]\n" 416 "- h : list of supported commands\n" 417 "- m : display on TXT0 mapper[path,page,nbytes]\n" 418 "- p : display on TXT0 process descriptors in cluster[cxy]\n" 419 "- q : display on TXT0 DQDT state\n" 420 "- s : display on TXT0 scheduler state for core[cxy,lid]\n" 421 "- t : display on TXT0 process decriptors attached to TXT[tid]\n" 422 "- v : display on TXT0 VMM state for process[cxy,pid]\n" 423 "- x : force calling process to exit\n" 424 "- y : activate/desactivate trace for core[cxy,lid]\n" 425 ); 426 } 427 // display MAPPER(path,page,nbytes) 428 else if( cmd == 'm' ) 429 { 430 char path[128]; 431 printf("m / path = "); 432 int error = get_string( path , 128 ); 433 printf(" / page = "); 434 unsigned int page = get_uint32(); 435 printf(" / nbytes = "); 436 unsigned int nbytes = get_uint32(); 437 if( error == 0 ) display_mapper( path , page , nbytes ); 438 } 439 // display all processes in cluster(cxy) 341 440 else if( cmd == 'p' ) 342 441 { 343 442 printf("p / cxy = "); 344 cxy = get_uint32();443 unsigned int cxy = get_uint32(); 345 444 display_cluster_processes( cxy , 0 ); 346 445 } 347 else if( cmd == 's' ) 348 { 349 printf("s / cxy = "); 350 cxy = get_uint32(); 351 printf(" / lid = "); 352 lid = get_uint32(); 353 display_sched( cxy , lid ); 354 } 355 else if( cmd == 'v' ) 356 { 357 printf("v / cxy = "); 358 cxy = get_uint32(); 359 printf(" / pid = "); 360 pid = get_uint32(); 361 display_vmm( cxy , pid ); 362 } 363 else if( cmd == 't' ) 364 { 365 printf("t / txt_id = "); 366 txt = get_uint32(); 367 display_txt_processes( txt ); 368 } 446 // display DQDT 369 447 else if( cmd == 'q' ) 370 448 { … … 372 450 display_dqdt(); 373 451 } 374 else if( cmd == 'y' ) 375 { 376 printf("y / active = "); 377 active = get_uint32(); 378 printf(" / cxy = "); 379 cxy = get_uint32(); 452 // display scheduler state for core(cxy,lid) 453 else if( cmd == 's' ) 454 { 455 printf("s / cxy = "); 456 unsigned int cxy = get_uint32(); 380 457 printf(" / lid = "); 381 lid = get_uint32(); 382 trace( active , cxy , lid ); 383 } 384 else if( cmd == 'b' ) 385 { 386 printf("b / pid = "); 387 pid = get_uint32(); 388 printf(" / trdid = "); 389 trdid = get_uint32(); 390 display_busylocks( pid , trdid ); 391 } 458 unsigned int lid = get_uint32(); 459 display_sched( cxy , lid ); 460 } 461 // display all processes attached to TXT(txt_id) 462 else if( cmd == 't' ) 463 { 464 printf("t / txt_id = "); 465 unsigned int txt_id = get_uint32(); 466 display_txt_processes( txt_id ); 467 } 468 // display vmm state for process(cxy, pid) 469 else if( cmd == 'v' ) 470 { 471 printf("v / cxy = "); 472 unsigned int cxy = get_uint32(); 473 printf(" / pid = "); 474 unsigned int pid = get_uint32(); 475 display_vmm( cxy , pid ); 476 } 477 // force the calling process to exit 392 478 else if( cmd == 'x' ) 393 479 { … … 395 481 exit( 0 ); 396 482 } 397 else if( cmd == 'c' ) 398 { 399 printf("c\n"); 400 break; 401 } 402 } 483 // activate scheduler trace for core(cxy,lid) 484 else if( cmd == 'y' ) 485 { 486 printf("y / active = "); 487 unsigned int active = get_uint32(); 488 printf(" / cxy = "); 489 unsigned int cxy = get_uint32(); 490 printf(" / lid = "); 491 unsigned int lid = get_uint32(); 492 trace( active , cxy , lid ); 493 } 494 } // en while 403 495 } // end idbg() 404 496 -
trunk/libs/libalmosmkh/almosmkh.h
r625 r626 238 238 int display_barrier( unsigned int pid ); 239 239 240 /*************************************************************************************** 241 * This debug syscall displays on the kernel terminal TXT0 the content of one given 242 * page of the FAT mapper. 243 * It can be called by any thread running in any cluster. 244 *************************************************************************************** 245 * @ page_id : page index in file. 246 * @ nb_entries : number of bytes to display. 247 * @ return 0 if success / return -1 if page not found. 248 **************************************************************************************/ 249 int display_fat( unsigned int page_id, 250 unsigned int nb_entries ); 251 240 252 /***************************************************************************************** 241 253 * This debug syscall is used to activate / desactivate the context switches trace -
trunk/libs/mini-libc/unistd.c
r625 r626 66 66 } 67 67 68 ////////////////// 69 int fsync( int fd ) 70 { 71 return hal_user_syscall( SYS_FSYNC, 72 (reg_t)fd, 0, 0, 0 ); 73 } 74 68 75 ///////////////////////////// 69 76 int getcwd( char * buf, … … 75 82 } 76 83 77 //////////// 84 ////////////////// 78 85 int getpid( void ) 79 86 { … … 132 139 } 133 140 141 ///////////////// 142 void sync( void ) 143 { 144 hal_user_syscall( SYS_SYNC, 0, 0, 0, 0 ); 145 } 146 134 147 /////////////////////////////////// 135 148 int unlink( const char * pathname ) -
trunk/libs/mini-libc/unistd.h
r610 r626 35 35 36 36 /***************************************************************************************** 37 * This function sets a timer to deliver the signal SIGALRM to the calling process, 37 * This function implements the "alarm" system call. 38 * sets a timer to deliver the signal SIGALRM to the calling process, 38 39 * after the specified number of seconds. 39 40 * If an alarm has already been set with alarm() but has not been delivered, … … 48 49 49 50 /***************************************************************************************** 50 * This function change the current working directory in the reference process descriptor. 51 * This function implements the "chdir" system call. 52 * It changes the current working directory in the reference process descriptor. 51 53 ***************************************************************************************** 52 54 * @ pathname : pathname (can be relative or absolute). … … 56 58 57 59 /***************************************************************************************** 58 * This function release the memory allocated for the file descriptor identified by 59 * the <fd> argument, and remove the fd array_entry in all process descriptor copies. 60 * This function implements the "close" system call. 61 * It releases the memory allocated for the file identified by the <fd> argument, 62 * and remove the fd array_entry in all process descriptor copies. 60 63 ***************************************************************************************** 61 64 * @ fd : file descriptor index in fd_array. … … 65 68 66 69 /***************************************************************************************** 67 * This function implement the "exec" system call on the user side.70 * This function implement the "exec" system call. 68 71 * It creates, in the same cluster as the calling thread, a new process descriptor, 69 72 * and a new associated main thread descriptor, executing a new memory image defined … … 87 90 88 91 /***************************************************************************************** 89 * This function implement the "fork" system call on the user side.92 * This function implement the "fork" system call. 90 93 * The calling process descriptor (parent process), and the associated thread descriptor 91 94 * are replicated in a - likely - remote cluster, that becomes the new process owner. … … 103 106 104 107 /***************************************************************************************** 105 * This function returns the pathname of the current working directory. 108 * This function implements the "fsync" system call. 109 * It causes all the modified data and attributes of file identified by the <fd> argument 110 * to be copied from the file mapper and file descriptor to the IOC device. 111 ***************************************************************************************** 112 * @ fd : file descriptor index in fd_array. 113 * @ return 0 if success / returns -1 if failure. 114 ****************************************************************************************/ 115 int fsync( int fd ); 116 117 /***************************************************************************************** 118 * This function implements the "getcwd" system call. 119 * It returns the pathname of the current working directory. 106 120 ***************************************************************************************** 107 121 * buf : buffer addres in user space. … … 113 127 114 128 /***************************************************************************************** 115 * This function implements the "getpid" system call on the user side. 129 * This function implements the "getpid" system call. 130 * It returns the process identifier. 116 131 ***************************************************************************************** 117 132 * @ returns the process PID for the calling thread process. … … 120 135 121 136 /***************************************************************************************** 122 * This function test whether a file descriptor refers to a terminal. 137 * This function implements the "isatty" system call. 138 * It test whether a file descriptor refers to a terminal. 123 139 ***************************************************************************************** 124 140 * @ fd : file descriptor index in fd_array. … … 128 144 129 145 /***************************************************************************************** 130 * This function repositions the offset of the file descriptor identified by <fd>, 146 * This function implements the "lseek" system call. 147 * It repositions the offset of the file descriptor identified by <fd>, 131 148 * according to the operation type defined by the <whence> argument. 132 149 ***************************************************************************************** … … 141 158 142 159 /***************************************************************************************** 143 * This function stops the calling process until any signal is received. 160 * This function implements the "pause" system call. 161 * It stops the calling process until a signal is received. 144 162 ***************************************************************************************** 145 163 * @ return 0 if success / returns -1 if failure. … … 148 166 149 167 /***************************************************************************************** 150 * This function creates in the calling thread cluster an unnamed pipe, and two151 * (read and write) file descriptors to access this pipe. The calling function must pass152 * the pointer on thefd[] array.168 * This function implements the "pipe" system call. 169 * It creates in the calling thread cluster an unnamed pipe, and two (read and write) 170 * file descriptors to access this pipe. The argument is a pointer a fd[] array. 153 171 * TODO not implemented yet... 154 172 ***************************************************************************************** … … 160 178 161 179 /***************************************************************************************** 162 * This function read bytes from an open file identified by the <fd> file descriptor. 180 * This function implements the "read" system call. 181 * It reads bytes from an open file identified by the <fd> file descriptor. 163 182 * This file can be a regular file or a character oriented device. 164 183 ***************************************************************************************** … … 173 192 174 193 /***************************************************************************************** 175 * This function removes a directory file whose name is given by <pathname>. 176 * The directory must not have any entries other than `.' and `..'. 194 * This function implements the "rmdir" system call. 195 * It removes a directory file whose name is given by <pathname>. 196 * The directory must not contain any entries other than `.' and `..'. 177 197 ***************************************************************************************** 178 198 * @ pathname : pathname (can be relative or absolute). … … 182 202 183 203 /***************************************************************************************** 184 * This function removes a directory entry identified by the <pathname> from the 185 * directory, and decrement the link count of the file referenced by the link. 204 * This function implements the "sync" system call. 205 * It forces all kernel mappers (file caches) to be copied to the IOC device. 206 ****************************************************************************************/ 207 void sync( void ); 208 209 /***************************************************************************************** 210 * This function implements the "unlink" system call. 211 * It removes a directory entry identified by the <pathname> from the parent directory, 212 * and decrement the link count of the file referenced by the link. 186 213 * If the link count reduces to zero, and no process has the file open, then all resources 187 214 * associated with the file are released. If one or more process have the file open when … … 195 222 196 223 /***************************************************************************************** 197 * This function writes bytes to an open file identified by the <fd> file descriptor. 224 * This function implements the "write" system call. 225 * It writes bytes to an open file identified by the <fd> file descriptor. 198 226 * This file can be a regular file or character oriented device. 199 227 ***************************************************************************************** -
trunk/params-hard.mk
r625 r626 2 2 3 3 ARCH = /users/alain/soc/tsar-trunk-svn-2013/platforms/tsar_generic_iob 4 X_SIZE = 14 X_SIZE = 4 5 5 Y_SIZE = 2 6 6 NB_PROCS = 1 -
trunk/user/ksh/ksh.c
r625 r626 15 15 // The children processes are created by the <load> command, and are 16 16 // attached to the same TXT terminal as the parent KSH process. 17 // A child process can be lau ched in foreground or in background:17 // A child process can be launched in foreground or in background: 18 18 // . when the child process is launched in foreground, the KSH process loses 19 19 // the TXT terminal ownership, that is transfered to the child process. … … 391 391 if( argc < 2 ) 392 392 { 393 printf(" usage: display vmm cxy pid\n"394 " display sched cxy lid\n"393 printf(" usage: display vmm cxy pid\n" 394 " display sched cxy lid\n" 395 395 " display process cxy\n" 396 396 " display txt txtid\n" … … 398 398 " display chdev\n" 399 399 " display dqdt\n" 400 " display locks pid trdid\n"400 " display locks pid trdid\n" 401 401 " display barrier pid\n" 402 " display mapper path page_id nbytes\n"); 402 " display mapper path page nbytes\n" 403 " display fat page entries\n" 404 " display fat cxy 0\n"); 403 405 } 404 406 //////////////////////////////////// … … 558 560 { 559 561 printf(" error: cannot display page %d of mapper %s\n", page_id, argv[2] ); 562 } 563 } 564 } 565 /////////////////////////////////////////// 566 else if( strcmp( argv[1] , "fat" ) == 0 ) 567 { 568 if( argc != 4 ) 569 { 570 printf(" usage: display fat page_id nb_entries\n"); 571 } 572 else 573 { 574 unsigned int page_id = atoi(argv[2]); 575 unsigned int nb_entries = atoi(argv[3]); 576 577 if( display_fat( page_id, nb_entries ) ) 578 { 579 printf(" error: cannot display page %d of fat\n", page_id ); 560 580 } 561 581 } … … 1141 1161 } // end execute() 1142 1162 1163 1164 1143 1165 /////////////////////////////// 1144 1166 static void interactive( void ) … … 1156 1178 #endif 1157 1179 1158 /* 1159 // To lauch one or several commands without interactive mode1180 /* 1181 // Lauch one or several commands without interactive mode 1160 1182 1161 1183 // 1. first command … … 1167 1189 else 1168 1190 { 1169 printf("\n[ksh] load bin/user/pgcd.elf\n");1191 printf("\n[ksh] display fat 0 32\n"); 1170 1192 } 1171 1193 1172 strcpy( cmd , " load bin/user/pgcd.elf" );1194 strcpy( cmd , "display fat 0 32" ); 1173 1195 execute( cmd ); 1174 1196 … … 1181 1203 else 1182 1204 { 1183 printf("\n[ksh] l s home\n");1205 printf("\n[ksh] load bin/user/pgcd.elf\n"); 1184 1206 } 1185 1207 1186 strcpy( cmd , "l s home" );1208 strcpy( cmd , "load bin/user/pgcd.elf" ); 1187 1209 execute( cmd ); 1188 1210 -
trunk/user/pgcd/pgcd.c
r625 r626 12 12 #include <almosmkh.h> 13 13 14 #define INSTRUMENTATION 0 15 #define IDBG 0 16 14 17 ///////////////// 15 18 void main( void ) … … 17 20 int opx; 18 21 int opy; 22 int x; 23 int y; 19 24 unsigned long long cycle; 20 25 unsigned int cxy; … … 24 29 get_core( &cxy , &lid ); 25 30 26 printf( "\n \n[pgcd] starts on core[%x,%d] / cycle %d\n",31 printf( "\n[pgcd] starts on core[%x,%d] / cycle %d\n\n", 27 32 cxy , lid , (unsigned int)cycle ); 28 33 29 while (1) 34 // get operand X 35 printf("operand X = "); 36 opx = get_uint32(); 37 printf("\n"); 38 39 // get operand Y 40 printf("operand Y = "); 41 opy = get_uint32(); 42 printf("\n"); 43 44 // check operands 45 if( (opx == 0) || (opy == 0) ) 30 46 { 31 printf("\n*******************\n"); 32 printf("operand X = "); 33 opx = get_uint32(); 34 printf("\n"); 35 printf("operand Y = "); 36 opy = get_uint32(); 37 printf("\n"); 47 printf("\n[pgcd error] operands must be strictly positive\n"); 48 exit(0); 49 } 38 50 39 if( (opx == 0) || (opy == 0) ) 40 { 41 printf("operands must be positive and larger than 0 => exit\n"); 42 exit( 0 ); 43 } 44 else 45 { 46 while (opx != opy) 47 { 48 if(opx > opy) opx = opx - opy; 49 else opy = opy - opx; 50 } 51 printf("pgcd = %d", opx); 52 } 51 // compute PGCD 52 x = opx; 53 y = opy; 54 while (x != y) 55 { 56 if(x > y) x = x - y; 57 else y = y - x; 53 58 } 59 60 // display result 61 printf("pgcd = %d\n", x); 62 63 #if INSTRUMENTATION 64 65 char name[64]; 66 char path[128]; 67 68 // build a file name from X and Y values 69 snprintf( name , 64 , "pgcd_%d_%d", opx, opy ); 70 71 // build file pathname 72 snprintf( path , 128 , "home/%s" , name ); 73 74 #if IDBG 75 idbg(); 76 #endif 77 78 // open file 79 FILE * stream = fopen( path , NULL ); 80 81 if( stream == NULL ) 82 { 83 printf("\n[pgcd error] cannot open instrumentation file <%s>\n", name ); 84 exit(0); 85 } 86 87 printf("\n[pgcd] file %s successfully open\n", path); 88 89 #if IDBG 90 idbg(); 91 #endif 92 93 // register results to file 94 int ret = fprintf( stream , "pgcd( %d , %d ) = %d\n", opx, opy, x ); 95 96 if( ret < 0 ) 97 { 98 printf("\n[pgcd error] cannot write to instrumentation file <%s>\n", name ); 99 exit(0); 100 } 101 102 printf("\n[pgcd] file %s successfully written\n", path); 103 104 display_mapper( path , 0 , 64 ); 105 106 // close instrumentation file 107 108 #if IDBG 109 idbg(); 110 #endif 111 112 if( fclose( stream ) ) 113 { 114 printf("\n[pgcd error] cannot close the file <%s>\n", name ); 115 exit(0); 116 } 117 118 printf("\n[pgcd] file %s successfully closed\n", path); 119 120 #endif 121 122 exit(0); 123 54 124 } // end pgcd 55 125 -
trunk/user/sort/sort.c
r625 r626 29 29 #include <hal_macros.h> 30 30 31 #define ARRAY_LENGTH 256// number of items31 #define ARRAY_LENGTH 1024 // number of items 32 32 #define MAX_THREADS 1024 // 16 * 16 * 4 33 33 … … 38 38 #define CHECK_RESULT 0 // for debug 39 39 #define INSTRUMENTATION 1 // register computation times on file 40 #define IDBG 0 // activate interactive debug in main 40 41 41 42 ///////////////////////////////////////////////////////////// … … 439 440 #if INSTRUMENTATION 440 441 441 char name[64]; 442 char path[128]; 442 char name[64]; 443 char path[128]; 444 unsigned long long instru_cycle; 443 445 444 446 // build a file name from n_items / n_clusters / n_cores … … 461 463 name, sequencial, parallel ); 462 464 465 #if IDBG 466 idbg(); 467 #endif 468 463 469 // open file 470 get_cycle( &instru_cycle ); 464 471 FILE * stream = fopen( path , NULL ); 472 465 473 if( stream == NULL ) 466 474 { 467 printf("\n[sort error] cannot open instrumentation file <%s>\n", name);475 printf("\n[sort error] cannot open instrumentation file <%s>\n", path ); 468 476 exit(0); 469 477 } 470 478 471 printf("\n[sort] file %s successfully open\n", path); 479 printf("\n[sort] file <%s> open at cycle %d\n", path, (unsigned int)instru_cycle ); 480 481 #if IDBG 482 idbg(); 483 #endif 472 484 473 485 // register results to file 486 get_cycle( &instru_cycle ); 474 487 int ret = fprintf( stream , "\n----- %s -----\n" 475 488 " - sequencial : %d cycles\n" … … 477 490 if( ret < 0 ) 478 491 { 479 printf("\n[sort error] cannot write to instrumentation file <%s>\n", name);492 printf("\n[sort error] cannot write to instrumentation file <%s>\n", path ); 480 493 exit(0); 481 494 } 482 495 483 printf("\n[sort] file %s successfully written\n", path); 496 printf("\n[sort] file <%s> written at cycle %d\n", path, (unsigned int)instru_cycle ); 497 498 #if IDBG 499 idbg(); 500 #endif 484 501 485 502 // close instrumentation file 486 487 if( fclose( stream ) ) 488 { 489 printf("\n[sort error] cannot close the file <%s>\n", name ); 503 get_cycle( &instru_cycle ); 504 ret = fclose( stream ); 505 506 if( ret ) 507 { 508 printf("\n[sort error] cannot close instrumentation file <%s>\n", path ); 490 509 exit(0); 491 510 } 492 511 493 printf("\n[sort] file %s successfully closed\n", path);512 printf("\n[sort] file <%s> closed at cycle %d\n", path, (unsigned int)instru_cycle ); 494 513 495 514 #endif
Note: See TracChangeset
for help on using the changeset viewer.