/* * dev_mmc.h - MMC (Generic L2 cache controller) device API definition. * * Authors 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 _DEV_MMC_H_ #define _DEV_MMC_H_ #include #include /***************************************************************************************** * Generic L2 cache controller definition * * The MMC (Memory Cache Controller) device describes an internal peripheral, * acting in all clusters containing a level 2 cache controller. * * It supports five command types: * - MMC_CC_INVAL : invalidate all cache lines covering a given buffer in L2 cache. * - MMC_CC_SYNC : synchronize all cache lines covering a given buffer to L3 cache. * - MMC_GET_ERROR : return content of a given error signaling register. * - MMC_SET_ERROR : set a given error signaling register. * - MMC_GET_INSTRU : return content of a given instrumentation register. * * As all L2 caches can be accessed by any thread running in any cluster, a calling * thread must get exclusive access to the MMC configuration interface. * As these operations consume few cycles, and access conflicts are expected to be * rare events, the calling threads use a busy waiting strategy to get the device * busylock, but do not register in the device waiting queue, and no server thread * is used for this device. ****************************************************************************************/ /**** Forward declarations ****/ struct chdev_s; /****************************************************************************************** * This enum defines the various implementations of the generic MMC peripheral. * It must be kept consistent with the define in arch_info.h file. *****************************************************************************************/ enum mmc_impl_e { IMPL_MMC_TSR = 0, } mmc_impl_t; /***************************************************************************************** * This structure defines the (implementation independant) command pased to the driver. * To have a fixed format, the arguments interpretation depends on the command type. ****************************************************************************************/ enum { MMC_CC_INVAL = 0, MMC_CC_SYNC = 1, MMC_GET_ERROR = 2, MMC_SET_ERROR = 3, MMC_GET_INSTRU = 4, }; typedef struct mmc_command_s { xptr_t dev_xp; /*! extended pointer on target MMC device descriptor */ uint32_t type; /*! CC_INVAL / CC_SYNC / GET_ERROR / SET_ERROR / GET_INSTRU */ void * buf_ptr; /*! local pointer on memory buffer (used by INVAL/SYNC) */ uint32_t buf_size; /*! memory buffer size (bytes) (used by INVAL/SYNC) */ uint32_t reg_index; /*! register index in MMC peripheral (used by SET/GET) */ uint32_t * reg_ptr; /*! local pointer on src/dst buffer (used by SET/GET) */ error_t error; /*! operation status (0 if success) */ } mmc_command_t; /***************************************************************************************** * This function initializes the driver specific fields in the generic MMC device * descriptor, and the implementation specific driver. * It must be executed once in any cluster containing an L2 cache. ***************************************************************************************** * @ chdev : pointer on MMC device descriptor. ****************************************************************************************/ void dev_mmc_init( struct chdev_s * chdev ); /***************************************************************************************** * This function invalidates all cache lines covering a memory buffer * in the physical address space. * It can be executed by any thread in any cluster, because it uses remote accesses * to access both the MMC device descriptor, and the L2 cache configuration interface. ***************************************************************************************** * @ buf_xp : extended pointer on memory buffer. * @ buf_size : buffer size (bytes). * @ return 0 if success / return EINVAL if failure ****************************************************************************************/ error_t dev_mmc_inval( xptr_t buf_xp, uint32_t buf_size ); /***************************************************************************************** * This function forces the L2 cache to synchronize the L3 cache for all cache lines * covering a memory buffer in the physical address space. * It can be executed by any thread in any cluster, because it uses remote accesses * to access both the MMC device descriptor, and the L2 cache configuration interface. ***************************************************************************************** * @ buf_xp : extended pointer on memory buffer. * @ buf_size : buffer size (bytes). * @ return 0 if success / return EINVAL if failure ****************************************************************************************/ error_t dev_mmc_sync( xptr_t buf_xp, uint32_t buf_size ); /***************************************************************************************** * This function set a value in one error signaling MMC register. * It can be executed by any thread in any cluster, because it uses remote accesses * to access the L2 cache instrumentation interface in any cluster. ***************************************************************************************** * @ cxy : MMC cluster identifier. * @ index : register index in MMC peripheral. * @ wdata : value to be written. * @ return 0 if success / return EINVAL if failure ****************************************************************************************/ error_t dev_mmc_set_error( cxy_t cxy, uint32_t index, uint32_t wdata ); /***************************************************************************************** * This function returns the value contained in one error signaling MMC register. * It can be executed by any thread in any cluster, because it uses remote accesses * to access the L2 cache instrumentation interface in any cluster. ***************************************************************************************** * @ cxy : MMC cluster identifier. * @ index : error register index in MMC peripheral. * @ rdata : local pointer on buffer for returned value. * @ return 0 if success / return EINVAL if failure ****************************************************************************************/ error_t dev_mmc_get_error( cxy_t cxy, uint32_t index, uint32_t * rdata ); /***************************************************************************************** * This function returns the value contained in one instrumentation MMC register. * It can be executed by any thread in any cluster, because it uses remote accesses * to access the L2 cache configuration interface in any cluster. ***************************************************************************************** * @ cxy : MMC cluster identifier. * @ index : instrumentation register index in MMC peripheral. * @ rdata : local pointer on buffer for returned value. * @ return 0 if success / return EINVAL if failure ****************************************************************************************/ error_t dev_mmc_get_instrumentation( cxy_t cxy, uint32_t index, uint32_t * rdata ); #endif /* _DEV_MMC_H_ */