   1              		.file	"miv_rv32_hal.c"
   2              		.option nopic
   3              		.attribute arch, "rv32i2p0_m2p0"
   4              		.attribute unaligned_access, 0
   5              		.attribute stack_align, 16
   6              		.text
   7              		.section	.text.MRV_systick_config,"ax",@progbits
   8              		.align	2
   9              		.globl	MRV_systick_config
  11              	MRV_systick_config:
  12 0000 B70E0000 		lui	t4,%hi(.LANCHOR0)
  13 0004 370E0000 		lui	t3,%hi(.LANCHOR1)
  14 0008 93070000 		li	a5,0
  15 000c 938E0E00 		addi	t4,t4,%lo(.LANCHOR0)
  16 0010 130E0E00 		addi	t3,t3,%lo(.LANCHOR1)
  17 0014 23A0FE00 		sw	a5,0(t4)
  18 0018 2320FE00 		sw	a5,0(t3)
  19 001c B7570002 		li	a5,33574912
  20 0020 13080000 		li	a6,0
  21 0024 83A70700 		lw	a5,0(a5)
  22 0028 23A20E01 		sw	a6,4(t4)
  23 002c 23220E01 		sw	a6,4(t3)
  24 0030 130101FF 		addi	sp,sp,-16
  25 0034 638C050C 		beq	a1,zero,.L18
  26              	.L12:
  27 0038 93061000 		li	a3,1
  28 003c 13080000 		li	a6,0
  29 0040 B7580002 		li	a7,33574912
  30 0044 6F00C000 		j	.L4
  31              	.L10:
  32 0048 93060600 		mv	a3,a2
  33 004c 13080700 		mv	a6,a4
  34              	.L4:
  35 0050 83A70800 		lw	a5,0(a7)
  36 0054 13861600 		addi	a2,a3,1
  37 0058 03A30800 		lw	t1,0(a7)
  38 005c B307F540 		sub	a5,a0,a5
  39 0060 3335F500 		sgtu	a0,a5,a0
  40 0064 3337D600 		sltu	a4,a2,a3
  41 0068 B385A540 		sub	a1,a1,a0
  42 006c 33070701 		add	a4,a4,a6
  43 0070 13850700 		mv	a0,a5
  44 0074 E39A05FC 		bne	a1,zero,.L10
  45 0078 E3F867FC 		bleu	t1,a5,.L10
  46 007c 23A0DE00 		sw	a3,0(t4)
  47 0080 23A20E01 		sw	a6,4(t4)
  48              	.L2:
  49 0084 23240100 		sw	zero,8(sp)
  50 0088 23260100 		sw	zero,12(sp)
  51 008c B7C70002 		li	a5,33603584
  52              	.L6:
  53 0090 03A7C7FF 		lw	a4,-4(a5)
  54 0094 2324E100 		sw	a4,8(sp)
  55 0098 03A787FF 		lw	a4,-8(a5)
  56 009c 2326E100 		sw	a4,12(sp)
  57 00a0 03A6C7FF 		lw	a2,-4(a5)
  58 00a4 03278100 		lw	a4,8(sp)
  59 00a8 E314E6FE 		bne	a2,a4,.L6
  60 00ac 03A7C7FF 		lw	a4,-4(a5)
  61 00b0 8327C100 		lw	a5,12(sp)
  62 00b4 33E60601 		or	a2,a3,a6
  63 00b8 33080701 		add	a6,a4,a6
  64 00bc B386D700 		add	a3,a5,a3
  65 00c0 B3B7F600 		sltu	a5,a3,a5
  66 00c4 B3870701 		add	a5,a5,a6
  67 00c8 2320DE00 		sw	a3,0(t3)
  68 00cc 2322FE00 		sw	a5,4(t3)
  69 00d0 13051000 		li	a0,1
  70 00d4 63160600 		bne	a2,zero,.L19
  71 00d8 13010101 		addi	sp,sp,16
  72 00dc 67800000 		jr	ra
  73              	.L19:
  74 00e0 37470002 		li	a4,33570816
  75 00e4 1306F0FF 		li	a2,-1
  76 00e8 2322C700 		sw	a2,4(a4)
  77 00ec 2320D700 		sw	a3,0(a4)
  78 00f0 2322F700 		sw	a5,4(a4)
  79 00f4 93070008 		li	a5,128
  80              	 #APP
  81              	# 180 "../miv_rv32_hal/miv_rv32_hal.c" 1
   1              	/*******************************************************************************
   2              	 * Copyright 2019 Microchip FPGA Embedded Systems Solutions.
   3              	 *
   4              	 * SPDX-License-Identifier: MIT
   5              	 *
   6              	 * @file miv_rv32_hal.c
   7              	 * @author Microchip FPGA Embedded Systems Solutions
   8              	 * @brief Implementation of Hardware Abstraction Layer for Mi-V soft processors
   9              	 *
  10              	 */
  11              	#include <unistd.h>
  12              	#include "miv_rv32_hal.h"
  13              	
  14              	#ifdef __cplusplus
  15              	extern "C" {
  16              	#endif
  17              	
  18              	#define SUCCESS                       0U
  19              	#define ERROR                         1U
  20              	#define MASK_32BIT                    0xFFFFFFFFu
  21              	
  22              	/*------------------------------------------------------------------------------
  23              	 *  Write in a sequence recommended by privileged spec to avoid spurious
  24              	 * interrupts
  25              	
  26              	   # New comparand is in a1:a0.
  27              	    li t0, -1
  28              	    sw t0, mtimecmp # No smaller than old value.
  29              	    sw a1, mtimecmp+4 # No smaller than new value.
  30              	    sw a0, mtimecmp # New value.
  31              	 */
  32              	#ifndef MIV_RV32_EXT_TIMECMP
  33              	#define WRITE_MTIMECMP(value)         MTIMECMPH = MASK_32BIT; \
  34              	                                      MTIMECMP  = value & MASK_32BIT;\
  35              	                                      MTIMECMPH =  (value >> 32u) & MASK_32BIT;
  36              	#else
  37              	#define WRITE_MTIMECMP(value)
  38              	#endif
  39              	
  40              	#ifndef MIV_RV32_EXT_TIMER
  41              	#define WRITE_MTIME(value)            MTIME  = value & MASK_32BIT;\
  42              	                                      MTIMEH = (value >> 32u) & MASK_32BIT;
  43              	#else
  44              	#define WRITE_MTIME(value)
  45              	#endif
  46              	
  47              	extern void Software_IRQHandler(void);
  48              	
  49              	#ifdef MIV_LEGACY_RV32
  50              	#define MTIME_PRESCALER                 100UL
  51              	/*------------------------------------------------------------------------------
  52              	 *
  53              	 */
  54              	uint8_t Invalid_IRQHandler(void);
  55              	uint8_t External_1_IRQHandler(void);
  56              	uint8_t External_2_IRQHandler(void);
  57              	uint8_t External_3_IRQHandler(void);
  58              	uint8_t External_4_IRQHandler(void);
  59              	uint8_t External_5_IRQHandler(void);
  60              	uint8_t External_6_IRQHandler(void);
  61              	uint8_t External_7_IRQHandler(void);
  62              	uint8_t External_8_IRQHandler(void);
  63              	uint8_t External_9_IRQHandler(void);
  64              	uint8_t External_10_IRQHandler(void);
  65              	uint8_t External_11_IRQHandler(void);
  66              	uint8_t External_12_IRQHandler(void);
  67              	uint8_t External_13_IRQHandler(void);
  68              	uint8_t External_14_IRQHandler(void);
  69              	uint8_t External_15_IRQHandler(void);
  70              	uint8_t External_16_IRQHandler(void);
  71              	uint8_t External_17_IRQHandler(void);
  72              	uint8_t External_18_IRQHandler(void);
  73              	uint8_t External_19_IRQHandler(void);
  74              	uint8_t External_20_IRQHandler(void);
  75              	uint8_t External_21_IRQHandler(void);
  76              	uint8_t External_22_IRQHandler(void);
  77              	uint8_t External_23_IRQHandler(void);
  78              	uint8_t External_24_IRQHandler(void);
  79              	uint8_t External_25_IRQHandler(void);
  80              	uint8_t External_26_IRQHandler(void);
  81              	uint8_t External_27_IRQHandler(void);
  82              	uint8_t External_28_IRQHandler(void);
  83              	uint8_t External_29_IRQHandler(void);
  84              	uint8_t External_30_IRQHandler(void);
  85              	uint8_t External_31_IRQHandler(void);
  86              	
  87              	
  88              	/*------------------------------------------------------------------------------
  89              	 * RISC-V interrupt handler for external interrupts.
  90              	 */
  91              	uint8_t (* const mrv_ext_irq_handler_table[32])(void) =
  92              	{
  93              	
  94              	    Invalid_IRQHandler,
  95              	    External_1_IRQHandler,
  96              	    External_2_IRQHandler,
  97              	    External_3_IRQHandler,
  98              	    External_4_IRQHandler,
  99              	    External_5_IRQHandler,
 100              	    External_6_IRQHandler,
 101              	    External_7_IRQHandler,
 102              	    External_8_IRQHandler,
 103              	    External_9_IRQHandler,
 104              	    External_10_IRQHandler,
 105              	    External_11_IRQHandler,
 106              	    External_12_IRQHandler,
 107              	    External_13_IRQHandler,
 108              	    External_14_IRQHandler,
 109              	    External_15_IRQHandler,
 110              	    External_16_IRQHandler,
 111              	    External_17_IRQHandler,
 112              	    External_18_IRQHandler,
 113              	    External_19_IRQHandler,
 114              	    External_20_IRQHandler,
 115              	    External_21_IRQHandler,
 116              	    External_22_IRQHandler,
 117              	    External_23_IRQHandler,
 118              	    External_24_IRQHandler,
 119              	    External_25_IRQHandler,
 120              	    External_26_IRQHandler,
 121              	    External_27_IRQHandler,
 122              	    External_28_IRQHandler,
 123              	    External_29_IRQHandler,
 124              	    External_30_IRQHandler,
 125              	    External_31_IRQHandler
 126              	};
 127              	
 128              	#else
 129              	/*------------------------------------------------------------------------------
 130              	 * Interrupt handlers as mapped into the MIE register of the MIV_RV32
 131              	 */
 132              	extern void Reserved_IRQHandler(void);
 133              	extern void External_IRQHandler(void);
 134              	extern void MGEUI_IRQHandler(void);
 135              	extern void MGECI_IRQHandler(void);
 136              	extern void MSYS_EI0_IRQHandler(void);
 137              	extern void MSYS_EI1_IRQHandler(void);
 138              	extern void MSYS_EI2_IRQHandler(void);
 139              	extern void MSYS_EI3_IRQHandler(void);
 140              	extern void MSYS_EI4_IRQHandler(void);
 141              	extern void MSYS_EI5_IRQHandler(void);
 142              	extern void SUBSYS_IRQHandler(void);
 143              	
 144              	#ifndef MIV_RV32_V3_0 /*For MIV_RV32 v3.1*/
 145              	extern void MSYS_EI6_IRQHandler(void);
 146              	extern void MSYS_EI7_IRQHandler(void);
 147              	extern void SUBSYSR_IRQHandler(void); // @suppress("Unused function declaration")
 148              	#endif /*MIV_RV32_V3_0*/
 149              	
 150              	#endif  /* MIV_LEGACY_RV32 */
 151              	
 152              	/*------------------------------------------------------------------------------
 153              	 * Increment value for the mtimecmp register in order to achieve a system tick
 154              	 * interrupt as specified through the MRV_systick_config() function.
 155              	 */
 156              	static uint64_t g_systick_increment = 0U;
 157              	static uint64_t g_systick_cmp_value = 0U;
 158              	
 159              	/*------------------------------------------------------------------------------
 160              	 * Configure the machine timer to generate an interrupt.
 161              	 */
 162              	uint32_t MRV_systick_config(uint64_t ticks)
 163              	{
 164              	    uint32_t ret_val = ERROR;
 165              	    uint64_t remainder = ticks;
 166              	    g_systick_increment = 0U;
 167              	    g_systick_cmp_value = 0U;
 168              	
 169              	    while (remainder >= MTIME_PRESCALER)
 170              	    {
 171              	        remainder -= MTIME_PRESCALER;
 172              	        g_systick_increment++;
 173              	    }
 174              	
 175              	    g_systick_cmp_value = g_systick_increment + MRV_read_mtime();
 176              	
 177              	    if (g_systick_increment > 0U)
 178              	    {
 179              	        WRITE_MTIMECMP(g_systick_cmp_value);
 180 00f8 F3A74730 	        set_csr(mie, MIP_MTIP);
 181              	        MRV_enable_interrupts();
  82              		csrrs a5, mie, a5
  83              	# 0 "" 2
  84              	# 617 "../miv_rv32_hal/miv_rv32_hal.h" 1
   1              	/*******************************************************************************
   2              	 * Copyright 2019 Microchip FPGA Embedded Systems Solutions.
   3              	 *
   4              	 * SPDX-License-Identifier: MIT
   5              	 * 
   6              	 * @file miv_rv32_hal.h
   7              	 * @author Microchip FPGA Embedded Systems Solutions
   8              	 * @brief Hardware Abstraction Layer functions for Mi-V soft processors
   9              	 *
  10              	 */
  11              	
  12              	/*=========================================================================*//**
  13              	  @mainpage MIV_RV32 Hardware Abstraction Layer
  14              	
  15              	  ==============================================================================
  16              	  Introduction
  17              	  ==============================================================================
  18              	  This document describes the Hardware Abstraction Layer (HAL) for the MIV_RV32 
  19              	  Soft IP Core. This release of the HAL corresponds to the Soft IP core MIV_RV32
  20              	  v3.1 release. It also supports earlier versions of the MIV_RV32 as well as the 
  21              	  legacy RV32 IP cores.
  22              	  The preprocessor macros provided with the MIV_RV32 HAL are used to customize 
  23              	  it to target the Soft Processor IP version being used in your project.
  24              	
  25              	  The term "MIV_RV32" represents following two cores:    
  26              	    - MIV_RV32 v3.0 and later (the latest and greatest Mi-V soft processor)      
  27              	    - MIV_RV32IMC v2.1 (MIV_RV32 v3.0 is a drop in replacement for this core)
  28              	  It is highly recommended to migrate your design to MIV_RV32 v3.1
  29              	 
  30              	  The term, Legacy RV32 IP cores, represents following IP cores:    
  31              	    - MIV_RV32IMA_L1_AHB     
  32              	    - MIV_RV32IMA_L1_AXI     
  33              	    - MIV_RV32IMAF_L1_AHB
  34              	
  35              	  These legacy RV32 IP cores are deprecated. It is highly recommended to migrate
  36              	  your designs to MIV_RV32 v3.1 (and subsequent IP releases) for the latest 
  37              	  enhancements, bug fixes, and support.
  38              	
  39              	  --------------------------------
  40              	  MIV_RV32 V3.1
  41              	  --------------------------------
  42              	  This is the latest release of the MIV_RV32 Soft IP core. For more details, 
  43              	  refer to the MIV_RV32 User [Guide](https://www.microchip.com/en-us/products/fpgas-and-plds/ip-cor
  44              	
  45              	  The MIV_RV32 Core as well as this document use the terms defined below:
  46              	
  47              	  --------------------------------
  48              	    - SUBSYS - Processor Subsystem for RISC-V
  49              	    - OPSRV - Offload Processor Subsystem for RISC-V
  50              	    - GPR - General Purpose Registers
  51              	    - MGECIE - Machine GPR ECC Correctable Interrupt Enable
  52              	    - MGEUIE - Machine GPR ECC Uncorrectable Interrupt Enable
  53              	    - MTIE - Machine Timer Interrupt Enable
  54              	    - MEIE - Machine External Interrupt Enable
  55              	    - MSIE - Machine Software Interrupt Enable
  56              	    - ISR - Interrupt Service Routine
  57              	
  58              	  ==============================================================================
  59              	  Customizing MIV_RV32 HAL
  60              	  ==============================================================================
  61              	  To use the HAL with older releases of MIV_RV32, preprocessor macros have been 
  62              	  provided. Using these macros, any of the IP version is targeted.
  63              	  The HAL is used to target any of the mentioned platforms by adding the 
  64              	  following macros in the way :
  65              	  Project Properties > C/C++ Build > Settings > Preprocessor in Assembler and 
  66              	  Compiler settings.
  67              	  The table below shows the macros corresponding to the MIV Core being used in 
  68              	  your libero project. By default, the HAL targets v3.1 of the IP core and no 
  69              	  macros need to be set for this configutation.
  70              	  
  71              	  | Libero MI-V Soft IP Version | SoftConsole Macro |
  72              	  |-----------------------------|-------------------|
  73              	  |       MIV_RV32 v3.1       |  no macro required  |
  74              	  |       MIV_RV32 v3.0       |    MIV_CORE_V3_0    |
  75              	  |     Legacy RV32 Cores     |    MIV_LEGACY_RV32  |
  76              	
  77              	  --------------------------------
  78              	  Interrupt Handling
  79              	  --------------------------------
  80              	  The MIE Register is defined as a enum in the HAL, and the table below is used 
  81              	  as a reference when the vectored interrupts are enabled in the GUI core
  82              	  configurator.
  83              	 
  84              	  The MIE register is a RISC-V Control and Status Register (CSR), which stands
  85              	  for the Machine Interrupt Enable. This is used to enable the machine mode
  86              	  interrupts in the MIV_RV32 hart. Refer to the RISC-V Priv spec for more details.
  87              	  
  88              	  The following table shows the trap entry addresses when an interrupt occurs and
  89              	  the vectored interrupts are enabled in the GUI configurator.
  90              	  
  91              	  | MIE Register Bit  | Interrupt Enable | Vector Address |
  92              	  |-------------------|------------------|----------------|
  93              	  |        31         |     MSYS_IE7     |  mtvec.BASE + 0x7C   |
  94              	  |        30         |     MSYS_IE6     |  mtvec.BASE + 0x78   |
  95              	  |        29         |     MSYS_IE5     |  mtvec.BASE + 0x74   |
  96              	  |        28         |     MSYS_IE4     |  mtvec.BASE + 0x70   |
  97              	  |        27         |     MSYS_IE3     |  mtvec.BASE + 0x6C   |
  98              	  |        26         |     MSYS_IE2     |  mtvec.BASE + 0x68   |
  99              	  |        25         |     MSYS_IE1     |  mtvec.BASE + 0x64   |
 100              	  |        24         |     MSYS_IE0     |  mtvec.BASE + 0x60   |
 101              	  |        23         |    SUBSYS_EI     |  mtvec.BASE + 0x5C   |
 102              	  |        22         |     SUBSYSR      |  mtvec.BASE + 0x58   |
 103              	  |        17         |      MGECIE      |  mtvec.BASE + 0x44   |
 104              	  |        16         |      MGEUIE      |  mtvec.BASE + 0x40   |
 105              	  |        11         |       MEIE       |  mtvec.BASE + 0x2C   |
 106              	  |         7         |       MTIE       |  mtvec.BASE + 0x1C   |
 107              	  |         3         |       MSIE       |  mtvec.BASE + 0x0C   |
 108              	
 109              	  
 110              	  For changes in MIE register map, see the [MIE Register Map for MIV_RV32 v3.0]
 111              	  (#mie-register-map-for-miv_rv32-v3.0) section. 
 112              	  
 113              	  SUBSYSR is currently not being used by the core and is Reserved for future use.
 114              	
 115              	  The mtvec.BASE field corresponds to the bits [31:2], where mtvec stands for 
 116              	  Machine Trap Vector, and all traps set the PC to the the value stored in the 
 117              	  mtvec.BASE field when in Non-Vectored mode. In this case, a generic trap 
 118              	  handler is as an interrupt service routine.
 119              	
 120              	  When Vectored interrupts are enabled, use this formula to calculate the trap
 121              	  address: (mtvec.BASE + 4*cause), where cause comes from the mcause CSR. The 
 122              	  mcause register is written with a code indicating the event that caused the trap.
 123              	  For more details, see the RISC-V priv specification. 
 124              	
 125              	  The MIV_RV32 Soft IP core does not contain a Platfrom Level Interrup Controller 
 126              	  (PLIC). It is advised to use the PLIC contained within the MIV_ESS sub-system.
 127              	  Connect the PLIC interrupt output of the MIV_ESS to the EXT_IRQ pin on the 
 128              	  MIV_RV32.
 129              	
 130              	  The following table is the MIE register map for the MIV_RV32 Core V3.0. It only
 131              	  highlights the differences between the V3.0 and V3.1 of the core.
 132              	
 133              	  --------------------------------
 134              	  MIE Register Map for MIV_RV32 V3.0 
 135              	  --------------------------------
 136              	   
 137              	  | MIE Register Bit  | Target Interrupt | Vector Address |
 138              	  |-------------------|------------------|----------------|
 139              	  |        31         |    Not in use    |   top table   |
 140              	  |        30         |     SUBSYS_EI    |  addr + 0x78   |
 141              	  |        23         |    Not in use    |   Not in use   |
 142              	  |        22         |    Not in use    |   Not in use   |
 143              	
 144              	  Other interrupt bit postions like the MGEUIE and MSYS_IE5 to MSYS_IE0 remain 
 145              	  unchanged.
 146              	
 147              	  --------------------------------
 148              	  Floating Point Interrupt Support
 149              	  --------------------------------
 150              	  When an interrupt is taken and Floating Point instructions are used in the 
 151              	  ISR, the floating point register context must be saved to resume the application
 152              	  correctly. To use this feature, enable the provided macro in the 
 153              	  Softconsole build settings.
 154              	  This feature is turned off by default as it adds overhead which is not required 
 155              	  when the ISR does not used FP insturctions and saving the general purpose 
 156              	  register context is sufficient.
 157              	
 158              	  |       Macro Name       |                    Definition                     |
 159              	  |--------------------------|-------------------------------------------------|
 160              	  |    MIV_FP_CONTEXT_SAVE   |     Define to save the FP register file         |
 161              	
 162              	  
 163              	  --------------------------------
 164              	  SUBSYS - SubSystem for RISC-V
 165              	  --------------------------------
 166              	  SUBSYS stands for SubSystem for RISC-V. This was previously (MIV_RV32 v3.0) 
 167              	  known as OPSRV, which stands for "Offload Processor Subsystem
 168              	  for RISC-V". See the earlier versions of the handbook for more details.
 169              	  In the latest release of the MIV_RV32 IP core v3.1, OPSRV has been renamed to 
 170              	  SUBSYS. The MIV_RV32 HAL now uses SUBSYS instead of OPSRV.
 171              	
 172              	 *//*=========================================================================*/
 173              	#ifndef RISCV_HAL_H
 174              	#define RISCV_HAL_H
 175              	
 176              	#include "miv_rv32_regs.h"
 177              	#include "miv_rv32_plic.h"
 178              	#include "miv_rv32_assert.h"
 179              	#include "miv_rv32_subsys.h"
 180              	
 181              	#ifndef LEGACY_DIR_STRUCTURE
 182              	#include "fpga_design_config/fpga_design_config.h"
 183              	#else
 184              	#include "hw_platform.h"
 185              	#endif  /*LEGACY_DIR_STRUCTURE*/
 186              	
 187              	#ifdef __cplusplus
 188              	extern "C" {
 189              	#endif
 190              	/*-------------------------------------------------------------------------*//**
 191              	  SUBSYS Backwards Compatibility 
 192              	  =======================================
 193              	  For application code using the older macro names and API functions, these macros
 194              	  act as a compatibility layer and applications which use OPSRV API features work 
 195              	  due to these macro definitions. However, it is adviced to update your
 196              	  application code to use the SUBSYS macros and API functions.
 197              	   
 198              	  |      Macro Name         |       Now Called         |
 199              	  |-------------------------|--------------------------|
 200              	  | OPSRV_TCM_ECC_CE_IRQ    | SUBSYS_TCM_ECC_CE_IRQ    | 
 201              	  | OPSRV_TCM_ECC_UCE_IRQ   | SUBSYS_TCM_ECC_UCE_IRQ   | 
 202              	  | OPSRV_AXI_WR_RESP_IRQ   | SUBSYS_AXI_WR_RESP_IRQ   | 
 203              	  | MRV32_MSYS_OPSRV_IRQn   | MRV32_SUBSYS_IRQn        | 
 204              	  | MRV32_opsrv_enable_irq  | MRV32_subsys_enable_irq  | 
 205              	  | MRV32_opsrv_disable_irq | MRV32_subsys_disable_irq | 
 206              	  | MRV32_opsrv_clear_irq   | MRV32_subsys_clear_irq   | 
 207              	  | OPSRV_IRQHandler        | SUBSYS_IRQHandler        |
 208              	 */
 209              	
 210              	/*-------------------------------------------------------------------------*//**
 211              	  MTIME Timer Interrupt Constants
 212              	  =======================================
 213              	  These values contain the register addresses for the registers used by the 
 214              	  machine timer interrupt
 215              	
 216              	  MTIME_PRESCALER is not defined on the MIV_RV32IMC v2.0 and v2.1. By using this
 217              	  definition the system crashes. For those core, use the following definition:
 218              	
 219              	  #define MTIME_PRESCALER              100u
 220              	
 221              	  MTIME and MTIMECMP
 222              	  --------------------------------
 223              	  MIV_RV32 core offers flexibility in terms of generating MTIME and MTIMECMP 
 224              	  registers internal to the core or using external time reference. There four
 225              	  possible combinations:
 226              	
 227              	  - Internal MTIME and Internal MTIME IRQ enabled Generate the MTIME and MTIMECMP
 228              	  registers internally. (The only combination available on legacy RV32 cores)
 229              	
 230              	  - Internal MTIME enabled and Internal MTIME IRQ disabled Generate the MTIME 
 231              	  internally and have a timer interrupt input to the core as external pin. In 
 232              	  this case, 1 pin port will be available on MIV_RV32 for timer interrupt.
 233              	
 234              	  - When the internal MTIME is disabled, and the Internal MTIME IRQ is enabled, the
 235              	  system generates the time value externally and generates the mtimecmp and 
 236              	  interrupt internally (for example, a multiprocessor system with a shared time 
 237              	  between all cores). In this case, a 64-bit port is available on the MIV_RV32 
 238              	  core as input.
 239              	
 240              	  - Internal MTIME and Internal MTIME IRQ disabled Generate both the time and 
 241              	  timer interrupts externally. In this case a 64 bit port will be available on 
 242              	  the MIV_RV32 core as input, and a 1 pin port will be available for timer 
 243              	  interrupt.
 244              	
 245              	  To handle all these combinations in the firmware, the following constants must 
 246              	  be defined in accordance with the configuration that you have made on your 
 247              	  MIV_RV32 core design.
 248              	
 249              	  MIV_RV32_EXT_TIMER
 250              	  --------------------------------
 251              	  When defined, it means that the MTIME register is not available internal to 
 252              	  the core. In this case, a 64 bit port will be available on the MIV_RV32 core as
 253              	  input. When this macro is not defined, it means that the MTIME register is 
 254              	  available internally to the core.
 255              	
 256              	  MIV_RV32_EXT_TIMECMP
 257              	  --------------------------------
 258              	  When defined, it means the MTIMECMP register is not available internally to 
 259              	  the core and the Timer interrupt input to the core comes as an external pin. 
 260              	  When this macro is not defined it means the that MTIMECMP register exists 
 261              	  internal to the core and that the timer interrupt is generated internally.
 262              	
 263              	NOTE: All these macros must not be defined if you are using a MIV_RV32 core.
 264              	 */
 265              	
 266              	#define OPSRV_TCM_ECC_CE_IRQ                SUBSYS_TCM_ECC_CE_IRQ
 267              	#define OPSRV_TCM_ECC_UCE_IRQ               SUBSYS_TCM_ECC_UCE_IRQ
 268              	#define OPSRV_AXI_WR_RESP_IRQ               SUBSYS_AXI_WR_RESP_IRQ
 269              	#define MRV32_MSYS_OPSRV_IRQn               MRV32_SUBSYS_IRQn
 270              	#define MRV32_opsrv_enable_irq              MRV32_subsys_enable_irq
 271              	#define MRV32_opsrv_disable_irq             MRV32_subsys_disable_irq
 272              	#define MRV32_opsrv_clear_irq               MRV32_subsys_clear_irq
 273              	#define OPSRV_IRQHandler                    SUBSYS_IRQHandler
 274              	
 275              	/*-------------------------------------------------------------------------*//**
 276              	  External IRQ
 277              	  =======================================
 278              	  Return value from External IRQ handler. This is used to disable the
 279              	  External Interrupt.
 280              	  
 281              	  | Macro Name  | Value |  Description|
 282              	  |-------------------|--------|----------------|
 283              	  | EXT_IRQ_KEEP_ENABLED  |    0    |  Keep external interrupts enabled |
 284              	  | EXT_IRQ_DISABLE       |    1    |  Disable external interrupts      |
 285              	 */
 286              	#define EXT_IRQ_KEEP_ENABLED                0U
 287              	#define EXT_IRQ_DISABLE                     1U
 288              	
 289              	#define MTIME_DELTA                     5
 290              	#ifdef MIV_LEGACY_RV32
 291              	#define MSIP                            (*(uint32_t*)0x44000000UL)
 292              	#define MTIMECMP                        (*(uint32_t*)0x44004000UL)
 293              	#define MTIMECMPH                       (*(uint32_t*)0x44004004UL)
 294              	#define MTIME                           (*(uint32_t*)0x4400BFF8UL)
 295              	#define MTIMEH                          (*(uint32_t*)0x4400BFFCUL)
 296              	
 297              	/* To maintain backward compatibility with FreeRTOS config code */
 298              	#define PRCI_BASE                       0x44000000UL
 299              	#else /* MIV_LEGACY_RV32 */
 300              	
 301              	/* To maintain backward compatibility with FreeRTOS config code */
 302              	#define PRCI_BASE                       0x02000000UL
 303              	
 304              	#ifndef MIV_RV32_EXT_TIMECMP
 305              	#define MTIMECMP                        (*(volatile uint32_t*)0x02004000UL)
 306              	#define MTIMECMPH                       (*(volatile uint32_t*)0x02004004UL)
 307              	#else
 308              	#define MTIMECMP                        (0u)
 309              	#define MTIMECMPH                       (0u)
 310              	#endif
 311              	
 312              	#define MTIME_PRESCALER                 (*(volatile uint32_t*)0x02005000UL)
 313              	
 314              	#ifndef MIV_RV32_EXT_TIMER
 315              	#define MTIME                           (*(volatile uint32_t*)0x0200BFF8UL)
 316              	#define MTIMEH                          (*(volatile uint32_t*)0x0200BFFCUL)
 317              	
 318              	/***************************************************************************//**
 319              	  MIMPID Register
 320              	  The MIMPID register is a RISC-V Control and Status Register In the v3.0 of 
 321              	  MIV_RV32, the value of `MIMPID = 0x000540AD`. In the v3.1 of MIV_RV32, the 
 322              	  value if `MIMPID = 0xE5010301` corresponding to (E)mbedded (5)ystem(01) core 
 323              	  version (03).(01) this terminology will be followed in the subsequent releases 
 324              	  of the core read the csr value and store it in a varible which may be used to 
 325              	  check the MIV_RV32 core version during runtime.
 326              	
 327              	  Future releases of the core will increment the 03 and 01 as major and minor 
 328              	  releases respectively and the register can be read at runtime to find the 
 329              	  Soft IP core version.
 330              	
 331              	  |  Core Version  |  Register  |  Value  |  Notes  |
 332              	  |----------------|------------|---------|---------|
 333              	  |  MIV_RV32 V3.1  |  mimpid |   0xE5010301  | implimentation ID |
 334              	  |  MIV_RV32 V3.0  |  mimpid |   0x000540AD  | implimentation ID |
 335              	 */
 336              	#define MIMPID                          read_csr(mimpid)
 337              	
 338              	/*Used as a mask to read and write to mte mtvec.BASE address*/
 339              	#define MTVEC_BASE_ADDR_MASK            0xFFFFFFFC
 340              	
 341              	#else
 342              	#define MTIME                           (0u)
 343              	#define MTIMEH                          (0u)
 344              	#endif  /*MIV_RV32_EXT_TIMER*/
 345              	
 346              	/*-------------------------------------------------------------------------*//**
 347              	  RISC-V Specification Interrupts
 348              	  =======================================
 349              	  These definitions are provided for easy identification of the interrupt
 350              	  in the MIE/MIP registers.
 351              	  Apart from the standard software, timer, and external interrupts, the names
 352              	  of the additional interrupts correspond to the names as used in the MIV_RV32
 353              	  handbook. Please refer the MIV_RV32 handbook for more details.
 354              	 
 355              	  All the interrups, provided by the MIV_RV32 core, follow the interrupt priority
 356              	  order and register description as mentioned in the RISC-V spec.
 357              	
 358              	  | Macro Name  | Value |  Description|
 359              	  |-------------------|--------|----------------|
 360              	  | MRV32_SOFT_IRQn   | MIE_3_IRQn  |  Software interrupt enable  |
 361              	  | MRV32_TIMER_IRQn  | MIE_7_IRQn  |  Timer interrupt enable     |
 362              	  | MRV32_EXT_IRQn    | MIE_11_IRQn |  External interrupt enable  |
 363              	
 364              	 */
 365              	#define MRV32_SOFT_IRQn                 MIE_3_IRQn
 366              	#define MRV32_TIMER_IRQn                MIE_7_IRQn
 367              	#define MRV32_EXT_IRQn                  MIE_11_IRQn
 368              	
 369              	/***************************************************************************//**
 370              	  Interrupt numbers:
 371              	  This enum represents the interrupt enable bits in the MIE register.
 372              	 */
 373              	enum
 374              	{
 375              	    MIE_0_IRQn  =  (0x01u),
 376              	    MIE_1_IRQn  =  (0x01u<<1u),
 377              	    MIE_2_IRQn  =  (0x01u<<2u),
 378              	    MIE_3_IRQn  =  (0x01u<<3u),         /*MSIE 0xC*/
 379              	    MIE_4_IRQn  =  (0x01u<<4u),
 380              	    MIE_5_IRQn  =  (0x01u<<5u),
 381              	    MIE_6_IRQn  =  (0x01u<<6u),
 382              	    MIE_7_IRQn  =  (0x01u<<7u),         /*MTIE 0x1C*/
 383              	    MIE_8_IRQn  =  (0x01u<<8u),
 384              	    MIE_9_IRQn  =  (0x01u<<9u),
 385              	    MIE_10_IRQn =  (0x01u<<10u),
 386              	    MIE_11_IRQn =  (0x01u<<11u),        /*MEIE 0x2C*/
 387              	    MIE_12_IRQn =  (0x01u<<12u),
 388              	    MIE_13_IRQn =  (0x01u<<13u),
 389              	    MIE_14_IRQn =  (0x01u<<14u),
 390              	    MIE_15_IRQn =  (0x01u<<15u),
 391              	    MIE_16_IRQn =  (0x01u<<16u),        /*MGEUIE ECC Uncorrectable 0x40*/
 392              	    MIE_17_IRQn =  (0x01u<<17u),        /*MGECIE ECC Correctable 0x44*/
 393              	    MIE_18_IRQn =  (0x01u<<18u),
 394              	    MIE_19_IRQn =  (0x01u<<19u),
 395              	    MIE_20_IRQn =  (0x01u<<20u),
 396              	    MIE_21_IRQn =  (0x01u<<21u),
 397              	    MIE_22_IRQn =  (0x01u<<22u),        /*SUBSYSR 0x58 (R)eserved*/        
 398              	    MIE_23_IRQn =  (0x01u<<23u),        /*SUBSYS_IE 0x5C for MIV_RV32 v3.1*/      
 399              	    MIE_24_IRQn =  (0x01u<<24u),        /*MSYS_IE0 0x60*/
 400              	    MIE_25_IRQn =  (0x01u<<25u),        /*MSYS_IE1 0x64*/
 401              	    MIE_26_IRQn =  (0x01u<<26u),        /*MSYS_IE2 0x68*/
 402              	    MIE_27_IRQn =  (0x01u<<27u),        /*MSYS_IE3 0x6C*/
 403              	    MIE_28_IRQn =  (0x01u<<28u),        /*MSYS_IE4 0x70*/        
 404              	    MIE_29_IRQn =  (0x01u<<29u),        /*MSYS_IE5 0x74*/
 405              	    MIE_30_IRQn =  (0x01u<<30u),        /*MSYS_IE6 0x78, read comment below*/
 406              	    MIE_31_IRQn =  (0x01u<<31u)         /*MSYS_IE7 0x7C*/
 407              	} MRV_LOCAL_IRQn_Type;
 408              	
 409              	#define MRV32_MGEUIE_IRQn               MIE_16_IRQn
 410              	#define MRV32_MGECIE_IRQn               MIE_17_IRQn
 411              	#define MRV32_MSYS_EIE0_IRQn            MIE_24_IRQn
 412              	#define MRV32_MSYS_EIE1_IRQn            MIE_25_IRQn
 413              	#define MRV32_MSYS_EIE2_IRQn            MIE_26_IRQn
 414              	#define MRV32_MSYS_EIE3_IRQn            MIE_27_IRQn
 415              	#define MRV32_MSYS_EIE4_IRQn            MIE_28_IRQn
 416              	#define MRV32_MSYS_EIE5_IRQn            MIE_29_IRQn
 417              	#ifndef MIV_RV32_V3_0 /*For MIV_RV32 v3.1*/
 418              	#define MRV32_SUBSYSR_IRQn              MIE_22_IRQn
 419              	#define MRV32_SUBSYS_IRQn               MIE_23_IRQn
 420              	#define MRV32_MSYS_EIE6_IRQn            MIE_30_IRQn
 421              	#define MRV32_MSYS_EIE7_IRQn            MIE_31_IRQn
 422              	#else
 423              	#define MRV32_SUBSYS_IRQn               MIE_30_IRQn
 424              	#endif /*MIV_RV32_V3_0*/
 425              	
 426              	/*--------------------------------Public APIs---------------------------------*/
 427              	
 428              	/***************************************************************************//**
 429              	  The MRV32_clear_gpr_ecc_errors() function clears single bit ECC errors on the 
 430              	  GPRs. The ECC block does not write back corrected data to memory. Hence, when 
 431              	  ECC is enabled for the GPRs and if that data has a single bit error then the 
 432              	  data coming out of the ECC block is corrected and will not have the error, but 
 433              	  the data source will still have the error. Therefore, if data has a single bit
 434              	  error, then the corrected data must be written back to prevent the single bit
 435              	  error from becoming a double bit error. Clear the pending interrupt bit after 
 436              	  this using MRV32_mgeci_clear_irq() function to complete the ECC error handling.
 437              	
 438              	  @param
 439              	  This function does not take any parameters.
 440              	
 441              	  @return
 442              	  This functions returns the CORE_GPR_DED_RESET_REG bit value.
 443              	  */
 444              	static inline void MRV32_clear_gpr_ecc_errors(void)
 445              	{
 446              	    uint32_t temp;
 447              	
 448              	    __asm__ __volatile__ (
 449              	            "sw x31, %0"
 450              	            :"=m" (temp));
 451              	
 452              	    __asm__ volatile (
 453              	            "mv x31, x1;"
 454              	            "mv x1, x31;"
 455              	
 456              	            "mv x31, x2;"
 457              	            "mv x2, x31;"
 458              	
 459              	            "mv x31, x3;"
 460              	            "mv x3, x31;"
 461              	
 462              	            "mv x31, x4;"
 463              	            "mv x4, x31;"
 464              	
 465              	            "mv x31, x5;"
 466              	            "mv x5, x31;"
 467              	
 468              	            "mv x31, x6;"
 469              	            "mv x6, x31;"
 470              	
 471              	            "mv x31, x7;"
 472              	            "mv x7, x31;"
 473              	
 474              	            "mv x31, x8;"
 475              	            "mv x8, x31;"
 476              	
 477              	            "mv x31, x9;"
 478              	            "mv x9, x31;"
 479              	
 480              	            "mv x31, x10;"
 481              	            "mv x10, x31;"
 482              	
 483              	            "mv x31, x11;"
 484              	            "mv x11, x31;"
 485              	
 486              	            "mv x31, x12;"
 487              	            "mv x12, x31;"
 488              	
 489              	            "mv x31, x13;"
 490              	            "mv x13, x31;"
 491              	
 492              	            "mv x31, x14;"
 493              	            "mv x14, x31;"
 494              	
 495              	            "mv x31, x15;"
 496              	            "mv x15, x31;"
 497              	
 498              	            "mv x31, x16;"
 499              	            "mv x16, x31;"
 500              	
 501              	            "mv x31, x17;"
 502              	            "mv x17, x31;"
 503              	
 504              	            "mv x31, x18;"
 505              	            "mv x18, x31;"
 506              	
 507              	            "mv x31, x19;"
 508              	            "mv x19, x31;"
 509              	
 510              	            "mv x31, x20;"
 511              	            "mv x20, x31;"
 512              	
 513              	            "mv x31, x21;"
 514              	            "mv x21, x31;"
 515              	
 516              	            "mv x31, x22;"
 517              	            "mv x22, x31;"
 518              	
 519              	            "mv x31, x23;"
 520              	            "mv x23, x31;"
 521              	
 522              	            "mv x31, x24;"
 523              	            "mv x24, x31;"
 524              	
 525              	            "mv x31, x25;"
 526              	            "mv x25, x31;"
 527              	
 528              	            "mv x31, x26;"
 529              	            "mv x26, x31;"
 530              	
 531              	            "mv x31, x27;"
 532              	            "mv x27, x31;"
 533              	
 534              	            "mv x31, x28;"
 535              	            "mv x28, x31;"
 536              	
 537              	            "mv x31, x29;"
 538              	            "mv x29, x31;"
 539              	
 540              	            "mv x31, x30;"
 541              	            "mv x30, x31;");
 542              	
 543              	    __asm__ __volatile__ (
 544              	            "lw x31, %0;"
 545              	            :
 546              	            :"m" (temp));
 547              	}
 548              	
 549              	
 550              	/***************************************************************************//**
 551              	  The MRV32_mgeui_clear_irq() function clears the GPR ECC Uncorrectable 
 552              	  Interrupt. MGEUI interrupt is available only when ECC is enabled in the MIV_RV32 
 553              	  IP configurator.
 554              	
 555              	  @return
 556              	  This function does not return any value.
 557              	 */
 558              	static inline void MRV32_mgeui_clear_irq(void)
 559              	{
 560              	    clear_csr(mip, MRV32_MGEUIE_IRQn);
 561              	}
 562              	
 563              	/***************************************************************************//**
 564              	  The MRV32_mgeci_clear_irq() function clears the GPR ECC Correctable Interrupt
 565              	  MGECI interrupt is available only when ECC is enabled in the MIV_RV32 IP 
 566              	  configurator.
 567              	
 568              	  @return 
 569              	  This function does not return any value.
 570              	 */
 571              	static inline void MRV32_mgeci_clear_irq(void)
 572              	{
 573              	    clear_csr(mip, MRV32_MGECIE_IRQn);
 574              	}
 575              	
 576              	/***************************************************************************//**
 577              	  The MRV_enable_local_irq() function enables the local interrupts. It takes a 
 578              	  mask value as input. For each set bit in the mask value, the corresponding 
 579              	  interrupt bit in the MIE register is enabled.
 580              	  
 581              	  MRV_enable_local_irq( MRV32_SOFT_IRQn | MRV32_TIMER_IRQn | MRV32_EXT_IRQn |
 582              	                        MRV32_MSYS_EIE0_IRQn |
 583              	                        MRV32_MSYS_SUBSYS_IRQn);                
 584              	 */
 585              	static inline void MRV_enable_local_irq(uint32_t mask)
 586              	{
 587              	    set_csr(mie, mask);
 588              	}
 589              	
 590              	/***************************************************************************//**
 591              	  The MRV_disable_local_irq() function disables the local interrupts. It takes a 
 592              	  mask value as input. For each set bit in the mask value, the corresponding 
 593              	  interrupt bit in the MIE register is disabled.
 594              	  
 595              	  MRV_disable_local_irq( MRV32_SOFT_IRQn | MRV32_TIMER_IRQn | MRV32_EXT_IRQn |
 596              	                         MRV32_MSYS_EIE0_IRQn |
 597              	                         MRV32_MSYS_SUBSYS_IRQn);
 598              	 */
 599              	static inline void MRV_disable_local_irq(uint32_t mask)
 600              	{
 601              	    clear_csr(mie, mask);
 602              	}
 603              	#endif /* MIV_LEGACY_RV32 */ 
 604              	
 605              	/***************************************************************************//**
 606              	  The MRV_enable_interrupts() function enables all interrupts by setting the
 607              	  machine mode interrupt enable bit in MSTATUS register.
 608              	
 609              	  @param
 610              	  This function does not take any parameters.
 611              	
 612              	  @return
 613              	  This functions returns the CORE_GPR_DED_RESET_REG bit value.
 614              	 */
 615              	static inline void MRV_enable_interrupts(void)
 616              	{
 617 00fc F3670430 	    set_csr(mstatus, MSTATUS_MIE);
 618              	}
  85              		csrrs a5, mstatus, 8
  86              	# 0 "" 2
  87              	 #NO_APP
  88 0100 13050000 		li	a0,0
  89 0104 13010101 		addi	sp,sp,16
  90 0108 67800000 		jr	ra
  91              	.L18:
  92 010c E376F5F2 		bleu	a5,a0,.L12
  93 0110 93060000 		li	a3,0
  94 0114 13080000 		li	a6,0
  95 0118 6FF0DFF6 		j	.L2
  97              		.section	.text.handle_m_timer_interrupt,"ax",@progbits
  98              		.align	2
  99              		.globl	handle_m_timer_interrupt
 101              	handle_m_timer_interrupt:
 102 0000 130101FE 		addi	sp,sp,-32
 103 0004 232E1100 		sw	ra,28(sp)
 104 0008 93070008 		li	a5,128
 105              	 #APP
 106              	# 193 "../miv_rv32_hal/miv_rv32_hal.c" 1
 182              	        ret_val = SUCCESS;
 183              	    }
 184              	
 185              	    return ret_val;
 186              	}
 187              	
 188              	/*------------------------------------------------------------------------------
 189              	 * RISC-V interrupt handler for machine timer interrupts.
 190              	 */
 191              	void handle_m_timer_interrupt(void)
 192              	{
 193 000c F3B74730 	    clear_csr(mie, MIP_MTIP);
 194              	
 107              		csrrc a5, mie, a5
 108              	# 0 "" 2
 109              	 #NO_APP
 110 0010 23240100 		sw	zero,8(sp)
 111 0014 23260100 		sw	zero,12(sp)
 112 0018 B7C70002 		li	a5,33603584
 113              	.L21:
 114 001c 03A7C7FF 		lw	a4,-4(a5)
 115 0020 2324E100 		sw	a4,8(sp)
 116 0024 03A787FF 		lw	a4,-8(a5)
 117 0028 2326E100 		sw	a4,12(sp)
 118 002c 83A6C7FF 		lw	a3,-4(a5)
 119 0030 03278100 		lw	a4,8(sp)
 120 0034 E394E6FE 		bne	a3,a4,.L21
 121 0038 03A8C7FF 		lw	a6,-4(a5)
 122 003c 0327C100 		lw	a4,12(sp)
 123 0040 370E0000 		lui	t3,%hi(.LANCHOR1)
 124 0044 130E0E00 		addi	t3,t3,%lo(.LANCHOR1)
 125 0048 930E5700 		addi	t4,a4,5
 126 004c 83274E00 		lw	a5,4(t3)
 127 0050 33B7EE00 		sltu	a4,t4,a4
 128 0054 33080701 		add	a6,a4,a6
 129 0058 03270E00 		lw	a4,0(t3)
 130 005c 63F20709 		bleu	a6,a5,.L31
 131              	.L26:
 132 0060 B7060000 		lui	a3,%hi(.LANCHOR0)
 133 0064 93860600 		addi	a3,a3,%lo(.LANCHOR0)
 134 0068 03A30600 		lw	t1,0(a3)
 135 006c 83A84600 		lw	a7,4(a3)
 136 0070 B7050000 		lui	a1,%hi(.LANCHOR2)
 137 0074 93850500 		addi	a1,a1,%lo(.LANCHOR2)
 138              	.L29:
 139 0078 83A60500 		lw	a3,0(a1)
 140 007c 33066700 		add	a2,a4,t1
 141 0080 3337E600 		sltu	a4,a2,a4
 142 0084 B3871701 		add	a5,a5,a7
 143 0088 93861600 		addi	a3,a3,1
 144 008c 3305F700 		add	a0,a4,a5
 145 0090 23A0D500 		sw	a3,0(a1)
 146 0094 93070500 		mv	a5,a0
 147 0098 13070600 		mv	a4,a2
 148 009c E36E05FD 		bgtu	a6,a0,.L29
 149 00a0 6314A800 		bne	a6,a0,.L27
 150 00a4 E36AD6FD 		bgtu	t4,a2,.L29
 151              	.L27:
 152 00a8 2320CE00 		sw	a2,0(t3)
 153 00ac 2322AE00 		sw	a0,4(t3)
 154              	.L22:
 155 00b0 B7460002 		li	a3,33570816
 156 00b4 1306F0FF 		li	a2,-1
 157 00b8 23A2C600 		sw	a2,4(a3)
 158 00bc 23A0E600 		sw	a4,0(a3)
 159 00c0 23A2F600 		sw	a5,4(a3)
 160 00c4 97000000 		call	SysTick_Handler
 160      E7800000 
 161 00cc 93070008 		li	a5,128
 162              	 #APP
 163              	# 227 "../miv_rv32_hal/miv_rv32_hal.c" 1
 195              	    uint64_t mtime_at_irq = MRV_read_mtime();
 196              	
 197              	#ifndef NDEBUG
 198              	    static volatile uint32_t d_tick = 0u;
 199              	#endif
 200              	
 201              	    while(g_systick_cmp_value < (mtime_at_irq + MTIME_DELTA)) {
 202              	        g_systick_cmp_value = g_systick_cmp_value + g_systick_increment;
 203              	
 204              	#ifndef NDEBUG
 205              	        d_tick += 1;
 206              	#endif
 207              	    }
 208              	/***************************************************************************//**
 209              	    /*
 210              	     * Note: If d_tick > 1 it means, that a system timer interrupt has been 
 211              	     * missed.
 212              	     * Please ensure that interrupt handlers are as short as possible to prevent
 213              	     * them stopping other interrupts from being handled. For example, if a
 214              	     * system timer interrupt occurs during a software interrupt, the system
 215              	     * timer interrupt will not be handled until the software interrupt handling
 216              	     * is complete. If the software interrupt handling time is more than one 
 217              	     * systick interval, it will result in d_tick > 1.
 218              	     * If you are running the program using the debugger and halt the CPU at a 
 219              	     * breakpoint, MTIME will continue to increment and interrupts will be 
 220              	     * missed; resulting in d_tick > 1.
 221              	     */
 222              	
 223              	    WRITE_MTIMECMP(g_systick_cmp_value);
 224              	
 225              	    SysTick_Handler();
 226              	
 227 00d0 F3A74730 	    set_csr(mie, MIP_MTIP);
 228              	}
 164              		csrrs a5, mie, a5
 165              	# 0 "" 2
 166              	 #NO_APP
 167 00d4 8320C101 		lw	ra,28(sp)
 168 00d8 13010102 		addi	sp,sp,32
 169 00dc 67800000 		jr	ra
 170              	.L31:
 171 00e0 E318F8FC 		bne	a6,a5,.L22
 172 00e4 E36ED7F7 		bgtu	t4,a4,.L26
 173 00e8 6FF09FFC 		j	.L22
 175              		.section	.text.handle_m_soft_interrupt,"ax",@progbits
 176              		.align	2
 177              		.globl	handle_m_soft_interrupt
 179              	handle_m_soft_interrupt:
 180 0000 130101FF 		addi	sp,sp,-16
 181 0004 23261100 		sw	ra,12(sp)
 182 0008 97000000 		call	Software_IRQHandler
 182      E7800000 
 183 0010 37670000 		li	a4,24576
 184 0014 83270702 		lw	a5,32(a4)
 185 0018 8320C100 		lw	ra,12(sp)
 186 001c 93F7D7FF 		andi	a5,a5,-3
 187 0020 2320F702 		sw	a5,32(a4)
 188 0024 13010101 		addi	sp,sp,16
 189 0028 67800000 		jr	ra
 191              		.section	.text.handle_local_ei_interrupts,"ax",@progbits
 192              		.align	2
 193              		.globl	handle_local_ei_interrupts
 195              	handle_local_ei_interrupts:
 196              	 #APP
 197              	# 306 "../miv_rv32_hal/miv_rv32_hal.c" 1
 229              	
 230              	void handle_m_soft_interrupt(void)
 231              	{
 232              	    Software_IRQHandler();
 233              	    MRV_clear_soft_irq();
 234              	}
 235              	/*------------------------------------------------------------------------------
 236              	 * RISC-V interrupt handler for software interrupts.
 237              	 */
 238              	#ifdef MIV_LEGACY_RV32
 239              	void handle_m_ext_interrupt(void)
 240              	{
 241              	    unsigned long hart_id = read_csr(mhartid);
 242              	    uint32_t int_num  = PLIC->TARGET[hart_id].CLAIM_COMPLETE;
 243              	    uint8_t disable = EXT_IRQ_KEEP_ENABLED;
 244              	
 245              	    if (0u !=int_num)
 246              	    {
 247              	        disable = mrv_ext_irq_handler_table[int_num]();
 248              	
 249              	        PLIC->TARGET[hart_id].CLAIM_COMPLETE = int_num;
 250              	
 251              	        if(EXT_IRQ_DISABLE == disable)
 252              	        {
 253              	            MRV_PLIC_disable_irq((IRQn_Type)int_num);
 254              	        }
 255              	    }
 256              	}
 257              	#else
 258              	
 259              	/*------------------------------------------------------------------------------
 260              	 * MSYS local interrupts table
 261              	 */
 262              	void (* const local_irq_handler_table[16])(void) =
 263              	{
 264              	#ifndef MIV_RV32_V3_0
 265              	    MGEUI_IRQHandler,
 266              	    MGECI_IRQHandler,
 267              	    SUBSYS_IRQHandler,
 268              	    SUBSYSR_IRQHandler,
 269              	    Reserved_IRQHandler,    
 270              	    Reserved_IRQHandler,
 271              	    Reserved_IRQHandler,
 272              	    Reserved_IRQHandler,    
 273              	    MSYS_EI0_IRQHandler,
 274              	    MSYS_EI1_IRQHandler,
 275              	    MSYS_EI2_IRQHandler,
 276              	    MSYS_EI3_IRQHandler,
 277              	    MSYS_EI4_IRQHandler,
 278              	    MSYS_EI5_IRQHandler,
 279              	    MSYS_EI6_IRQHandler,
 280              	    MSYS_EI7_IRQHandler
 281              	#else
 282              	    MGEUI_IRQHandler,
 283              	    MGECI_IRQHandler,
 284              	    Reserved_IRQHandler,    
 285              	    Reserved_IRQHandler,    
 286              	    Reserved_IRQHandler,
 287              	    Reserved_IRQHandler,
 288              	    Reserved_IRQHandler,
 289              	    Reserved_IRQHandler,
 290              	    MSYS_EI0_IRQHandler,
 291              	    MSYS_EI1_IRQHandler,
 292              	    MSYS_EI2_IRQHandler,
 293              	    MSYS_EI3_IRQHandler,
 294              	    MSYS_EI4_IRQHandler,
 295              	    MSYS_EI5_IRQHandler,
 296              	    SUBSYS_IRQHandler,
 297              	    Reserved_IRQHandler,
 298              	#endif
 299              	};
 300              	
 301              	/*------------------------------------------------------------------------------
 302              	 * Jump to interrupt table containing local interrupts
 303              	 */
 304              	void handle_local_ei_interrupts(uint8_t irq_no)
 305              	{
 306 0000 F32740F1 	    uint64_t mhart_id = read_csr(mhartid);
 307              	    ASSERT(irq_no <= MIV_LOCAL_IRQ_MAX)
 198              		csrr a5, mhartid
 199              	# 0 "" 2
 200              	 #NO_APP
 201 0004 9307F001 		li	a5,31
 202 0008 63E6A700 		bgtu	a0,a5,.L37
 203 000c 9307F000 		li	a5,15
 204 0010 63E4A700 		bgtu	a0,a5,.L36
 205              	.L37:
 206              	 #APP
 207              	# 308 "../miv_rv32_hal/miv_rv32_hal.c" 1
 308 0014 73001000 	    ASSERT(irq_no >= MIV_LOCAL_IRQ_MIN)
 309              	
 208              		ebreak
 209              	# 0 "" 2
 210              	 #NO_APP
 211              	.L36:
 212 0018 130505FF 		addi	a0,a0,-16
 213 001c 1375F50F 		andi	a0,a0,0xff
 214 0020 B7070000 		lui	a5,%hi(.LANCHOR3)
 215 0024 13152500 		slli	a0,a0,2
 216 0028 93870700 		addi	a5,a5,%lo(.LANCHOR3)
 217 002c 3385A700 		add	a0,a5,a0
 218 0030 03230500 		lw	t1,0(a0)
 219 0034 67000300 		jr	t1
 221              		.section	.text.handle_trap,"ax",@progbits
 222              		.align	2
 223              		.globl	handle_trap
 225              	handle_trap:
 226 0000 63420502 		blt	a0,zero,.L52
 227              	 #APP
 228              	# 382 "../miv_rv32_hal/miv_rv32_hal.c" 1
 310              	    uint8_t ei_no = (uint8_t)(irq_no - MIV_LOCAL_IRQ_MIN);
 311              	    (*local_irq_handler_table[ei_no])();
 312              	}
 313              	#endif /* MIV_LEGACY_RV32 */
 314              	
 315              	
 316              	/*------------------------------------------------------------------------------
 317              	 * Trap handler. This function is invoked in the non-vectored mode.
 318              	 */
 319              	void handle_trap(uintptr_t mcause, uintptr_t mepc)
 320              	{   
 321              	    uint64_t is_interrupt = mcause & MCAUSE_INT;
 322              	
 323              	    if (is_interrupt)
 324              	    {
 325              	#ifndef MIV_LEGACY_RV32
 326              	        if (((mcause & MCAUSE_CAUSE) >= MIV_LOCAL_IRQ_MIN) && ((mcause & MCAUSE_CAUSE) <= MIV_LOCAL
 327              	        {
 328              	            handle_local_ei_interrupts((uint8_t)(mcause & MCAUSE_CAUSE));
 329              	        }
 330              	        else if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)
 331              	#else
 332              	        if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)
 333              	#endif
 334              	        {
 335              	#ifndef MIV_LEGACY_RV32
 336              	            External_IRQHandler();
 337              	#else
 338              	            handle_m_ext_interrupt();
 339              	#endif
 340              	        }
 341              	        else if ((mcause & MCAUSE_CAUSE) == IRQ_M_SOFT)
 342              	        {
 343              	            handle_m_soft_interrupt();
 344              	        }
 345              	        else if ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)
 346              	        {
 347              	            handle_m_timer_interrupt();
 348              	        }
 349              	    }
 350              	    else
 351              	    {
 352              	#ifndef NDEBUG
 353              	        /*
 354              	         Arguments supplied to this function are mcause, mepc (exception PC) and
 355              	         stack pointer.
 356              	         Based on privileged-isa specification mcause values and meanings are:
 357              	
 358              	         0 Instruction address misaligned (mtval/mtval is the address)
 359              	         1 Instruction access fault       (mtval/mtval is the address)
 360              	         2 Illegal instruction            (mtval/mtval contains the
 361              	                                           offending instruction opcode)
 362              	         3 Breakpoint
 363              	         4 Load address misaligned        (mtval/mtval is the address)
 364              	         5 Load address fault             (mtval/mtval is the address)
 365              	         6 Store/AMO address fault        (mtval/mtval is the address)
 366              	         7 Store/AMO access fault         (mtval/mtval is the address)
 367              	         8 Environment call from U-mode
 368              	         9 Environment call from S-mode
 369              	         A Environment call from M-mode
 370              	         B Instruction page fault
 371              	         C Load page fault                (mtval/mtval is the address)
 372              	         E Store page fault               (mtval/mtval is the address)
 373              	
 374              	         # Please note: mtval is the newer name for register mbadaddr
 375              	         # If you get a compile failure here, use the older name.
 376              	         # At this point, both are supported in latest compiler, older compiler
 377              	         # versions only support mbadaddr.
 378              	         # See: https://github.com/riscv/riscv-gcc/issues/133
 379              	        */
 380              	
 381              	         /* interrupt pending */
 382 0004 F3274034 	         uintptr_t mip      = read_csr(mip);
 383              	
 229              		csrr a5, mip
 230              	# 0 "" 2
 231              	# 385 "../miv_rv32_hal/miv_rv32_hal.c" 1
 384              	         /* additional info and meaning depends on mcause */
 385 0008 F3273034 	         uintptr_t mtval = read_csr(mtval);
 386              	
 232              		csrr a5, mtval
 233              	# 0 "" 2
 234              	# 388 "../miv_rv32_hal/miv_rv32_hal.c" 1
 387              	         /* trap vector */
 388 000c F3275030 	         uintptr_t mtvec    = read_csr(mtvec);
 389              	
 235              		csrr a5, mtvec
 236              	# 0 "" 2
 237              	# 391 "../miv_rv32_hal/miv_rv32_hal.c" 1
 390              	         /* temporary, sometimes might hold temporary value of a0 */
 391 0010 F3270034 	         uintptr_t mscratch = read_csr(mscratch);
 392              	
 238              		csrr a5, mscratch
 239              	# 0 "" 2
 240              	# 394 "../miv_rv32_hal/miv_rv32_hal.c" 1
 393              	         /* status contains many smaller fields: */
 394 0014 F3270030 	         uintptr_t mstatus  = read_csr(mstatus);
 395              	
 241              		csrr a5, mstatus
 242              	# 0 "" 2
 243              	# 397 "../miv_rv32_hal/miv_rv32_hal.c" 1
 396              	         /* PC value when the exception was taken*/
 397 0018 F3271034 	         uintptr_t mmepc  = read_csr(mepc);
 398              	
 244              		csrr a5, mepc
 245              	# 0 "" 2
 246              	# 400 "../miv_rv32_hal/miv_rv32_hal.c" 1
 399              	        /* breakpoint */
 400 001c 73001000 	        __asm__("ebreak");
 401              	#else
 247              		ebreak
 248              	# 0 "" 2
 249              	 #NO_APP
 250 0020 67800000 		ret
 251              	.L52:
 252 0024 B7070080 		li	a5,-2147483648
 253 0028 13C707FF 		xori	a4,a5,-16
 254 002c 3377E500 		and	a4,a0,a4
 255 0030 63020704 		beq	a4,zero,.L40
 256 0034 93C707FE 		xori	a5,a5,-32
 257 0038 B377F500 		and	a5,a0,a5
 258 003c 639C0702 		bne	a5,zero,.L40
 259 0040 1375F50F 		andi	a0,a0,0xff
 260              	 #APP
 261              	# 306 "../miv_rv32_hal/miv_rv32_hal.c" 1
 262              		csrr a5, mhartid
 263              	# 0 "" 2
 264              	 #NO_APP
 265 0048 9307F000 		li	a5,15
 266 004c 63E4A700 		bgtu	a0,a5,.L41
 267              	 #APP
 268              	# 308 "../miv_rv32_hal/miv_rv32_hal.c" 1
 269              		ebreak
 270              	# 0 "" 2
 271              	 #NO_APP
 272              	.L41:
 273 0054 130505FF 		addi	a0,a0,-16
 274 0058 1375F50F 		andi	a0,a0,0xff
 275 005c B7070000 		lui	a5,%hi(.LANCHOR3)
 276 0060 13152500 		slli	a0,a0,2
 277 0064 93870700 		addi	a5,a5,%lo(.LANCHOR3)
 278 0068 3385A700 		add	a0,a5,a0
 279 006c 03230500 		lw	t1,0(a0)
 280 0070 67000300 		jr	t1
 281              	.L40:
 282 0074 13151500 		slli	a0,a0,1
 283 0078 13551500 		srli	a0,a0,1
 284 007c 9307B000 		li	a5,11
 285 0080 630CF500 		beq	a0,a5,.L53
 286 0084 93073000 		li	a5,3
 287 0088 630CF500 		beq	a0,a5,.L54
 288 008c 93077000 		li	a5,7
 289 0090 630EF502 		beq	a0,a5,.L55
 290 0094 67800000 		ret
 291              	.L53:
 292 0098 17030000 		tail	External_IRQHandler
 292      67000300 
 293              	.L54:
 294 00a0 130101FF 		addi	sp,sp,-16
 295 00a4 23261100 		sw	ra,12(sp)
 296 00a8 97000000 		call	Software_IRQHandler
 296      E7800000 
 297 00b0 37670000 		li	a4,24576
 298 00b4 83270702 		lw	a5,32(a4)
 299 00b8 8320C100 		lw	ra,12(sp)
 300 00bc 93F7D7FF 		andi	a5,a5,-3
 301 00c0 2320F702 		sw	a5,32(a4)
 302 00c4 13010101 		addi	sp,sp,16
 303 00c8 67800000 		jr	ra
 304              	.L55:
 305 00cc 17030000 		tail	handle_m_timer_interrupt
 305      67000300 
 307              		.globl	local_irq_handler_table
 308              		.comm	MRV_LOCAL_IRQn_Type,4,4
 309              		.section	.rodata.local_irq_handler_table,"a"
 310              		.align	2
 311              		.set	.LANCHOR3,. + 0
 314              	local_irq_handler_table:
 315 0000 00000000 		.word	MGEUI_IRQHandler
 316 0004 00000000 		.word	MGECI_IRQHandler
 317 0008 00000000 		.word	SUBSYS_IRQHandler
 318 000c 00000000 		.word	SUBSYSR_IRQHandler
 319 0010 00000000 		.word	Reserved_IRQHandler
 320 0014 00000000 		.word	Reserved_IRQHandler
 321 0018 00000000 		.word	Reserved_IRQHandler
 322 001c 00000000 		.word	Reserved_IRQHandler
 323 0020 00000000 		.word	MSYS_EI0_IRQHandler
 324 0024 00000000 		.word	MSYS_EI1_IRQHandler
 325 0028 00000000 		.word	MSYS_EI2_IRQHandler
 326 002c 00000000 		.word	MSYS_EI3_IRQHandler
 327 0030 00000000 		.word	MSYS_EI4_IRQHandler
 328 0034 00000000 		.word	MSYS_EI5_IRQHandler
 329 0038 00000000 		.word	MSYS_EI6_IRQHandler
 330 003c 00000000 		.word	MSYS_EI7_IRQHandler
 331              		.section	.sbss.d_tick.2196,"aw",@nobits
 332              		.align	2
 333              		.set	.LANCHOR2,. + 0
 336              	d_tick.2196:
 337 0000 00000000 		.zero	4
 338              		.section	.sbss.g_systick_cmp_value,"aw",@nobits
 339              		.align	3
 340              		.set	.LANCHOR1,. + 0
 343              	g_systick_cmp_value:
 344 0000 00000000 		.zero	8
 344      00000000 
 345              		.section	.sbss.g_systick_increment,"aw",@nobits
 346              		.align	3
 347              		.set	.LANCHOR0,. + 0
 350              	g_systick_increment:
 351 0000 00000000 		.zero	8
 351      00000000 
 352              		.ident	"GCC: (xPack GNU RISC-V Embedded GCC (Microsemi SoftConsole build), 64-bit) 8.3.0"
DEFINED SYMBOLS
                            *ABS*:0000000000000000 miv_rv32_hal.c
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:11     .text.MRV_systick_config:0000000000000000 MRV_systick_config
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:101    .text.handle_m_timer_interrupt:0000000000000000 handle_m_timer_interrupt
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:179    .text.handle_m_soft_interrupt:0000000000000000 handle_m_soft_interrupt
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:195    .text.handle_local_ei_interrupts:0000000000000000 handle_local_ei_interrupts
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:225    .text.handle_trap:0000000000000000 handle_trap
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:314    .rodata.local_irq_handler_table:0000000000000000 local_irq_handler_table
                            *COM*:0000000000000004 MRV_LOCAL_IRQn_Type
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:311    .rodata.local_irq_handler_table:0000000000000000 .LANCHOR3
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:333    .sbss.d_tick.2196:0000000000000000 .LANCHOR2
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:336    .sbss.d_tick.2196:0000000000000000 d_tick.2196
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:340    .sbss.g_systick_cmp_value:0000000000000000 .LANCHOR1
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:343    .sbss.g_systick_cmp_value:0000000000000000 g_systick_cmp_value
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:347    .sbss.g_systick_increment:0000000000000000 .LANCHOR0
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:350    .sbss.g_systick_increment:0000000000000000 g_systick_increment
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:91     .text.MRV_systick_config:000000000000010c .L18
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:34     .text.MRV_systick_config:0000000000000050 .L4
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:31     .text.MRV_systick_config:0000000000000048 .L10
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:52     .text.MRV_systick_config:0000000000000090 .L6
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:73     .text.MRV_systick_config:00000000000000e0 .L19
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:26     .text.MRV_systick_config:0000000000000038 .L12
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:48     .text.MRV_systick_config:0000000000000084 .L2
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:113    .text.handle_m_timer_interrupt:000000000000001c .L21
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:170    .text.handle_m_timer_interrupt:00000000000000e0 .L31
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:138    .text.handle_m_timer_interrupt:0000000000000078 .L29
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:151    .text.handle_m_timer_interrupt:00000000000000a8 .L27
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:154    .text.handle_m_timer_interrupt:00000000000000b0 .L22
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:131    .text.handle_m_timer_interrupt:0000000000000060 .L26
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:205    .text.handle_local_ei_interrupts:0000000000000014 .L37
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:211    .text.handle_local_ei_interrupts:0000000000000018 .L36
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:251    .text.handle_trap:0000000000000024 .L52
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:281    .text.handle_trap:0000000000000074 .L40
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:272    .text.handle_trap:0000000000000054 .L41
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:291    .text.handle_trap:0000000000000098 .L53
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:293    .text.handle_trap:00000000000000a0 .L54
C:\Users\i68629\AppData\Local\Temp\ccyQN3eA.s:304    .text.handle_trap:00000000000000cc .L55

UNDEFINED SYMBOLS
SysTick_Handler
Software_IRQHandler
External_IRQHandler
MGEUI_IRQHandler
MGECI_IRQHandler
SUBSYS_IRQHandler
SUBSYSR_IRQHandler
Reserved_IRQHandler
MSYS_EI0_IRQHandler
MSYS_EI1_IRQHandler
MSYS_EI2_IRQHandler
MSYS_EI3_IRQHandler
MSYS_EI4_IRQHandler
MSYS_EI5_IRQHandler
MSYS_EI6_IRQHandler
MSYS_EI7_IRQHandler
