/////////////////////////////////////////////////////////////////////////////////// // File : bdv_driver.h // Date : 01/11/2013 // Author : alain greiner // Maintainer: cesar fuguet // Copyright (c) UPMC-LIP6 /////////////////////////////////////////////////////////////////////////////////// // The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel. // This driver supports the SocLib vci_block_device component, that is // a single channel, block oriented, external storage contrĂ´ler. // // The _bdv_read() and _bdv_write() functions are always blocking. // They can be called in 3 modes: // // - In BOOT mode, these functions use a polling policy on the BDV STATUS // register to detect transfer completion, as interrupts are not activated. // This mode is used by the boot code to load the map.bin file into memory // (before MMU activation), or to load the .elf files (after MMU activation). // // - In KERNEL mode, these functions use a descheduling strategy: // The ISR executed when transfer completes should restart the calling task. // There is no checking of user access right to the memory buffer. // This mode must be used, for an "open" system call. // // - In USER mode, these functions use a descheduling strategy: // The ISR executed when transfer completes should restart the calling task, // The user access right to the memory buffer must be checked. // This mode must be used for a "read/write" system call. // // As the BDV component can be used by several programs running in parallel, // the _bdv_lock variable guaranties exclusive access to the device. The // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock. // // Finally, the memory buffer must fulfill the following conditions: // - The buffer must be word aligned, // - The buffer must be mapped in user space for an user access, // - The buffer must be writable in case of (to_mem) access, // - The total number of physical pages occupied by the user buffer cannot // be larger than 512 pages if the IOMMU is activated, // - All physical pages occupied by the user buffer must be contiguous // if the IOMMU is not activated. // An error code is returned if these conditions are not verified. // // The SEG_IOC_BASE address must be defined in the hard_config.h file. /////////////////////////////////////////////////////////////////////////////////// #ifndef _GIET_BDV_DRIVER_H_ #define _GIET_BDV_DRIVER_H_ #include "locks.h" /////////////////////////////////////////////////////////////////////////////////// // BDV registers, operations and status values /////////////////////////////////////////////////////////////////////////////////// enum BDV_registers { BLOCK_DEVICE_BUFFER, BLOCK_DEVICE_LBA, BLOCK_DEVICE_COUNT, BLOCK_DEVICE_OP, BLOCK_DEVICE_STATUS, BLOCK_DEVICE_IRQ_ENABLE, BLOCK_DEVICE_SIZE, BLOCK_DEVICE_BLOCK_SIZE, BLOCK_DEVICE_BUFFER_EXT, }; enum BDV_operations { BLOCK_DEVICE_NOOP, BLOCK_DEVICE_READ, BLOCK_DEVICE_WRITE, }; enum BDV_status { BLOCK_DEVICE_IDLE, BLOCK_DEVICE_BUSY, BLOCK_DEVICE_READ_SUCCESS, BLOCK_DEVICE_WRITE_SUCCESS, BLOCK_DEVICE_READ_ERROR, BLOCK_DEVICE_WRITE_ERROR, BLOCK_DEVICE_ERROR, }; /////////////////////////////////////////////////////////////////////////////// // BDV global variables /////////////////////////////////////////////////////////////////////////////// extern spin_lock_t _bdv_lock; extern unsigned int _bdv_status; extern unsigned int _bdv_gtid; /////////////////////////////////////////////////////////////////////////////////// // Access functions /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // This function cheks block size == 512, and desactivates the interrupts. // Return 0 for success, > 0 if error /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _bdv_init(); /////////////////////////////////////////////////////////////////////////////////// // Transfer data from the block device to a memory buffer. // - mode : BOOT / KERNEL / USER // - lba : first block index on the block device // - buffer : base address of the memory buffer (must be word aligned) // - count : number of blocks to be transfered. // Returns 0 if success, > 0 if error. //////////////////////////////////////////////////////////////////////////////////// extern unsigned int _bdv_read( unsigned int mode, unsigned int lba, unsigned long long buffer, unsigned int count ); /////////////////////////////////////////////////////////////////////////////////// // Transfer data from a memory buffer to the block device. // - mode : BOOT / KERNEL / USER // - lba : first block index on the block device // - buffer : base address of the memory buffer (must be word aligned) // - count : number of blocks to be transfered. // Returns 0 if success, > 0 if error. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _bdv_write( unsigned int mode, unsigned int lba, unsigned long long buffer, unsigned int count ); /////////////////////////////////////////////////////////////////////////////////// // Returns device status. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _bdv_get_status(); /////////////////////////////////////////////////////////////////////////////////// // Returns block size. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _bdv_get_block_size(); /////////////////////////////////////////////////////////////////////////////////// // This ISR save the status, acknowledge the IRQ, and activates the task // waiting on IO transfer. It can be an HWI or a SWI. // // TODO the _set_task_slot access should be replaced by an atomic LL/SC // when the CTX_RUN bool will be replaced by a bit_vector. /////////////////////////////////////////////////////////////////////////////////// extern void _bdv_isr( unsigned irq_type, unsigned irq_id, unsigned channel ); #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