NMSIS-Core  Version 1.0.0-HummingBird
NMSIS-Core support for HummingBird RISC-V processor-based devices
system_hbird.c
1 /*
2  * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
3  * Copyright (c) 2019 HBIRD Limited. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the License); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 /******************************************************************************
20  * @file system_hbird.c
21  * @brief NMSIS HummingBird RISC-V Core Device Peripheral Access Layer Source File for
22  * HummingBird RISC-V evaluation SoC which support HummingBird RISC-V cores
23  * @version V1.00
24  * @date 14. Jul 2020
25  ******************************************************************************/
26 #include <stdint.h>
27 #include <stdio.h>
28 #include "hbird_sdk_hal.h"
29 
30 /*----------------------------------------------------------------------------
31  Define clocks
32  *----------------------------------------------------------------------------*/
33 /* ToDo: add here your necessary defines for device initialization
34  following is an example for different system frequencies */
35 #ifndef SYSTEM_CLOCK
36 #define SYSTEM_CLOCK (80000000UL)
37 #endif
38 
70 /*----------------------------------------------------------------------------
71  System Core Clock Variable
72  *----------------------------------------------------------------------------*/
73 /* ToDo: initialize SystemCoreClock with the system core clock frequency value
74  achieved after system intitialization.
75  This means system core clock frequency after call to SystemInit() */
88 uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Clock Frequency (Core Clock) */
89 
90 /*----------------------------------------------------------------------------
91  Clock functions
92  *----------------------------------------------------------------------------*/
93 
101 void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
102 {
103  /* ToDo: add code to calculate the system frequency based upon the current
104  * register settings.
105  * Note: This function can be used to retrieve the system core clock frequeny
106  * after user changed register settings.
107  */
108  SystemCoreClock = SYSTEM_CLOCK;
109 }
110 
119 void SystemInit (void)
120 {
121  /* ToDo: add code to initialize the system
122  * Warn: do not use global variables because this function is called before
123  * reaching pre-main. RW section maybe overwritten afterwards.
124  */
125  SystemCoreClock = SYSTEM_CLOCK;
126 }
127 
139 #define MAX_SYSTEM_EXCEPTION_NUM 11
140 
147 static unsigned long SystemExtInterruptHandlers[__PLIC_INTNUM];
148 static unsigned long SystemCoreInterruptHandlers[10];
149 
156 typedef void (*EXC_HANDLER) (unsigned long mcause, unsigned long sp);
157 typedef void (*INT_HANDLER) (unsigned long mcause, unsigned long sp);
158 
159 static uint32_t core_exception_handler(unsigned long mcause, unsigned long sp);
160 
167 static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
168 {
169  /* TODO: Uncomment this if you have implement printf function */
170  printf("Trap in Exception\r\n");
171  printf("MCAUSE: 0x%lx\r\n", mcause);
172  printf("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
173  printf("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MBADADDR));
174  while(1);
175 }
176 
182 static void system_default_interrupt_handler(unsigned long mcause, unsigned long sp)
183 {
184  /* TODO: Uncomment this if you have implement printf function */
185  printf("Trap in Interrupt\r\n");
186  printf("MCAUSE: 0x%lx\r\n", mcause);
187  printf("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
188  printf("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MBADADDR));
189 }
190 
198 static void Exception_Init(void)
199 {
200  for (int i = 0; i < MAX_SYSTEM_EXCEPTION_NUM; i++) {
202  }
203 }
204 
212 static void Interrupt_Init(void)
213 {
214  int i;
215  for (i = 0; i < __PLIC_INTNUM; i++) {
217  }
218  for (i = 0; i < 10; i++) {
220  }
221 }
222 
230 void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
231 {
232  if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
233  SystemExceptionHandlers[EXCn] = exc_handler;
234  }
235 }
236 
244 void Interrupt_Register_CoreIRQ(uint32_t irqn, unsigned long int_handler)
245 {
246  if ((irqn <= 10) && (irqn >= 0)) {
247  SystemCoreInterruptHandlers[irqn] = int_handler;
248  }
249 }
250 
258 void Interrupt_Register_ExtIRQ(uint32_t irqn, unsigned long int_handler)
259 {
260  if ((irqn <= __PLIC_INTNUM) && (irqn >= 0)) {
261  SystemExtInterruptHandlers[irqn] = int_handler;
262  }
263 }
264 
271 unsigned long Interrupt_Get_CoreIRQ(uint32_t irqn)
272 {
273  if ((irqn <= 10) && (irqn >= 0)) {
274  return SystemCoreInterruptHandlers[irqn];
275  }
276  return 0;
277 }
278 
285 unsigned long Interrupt_Get_ExtIRQ(uint32_t irqn)
286 {
287  if ((irqn <= __PLIC_INTNUM) && (irqn >= 0)) {
288  return SystemExtInterruptHandlers[irqn];
289  }
290  return 0;
291 }
292 
300 unsigned long Exception_Get_EXC(uint32_t EXCn)
301 {
302  if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
303  return SystemExceptionHandlers[EXCn];
304  } else {
305  return 0;
306  }
307 }
308 
321 uint32_t core_trap_handler(unsigned long mcause, unsigned long sp)
322 {
323  if (mcause & MCAUSE_INTERRUPT) {
324  INT_HANDLER int_handler = NULL;
325  uint32_t irqn = (uint32_t)(mcause & 0X00000fff);
326  if (irqn == IRQ_M_EXT) {
327 #if defined(__PLIC_PRESENT) && __PLIC_PRESENT == 1
328  irqn = PLIC_ClaimInterrupt();
329  if (irqn < __PLIC_INTNUM) {
330  int_handler = (INT_HANDLER)(SystemExtInterruptHandlers[irqn]);
331  if (int_handler != NULL) {
332  int_handler(mcause, sp);
333  }
335  }
336 #endif
337  } else {
338  int_handler = (INT_HANDLER)(SystemCoreInterruptHandlers[irqn]);
339  if (int_handler != NULL) {
340  int_handler(mcause, sp);
341  }
342  }
343  return 0;
344  } else {
345  return core_exception_handler(mcause, sp);
346  }
347 }
348 
360 static uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
361 {
362  uint32_t EXCn = (uint32_t)(mcause & 0X00000fff);
363  EXC_HANDLER exc_handler;
364 
365  if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
366  exc_handler = (EXC_HANDLER)SystemExceptionHandlers[EXCn];
367  } else {
369  }
370  if (exc_handler != NULL) {
371  exc_handler(mcause, sp);
372  }
373  return 0;
374 } /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
376 
379 {
380 #if defined(HBIRD_BANNER) && (HBIRD_BANNER == 1)
381  printf("HummingBird SDK Build Time: %s, %s\r\n", __DATE__, __TIME__);
382 #ifdef DOWNLOAD_MODE_STRING
383  printf("Download Mode: %s\r\n", DOWNLOAD_MODE_STRING);
384 #endif
385  printf("CPU Frequency %lu Hz\r\n", SystemCoreClock);
386 #endif
387 }
388 
399 int32_t Core_Register_IRQ(uint32_t irqn, void *handler)
400 {
401  if ((irqn > 10)) {
402  return -1;
403  }
404 
405  if (handler != NULL) {
406  /* register interrupt handler entry to core handlers */
407  Interrupt_Register_CoreIRQ(irqn, (unsigned long)handler);
408  }
409  switch (irqn) {
410  case SysTimerSW_IRQn:
411  __enable_sw_irq();
412  break;
413  case SysTimer_IRQn:
415  break;
416  default:
417  break;
418  }
419 
420  return 0;
421 }
422 
423 #if defined(__PLIC_PRESENT) && __PLIC_PRESENT == 1
424 
435 int32_t PLIC_Register_IRQ(uint32_t source, uint8_t priority, void *handler)
436 {
437  if ((source >= __PLIC_INTNUM)) {
438  return -1;
439  }
440 
441  /* set interrupt priority */
442  PLIC_SetPriority(source, priority);
443  if (handler != NULL) {
444  /* register interrupt handler entry to external handlers */
445  Interrupt_Register_ExtIRQ(source, (unsigned long)handler);
446  }
447  /* enable interrupt */
448  PLIC_EnableInterrupt(source);
450  return 0;
451 }
452 #endif
453  /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
454 
463 void _premain_init(void)
464 {
465  /* TODO: Add your own initialization code here, called before main */
466  SystemCoreClock = get_cpu_freq();
467 #if ! defined(SIMULATION_SPIKE) && ! defined(SIMULATION_XLSPIKE)
468  gpio_iof_config(GPIO, IOF0_UART0_MASK, IOF_SEL_0);
469  uart_init(SOC_DEBUG_UART, 115200);
470 #endif
471  /* Display banner after UART initialized */
473  /* Initialize exception default handlers */
474  Exception_Init();
475  /* Initialize Interrupt default handlers */
476  Interrupt_Init();
477 #if defined(__PLIC_PRESENT) && __PLIC_PRESENT == 1
478  /* PLIC initilization */
479  PLIC_Init(__PLIC_INTNUM);
480 #endif
481 }
482 
491 void _postmain_fini(int status)
492 {
493  /* TODO: Add your own finishing code here, called after main */
494 #ifdef SIMULATION_XLSPIKE
495 extern void xlspike_exit(int status);
496  xlspike_exit(status);
497 #endif
498 #ifdef SIMULATION_SPIKE
499 extern void spike_exit(int status);
500  spike_exit(status);
501 #endif
502 }
503 
513 void _init(void)
514 {
515  /* Don't put any code here, please use _premain_init now */
516 }
517 
527 void _fini(void)
528 {
529  /* Don't put any code here, please use _postmain_fini now */
530 
531 }
532  /* End of Doxygen Group NMSIS_Core_SystemAndClock */
SysTimer_IRQn
@ SysTimer_IRQn
System Timer Interrupt.
Definition: core_feature_plic.h:105
SystemBannerPrint
void SystemBannerPrint(void)
Banner Print for HummingBird SDK.
Definition: system_hbird.c:378
PLIC_Init
__STATIC_FORCEINLINE void PLIC_Init(uint32_t num_sources)
Perform init for plic of current hart.
Definition: core_feature_plic.h:314
__enable_timer_irq
__STATIC_FORCEINLINE void __enable_timer_irq(void)
Enable Timer IRQ Interrupts.
Definition: core_feature_base.h:397
Interrupt_Get_ExtIRQ
unsigned long Interrupt_Get_ExtIRQ(uint32_t irqn)
Get an external interrupt handler for external interrupt number.
Definition: system_hbird.c:285
__enable_sw_irq
__STATIC_FORCEINLINE void __enable_sw_irq(void)
Enable software IRQ Interrupts.
Definition: core_feature_base.h:419
system_default_exception_handler
static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
System Default Exception Handler.
Definition: system_hbird.c:167
IRQ_M_EXT
#define IRQ_M_EXT
Definition: riscv_encoding.h:180
SystemCoreInterruptHandlers
static unsigned long SystemCoreInterruptHandlers[10]
Definition: system_hbird.c:148
SystemCoreClockUpdate
void SystemCoreClockUpdate(void)
Function to update the variable SystemCoreClock.
Definition: system_hbird.c:101
INT_HANDLER
void(* INT_HANDLER)(unsigned long mcause, unsigned long sp)
Definition: system_hbird.c:157
PLIC_EnableInterrupt
__STATIC_FORCEINLINE void PLIC_EnableInterrupt(uint32_t source)
Enable interrupt for selected source plic.
Definition: core_feature_plic.h:169
SystemExceptionHandlers
static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]
Store the exception handlers for each exception ID.
Definition: system_hbird.c:146
MAX_SYSTEM_EXCEPTION_NUM
#define MAX_SYSTEM_EXCEPTION_NUM
Max exception handler number.
Definition: system_hbird.c:139
MCAUSE_INTERRUPT
#define MCAUSE_INTERRUPT
Definition: riscv_encoding.h:126
__enable_ext_irq
__STATIC_FORCEINLINE void __enable_ext_irq(void)
Enable External IRQ Interrupts.
Definition: core_feature_base.h:375
SystemCoreClock
uint32_t SystemCoreClock
Variable to hold the system core clock value.
Definition: system_hbird.c:88
Exception_Register_EXC
void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
Register an exception handler for exception code EXCn.
Definition: system_hbird.c:230
Interrupt_Register_ExtIRQ
void Interrupt_Register_ExtIRQ(uint32_t irqn, unsigned long int_handler)
Register an external interrupt handler for plic external interrupt number.
Definition: system_hbird.c:258
Exception_Init
static void Exception_Init(void)
Initialize all the default core exception handlers.
Definition: system_hbird.c:198
EXC_HANDLER
void(* EXC_HANDLER)(unsigned long mcause, unsigned long sp)
Exception Handler Function Typedef.
Definition: system_hbird.c:156
PLIC_Register_IRQ
int32_t PLIC_Register_IRQ(uint32_t source, uint8_t priority, void *handler)
Register a specific plic interrupt and register the handler.
Definition: system_hbird.c:435
Interrupt_Get_CoreIRQ
unsigned long Interrupt_Get_CoreIRQ(uint32_t irqn)
Get an core interrupt handler for core interrupt number.
Definition: system_hbird.c:271
Interrupt_Init
static void Interrupt_Init(void)
Initialize all the default interrupt handlers.
Definition: system_hbird.c:212
__RV_CSR_READ
#define __RV_CSR_READ(csr)
CSR operation Macro for csrr instruction.
Definition: core_feature_base.h:245
SystemExtInterruptHandlers
static unsigned long SystemExtInterruptHandlers[__PLIC_INTNUM]
Definition: system_hbird.c:147
SystemInit
void SystemInit(void)
Function to Initialize the system.
Definition: system_hbird.c:119
Core_Register_IRQ
int32_t Core_Register_IRQ(uint32_t irqn, void *handler)
Register a riscv core interrupt and register the handler.
Definition: system_hbird.c:399
core_trap_handler
uint32_t core_trap_handler(unsigned long mcause, unsigned long sp)
Common trap entry.
Definition: system_hbird.c:321
PLIC_CompleteInterrupt
__STATIC_FORCEINLINE void PLIC_CompleteInterrupt(uint32_t source)
Complete interrupt for plic of current hart.
Definition: core_feature_plic.h:296
Exception_Get_EXC
unsigned long Exception_Get_EXC(uint32_t EXCn)
Get current exception handler for exception code EXCn.
Definition: system_hbird.c:300
system_default_interrupt_handler
static void system_default_interrupt_handler(unsigned long mcause, unsigned long sp)
System Default Interrupt Handler.
Definition: system_hbird.c:182
PLIC_ClaimInterrupt
__STATIC_FORCEINLINE uint32_t PLIC_ClaimInterrupt(void)
Claim interrupt for plic of current hart.
Definition: core_feature_plic.h:271
SysTimerSW_IRQn
@ SysTimerSW_IRQn
System Timer SW interrupt.
Definition: core_feature_plic.h:101
PLIC_SetPriority
__STATIC_FORCEINLINE void PLIC_SetPriority(uint32_t source, uint32_t priority)
Set interrupt priority for selected source plic.
Definition: core_feature_plic.h:232
Interrupt_Register_CoreIRQ
void Interrupt_Register_CoreIRQ(uint32_t irqn, unsigned long int_handler)
Register an core interrupt handler for core interrupt number.
Definition: system_hbird.c:244
CSR_MBADADDR
#define CSR_MBADADDR
Definition: riscv_encoding.h:333
core_exception_handler
static uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
Common Exception handler entry.
Definition: system_hbird.c:360
CSR_MEPC
#define CSR_MEPC
Definition: riscv_encoding.h:331