1 /******************************************************************************* 2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * MPFS HAL Embedded Software 7 * 8 */ 9 10 /******************************************************************************* 11 * 12 * @file mss_clint.h 13 * @author Microchip-FPGA Embedded Systems Solutions 14 * @brief CLINT access data structures and functions. 15 * 16 */ 17 #ifndef MSS_CLINT_H 18 #define MSS_CLINT_H 19 20 #include <stdint.h> 21 #include "encoding.h" 22 #include "atomic.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #define RTC_PRESCALER 100U 29 #define SUCCESS 0U 30 #define ERROR 1U 31 32 33 /*============================================================================== 34 * CLINT: Core Local Interrupter 35 */ 36 typedef struct CLINT_Type_t 37 { 38 volatile uint32_t MSIP[5]; 39 volatile uint32_t reserved1[(0x4000U - 0x14U)/4U]; 40 volatile uint64_t MTIMECMP[5]; /* mtime compare value for each hart. When mtime equals this value, interrupt is generated for particular hart */ 41 volatile uint32_t reserved2[((0xbff8U - 0x4028U)/4U)]; 42 volatile uint64_t MTIME; /* contains the current mtime value */ 43 } CLINT_Type; 44 45 #define CLINT ((CLINT_Type *)CLINT_BASE) 46 47 48 /*============================================================================== 49 * The function raise_soft_interrupt() raises a synchronous software interrupt by 50 * writing into the MSIP register. 51 */ raise_soft_interrupt(unsigned long hart_id)52static inline void raise_soft_interrupt(unsigned long hart_id) 53 { 54 /*You need to make sure that the global interrupt is enabled*/ 55 /*Note: set_csr(mie, MIP_MSIP) needs to be set on hart you are setting sw interrupt */ 56 CLINT->MSIP[hart_id] = 0x01U; /*raise soft interrupt for hart(x) where x== hart ID*/ 57 mb(); 58 } 59 60 /*============================================================================== 61 * The function clear_soft_interrupt() clears a synchronous software interrupt by 62 * clearing the MSIP register. 63 */ clear_soft_interrupt(void)64static inline void clear_soft_interrupt(void) 65 { 66 volatile uint32_t reg; 67 uint64_t hart_id = read_csr(mhartid); 68 CLINT->MSIP[hart_id] = 0x00U; /*clear soft interrupt for hart0*/ 69 reg = CLINT->MSIP[hart_id]; /* we read back to make sure it has been written before moving on */ 70 /* todo: verify line above guaranteed and best way to achieve result */ 71 (void)reg; /* use reg to avoid compiler warning */ 72 } 73 74 /* 75 * return mtime 76 */ 77 uint64_t readmtime(void); 78 79 /** 80 * call once at startup 81 * @return 82 */ 83 void reset_mtime(void); 84 85 /** 86 * Configure system tick 87 * @return SUCCESS or FAIL 88 */ 89 uint32_t SysTick_Config(void); 90 91 /** 92 * Disable system tick interrupt 93 */ 94 void disable_systick(void); 95 96 /*------------------------------------------------------------------------------ 97 * RISC-V interrupt handler for machine timer interrupts. 98 */ 99 void handle_m_timer_interrupt(void); 100 101 /** 102 * 103 */ 104 void handle_m_soft_interrupt(void); 105 106 #ifdef __cplusplus 107 } 108 #endif 109 110 #endif /* MSS_CLINT_H */ 111