Index: /soft/giet_vm/giet_drivers/cma_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/cma_driver.c	(revision 298)
+++ /soft/giet_vm/giet_drivers/cma_driver.c	(revision 298)
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File      : cma_driver.c
+// Date      : 01/03/2014
+// Author    : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_chbuf_dma component, that is
+// a multi channels, chained buffer DMA controller.
+//
+// This component can be used in conjonction with the SocLib vci_frame_buffer 
+// to display images, or with the SocLib vci_multi_nic controller to tranfer
+// both RX and TX packets between NIC and memory buffers.
+///////////////////////////////////////////////////////////////////////////////////
+// Implementation notes:
+// 1. The higher level access functions can be found in the fbf_driver and 
+//    nic_driver files.
+// 2. All accesses to CMA registers are done by the two
+//    _cma_set_register() and _cma_get_register() low-level functions,
+//    that are handling virtual / physical extended addressing.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <cma_driver.h>
+#include <utils.h>                  // for seg_cma_base
+#include <hard_config.h>            // for X_IO / Y_IO
+
+///////////////////////////////////////////////////////////////////////////////
+// This low_level function returns the value contained in register (index).
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _cma_get_register( unsigned int channel,
+                                unsigned int index )
+{
+    unsigned int* vaddr = (unsigned int*)&seg_cma_base + 
+                           CHBUF_CHANNEL_SPAN*channel + index;
+    return _io_extended_read( vaddr );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This low-level function set a new value in register (index).
+///////////////////////////////////////////////////////////////////////////////
+void _cma_set_register( unsigned int channel,
+                        unsigned int index,
+                        unsigned int value ) 
+{
+    unsigned int* vaddr = (unsigned int*)&seg_cma_base + 
+                           CHBUF_CHANNEL_SPAN*channel + index;
+    _io_extended_write( vaddr, value );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This ISR handles the IRQ generated by a CMA channel.
+///////////////////////////////////////////////////////////////////////////////
+void _cma_isr( unsigned int irq_type,
+               unsigned int irq_id,
+               unsigned int channel )
+{
+    _printf("\n[GIET ERROR] _cma_isr() nor implemented\n");
+    _exit();
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_drivers/dma_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/dma_driver.c	(revision 297)
+++ /soft/giet_vm/giet_drivers/dma_driver.c	(revision 298)
@@ -174,7 +174,8 @@
 }
 ///////////////////////////////////////////////////////////////////////////////////
-// This function copies a source memory buffer to a destnation memory buffer, 
+// This function copies a source memory buffer to a destination memory buffer, 
 // using the distributed DMA. As it makes virtual to physical address translation, 
-// the MMU should be activated. As there is one DMA channel per processor, 
+// the MMU should be activated. 
+// This driver makes the assumption that each processor has a private DMA channel: 
 // the DMA cluster and channel indexes are obtained from the processor index.
 // The source and destination buffers base addresses must be word aligned, 
@@ -196,6 +197,4 @@
     unsigned int procid    = _get_procid();
     unsigned int cluster_xy = procid/NB_PROCS_MAX;
-    unsigned int x          = cluster_xy >> Y_WIDTH;
-    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     unsigned int channel_id = procid%NB_PROCS_MAX;
 
Index: /soft/giet_vm/giet_drivers/iob_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/iob_driver.c	(revision 297)
+++ /soft/giet_vm/giet_drivers/iob_driver.c	(revision 298)
@@ -8,6 +8,8 @@
 // This driver supports the TSAR vci_io_bridge, that is a bridge to access
 // The external peripherals, implementing an IO_MMU.
+// This component can be instanciated in more than one cluster.
 ///////////////////////////////////////////////////////////////////////////////////
 // The seg_iob_base virtual base addresses must be defined in giet_vsegs.ld file.
+// The physical base address is supposed to be (cluster_xy << 32) | seg_iob_base.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -24,23 +26,80 @@
 #endif
 
+
 ///////////////////////////////////////////////////////////////////////////////
-//      _iob_inval_tlb_entry()
+// This low level function returns the value contained in register "index"
+// in the IOB component contained in cluster "cluster_xy"
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _iob_get_register( unsigned int cluster_xy,   // cluster index
+                                unsigned int index )       // register index
+{
+    unsigned long long paddr = (unsigned long long)(unsigned int)&seg_iob_base + 
+                               ((unsigned long long)cluster_xy << 32) +
+                               ((unsigned long long)index << 2);
+
+    return _physical_read( paddr );
+}
+///////////////////////////////////////////////////////////////////////////////
+// This low level function sets a new value in register "index"
+// in the IOB component contained in cluster "cluster_xy"
+///////////////////////////////////////////////////////////////////////////////
+void _iob_set_register( unsigned int cluster_xy,       // cluster index
+                        unsigned int index,            // register index
+                        unsigned int value )           // value to be written
+{
+    unsigned long long paddr = (unsigned long long)(unsigned int)&seg_iob_base + 
+                               ((unsigned long long)cluster_xy << 32) +
+                               ((unsigned long long)index << 2);
+
+    _physical_write( paddr, value );
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
 // This function invalidates a TLB entry identified by a virtual address.
-// Returns 0 if success, returns 1 if failure
 ///////////////////////////////////////////////////////////////////////////////
-unsigned int _iob_inval_tlb_entry( unsigned int vaddr )
+void _iob_inval_tlb_entry( unsigned int cluster_xy,
+                           unsigned int vaddr )
 {
-#if USE_IOB
+    _iob_set_register( cluster_xy,
+                       IOB_INVAL_PTE,
+                       vaddr );
+}
 
-    unsigned int * iob_address = (unsigned int *) &seg_iob_base ;
-    iob_address[IOB_INVAL_PTE] = vaddr;
-    return 0; 
+///////////////////////////////////////////////////////////////////////////////
+// This function sets a new value in IOB_IOMMU_PTPR register.
+///////////////////////////////////////////////////////////////////////////////
+void _iob_set_iommu_ptpr( unsigned int cluster_xy,
+                          unsigned int value )
+{
+    _iob_set_register( cluster_xy,
+                       IOB_IOMMU_PTPR,
+                       value );
+}
 
-#else
+///////////////////////////////////////////////////////////////////////////////
+// This function sets a new value in IOB_XICU_BASE register.
+///////////////////////////////////////////////////////////////////////////////
+void _iob_set_xicu_base( unsigned int cluster_xy,
+                         unsigned int value )
+{
+    _iob_set_register( cluster_xy,
+                       IOB_XICU_BASE,
+                       value );
+}
 
-    return 1;
+///////////////////////////////////////////////////////////////////////////////
+// This function sets a new value in IOB_XICU_SIZE register.
+///////////////////////////////////////////////////////////////////////////////
+void _iob_set_xicu_size( unsigned int cluster_xy,
+                         unsigned int value )
+{
+    _iob_set_register( cluster_xy,
+                       IOB_XICU_SIZE,
+                       value );
+}
 
-#endif
-}
 
 
Index: /soft/giet_vm/giet_drivers/iob_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/iob_driver.h	(revision 297)
+++ /soft/giet_vm/giet_drivers/iob_driver.h	(revision 298)
@@ -10,19 +10,34 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// TSAR IOB (vci_io_bridge) registers offsets
+// vci_io_bridge : registers offsets and iommu error codes
 ///////////////////////////////////////////////////////////////////////////////////
 
 enum IOB_registers 
 {
-    IOB_IOMMU_PTPR       = 0, /* R/W : Page Table Pointer Register */
-    IOB_IOMMU_ACTIVE     = 1, /* R/W : IOMMU activated if not 0 */
-    IOB_IOMMU_BVAR       = 2, /* R   : Bad Virtual Address (unmapped) */
-    IOB_IOMMU_ETR        = 3, /* R   : Error Type */
-    IOB_IOMMU_BAD_ID     = 4, /* R   : Faulty Peripheral Index */
-    IOB_INVAL_PTE        = 5, /* W   : Invalidate a PTE (virtual address) */
-    IOB_IT_ADDR_IOMMU_LO = 6, /* W/R : 32 LSB bits for IOMMU IT*/
-    IOB_IT_ADDR_IOMMU_HI = 7, /* W/R : 32 MSB bits for IOMMU IT */
-    IOB_IT_ADDRESS_BEGIN = 8, /* R/W : Peripheral IT address (2 32 bits registers) */
+    IOB_IOMMU_PTPR       = 0,      // R/W : Page Table Pointer Register
+    IOB_IOMMU_ACTIVE     = 1,      // R/W : IOMMU activated if not 0
+    IOB_IOMMU_BVAR       = 2,      // R   : Bad Virtual Address (unmapped) 
+    IOB_IOMMU_ETR        = 3,      // R   : Error Type 
+    IOB_IOMMU_BAD_ID     = 4,      // R   : Faulty Peripheral Index (SRCID)
+    IOB_INVAL_PTE        = 5,      // W   : Invalidate a PTE (virtual address)
+    IOB_WTI_ENABLE       = 6,      // R/W : Enable WTIs (both IOMMU and peripherals)
+    IOB_WTI_ADDR_LO      = 7,      // W/R : 32 LSB bits for IOMMU WTI
+    IOB_WTI_ADDR_HI      = 8,      // W/R : 32 MSB bits for IOMMU WTI
+    IOB_XICU_BASE        = 9,      // R/W : XICU pbase address in cluster 0
+    IOB_XICU_SIZE        = 10,     // R/W : XICU segment size 
 };
+
+enum mmu_error_type_e 
+{
+    MMU_NONE                      = 0x0000, // None
+    MMU_WRITE_ACCES_VIOLATION     = 0x0008, // Write access to a non writable page 
+    MMU_WRITE_PT1_ILLEGAL_ACCESS  = 0x0040, // Write Bus Error accessing Table 1       
+    MMU_READ_PT1_UNMAPPED 	      = 0x1001, // Read  Page fault on Page Table 1  	
+    MMU_READ_PT2_UNMAPPED 	      = 0x1002, // Read  Page fault on Page Table 2  
+    MMU_READ_PT1_ILLEGAL_ACCESS   = 0x1040, // Read  Bus Error in Table1 access      
+    MMU_READ_PT2_ILLEGAL_ACCESS   = 0x1080, // Read  Bus Error in Table2 access 	
+    MMU_READ_DATA_ILLEGAL_ACCESS  = 0x1100, // Read  Bus Error in cache access 
+};
+
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -30,7 +45,15 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _iob_inval_tlb_entry( unsigned int vaddr );
+extern void _iob_inval_tlb_entry( unsigned int cluster_xy,
+                                  unsigned int vaddr );
 
-extern unsigned int _iob_set_iommu_ptpr( unsigned int value );
+extern void _iob_set_iommu_ptpr(  unsigned int cluster_xy,
+                                  unsigned int value );
+
+extern void _iob_set_xicu_base(   unsigned int cluster_xy,
+                                  unsigned int value );
+
+extern void _iob_set_xicu_size(   unsigned int cluster_xy,
+                                  unsigned int value );
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_drivers/mmc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 297)
+++ /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 298)
@@ -123,5 +123,12 @@
                unsigned int channel )  // unused
 {
-    _printf("[GIET ERROR] MMC IRQ received, but _mmc_isr() not implemented...\n");
+    unsigned int procid     = _get_procid();
+    unsigned int cluster_xy = procid / NB_PROCS_MAX;
+    unsigned int lpid       = procid % NB_PROCS_MAX;
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+    _printf("[GIET ERROR] MMC IRQ received by processor[%d,%d,%d]"
+            " but _mmc_isr() not implemented...\n", x, y, lpid );
 }
 
