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.c
13  * @author Microchip-FPGA Embedded Systems Solutions
14  * @brief CLINT access data structures and functions.
15  *
16  */
17 #include <stdint.h>
18 #include "mpfs_hal/mss_hal.h"
19 
20 static uint64_t g_systick_increment[5] = {0ULL,0ULL,0ULL,0ULL,0ULL};
21 
22 /**
23  * call once at startup
24  * @return
25  */
reset_mtime(void)26 void reset_mtime(void)
27 {
28 #if ROLLOVER_TEST
29     CLINT->MTIME = 0xFFFFFFFFFFFFF000ULL;
30 #else
31     CLINT->MTIME = 0ULL;
32 #endif
33 }
34 
35 /**
36  * readmtime
37  * @return mtime
38  */
readmtime(void)39 uint64_t readmtime(void)
40 {
41     return (CLINT->MTIME);
42 }
43 
44 /**
45  * Configure system tick
46  * @return SUCCESS or FAIL
47  */
SysTick_Config(void)48 uint32_t SysTick_Config(void)
49 {
50     const uint32_t tick_rate[5] = {HART0_TICK_RATE_MS,    HART1_TICK_RATE_MS    ,HART2_TICK_RATE_MS    ,HART3_TICK_RATE_MS    ,HART4_TICK_RATE_MS};
51     volatile uint32_t ret_val = ERROR;
52 
53     uint64_t mhart_id = read_csr(mhartid);
54 
55     /*
56      * We are assuming the tick rate is in milli-seconds
57      *
58      * convert RTC frequency into milliseconds and multiple by the tick rate
59      *
60      */
61 
62     g_systick_increment[mhart_id] = ((LIBERO_SETTING_MSS_RTC_TOGGLE_CLK/1000U)  * tick_rate[mhart_id]);
63 
64     if (g_systick_increment[mhart_id] > 0ULL)
65     {
66 
67         CLINT->MTIMECMP[mhart_id] = CLINT->MTIME + g_systick_increment[mhart_id];
68 
69         set_csr(mie, MIP_MTIP);   /* mie Register - Machine Timer Interrupt Enable */
70 
71         __enable_irq();
72 
73         ret_val = SUCCESS;
74     }
75 
76     return (ret_val);
77 }
78 
79 /**
80  * Disable system tick interrupt
81  */
disable_systick(void)82 void disable_systick(void)
83 {
84     clear_csr(mie, MIP_MTIP);   /* mie Register - Machine Timer Interrupt Enable */
85     return;
86 }
87 
88 
89 /*------------------------------------------------------------------------------
90  * RISC-V interrupt handler for machine timer interrupts.
91  */
handle_m_timer_interrupt(void)92 void handle_m_timer_interrupt(void)
93 {
94 
95     volatile uint64_t hart_id = read_csr(mhartid);
96     volatile uint32_t error_loop;
97     clear_csr(mie, MIP_MTIP);
98 
99     switch(hart_id)
100     {
101         case 0U:
102             SysTick_Handler_h0_IRQHandler();
103             break;
104         case 1U:
105             SysTick_Handler_h1_IRQHandler();
106             break;
107         case 2U:
108             SysTick_Handler_h2_IRQHandler();
109             break;
110         case 3U:
111             SysTick_Handler_h3_IRQHandler();
112             break;
113         case 4U:
114             SysTick_Handler_h4_IRQHandler();
115             break;
116         default:
117             while (hart_id != 0U)
118              {
119                  error_loop++;
120              }
121             break;
122     }
123 
124     CLINT->MTIMECMP[read_csr(mhartid)] = CLINT->MTIME + g_systick_increment[hart_id];
125 
126     set_csr(mie, MIP_MTIP);
127 
128 }
129 
130 
131 /**
132  *
133  */
handle_m_soft_interrupt(void)134 void handle_m_soft_interrupt(void)
135 {
136     volatile uint64_t hart_id = read_csr(mhartid);
137     volatile uint32_t error_loop;
138 
139     switch(hart_id)
140     {
141         case 0U:
142             Software_h0_IRQHandler();
143             break;
144         case 1U:
145             Software_h1_IRQHandler();
146             break;
147         case 2U:
148             Software_h2_IRQHandler();
149             break;
150         case 3U:
151             Software_h3_IRQHandler();
152             break;
153         case 4U:
154             Software_h4_IRQHandler();
155             break;
156         default:
157             while (hart_id != 0U)
158             {
159                 error_loop++;
160             }
161             break;
162     }
163 
164     /*Clear software interrupt*/
165     clear_soft_interrupt();
166 }
167 
168