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