Index: /soft/giet_vm/giet_drivers/pic_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/pic_driver.c	(revision 298)
+++ /soft/giet_vm/giet_drivers/pic_driver.c	(revision 298)
@@ -0,0 +1,71 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : pic_driver.c
+// Date     : 05/03/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The pic_driver.c and pic_drivers.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_iopic component.
+//
+// The seg_pic_base address must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+// Implementation note:
+// 
+// All physical accesses to device registers are done by the two
+// _pic_get_register(), _pic_set_register() low-level functions,
+// that are handling virtual / physical addressing.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <pic_driver.h>
+#include <utils.h>
+
+/////////////////////////////////////////////////////////////////////////////////
+// This low level function returns the value of register (channel / index)
+/////////////////////////////////////////////////////////////////////////////////
+unsigned int _pic_get_register( unsigned int channel,
+                                unsigned int index )
+{
+    unsigned int* vaddr = (unsigned int*)&seg_pic_base + channel*IOPIC_SPAN + index;
+    return _io_extended_read( vaddr );
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// This low level function set a new value in register (channel / index)  
+/////////////////////////////////////////////////////////////////////////////////
+void _pic_set_register( unsigned int channel,
+                        unsigned int index,
+                        unsigned int value )
+{
+    unsigned int* vaddr = (unsigned int*)&seg_pic_base + channel*IOPIC_SPAN + index;
+    _io_extended_write( vaddr, value );
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// This function initializes the XICU target physical address corresponding
+// to a given HWI channel.
+/////////////////////////////////////////////////////////////////////////////////
+void _pic_init( unsigned int channel,      // source PIC HWI channel
+                unsigned int vaddr,        // dest XCU WTI address
+                unsigned int extend )      // dest XCU cluster_xy
+{
+    _pic_set_register( channel, IOPIC_ADDRESS, vaddr );
+    _pic_set_register( channel, IOPIC_EXTEND, extend );
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// This function returns the status of a given HWI channel.
+/////////////////////////////////////////////////////////////////////////////////
+unsigned int _pic_get_status( unsigned int channel )
+{
+    return _pic_get_register( channel, IOPIC_STATUS );
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_drivers/pic_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/pic_driver.h	(revision 298)
+++ /soft/giet_vm/giet_drivers/pic_driver.h	(revision 298)
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : pic_driver.h
+// Date     : 05/03/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_PIC_DRIVERS_H_
+#define _GIET_PIC_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// PIC (vci_iopic) registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum PIC_registers 
+{
+    IOPIC_ADDRESS = 0,
+    IOPIC_EXTEND  = 1,
+    IOPIC_STATUS  = 2,
+    /**/
+    IOPIC_SPAN    = 4,
+};
+
+//////////////////////////////////////////////////////////////////////////////////
+// PIC access functions
+//////////////////////////////////////////////////////////////////////////////////
+
+extern void _pic_init( unsigned int channel,     // source PIC HWI channel
+                       unsigned int vaddr,       // dest XCU WTI address
+                       unsigned int extend );    // dest XCU cluster_xy
+
+extern unsigned int _pic_get_status( unsigned int channel ); 
+
+///////////////////////////////////////////////////////////////////////////////////
+// low-level access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _pic_get_register( unsigned int channel,
+                                       unsigned int index );
+
+extern void _pic_set_register( unsigned int channel,
+                               unsigned int index,
+                               unsigned int value );
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_drivers/rdk_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/rdk_driver.c	(revision 298)
+++ /soft/giet_vm/giet_drivers/rdk_driver.c	(revision 298)
@@ -0,0 +1,125 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File      : rdk_driver.c
+// Date      : 13/02/2014
+// Author    : alain greiner
+// Maintainer: cesar fuguet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.
+//
+// This driver supports a virtual disk implemented as a memory segment, 
+// in the address space. 
+//
+// The _rdk_read() and _rdk_write() blocking functions use a software memcpy,
+// whatever the selected mode. They return only when the transfer is completed.
+// As the number of concurrent accesses is not bounded, these functions
+// don't use the _ioc_lock variable.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <rdk_driver.h>
+#include <utils.h>
+#include <tty_driver.h>
+#include <ctx_handler.h>
+
+///////////////////////////////////////////////////////////////////////////////
+//       _rdk_init()
+// This function does nothing, and return 0 for success.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _rdk_init( unsigned int channel )
+{
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _rdk_read()
+// Transfer data from the RAMDISK to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : virtual base address of the memory buffer
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _rdk_read( unsigned int lba, 
+                        unsigned int buffer, 
+                        unsigned int count) 
+{
+
+#if GIET_DEBUG_IOC_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[IOC DEBUG] Enter _rdk_read() at cycle ");
+_putd( _get_proctime() );
+_puts(" for processor ");
+_putd( _get_procid() );
+_puts("\n - vaddr   = ");
+_putx( buffer );
+_puts("\n - sectors = ");
+_putd( count );
+_puts("\n - lba     = ");
+_putx( lba );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    char* src = (char*)&seg_ram_disk_base + (512*lba);
+    char* dst = (char*)buffer;
+    _memcpy( dst, src, count*512 );
+
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _rdk_write()
+// Transfer data from a memory buffer to the block device. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : virtual base address of the memory buffer 
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _rdk_write( unsigned int lba, 
+                         unsigned int buffer, 
+                         unsigned int count ) 
+{
+
+#if GIET_DEBUG_IOC_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[IOC DEBUG] Enter _rdk_write() at cycle ");
+_putd( _get_proctime() );
+_puts(" for processor ");
+_putd( _get_procid() );
+_puts("\n - vaddr   = ");
+_putx( buffer );
+_puts("\n - sectors = ");
+_putd( count );
+_puts("\n - lba     = ");
+_putx( lba );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    char* dst = (char*)&seg_ram_disk_base + (512*lba);
+    char* src = (char*)buffer;
+    _memcpy( dst, src, count*512 );
+
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _rdk_get_block_size()
+// This function returns the block_size.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _rdk_get_block_size() 
+{
+    return 512;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /soft/giet_vm/giet_drivers/rdk_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/rdk_driver.h	(revision 298)
+++ /soft/giet_vm/giet_drivers/rdk_driver.h	(revision 298)
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File      : rdk_driver.h
+// Date      : 13/02/2014
+// Author    : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_RDK_DRIVERS_H_
+#define _GIET_RDK_DRIVERS_H_
+
+#include <mapping_info.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// BDV access functions and variables (vci_block_device)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _rdk_init();
+
+extern unsigned int _rdk_write( unsigned int lba, 
+                                unsigned int buffer, 
+                                unsigned int count );
+
+extern unsigned int _rdk_read(  unsigned int lba, 
+                                unsigned int buffer,
+                                unsigned int count );
+
+extern unsigned int _rdk_get_block_size();
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
