Changeset 626


Ignore:
Timestamp:
Apr 29, 2019, 7:25:09 PM (3 months ago)
Author:
alain
Message:

This version has been tested on the sort multithreaded application
for TSAR_IOB architectures ranging from 1 to 8 clusters.
It fixes three bigs bugs:
1) the dev_ioc device API has been modified: the dev_ioc_sync_read()
and dev_ioc_sync_write() function use now extended pointers on the
kernel buffer to access a mapper stored in any cluster.
2) the hal_uspace API has been modified: the hal_copy_to_uspace()
and hal_copy_from_uspace() functions use now a (cxy,ptr) couple
to identify the target buffer (equivalent to an extended pointer.
3) an implementation bug has been fixed in the assembly code contained
in the hal_copy_to_uspace() and hal_copy_from_uspace() functions.

Location:
trunk
Files:
51 edited

Legend:

Unmodified
Added
Removed
  • trunk/Makefile

    r625 r626  
    6060# Rule to generate boot.elf, kernel.elf, all user.elf files, and update the virtual disk
    6161# when the corresponding sources files have been modified or destroyed.
    62 # The /home directory on the virtual disk is not modified
     62# The "home" directory on the virtual disk is not modified
    6363compile: dirs                              \
    6464         hard_config.h                     \
     
    123123        mmd             -o -i $(DISK_IMAGE) ::/bin/user       || true
    124124        mmd             -o -i $(DISK_IMAGE) ::/home           || true
    125         mcopy           -o -i $(DISK_IMAGE) Makefile ::/home  || true
    126125        mdir                -/ -b -i $(DISK_IMAGE) ::/
    127126
  • trunk/hal/generic/hal_uspace.h

    r570 r626  
    22 * hal_uspace.h - Generic User Space Access API definition
    33 *
    4  * Authors    Alain Greiner (2016,2017)
     4 * Authors    Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
     
    3838
    3939/*****************************************************************************************
    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.
    4242 *****************************************************************************************
    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.
    4445 * @ u_src     : source buffer address in user space.
    4546 * @ size      : size (number of bytes).
    4647 ****************************************************************************************/
    47 extern void hal_copy_from_uspace( void     * k_dst,
     48extern void hal_copy_from_uspace( cxy_t      k_cxy,
     49                                  void     * k_dst,
    4850                                  void     * u_src,
    4951                                  uint32_t   size );
    5052
    5153/*****************************************************************************************
    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.
    5456 *****************************************************************************************
     57 * @ k_cxy     : cluster identifier for kernel source buffer.
     58 * @ k_src     : local pointer on kernel source buffer.
    5559 * @ u_dst     : destination buffer address in user space.
    56  * @ k_src     : source address in kernel space.
    5760 * @ size      : size (number of bytes).
    5861 ****************************************************************************************/
    59 extern void hal_copy_to_uspace( void     * u_dst,
     62extern void hal_copy_to_uspace( cxy_t      k_cxy,
    6063                                void     * k_src,
     64                                void     * u_dst,
    6165                                uint32_t   size );
    6266
  • trunk/hal/tsar_mips32/core/hal_uspace.c

    r625 r626  
    22 * hal_uspace.c - implementation of Generic User Space Access API for MIPS32
    33 *
    4  * Author  Mohamed Karaoui (2015)
    5  *         Alain Greiner   (2016)
     4 * Author        Alain Greiner   (2016,2017,2018,2019)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    2322 */
    2423
    25 #include <errno.h>
    26 #include <vmm.h>
    2724#include <hal_kernel_types.h>
    2825#include <hal_uspace.h>
     26#include <hal_special.h>
    2927#include <hal_irqmask.h>
    3028
     
    3230#include <thread.h>
    3331
    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///////////////////////////////////////////////////////////////////////////////////////
     48void hal_copy_from_uspace( cxy_t      k_cxy,
     49                           void     * k_dst,
    3650                           void     * u_src,
    3751                           uint32_t   size ) 
    3852{
    3953    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)
    4255    uint32_t src = (uint32_t)u_src;
    4356    uint32_t dst = (uint32_t)k_dst;
    44 
     57 
    4558#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 );
     59thread_t * this  = CURRENT_THREAD;
     60uint32_t   cycle = (uint32_t)hal_get_cycles();
     61if( cycle > DEBUG_HAL_USPACE )
     62printk("\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 );
    4964#endif
    5065
    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
    5470    hal_disable_irq( &save_sr );
    5571
    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
    87124    hal_restore_irq( save_sr );
    88125
    89126#if DEBUG_HAL_USPACE
    90 printk("\n[%s] thread[%x,%x] exit\n",
    91 __FUNCTION__, this->process->pid, this->trdid );
     127cycle = (uint32_t)hal_get_cycles();
     128if( cycle > DEBUG_HAL_USPACE )
     129printk("\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 );
    92131#endif
    93132
    94133}  // end hal_copy_from_uspace()
    95134
    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///////////////////////////////////////////////////////////////////////////////////////
     151void hal_copy_to_uspace( cxy_t      k_cxy,
    98152                         void     * k_src,
     153                         void     * u_dst,
    99154                         uint32_t   size )
    100155{
    101156    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)
    104158    uint32_t src = (uint32_t)k_src;
    105159    uint32_t dst = (uint32_t)u_dst;
    106160
    107161#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 );
     162thread_t * this  = CURRENT_THREAD;
     163uint32_t   cycle = (uint32_t)hal_get_cycles();
     164if( cycle > DEBUG_HAL_USPACE )
     165printk("\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 );
    111167#endif
    112168
    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
    116173    hal_disable_irq( &save_sr );
    117174
    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
    148227    hal_restore_irq( save_sr );
    149228
    150229#if DEBUG_HAL_USPACE
    151 printk("\n[%s] thread[%x,%x] exit\n",
    152 __FUNCTION__, this->process->pid, this->trdid );
     230cycle = (uint32_t)hal_get_cycles();
     231if( cycle > DEBUG_HAL_USPACE )
     232printk("\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 );
    153234#endif
    154235
  • trunk/hal/tsar_mips32/drivers/soclib_bdv.c

    r622 r626  
    5858void __attribute__ ((noinline)) soclib_bdv_cmd( xptr_t th_xp )
    5959{
    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
    6161    uint32_t   lba;
    6262    uint32_t   count;
     
    8686    ioc_xp   = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) );
    8787
    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" );
    9992
    10093    // get IOC device cluster and local pointer
     
    110103    uint32_t   buf_lsb = (uint32_t)(buf_xp);
    111104    uint32_t   buf_msb = (uint32_t)(buf_xp>>32);
     105
     106#if DEBUG_HAL_IOC_RX
     107if( DEBUG_HAL_IOC_RX < cycle )
     108printk("\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,
     110cmd_type, lba, buf_msb, buf_lsb, cycle );
     111#endif
     112
     113#if DEBUG_HAL_IOC_TX
     114if( DEBUG_HAL_IOC_TX < cycle )
     115printk("\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,
     117cmd_type, lba, buf_msb, buf_lsb, cycle );
     118#endif
    112119
    113120    // select operation
     
    143150            {
    144151                hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 0 );
     152
     153#if DEBUG_HAL_IOC_RX
     154cycle = (uint32_t)hal_get_cycles();
     155if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type == IOC_SYNC_READ) )
     156printk("\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
     161cycle = (uint32_t)hal_get_cycles();
     162if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_SYNC_WRITE) )
     163printk("\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
    145166                break;
    146167            }
    147             else if( status == BDV_BUSY )   // non completed
     168            else if( status == BDV_BUSY )      // non completed
    148169            {
    149170                continue;
    150171            }
    151             else                            // error reported
     172            else                               // error reported
    152173            {
    153174                hal_remote_s32( XPTR( th_cxy , &th_ptr->ioc_cmd.error ) , 1 );
     
    170191#if DEBUG_HAL_IOC_RX
    171192if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) )
    172 printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching RX transfer\n",
     193printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching READ transfer\n",
    173194__FUNCTION__ , this->process->pid, this->trdid );
    174195#endif
     
    176197#if DEBUG_HAL_IOC_TX
    177198if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
    178 printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching TX transfer\n",
     199printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching WRITE transfer\n",
    179200__FUNCTION__ , this->process->pid, this->trdid );
    180201#endif
     
    184205        // exit critical section
    185206        hal_restore_irq( save_sr );
    186     }
    187207   
    188208#if DEBUG_HAL_IOC_RX
    189209cycle = (uint32_t)hal_get_cycles();
    190210if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE) )
    191 printk("\n[%s] thread[%x,%x] exit after RX for client thread[%x,%x] / cycle %d\n",
     211printk("\n[%s] thread[%x,%x] exit after READ for client thread[%x,%x] / cycle %d\n",
    192212__FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle );
    193213#endif
     
    196216cycle = (uint32_t)hal_get_cycles();
    197217if( (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
     218printk("\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    }
    201223
    202224} // end soclib_bdv_cmd()
     
    263285    else
    264286    {
    265         assert( false , "IOC_SYNC_READ should not use IRQ" );
     287        assert( false , "illegal command %d", cmd_type );
    266288    }
    267289
  • trunk/hal/tsar_mips32/drivers/soclib_mmc.c

    r570 r626  
    11/*
    2  * soclib_mmc.c - soclib L2 cache controller driver implementation.
     2 * soclib_mmc.c - soclib L2 cache driver implementation.
    33 *
    4  * Author     Alain Greiner (2016)
     4 * Author     Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    6161
    6262    // get command type and extended pointer on MMC device
    63     type   =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->mmc_cmd.type   ) );
     63    type   =         hal_remote_l32( XPTR( th_cxy , &th_ptr->mmc_cmd.type   ) );
    6464    dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->mmc_cmd.dev_xp ) );
    6565
  • trunk/hal/tsar_mips32/drivers/soclib_mmc.h

    r451 r626  
    11/*
    2  * soclib_mmc.h - SOCLIB_MMC (TSAR L2 cache) driver definition.
     2 * soclib_mmc.h - TSAR L2 cache driver definition.
    33 *
    4  * Author    Alain Greiner
     4 * Author    Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
  • trunk/kernel/Makefile

    r612 r626  
    185185              build/syscalls/sys_is_fg.o
    186186
    187 SYS_OBJS_5  = build/syscalls/sys_exit.o
     187SYS_OBJS_5  = build/syscalls/sys_exit.o            \
     188              build/syscalls/sys_sync.o            \
     189              build/syscalls/sys_fsync.o
    188190
    189191VFS_OBJS    = build/fs/vfs.o              \
     
    194196# List of directories to be searched for included files
    195197# when compiling for kernel.elf generation
    196 KERNEL_INCLUDE = -I.                  \
    197                  -Ikern             \
    198                  -Idevices          \
    199                  -Isyscalls         \
    200                  -I$(SHARED_INCLUDE)  \
     198KERNEL_INCLUDE = -I.                   \
     199                 -Ikern                \
     200                 -Idevices             \
     201                 -Isyscalls            \
     202                 -I$(SHARED_INCLUDE)   \
    201203                 -I$(HAL_ARCH)/drivers \
    202204                 -Isyscalls            \
  • trunk/kernel/devices/dev_ioc.c

    r619 r626  
    22 * dev_ioc.c - IOC (Block Device Controler) generic device API implementation.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3636
    3737extern chdev_directory_t  chdev_dir;     // allocated in kernel_init.c
     38
     39////////////////////////////////////////
     40char * 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}
    3848
    3949//////////////////////////////////
     
    192202////////////////////////////////////i/////////////////////////////////////////////
    193203error_t dev_ioc_sync_access( uint32_t   cmd_type,
    194                              uint8_t  * buffer,
     204                             xptr_t     buffer_xp,
    195205                             uint32_t   lba,
    196206                             uint32_t   count )
     
    202212    if( chdev_dir.iob )
    203213    {
    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 );
    206216    }
    207217
     
    215225    this->ioc_cmd.dev_xp    = ioc_xp;
    216226    this->ioc_cmd.type      = cmd_type;
    217     this->ioc_cmd.buf_xp    = XPTR( local_cxy , buffer );
     227    this->ioc_cmd.buf_xp    = buffer_xp;
    218228    this->ioc_cmd.lba       = lba;
    219229    this->ioc_cmd.count     = count;
     
    241251    return this->ioc_cmd.error;
    242252
    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////////////////////////////////////////////////
     256error_t dev_ioc_sync_read( xptr_t     buffer_xp,
    247257                           uint32_t   lba,
    248258                           uint32_t   count )
     
    253263uint32_t   cycle = (uint32_t)hal_get_cycles();
    254264if( 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 );
     265printk("\n[%s] thread[%x,%x] : lba  %x / buffer(%x,%x) / count %d / cycle %d\n",
     266__FUNCTION__ , this->process->pid, this->trdid,
     267lba, 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 );
    260271}
    261272
    262 //////////////////////////////////////////////
    263 error_t dev_ioc_sync_write( uint8_t  * buffer,
     273/////////////////////////////////////////////////
     274error_t dev_ioc_sync_write( xptr_t     buffer_xp,
    264275                            uint32_t   lba,
    265276                            uint32_t   count )
    266277{
    267278
    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
     280thread_t * this  = CURRENT_THREAD;
     281uint32_t   cycle = (uint32_t)hal_get_cycles();
     282if( DEBUG_DEV_IOC_TX < cycle )
     283printk("\n[%s] thread[%x,%x] : lba  %x / buffer(%x,%x) / count %d / cycle %d\n",
     284__FUNCTION__ , this->process->pid, this->trdid,
     285lba, 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 );
    277289}
    278290
  • trunk/kernel/devices/dev_ioc.h

    r614 r626  
    22 * dev_ioc.h - IOC (Block Device Controler) generic device API definition.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    4444 * - SYNC_WRITE : move blocks from memory to device, with a busy waiting policy.
    4545
    46  * A READ or WRITE operation requires dynamic ressource allocation. The calling thread
     46 * The READ or WRITE operations require dynamic ressource allocation. The calling thread
    4747 * is descheduled, and the work is done by the server thread associated to IOC device.
    4848 * The general scenario is detailed below.
     
    6666 *
    6767 * 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
    7074 *****************************************************************************************/
    7175
     
    119123}
    120124ioc_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 *****************************************************************************************/
     132char * dev_ioc_cmd_str( cmd_type_t cmd );
    121133
    122134/******************************************************************************************
     
    138150 * registered in the device pending request queue, and the calling thread is descheduled,
    139151 * 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.
    141153 ******************************************************************************************
    142154 * @ buffer    : local pointer on target buffer in memory (must be block aligned).
    143155 * @ lba       : first block index on device.
    144156 * @ count     : number of blocks to transfer.
    145  * @ returns 0 if success / returns EINVAL if error.
     157 * @ returns 0 if success / returns -1 if error.
    146158 *****************************************************************************************/
    147159error_t dev_ioc_read( uint8_t      * buffer,
     
    154166 * registered in the device pending request queue, and the calling thread is descheduled,
    155167 * 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.
    157169 ******************************************************************************************
    158170 * @ buffer    : local pointer on source buffer in memory (must be block aligned).
    159171 * @ lba       : first block index on device.
    160172 * @ count     : number of blocks to transfer.
    161  * @ returns 0 if success / returns EINVAL if error.
     173 * @ returns 0 if success / returns -1 if error.
    162174 *****************************************************************************************/
    163175error_t dev_ioc_write( uint8_t      * buffer,
     
    167179/******************************************************************************************
    168180 * This blocking function moves one or several contiguous blocks of data
    169  * from the block device to a local memory buffer.
     181 * from the block device to a - possibly remote - memory buffer.
    170182 * It does  not uses the IOC device waiting queue and server thread, and does not use
    171183 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
    172184 * policy for the calling thread.
    173  * It must be called in the client cluster.
    174  ******************************************************************************************
    175  * @ buffer    : local pointer 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 EINVAL if 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 *****************************************************************************************/
     192error_t dev_ioc_sync_read( xptr_t         buffer_xp,
    181193                           uint32_t       lba,
    182194                           uint32_t       count );
     
    184196/******************************************************************************************
    185197 * This blocking function moves one or several contiguous blocks of data
    186  * from a local memory buffer to the block device.
     198 * from a - possibly remote - memory buffer to the block device.
    187199 * It does  not uses the IOC device waiting queue and server thread, and does not use
    188200 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
    189201 * policy for the calling thread.
    190  * It must be called in the client cluster.
    191  ******************************************************************************************
    192  * @ buffer    : local pointer 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 EINVAL if 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 *****************************************************************************************/
     209error_t dev_ioc_sync_write( xptr_t         buffer_xp,
    198210                            uint32_t       lba,
    199211                            uint32_t       count );
  • trunk/kernel/devices/dev_mmc.c

    r605 r626  
    108108
    109109    // 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 );
    112112   
    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;
    115117
    116118    // store command arguments in thread descriptor
    117119    this->mmc_cmd.dev_xp    = chdev_dir.mmc[buf_cxy];
    118120    this->mmc_cmd.type      = MMC_CC_INVAL;
    119     this->mmc_cmd.buf_ptr   = buf_ptr;
    120     this->mmc_cmd.buf_size  = buf_size;
     121    this->mmc_cmd.buf_ptr   = base;
     122    this->mmc_cmd.buf_size  = size;
    121123
    122124    // call MMC driver
     
    152154    void * buf_ptr = GET_PTR( buf_xp );
    153155   
    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;
    156160
    157161    // store command arguments in thread descriptor
    158162    this->mmc_cmd.dev_xp    = chdev_dir.mmc[buf_cxy];
    159163    this->mmc_cmd.type      = MMC_CC_SYNC;
    160     this->mmc_cmd.buf_ptr   = buf_ptr;
    161     this->mmc_cmd.buf_size  = buf_size;
     164    this->mmc_cmd.buf_ptr   = base;
     165    this->mmc_cmd.buf_size  = size;
    162166
    163167    // call MMC driver
  • trunk/kernel/devices/dev_txt.c

    r619 r626  
    22 * dev_txt.c - TXT (Text Terminal) generic device API implementation.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
  • trunk/kernel/devices/dev_txt.h

    r565 r626  
    22 * dev_txt.h - TXT (Text Terminal) generic device API definition.
    33 *
    4  * Author  Alain Greiner    (2016)
     4 * Author  Alain Greiner    (2016,2017,2018,2019))
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    106106    const char * buffer;    /*! local pointer on characters array                        */
    107107    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                       */
    109109}
    110110txt_sync_args_t;
    111111
    112112/******************************************************************************************
    113  * This function returns a printable string for the comman type.
     113 * This function returns a printable string for the command type.
    114114 ******************************************************************************************
    115115 * @ type     : command type (TXT_READ / TXT_WRITE / TXT_SYNC_WRITE)
     
    166166 * interfering with another possible TXT access to another terminal.
    167167 * 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.
    169169 ****************************************************************************************
    170170 * @ buffer    : local pointer on source buffer containing the string.
  • trunk/kernel/fs/fatfs.c

    r625 r626  
    3737#include <fatfs.h>
    3838
     39#define LITTLE_ENDIAN  1
    3940
    4041//////////////////////////////////////////////////////////////////////////////////////////
     
    7273
    7374//////////////////////////////////////////////////////////////////////////////////////////
    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.
    8182// @ return the integer value in a 32 bits word.
    8283//////////////////////////////////////////////////////////////////////////////////////////
    8384static 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];
    9898    }
    9999    return res;
     
    102102
    103103//////////////////////////////////////////////////////////////////////////////////////////
    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.
    111111// @ return the integer value in a 32 bits word.
    112112//////////////////////////////////////////////////////////////////////////////////////////
     113static 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//////////////////////////////////////////////////////////////////////////////////////////
    113148static void fatfs_set_record( uint32_t    offset,
    114                               uint32_t    size,
     149                              uint32_t    nbytes,
    115150                              uint8_t   * buffer,
    116                               uint32_t    little_endian,
    117151                              uint32_t    value )
    118152{
    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//////////////////////////////////////////////////////////////////////////////////////////
     176static 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        }
    128196    }
    129197
     
    374442
    375443//////////////////////////////////////////////////////////////////////////////////////////
     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//////////////////////////////////////////////////////////////////////////////////////////
     454static 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//////////////////////////////////////////////////////////////////////////////////////////
    376485// 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.
    379488// It scan all slots in the FAT mapper seen as an array of 32 bits words, looking for the
    380489// 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.
    381492//
    382493// WARNING : The free_lock protecting exclusive access to these variables
    383494//           must be taken by the calling function.
    384495//////////////////////////////////////////////////////////////////////////////////////////
    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//////////////////////////////////////////////////////////////////////////////////////////
     500static 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
    393506    xptr_t        mapper_xp;    // extended pointer on FAT mapper
    394507    xptr_t        hint_xp;      // extended pointer on "free_cluster_hint" shared variable
    395508    xptr_t        numb_xp;      // extended pointer on "free_clusters" shared variable
    396509    uint32_t      numb;         // "free_clusters" variable current value
     510    uint32_t      hint;         // "free_cluster_hint" variable current value
    397511    uint32_t      page_id;      // page index in FAT mapper
    398512    uint32_t      slot_id;      // slot index in one page of FAT (1024 slots per page)
     
    405519uint32_t   cycle = (uint32_t)hal_get_cycles();
    406520thread_t * this  = CURRENT_THREAD;
    407 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
     521if( DEBUG_FATFS_FREE_CLUSTERS < cycle )
    408522printk("\n[%s] thread[%x,%x] enter for allocated cluster %x / cycle %d\n",
    409523__FUNCTION__, this->process->pid, this->trdid, cluster , cycle );
    410524#endif
    411525
    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 );
    419537
    420538    // get extended pointer on FAT mapper
    421     mapper_xp = hal_remote_l64( XPTR( fat_ctx_cxy , &fat_ctx_ptr->fat_mapper_xp ) );
     539    mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper_xp ) );
    422540
    423541    // initialise variables to scan the FAT mapper
     
    425543    page_id  = (cluster + 1) >> 10;
    426544    slot_id  = (cluster + 1) & 0x3FF;
    427     page_max = hal_remote_l32( XPTR( fat_ctx_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;
     545    page_max = hal_remote_l32( XPTR( fat_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;
    428546
    429547    // scan FAT mapper / loop on pages
     
    451569            if ( hal_remote_l32( slot_xp ) == FREE_CLUSTER )
    452570            {
    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                }
    455583
    456584#if DEBUG_FATFS_FREE_CLUSTERS
    457585cycle = (uint32_t)hal_get_cycles();
    458586if( 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 );
     587printk("\n[%s] thread[%x,%x] updated free cluster info  / hint %x / number %x\n",
     588__FUNCTION__, this->process->pid, this->trdid, 
     589hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) );
    462590#endif
    463591                return 0;
     
    469597        }  // end loop on slots
    470598
    471         // update (page_id,slot_id) variables
     599        // update page_id & slot_id variables
    472600        page_id++;
    473601        slot_id = 0;
     
    483611//////////////////////////////////////////////////////////////////////////////////////////
    484612// 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.
    487615// If the released cluster index is smaller than the current (hint) value,
    488616// 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.
    489619//
    490620// WARNING : The free_lock protecting exclusive access to these variables
    491621//           must be taken by the calling function.
    492622//////////////////////////////////////////////////////////////////////////////////////////
    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//////////////////////////////////////////////////////////////////////////////////////////
     627static 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
    501633    xptr_t        hint_xp;      // extended pointer on "free_cluster_hint" shared variable
    502634    xptr_t        numb_xp;      // extended pointer on "free_clusters" shared variable
     
    504636    uint32_t      numb;         // "free_clusters" variable current value
    505637
     638#if DEBUG_FATFS_FREE_CLUSTERS
     639uint32_t   cycle = (uint32_t)hal_get_cycles();
     640thread_t * this  = CURRENT_THREAD;
     641if( DEBUG_FATFS_FREE_CLUSTERS < cycle )
     642printk("\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   
    506650    // build extended pointers on free_clusters, and free_cluster_hint
    507     hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint );
    508     numb_xp = XPTR( fat_ctx_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 );
    509653
    510654    // get current value of free_cluster_hint and free_clusters
     
    512656    numb = hal_remote_l32( numb_xp );
    513657
    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;
    516661
    517662    // 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    }
    519674
    520675#if DEBUG_FATFS_FREE_CLUSTERS
    521676thread_t * this = CURRENT_THREAD;
    522677if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
    523 printk("\n[%s] thread[%x,%x] updates free cluster info : hint %x / number %x\n",
     678printk("\n[%s] thread[%x,%x] updated free cluster info : hint %x / number %x\n",
    524679__FUNCTION__, this->process->pid, this->trdid,
    525680hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) );
    526681#endif
     682
     683    return 0;
    527684
    528685}  // end fatfs_free_clusters_increment()
     
    576733                               FREE_CLUSTER ) ) return -1;
    577734
    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 );
    584737
    585738}  // end fatfs_recursive_release()
     
    590743//////////////////////////////////////////////////////////////////////////////////////////
    591744
    592 ///////////////////////////////////////////
    593 void fatfs_ctx_display( fatfs_ctx_t * ctx )
    594 {
    595     printk("\n*** FAT context ***\n"
     745///////////////////////////////////
     746void 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"
    596765           "- fat_sectors       = %d\n"
    597766           "- sector size       = %d\n"
    598767           "- 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()
    616790
    617791//////////////////////////////////////////
     
    622796    uint32_t maxline;
    623797
    624     // copute numner of lines to display
     798    // compute number of lines to display
    625799    maxline = nentries >> 3;
    626800    if( nentries & 0x7 ) maxline++;
    627801
    628802    // 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;
    631805
    632806    // 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
    636820    xptr_t     page_xp  = mapper_remote_get_page( fat_mapper_xp , page_id );
    637821
    638822    // get extended pointer on requested page base
    639823    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
    642829    for( line = 0 ; line < maxline ; line++ )
    643830    {
     
    766953    kmem_req_t    req;
    767954    uint8_t     * buffer;
     955    xptr_t        buffer_xp;
    768956
    769957#if DEBUG_FATFS_CTX_INIT
     
    778966assert( (fatfs_ctx != NULL) , "pointer on FATFS context is NULL" );
    779967
    780 // check only cluster 0 does FATFS init
     968// check only cluster 0 does FATFS initialization
    781969assert( (local_cxy == 0) , "only cluster 0 can initialize FATFS");
    782970
    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
    784974        req.type    = KMEM_512_BYTES;
    785975    req.flags   = AF_KERNEL | AF_ZERO;
    786976        buffer      = (uint8_t *)kmem_alloc( &req );
     977    buffer_xp   = XPTR( local_cxy , buffer );
    787978
    788979    if( buffer == NULL )
     
    793984     
    794985    // 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 );
    796987
    797988    if ( error )
     
    807998
    808999    // 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 );
    8101001    if ( sector_size != 512 )
    8111002    {
     
    8151006
    8161007    // 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 );
    8181009    if ( nb_sectors != 8 )
    8191010    {
     
    8231014
    8241015    // 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 );
    8261017    if ( nb_fats != 1 )
    8271018    {
     
    8311022
    8321023    // 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 );
    8341025    if ( (fat_sectors & 0xF) != 0 )
    8351026    {
     
    8391030
    8401031    // 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 );
    8421033    if ( root_cluster != 2 )
    8431034    {
     
    8471038
    8481039    // 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 );
    8501041
    8511042    // 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 );
    8531044
    8541045    // 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 );
    8561047
    8571048    if ( error )
     
    8611052    }
    8621053
    863     // get free clusters number from FS_INFO record
    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 );
    8651056    if ( free_clusters >= fat_sectors << 7 )
    8661057    {
     
    8691060    }
    8701061
    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
    8731065    if ( free_cluster_hint >= fat_sectors << 7 )
    8741066    {
     
    8761068        hal_core_sleep();
    8771069    }
    878 
    879     // release the 512 bytes buffer
    880     req.type = KMEM_512_BYTES;
    881     req.ptr  = buffer;
    882     kmem_free( &req );
    8831070
    8841071    // allocate a mapper for the FAT itself
     
    8901077    }
    8911078
    892     // WARNING : the inode field MUST be NULL for the FAT mapper
     1079    // the inode field is NULL for the FAT mapper
    8931080    fat_mapper->inode = NULL;
    894 
    8951081
    8961082    // initialize the FATFS context
     
    9021088    fatfs_ctx->root_dir_cluster      = 2;
    9031089    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
     1090    fatfs_ctx->fs_info_lba           = fs_info_lba;
    9041091    fatfs_ctx->free_clusters         = free_clusters;
    9051092    fatfs_ctx->free_cluster_hint     = free_cluster_hint;
     1093    fatfs_ctx->fs_info_buffer        = buffer;
    9061094
    9071095    remote_queuelock_init( XPTR( local_cxy , &fatfs_ctx->free_lock ) , LOCK_FATFS_FREE );
     
    10191207        while ( (offset < 4096) && (found == 0) )
    10201208        {
    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 )
    10221210            {
    10231211                found = 1;
     
    13351523
    13361524// check for LFN entry
    1337 assert( (fatfs_get_record( DIR_ATTR, base + offset, 0 ) == ATTR_LONG_NAME_MASK ),
     1525assert( (fatfs_get_record( DIR_ATTR, base + offset ) == ATTR_LONG_NAME_MASK ),
    13381526"this directory entry must be a LFN\n");
    13391527
     
    14391627        while( (offset < 4096) && (found == 0) )
    14401628        {
    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 );   
    14431631
    14441632            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     
    15591747
    15601748// 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" );
     1749assert( (parent_inode   != NULL)       , "parent_inode is NULL\n" );
     1750assert( (name           != NULL)       , "name is NULL\n" );
     1751assert( (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
     1761assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
    15641762
    15651763#if DEBUG_FATFS_GET_DENTRY
     
    15781776    error  = fatfs_scan_directory( mapper, name , &entry , &index );
    15791777
    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;
    15871780
    15881781    // 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 );
    16031786
    16041787    // scan list of parent dentries to search the parent_inode
     
    16921875
    16931876    // 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 );
    16951878
    16961879    // get local pointer on modified page base
     
    17951978            bool_t valid = (dentry_id >= min_dentry) && (dirent_id <  max_dirent );
    17961979
    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 );   
    17991982
    18001983            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     
    20332216error_t fatfs_sync_free_info( void )
    20342217{
     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
    20352229
    20362230#if DEBUG_FATFS_SYNC_FSINFO
     
    20422236#endif
    20432237
    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
    20662254    if ( error )
    20672255    {
    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    }
    20882290
    20892291#if DEBUG_FATFS_SYNC_FSINFO
     
    20962298    return 0;
    20972299
    2098 }  // end fatfs_sync_fs_info()
     2300}  // end fatfs_sync_free_info()
    20992301
    21002302//////////////////////////////////////////////////////////
    21012303error_t fatfs_cluster_alloc( uint32_t * searched_cluster )
    21022304{
     2305    error_t       error;
    21032306    uint32_t      page_id;        // page index in FAT mapper
    21042307    uint32_t      slot_id;        // slot index in page (1024 slots per page)
     
    21092312    fatfs_ctx_t * fat_fatfs_ctx;  // local pointer on FATFS context in FAT cluster
    21102313    xptr_t        mapper_xp;      // extended pointer on FAT mapper
    2111     cxy_t         mapper_cxy;     // Fat mapper cluster identifier
     2314    cxy_t         fat_cxy;        // Fat mapper cluster identifier
    21122315    xptr_t        page_xp;        // extended pointer on current page descriptor in mapper
    21132316    xptr_t        slot_xp;        // extended pointer on FAT slot defined by hint
    21142317    xptr_t        lock_xp;        // extended pointer on lock protecting free clusters info
    21152318    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 cluster
     2319    xptr_t        free_xp;        // extended pointer on free_clusters_number in FAT cluster
    21172320
    21182321#if DEBUG_FATFS_CLUSTER_ALLOC
     
    21302333    loc_fatfs_ctx = vfs_ctx->extend;
    21312334
    2132     // get extended pointer and cluster on FAT mapper
     2335    // get extended pointer on FAT mapper
    21332336    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 );
    21352340   
    21362341    // 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 ) );
    21382343
    21392344    // 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 );
    21432348
    21442349    // take the lock protecting free clusters
    21452350    remote_queuelock_acquire( lock_xp );
    21462351
    2147     // get hint and free_clusters values from FATFS context
     2352    // get hint and free_clusters values from FATFS context in FAT cluster
    21482353    cluster       = hal_remote_l32( hint_xp ) + 1;
    2149     free_clusters = hal_remote_l32( numb_xp );
     2354    free_clusters = hal_remote_l32( free_xp );
    21502355       
    21512356#if (DEBUG_FATFS_CLUSTER_ALLOC & 1)
     
    21682373    }
    21692374
    2170 
    2171 
    21722375    // get page index & slot index for selected cluster
    21732376    page_id  = cluster >> 10;
    21742377    slot_id  = cluster & 0x3FF;
    21752378
    2176     // get relevant page descriptor from mapper
     2379    // get relevant page descriptor from FAT mapper
    21772380    page_xp = mapper_remote_get_page( mapper_xp , page_id );
    21782381
     
    21942397    }
    21952398
    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    }
    21982421
    21992422    // release free clusters busylock
    22002423    remote_queuelock_release( lock_xp );
    2201 
    2202     // update FAT mapper
    2203     hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );
    2204 
    2205     // synchronously update FAT on device
    2206     fatfs_move_page( page_xp , IOC_SYNC_WRITE );
    22072424
    22082425#if DEBUG_FATFS_CLUSTER_ALLOC
    22092426cycle = (uint32_t)hal_get_cycles();
    22102427if( DEBUG_FATFS_CLUSTER_ALLOC < cycle )
    2211 printk("\n[%s] thread[%x,%x] exit / updated cluster %x in FAT / cycle %d\n",
     2428printk("\n[%s] thread[%x,%x] exit / allocated cluster %x in FAT / cycle %d\n",
    22122429__FUNCTION__, this->process->pid, this->trdid, cluster, cycle );
    22132430#endif
     
    22302447    xptr_t        first_xp;       // extended pointer on inode extension
    22312448    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
    22342451
    22352452// check inode pointer
     
    23572574
    23582575    // get page base address
    2359     xptr_t    base_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 );
    23612578 
    23622579    // get inode pointer from mapper
    23632580    inode_ptr  = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) );
    23642581
    2365     ////////////////////////////// it is the FAT mapper
     2582#if DEBUG_FATFS_MOVE_PAGE
     2583if( DEBUG_FATFS_MOVE_PAGE < cycle )
     2584printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n",
     2585__FUNCTION__, this->process->pid, this->trdid,
     2586dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, buffer_ptr );
     2587#endif
     2588
     2589    //////////////////////////////  FAT mapper
    23662590    if( inode_ptr == NULL )
    23672591    {
     
    23702594 
    23712595        // 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        }
    23792607
    23802608#if DEBUG_FATFS_MOVE_PAGE
     
    23822610{
    23832611    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          __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
     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 );
    23862614    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",
    23882616        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    23892617}
     
    23912619
    23922620    }
    2393     ///////////////////////// it is an inode mapper
     2621    ///////////////////////// inode mapper
    23942622    else                       
    23952623    {
     
    24252653        }
    24262654
    2427         // get lba from searched_cluster
     2655        // get lba for searched_cluster
    24282656        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        }
    24292670
    24302671#if DEBUG_FATFS_MOVE_PAGE
     
    24402681#endif
    24412682
    2442         // access device
    2443         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         }
    24542683    }
    24552684
  • trunk/kernel/fs/fatfs.h

    r625 r626  
    173173/*****************************************************************************************
    174174 * 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.
    180183 ****************************************************************************************/
    181184
    182185typedef struct fatfs_ctx_s
    183186{
     187    /* read-only constants replicated in all clusters                                   */
    184188    uint32_t            fat_sectors_count;     /*! number of sectors in FAT region      */
    185189    uint32_t            bytes_per_sector;      /*! number of bytes per sector           */
     
    190194    uint32_t            root_dir_cluster;      /*! cluster index for  root directory    */
    191195    xptr_t              fat_mapper_xp;         /*! extended pointer on FAT mapper       */
     196
     197    /* shared variables (only the copy in FAT cluster must be used)                     */
    192198    uint32_t            free_cluster_hint;     /*! cluster[hint+1] is the first free    */
    193199    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      */
    195202}
    196203fatfs_ctx_t;
     
    224231
    225232/*****************************************************************************************
    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 ****************************************************************************************/
     239void 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).
    238248 ****************************************************************************************/
    239249void fatfs_display_fat( uint32_t  page_id,
    240                         uint32_t  nentries );
     250                        uint32_t  nb_entries );
    241251
    242252
     
    254264
    255265/*****************************************************************************************
    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.
    258269 *****************************************************************************************
    259270 * @ vfs_ctx   : local pointer on VFS context for FATFS.
     
    271282 * This function implements the generic vfs_fs_add_dentry() function for the FATFS.
    272283 *****************************************************************************************
    273  * This function updates a directory identified by the <inode> argument
     284 * This function updates a directory mapper identified by the <inode> argument
    274285 * 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.
    277288 *
    278289 * Implementation note : this function works in two steps:
     
    313324 * This function implements the generic vfs_fs_new_dentry() function for the FATFS.
    314325 *****************************************************************************************
    315  * It initializes a new inode/dentry couple in Inode Tree, attached to the directory
    316  * identified by the <parent_inode> argument. The directory entry is identified
    317  * 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.
    322333 * It must be called by a thread running in the cluster containing the parent inode.
    323334 *****************************************************************************************
     
    325336 * @ name            : child name.
    326337 * @ child_inode_xp  : extended pointer on remote child inode (file or directory).
    327  * @ return 0 if success / return ENOENT if child not found.
     338 * @ return 0 if success / return -1 if child not found.
    328339 ****************************************************************************************/
    329340error_t fatfs_new_dentry( struct vfs_inode_s * parent_inode,
     
    392403 *****************************************************************************************
    393404 * @ inode   : local pointer on inode.
    394  * @ return 0 if success / return EIO if failure during device access.
     405 * @ return 0 if success / return -1 if failure during IOC device access.
    395406 ****************************************************************************************/
    396407error_t fatfs_sync_inode( struct vfs_inode_s * inode );
     
    399410 * This function implements the generic vfs_fs_sync_fat() function for the FATFS.
    400411 *****************************************************************************************
    401  * It updates the FATFS on the IOC device for the FAT itself.
     412 * It updates the FAT on the IOC device for the FAT itself.
    402413 * It scan all clusters registered in the FAT mapper, and copies from mapper to device
    403414 * each page marked as dirty.
     
    408419 *  variables defining the smallest/largest dirty page index in FAT mapper...
    409420 *****************************************************************************************
    410  * @ return 0 if success / return EIO if failure during device access.
     421 * @ return 0 if success / return -1 if failure during IOC device access.
    411422 ****************************************************************************************/
    412423error_t fatfs_sync_fat( void );
     
    415426 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS.
    416427 *****************************************************************************************
    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.
    422436 ****************************************************************************************/
    423437error_t fatfs_sync_free_info( void );
     
    430444 * It can be called by a thread running in any cluster, as it uses remote access
    431445 * 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 exclusive
    433  * access to the FAT. It uses the <free_cluster_hint> and <free_clusters> variables
    434  * 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.
    435449 * - it updates the <free_cluster_hint> and <free_clusters> variables in FATFS context.
    436450 * - it updates the FAT mapper (handling miss from IOC device if required).
     
    445459/*****************************************************************************************
    446460 * This function implements the generic vfs_fs_release_inode() function for the FATFS.
    447  *****************************************************************************************
     461  *****************************************************************************************
    448462 * It releases all clusters allocated to a file/directory identified by the <inode_xp>
    449463 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper.
     
    466480 * The pointer on the mapper and the page index in file are found in the page descriptor.
    467481 * 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.
    470484 * It can be called by any thread running in any cluster.
    471485 *
  • trunk/kernel/fs/vfs.c

    r625 r626  
    423423}  // end vfs_inode_load_all_pages()
    424424
     425/////////////////////////////////////////
     426void 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
    425466////////////////////////////////////////////////////////////////////////////////////////////
    426467//          VFS dentry descriptor related functions
     
    737778cycle = (uint32_t)hal_get_cycles();
    738779if( DEBUG_VFS_OPEN < cycle )
    739 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cluster %x / cycle %d\n",
     780printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cxy %x / cycle %d\n",
    740781__FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle );
    741782#endif
     
    773814// check inode type
    774815assert( (inode_type == INODE_TYPE_FILE), "bad inode type" );
     816
     817#if DEBUG_VFS_USER_MOVE
     818char          name[CONFIG_VFS_MAX_NAME_LENGTH];
     819uint32_t      cycle      = (uint32_t)hal_get_cycles();
     820thread_t    * this       = CURRENT_THREAD;
     821vfs_inode_t * inode      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
     822vfs_inode_get_name( XPTR( file_cxy , inode ) , name );
     823if( 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
    775833
    776834    // get mapper pointer and file offset from file descriptor
     
    794852
    795853#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 );
     854cycle = (uint32_t)hal_get_cycles();
    801855if( cycle > DEBUG_VFS_USER_MOVE )
    802856{
    803857    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 );
    806860    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 );
    809863}
    810864#endif
     
    17941848            xptr_t inode_children_xp = XPTR( inode_cxy , &inode_ptr->children.items );
    17951849
    1796 printk("\n@@@ in %s : children_xp = (%x,%x)\n",
    1797 __FUNCTION__, inode_cxy, &inode_ptr->children.items );
    1798 
    17991850            // get target inode number of children
    18001851            inode_children = hal_remote_l32( inode_children_xp );
     
    21662217
    21672218    // 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",
    21692220    indent_str[indent], name, vfs_inode_type_str( inode_type ), (uint32_t)inode_extd,
    21702221    inode_size, inode_dirty, inode_cxy, inode_ptr, mapper_ptr );
     
    23012352// This static function is used by the vfs_lookup() function.
    23022353// 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.
    23042356// It can be used by any thread running in any cluster.
    23052357//////////////////////////////////////////////////////////////////////////////////////////
     
    24242476    bool_t             create;       // searched inode must be created if not found
    24252477    bool_t             excl;         // searched inode must not exist
    2426     bool_t             par;          // searched inode is the parent
     2478    bool_t             parent;       // searched inode is the parent
    24272479    thread_t         * this;         // pointer on calling thread descriptor
    24282480    process_t        * process;      // pointer on calling process descriptor
     
    24492501    create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE;
    24502502    excl   = (lookup_mode & VFS_LOOKUP_EXCL)   == VFS_LOOKUP_EXCL;
    2451     par    = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT;
     2503    parent = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT;
    24522504
    24532505    // initialise loop variables
     
    24992551        child_cxy  = GET_CXY( child_xp );
    25002552
    2501         // analyse found & last, depending on lookup_mode
    25022553        if( found == false )                              // not found in Inode Tree
    25032554        {
    25042555            // when a inode is not found in the Inode Tree:
    2505             // - if (last and par) the Inode Tree is not modified
     2556            // - if (last and parent) the Inode Tree is not modified
    25062557            // - else we speculatively introduce a new (dentry/inode) in inode tree,
    25072558            //        and scan the parent directory mapper to initialise it.
     
    25142565            //         - if the child is a directory, the child mapper is loaded from device
    25152566
    2516             if( last && par )   //  does nothing
     2567            if( last && parent )   //  does nothing
    25172568            {
    25182569
     
    25772628                }
    25782629
    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 )
    25802633                {
    25812634                    if ( last && create )  // add a brand new dentry in parent directory
     
    25942647#if (DEBUG_VFS_LOOKUP & 1)
    25952648if( DEBUG_VFS_LOOKUP < cycle )
    2596 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => create it\n",
     2649printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => created it\n",
    25972650__FUNCTION__, process->pid, this->trdid, name );
    2598 #endif
     2651vfs_inode_display( child_xp );
     2652#endif
     2653
     2654
    25992655                    }
    26002656                    else                   // not last or not create => error
     
    26872743        if ( last )           // last inode in path  => return relevant info
    26882744        {
    2689             if ( par )  // return parent inode and child name
     2745            if ( parent )  // return parent inode and child name
    26902746            {
    26912747
     
    27572813    vfs_inode_t  * child_ptr  = GET_PTR( child_xp );
    27582814
    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.
    27612818    vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) );
    27622819
     
    27722829#if( DEBUG_VFS_NEW_DENTRY_INIT & 1)
    27732830if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )
    2774 printk("\n[%s] thread[%x,%x] allocated FAT cluster %x to <%s>\n",
     2831printk("\n[%s] thread[%x,%x] allocated FS cluster %x to <%s>\n",
    27752832__FUNCTION__ , this->process->pid, this->trdid, cluster, child_name );
    27762833#endif
    27772834
    2778     // 2. update the child inode descriptor
     2835    // 2. update the child inode descriptor size and extend
    27792836    child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );
    27802837    child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0;
     
    33013358#endif
    33023359
    3303     // register new_dentry in parent_inode xhtab of children
     3360    // 4. register new_dentry in parent_inode xhtab of children
    33043361    children_xhtab_xp = XPTR( parent_cxy , &parent_inode_ptr->children );
    33053362    children_entry_xp = XPTR( parent_cxy , &new_dentry_ptr->children );
     
    33133370#endif
    33143371
    3315     // update "parent" and "child_xp" fields in new_dentry
     3372    // 5. update "parent" and "child_xp" fields in new_dentry
    33163373    hal_remote_s64( XPTR( parent_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp );
    33173374    hal_remote_spt( XPTR( parent_cxy , &new_dentry_ptr->parent ) , parent_inode_ptr );
  • trunk/kernel/fs/vfs.h

    r625 r626  
    376376 * argument to a local buffer identified by the <name> argument.
    377377 * The local buffer size must be at least CONFIG_VFS_MAX_NAME_LENGTH.
    378  *****************************************************************************************
     378 ******************************************************************************************
    379379 * @ inode_xp  : extended pointer on the remote inode.
    380380 * @ name      : local buffer pointer.
     
    396396error_t vfs_inode_load_all_pages( vfs_inode_t * inode );
    397397
    398 
     398/******************************************************************************************
     399 * This debug function display the curren state of an inode descriptor identified by
     400 * the <inode_xp> argument.
     401 *****************************************************************************************/
     402void vfs_inode_display( xptr_t inode_xp );
    399403
    400404/******************************************************************************************
     
    547551 * It can be executed by any thread running in any cluster (can be different from both
    548552 * 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]
    551555 * As there are cross-references between inode and dentry, this function implements
    552  * a three steps scenario :
     556 * a five steps scenario :
    553557 * 1) The dentry descriptor is created in the cluster containing the existing <parent_xp>
    554558 *    inode, and partially initialized, using the RPC_VFS_CREATE DENTRY if required.
    555559 * 2) The inode and its associated mapper are created in cluster identified by <child_cxy>,
    556560 *    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 inode
    559  *    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 *****************************************************************************************
    561565 * @ child_inode_cxy  : [in]  target cluster for child inode.
    562566 * @ fs_type          : [in]  child inode FS type.
     
    591595
    592596/******************************************************************************************
    593  * This function is called by the vfs_lookup() function when a new dentry/inode must
    594  * be created from scratch and introduced in both the Inode Tree and the IOC device.
    595  * The dentry and inode descriptors have been created by the caller.
    596  * - It allocates one cluster from the relevant FS, and updates the File Allocation
    597  *   Table (both the FAT mapper, and the 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 directory
    600  *   inode descriptor (radix tree), in theparent inode mapper, and on IOC 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.
    602606 * It can be called by a thread running in any cluster.
    603607 ******************************************************************************************
  • trunk/kernel/kern/do_syscall.c

    r610 r626  
    22 * do_syscall.c - architecture independant entry-point for system calls.
    33 *
    4  * Author    Alain Greiner (2016,2017,2018)
     4 * Author    Alain Greiner (2016,2017,2018, 2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    106106
    107107    sys_exit,               // 50
     108    sys_sync,               // 51
     109    sys_fsync,              // 52
    108110};
    109111
     
    169171
    170172    case SYS_EXIT:                         return "EXIT";             // 50
     173    case SYS_SYNC:                         return "SYNC";             // 51
     174    case SYS_FSYNC:                        return "FSYNc";            // 52
    171175
    172176    default:                               return "undefined";
  • trunk/kernel/kern/kernel_init.c

    r624 r626  
    898898}
    899899
     900
     901
     902
     903
     904/////////////////////////////////
     905// kleenex debug function
     906/////////////////////////////////
     907void 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
    900926///////////////////////////////////////////////////////////////////////////////////////////
    901927// This function is the entry point for the kernel initialisation.
     
    11431169        if( CONFIG_VFS_ROOT_IS_FATFS )
    11441170        {
    1145             // 1. allocate memory for FATFS context extension in cluster 0
     1171            // 1. allocate memory for FATFS context in cluster 0
    11461172            fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc();
    11471173
     
    11551181            // 2. access boot device to initialize FATFS context
    11561182            fatfs_ctx_init( fatfs_ctx );
    1157  
     1183
    11581184            // 3. get various informations from FATFS context
    11591185            uint32_t root_dir_cluster = fatfs_ctx->root_dir_cluster;
  • trunk/kernel/kern/process.c

    r625 r626  
    14471447#if( DEBUG_PROCESS_MAKE_FORK & 1 )
    14481448cycle = (uint32_t)hal_get_cycles();
    1449 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1449if( DEBUG_PROCESS_MAKE_FORK < cycle )
    14501450printk("\n[%s] thread[%x,%x] / child takes TXT ownership / cycle %d\n",
    14511451__FUNCTION__ , pid, trdid, cycle );
     
    15561556#if DEBUG_PROCESS_MAKE_EXEC
    15571557uint32_t cycle = (uint32_t)hal_get_cycles();
    1558 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1558if( local_cxy == 0x11 )
    15591559printk("\n[%s] thread[%x,%x] enters for %s / cycle %d\n",
    15601560__FUNCTION__, pid, thread->trdid, path, cycle );
     
    15791579#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    15801580cycle = (uint32_t)hal_get_cycles();
    1581 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1581if( local_cxy == 0x11 )
    15821582printk("\n[%s] thread[%x,%x] opened file <%s> / cycle %d\n",
    15831583__FUNCTION__, pid, thread->trdid, path, cycle );
     
    15891589#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    15901590cycle = (uint32_t)hal_get_cycles();
    1591 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1591if( local_cxy == 0x11 )
    15921592printk("\n[%s] thread[%x,%x] deleted existing threads / cycle %d\n",
    15931593__FUNCTION__, pid, thread->trdid, cycle );
     
    15991599#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    16001600cycle = (uint32_t)hal_get_cycles();
    1601 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1601if( local_cxy == 0x11 )
    16021602printk("\n[%s] thread[%x,%x] completed VMM reset / cycle %d\n",
    16031603__FUNCTION__, pid, thread->trdid, cycle );
     
    16161616#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    16171617cycle = (uint32_t)hal_get_cycles();
    1618 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1618if( local_cxy == 0x11 )
    16191619printk("\n[%s] thread[%x,%x] registered args/envs vsegs / cycle %d\n",
    16201620__FUNCTION__, pid, thread->trdid, cycle );
     
    16341634#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    16351635cycle = (uint32_t)hal_get_cycles();
    1636 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1636if( local_cxy == 0x11 )
    16371637printk("\n[%s] thread[%x,%x] registered code/data vsegs / cycle %d\n",
    16381638__FUNCTION__, pid, thread->trdid, cycle );
  • trunk/kernel/libk/grdxt.c

    r610 r626  
    11/*
    2  * grdxt.c - Three-levels Generic Radix-tree implementation
     2 * grdxt.c - Three-levels Generic Radix-tree implementation.
    33 *
    4  * authors  Alain Greiner (2016)
     4 * authors  Alain Greiner (2016,2017,2018,2019))
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
  • trunk/kernel/libk/grdxt.h

    r623 r626  
    11/*
    2  * grdxt.h - Three-levels Generic Radix-tree interface
     2 * grdxt.h - Three-levels Generic Radix-tree definition.
    33 *
    4  * Authors  Alain Greiner (2016)
     4 * Authors  Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright  UPMC Sorbonne Universites
  • trunk/kernel/libk/remote_rwlock.c

    r625 r626  
    251251        thread_t *  thread_ptr = GET_PTR( thread_xp );
    252252
    253 printk("\n@@@ in %s : release first waiting writer[%x,%x]\n",
    254 __FUNCTION__, thread_cxy, thread_ptr );
    255 
    256253        // remove this waiting thread from waiting list
    257254        xlist_unlink( XPTR( thread_cxy , &thread_ptr->wait_xlist ) );
  • trunk/kernel/mm/mapper.c

    r625 r626  
    280280    printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cycle %d",
    281281    __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 );
    283283}
    284284if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
     
    286286    printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cycle %d",
    287287    __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" );
    289289}
    290290#endif
     
    324324    }
    325325
    326     // launch I/O operation to load page from device to mapper
     326    // launch I/O operation to load page from IOC device to mapper
    327327    error = vfs_fs_move_page( XPTR( local_cxy , page ) , IOC_SYNC_READ );
    328328
     
    401401
    402402#if DEBUG_MAPPER_MOVE_USER
    403 uint32_t   cycle = (uint32_t)hal_get_cycles();
    404 thread_t * this  = CURRENT_THREAD;
     403uint32_t      cycle      = (uint32_t)hal_get_cycles();
     404thread_t    * this       = CURRENT_THREAD;
     405cxy_t         mapper_cxy = GET_CXY( mapper_xp );
     406mapper_t    * mapper_ptr = GET_PTR( mapper_xp );
     407vfs_inode_t * inode_ptr  = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) );
     408xptr_t        inode_xp   = XPTR( mapper_cxy , inode_ptr );
     409char          name[CONFIG_VFS_MAX_NAME_LENGTH];
     410vfs_inode_get_name( inode_xp , name );
    405411if( 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}
    409420#endif
    410421
     
    419430#if (DEBUG_MAPPER_MOVE_USER & 1)
    420431if( 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 );
     432printk("\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 );
    423434#endif
    424435
     
    440451#if (DEBUG_MAPPER_MOVE_USER & 1)
    441452if( DEBUG_MAPPER_MOVE_USER < cycle )
    442 printk("\n[%s] thread[%x,%x] : page_id = %d / page_offset = %d / page_count = %d\n",
     453printk("\n[%s] thread[%x,%x] : page_id %d / page_offset %d / bytes %d\n",
    443454__FUNCTION__, this->process->pid, this->trdid, page_id , page_offset , page_count );
    444455#endif
     
    449460        if ( page_xp == XPTR_NULL ) return -1;
    450461
     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
    451467#if (DEBUG_MAPPER_MOVE_USER & 1)
    452468if( 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
     469printk("\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
    462473        uint8_t * buf_ptr = (uint8_t *)buffer + done;
    463474
     
    465476        if( to_buffer )
    466477        {
    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
     481if( DEBUG_MAPPER_MOVE_USER < cycle )
     482printk("\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,
     484name, map_cxy, map_ptr, local_cxy, buf_ptr );
     485#endif
     486
    468487        }
    469488        else
    470489        {
    471490            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
     494if( DEBUG_MAPPER_MOVE_USER < cycle )
     495printk("\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,
     497local_cxy, buf_ptr, name, map_cxy, map_ptr );
     498mapper_display_page(  mapper_xp , page_id, 128 );
     499#endif
     500
    473501        }
    474502
     
    477505
    478506#if DEBUG_MAPPER_MOVE_USER
    479 cycle = (uint32_t)hal_get_cycles();
     507cycle      = (uint32_t)hal_get_cycles();
    480508if( 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}
    483517#endif
    484518
     
    717751#if DEBUG_MAPPER_SYNC
    718752if( cycle > DEBUG_MAPPER_SYNC )
    719 printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to device\n",
     753printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to IOC device\n",
    720754__FUNCTION__, this->process->pid, this->trdid, page->index, name );
    721755#endif
     
    804838    // display 8 words per line
    805839    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) );
    807842    for( line = 0 ; line < (nbytes >> 5) ; line++ )
    808843    {
  • trunk/kernel/mm/mapper.h

    r625 r626  
    6262 *   and the  allocated memory is only released when the mapper/inode is destroyed.
    6363 *
    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...
    6667 ******************************************************************************************/
    6768
     
    230231
    231232/*******************************************************************************************
    232  * This scans all 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,
    233234 * and synchronize all pages maked as dirty" on disk.
    234235 * These pages are unmarked and removed from the local PPM dirty_list.
  • trunk/kernel/syscalls/shared_include/shared_almos.h

    r623 r626  
    5454    DISPLAY_MAPPER            = 9,
    5555    DISPLAY_BARRIER           = 10,
     56    DISPLAY_FAT               = 11,
    5657}
    5758display_type_t;
  • trunk/kernel/syscalls/shared_include/syscalls_numbers.h

    r610 r626  
    22 * syscalls_numbers.c - Contains enum of the syscalls.
    33 *
    4  * Author    Alain Greiner (2018)
     4 * Author    Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    8686
    8787    SYS_EXIT           = 50,
     88    SYS_SYNC           = 51,
     89    SYS_FSYNC          = 52,
    8890
    89     SYSCALLS_NR        = 51,
     91    SYSCALLS_NR        = 53,
    9092
    9193} syscalls_t;
  • trunk/kernel/syscalls/sys_barrier.c

    r625 r626  
    104104 
    105105                // 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) );
    107110
    108111                if ( count != k_attr.x_size * k_attr.y_size *k_attr.nthreads ) 
  • trunk/kernel/syscalls/sys_display.c

    r625 r626  
    5656    else if( type == DISPLAY_MAPPER            ) return "MAPPER";
    5757    else if( type == DISPLAY_BARRIER           ) return "BARRIER";
     58    else if( type == DISPLAY_FAT               ) return "FAT";
    5859    else                                         return "undefined";
    5960}
     
    436437            break;
    437438        }
     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
     448printk("\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
     463printk("\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        }
    438481        ////////
    439482        default:
  • trunk/kernel/syscalls/sys_exec.c

    r625 r626  
    9696
    9797    // 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,
    99100                          u_pointers,
    100101                          CONFIG_PPM_PAGE_SIZE );
     
    115116
    116117        // 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,
    118120                              k_pointers[index],
    119121                              length );
  • trunk/kernel/syscalls/sys_fsync.c

    r1 r626  
    11/*
    2  * sys_fsync: sync file
     2 * sys_fsync.c - copy all modified pages of a given file mapper to IOC device.
    33 *
    4  * Copyright (c) 2015 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016,1017)
    55 *
    6  * This file is part of ALMOS-kernel.
     6 * Copyright (c)  UPMC Sorbonne Universites
    77 *
    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
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * 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,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
     24#include <hal_kernel_types.h>
     25#include <vfs.h>
     26#include <process.h>
     27#include <thread.h>
     28#include <printk.h>
    2229
    23 #include <types.h>
     30#include <syscalls.h>
    2431
    25 int sys_fsync (uint_t fd)
     32/////////////////////////////////
     33int sys_fsync( uint32_t file_id )
    2634{
    27         //TODO
    28         return 0;
     35    printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__, file_id );
     36    return ENOSYS;
    2937}
  • trunk/kernel/syscalls/sys_get_config.c

    r625 r626  
    111111
    112112    // 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) );
    116116
    117117    hal_fence();
  • trunk/kernel/syscalls/sys_get_core.c

    r625 r626  
    8282
    8383    // copy to user space
    84         hal_copy_to_uspace( cxy , &k_cxy , sizeof(uint32_t) );
    85         hal_copy_to_uspace( lid , &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) );
    8686
    8787        return 0;
  • trunk/kernel/syscalls/sys_get_cycle.c

    r625 r626  
    6464
    6565    // 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) );
    6767
    6868        return 0;
  • trunk/kernel/syscalls/sys_is_fg.c

    r625 r626  
    9191
    9292    // 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) );
    9494
    9595    hal_fence();
  • trunk/kernel/syscalls/sys_mmap.c

    r625 r626  
    7777
    7878    // 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) );
    8083
    8184    // get addr, fdid, offset, and length attributes
     
    305308
    306309    // 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) );
    309314    hal_fence();
    310315
  • trunk/kernel/syscalls/sys_opendir.c

    r625 r626  
    175175
    176176    // 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) );
    178181
    179182    hal_fence();
  • trunk/kernel/syscalls/sys_readdir.c

    r625 r626  
    22 * sys_readdir.c - Copy one entry from an open VFS directory to an user buffer.
    33 *
    4  * Author    Alain Greiner (2016,2017,2018)
     4 * Author    Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    113113
    114114    // 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 *) );
    116119
    117120    // update current index in user_dir structure
  • trunk/kernel/syscalls/sys_sem.c

    r624 r626  
    139139 
    140140            // return value to user
    141             hal_copy_to_uspace( current_value , &current , sizeof(uint32_t) );
     141            hal_copy_to_uspace( local_cxy,
     142                                &current,
     143                                current_value,
     144                                sizeof(uint32_t) );
    142145        }
    143146        break;
  • trunk/kernel/syscalls/sys_stat.c

    r624 r626  
    122122   
    123123    // 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) );
    125128
    126129    hal_fence();
  • trunk/kernel/syscalls/sys_thread_create.c

    r624 r626  
    106106            }
    107107       
    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) );
    109112    }
    110113
     
    212215        // returns trdid to user space
    213216        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) );
    215221
    216222    // activate new thread
  • trunk/kernel/syscalls/sys_timeofday.c

    r624 r626  
    8383
    8484    // 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) );
    8689
    8790    hal_fence();
  • trunk/kernel/syscalls/sys_wait.c

    r625 r626  
    154154#endif
    155155                 // 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) );
    157160                 return child_pid;
    158161            }
  • trunk/kernel/syscalls/syscalls.h

    r623 r626  
    22 * syscalls.h - Kernel side services for syscall handling.
    33 *
    4  * Author     Alain Greiner (2016,2017,2018)
     4 * Author     Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    584584 * [43] This debug function displays on the kernel terminal TXT0 an user defined string,
    585585 * 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.
    597587 ******************************************************************************************
    598588 * type      : [in] type of display
     
    671661
    672662/******************************************************************************************
    673  * [50] This function implements the exit system call terminating a POSIX process.
     663 * [50] This function implements the "exit" system call terminating a POSIX process.
    674664 * It can be called by any thread running in any cluster.
    675665 * 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.
    677667 * In the present implementation, this function implements actually the _exit():
    678668 * - it does not flush open output streams.
    679669 * - it does not close open streams.
    680670 ******************************************************************************************
    681  * @ status   : terminaison status.
     671 * @ status   : terminaison status returned to parent process.
     672 * @ return 0 if success / return -1 if failure.
    682673 *****************************************************************************************/
    683674int sys_exit( uint32_t status );
    684675
     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 *****************************************************************************************/
     684int 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 *****************************************************************************************/
     696int sys_fsync( uint32_t file_id );
     697
    685698#endif  // _SYSCALLS_H_
  • trunk/libs/libalmosmkh/almosmkh.c

    r623 r626  
    199199}  // end get_uint32()
    200200
     201//////////////////////////////
     202int 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
    201252
    202253///////////////    non standard debug functions    //////////////////////////
     
    298349}
    299350
     351///////////////////////////////////////
     352int 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
    300361///////////////////////////////
    301362int trace( unsigned int active,
     
    313374{
    314375   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;
    321376
    322377   while( 1 )
    323378   {
     379        // display prompt
    324380        printf("\n[idbg] cmd = ");
     381
     382        // get a one character command
    325383        cmd = (char)getchar();
    326384
    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)
    341440        else if( cmd == 'p' )
    342441        {
    343442            printf("p / cxy = ");
    344             cxy = get_uint32();
     443            unsigned int cxy = get_uint32();
    345444            display_cluster_processes( cxy , 0 );
    346445        }
    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
    369447        else if( cmd == 'q' )
    370448        {
     
    372450            display_dqdt();
    373451        }
    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();
    380457            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
    392478        else if( cmd == 'x' )
    393479        {
     
    395481            exit( 0 );
    396482        }
    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
    403495}  // end idbg()
    404496
  • trunk/libs/libalmosmkh/almosmkh.h

    r625 r626  
    238238int display_barrier( unsigned int pid );
    239239
     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 **************************************************************************************/
     249int display_fat( unsigned int page_id,
     250                 unsigned int nb_entries );
     251
    240252/*****************************************************************************************
    241253* This debug syscall is used to activate / desactivate the context switches trace
  • trunk/libs/mini-libc/unistd.c

    r625 r626  
    6666}
    6767
     68//////////////////
     69int fsync( int fd )
     70{
     71    return hal_user_syscall( SYS_FSYNC,
     72                             (reg_t)fd, 0, 0, 0 );
     73}
     74
    6875/////////////////////////////
    6976int getcwd( char       * buf,
     
    7582}
    7683
    77 ////////////
     84//////////////////
    7885int getpid( void )
    7986{
     
    132139}
    133140
     141/////////////////
     142void sync( void )
     143{
     144    hal_user_syscall( SYS_SYNC, 0, 0, 0, 0 );
     145}
     146
    134147///////////////////////////////////
    135148int unlink( const char * pathname )
  • trunk/libs/mini-libc/unistd.h

    r610 r626  
    3535
    3636/*****************************************************************************************
    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,
    3839 * after the specified number of seconds.
    3940 * If an alarm has already been set with alarm() but has not been delivered,
     
    4849
    4950/*****************************************************************************************
    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.
    5153 *****************************************************************************************
    5254 * @ pathname   : pathname (can be relative or absolute).
     
    5658
    5759/*****************************************************************************************
    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.
    6063 *****************************************************************************************
    6164 * @ fd   : file descriptor index in fd_array.
     
    6568
    6669/*****************************************************************************************
    67  * This function implement the "exec" system call on the user side.
     70 * This function implement the "exec" system call.
    6871 * It creates, in the same cluster as the calling thread, a new process descriptor,
    6972 * and a new associated main thread descriptor, executing a new memory image defined
     
    8790
    8891/*****************************************************************************************
    89  * This function implement the "fork" system call on the user side.
     92 * This function implement the "fork" system call.
    9093 * The calling process descriptor (parent process), and the associated thread descriptor
    9194 * are replicated in a - likely - remote cluster, that becomes the new process owner.
     
    103106
    104107/*****************************************************************************************
    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 ****************************************************************************************/
     115int fsync( int fd );
     116
     117/*****************************************************************************************
     118 * This function implements the "getcwd" system call.
     119 * It returns the pathname of the current working directory.
    106120 *****************************************************************************************
    107121 * buf     : buffer addres in user space.
     
    113127
    114128/*****************************************************************************************
    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.
    116131 *****************************************************************************************
    117132 * @ returns the process PID for the calling thread process.
     
    120135
    121136/*****************************************************************************************
    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.
    123139 *****************************************************************************************
    124140 * @ fd   : file descriptor index in fd_array.
     
    128144
    129145/*****************************************************************************************
    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>,
    131148 * according to the operation type defined by the <whence> argument.
    132149 *****************************************************************************************
     
    141158
    142159/*****************************************************************************************
    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.
    144162 *****************************************************************************************
    145163 * @ return 0 if success / returns -1 if failure.
     
    148166
    149167/*****************************************************************************************
    150  * This function creates in the calling thread cluster an unnamed pipe, and two
    151  * (read and write) file descriptors to access this pipe. The calling function must pass
    152  * the pointer on the fd[] 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.
    153171 * TODO not implemented yet...
    154172 *****************************************************************************************
     
    160178
    161179/*****************************************************************************************
    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.
    163182 * This file can be a regular file or a character oriented device.
    164183 *****************************************************************************************
     
    173192
    174193/*****************************************************************************************
    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 `..'.
    177197 *****************************************************************************************
    178198 * @ pathname   : pathname (can be relative or absolute).
     
    182202
    183203/*****************************************************************************************
    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 ****************************************************************************************/
     207void 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.
    186213 * If the link count reduces to zero, and no process has the file open, then all resources
    187214 * associated with the file are released.  If one or more process have the file open when
     
    195222
    196223/*****************************************************************************************
    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.
    198226 * This file can be a regular file or character oriented device.
    199227 *****************************************************************************************
  • trunk/params-hard.mk

    r625 r626  
    22
    33ARCH      = /users/alain/soc/tsar-trunk-svn-2013/platforms/tsar_generic_iob
    4 X_SIZE    = 1
     4X_SIZE    = 4
    55Y_SIZE    = 2
    66NB_PROCS  = 1
  • trunk/user/ksh/ksh.c

    r625 r626  
    1515// The children processes are created by the <load> command, and are
    1616// attached to the same TXT terminal as the parent KSH process.
    17 // A child process can be lauched in foreground or in background:
     17// A child process can be launched in foreground or in background:
    1818// . when the child process is launched in foreground, the KSH process loses
    1919//   the TXT terminal ownership, that is transfered to the child process.
     
    391391    if( argc < 2 )
    392392    {
    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"             
    395395               "         display  process  cxy\n"             
    396396               "         display  txt      txtid\n"             
     
    398398               "         display  chdev\n"             
    399399               "         display  dqdt\n"             
    400                "         display  locks    pid    trdid\n"
     400               "         display  locks    pid      trdid\n"
    401401               "         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");
    403405    }
    404406    ////////////////////////////////////
     
    558560            {
    559561                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 );
    560580            }
    561581        }
     
    11411161}  // end execute()
    11421162
     1163
     1164
    11431165///////////////////////////////
    11441166static void interactive( void )
     
    11561178#endif
    11571179
    1158 /* 
    1159 // To lauch one or several commands without interactive mode
     1180/*
     1181// Lauch one or several commands without interactive mode
    11601182
    11611183// 1. first command
     
    11671189else
    11681190{
    1169     printf("\n[ksh] load bin/user/pgcd.elf\n");
     1191    printf("\n[ksh] display fat 0 32\n");
    11701192}
    11711193
    1172 strcpy( cmd , "load bin/user/pgcd.elf" );
     1194strcpy( cmd , "display fat 0 32" );
    11731195execute( cmd );
    11741196
     
    11811203else
    11821204{
    1183     printf("\n[ksh] ls home\n");
     1205    printf("\n[ksh] load bin/user/pgcd.elf\n");
    11841206}
    11851207
    1186 strcpy( cmd , "ls home" );
     1208strcpy( cmd , "load bin/user/pgcd.elf" );
    11871209execute( cmd );
    11881210
  • trunk/user/pgcd/pgcd.c

    r625 r626  
    1212#include <almosmkh.h>
    1313
     14#define   INSTRUMENTATION  0
     15#define   IDBG             0
     16
    1417/////////////////
    1518void main( void )
     
    1720    int                opx;
    1821    int                opy;
     22    int                x;
     23    int                y;
    1924    unsigned long long cycle;
    2025    unsigned int       cxy;
     
    2429    get_core( &cxy , &lid );
    2530
    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",
    2732    cxy , lid , (unsigned int)cycle );
    2833
    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) )
    3046    {
    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    }
    3850
    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;
    5358    }
     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
     75idbg();
     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
     90idbg();
     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
     109idbg();
     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       
    54124} // end pgcd
    55125
  • trunk/user/sort/sort.c

    r625 r626  
    2929#include <hal_macros.h>
    3030
    31 #define ARRAY_LENGTH        256        // number of items
     31#define ARRAY_LENGTH        1024       // number of items
    3232#define MAX_THREADS         1024       // 16 * 16 * 4
    3333
     
    3838#define CHECK_RESULT        0          // for debug
    3939#define INSTRUMENTATION     1          // register computation times on file
     40#define IDBG                0          // activate interactive debug in main
    4041
    4142/////////////////////////////////////////////////////////////
     
    439440#if INSTRUMENTATION
    440441
    441     char   name[64];
    442     char   path[128];
     442    char               name[64];
     443    char               path[128];
     444    unsigned long long instru_cycle;
    443445
    444446    // build a file name from n_items / n_clusters / n_cores
     
    461463           name, sequencial, parallel );
    462464
     465#if IDBG
     466idbg();
     467#endif
     468
    463469    // open file
     470    get_cycle( &instru_cycle );
    464471    FILE * stream = fopen( path , NULL );
     472
    465473    if( stream == NULL )
    466474    {
    467         printf("\n[sort error] cannot open instrumentation file <%s>\n", name );
     475        printf("\n[sort error] cannot open instrumentation file <%s>\n", path );
    468476        exit(0);
    469477    }
    470478
    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
     482idbg();
     483#endif
    472484
    473485    // register results to file
     486    get_cycle( &instru_cycle );
    474487    int ret = fprintf( stream , "\n----- %s -----\n"
    475488                                " - sequencial : %d cycles\n"
     
    477490    if( ret < 0 )
    478491    {
    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 );
    480493        exit(0);
    481494    }
    482495
    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
     499idbg();
     500#endif
    484501
    485502    // 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 );
    490509        exit(0);
    491510    }
    492511
    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 );
    494513
    495514#endif
Note: See TracChangeset for help on using the changeset viewer.