/*
 * soclib_bdv.h - SOCLIB_BDV (simple block device) driver definition.
 *
 * Author    Alain Greiner (2016,2017,2018)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _SOCLIB_BDV_H_
#define _SOCLIB_BDV_H_

#include <chdev.h>
#include <hal_kernel_types.h>

/********************************************************************************************
 * This driver supports the SocLib VciBlockDevice component, that is a simgle channel,
 * block oriented, external storage controler, supporting only one I/O transaction,
 * at a given time.
 *******************************************************************************************/

/********************************************************************************************
 *       SOCLIB_BDV registers offset 
 *******************************************************************************************/

enum SoclibBlockDeviceRegisters
{
    BDV_BUFFER_REG     = 0,
    BDV_LBA_REG	       = 1,
    BDV_COUNT_REG      = 2,
    BDV_OP_REG	       = 3,
    BDV_STATUS_REG	   = 4,
    BDV_IRQ_ENABLE_REG = 5,
    BDV_SIZE_REG       = 6,
    BDV_BLOCK_SIZE_REG = 7,
    BDV_BUFFER_EXT_REG = 8,
};

/********************************************************************************************
 *       SOCLIB_BDV status values
 *******************************************************************************************/

#define BDV_IDLE	        0
#define BDV_BUSY	        1
#define BDV_READ_SUCCESS	2
#define BDV_WRITE_SUCCESS	3
#define BDV_READ_ERROR	    4
#define BDV_WRITE_ERROR	    5
#define BDV_ERROR	        6

/********************************************************************************************
 *        SOCLIB_BDV operations 
 *******************************************************************************************/

#define BDV_OP_NOP          0
#define BDV_OP_READ         1
#define BDV_OP_WRITE        2

/********************************************************************************************
 * This function access the SOCLIB_BDV hardware registers to get the block size and the
 * number of blocks, and initialises the "extension" field of the IOC device descriptor.
 ********************************************************************************************
 * @ chdev     : local pointer on the generic IOC chdev descriptor.
 *******************************************************************************************/
extern void soclib_bdv_init( chdev_t * chdev );

/********************************************************************************************
 * This function is called by the server thread associated to the IOC device.
 * It decode the IOC device command embedded in the calling thread descriptor,
 * (format defined in the dev_ioc.h file) and starts execution of this generic command, 
 * accessing the relevant SOCLIB_BDV hardware registers.
 * Then it blocks on the THREAD_BLOCKED_DEV_ISR and deschedule, because the SOCLIB_BDV 
 * device cannot register several commands. It is re-activated by the ISR signaling the
 * I/O operation completion.
 ********************************************************************************************
 * @ thread_xp  : extended pointer on the client thread.
 *******************************************************************************************/
extern void soclib_bdv_cmd( xptr_t thread_xp );

/********************************************************************************************
 * This Interrupt Service Routine is executed when the IRQ signaling the completion of 
 * an IOC command is received by a core. It acknowledge the IRQ by accessing the proper
 * SOCLIB_BDV register, unblock the client thread, and unblock the server thread that
 * can starts execution of a new command if the waiting queue is not emppty.
 ********************************************************************************************
 * @ chdev     : local pointer on the generic IOC device descriptor.
 *******************************************************************************************/
extern void soclib_bdv_isr( chdev_t * chdev );


#endif /* _BLOCK_H_ */
