1 /*
2  * Copyright (c) 2021-2023 HPMicro
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include <stdint.h>
7 #include "hpm_common.h"
8 #include "hpm_soc.h"
9 #include "hpm_l1c_drv.h"
10 #include "hpm_interrupt.h"
11 
12 
13 extern void system_init(void);
14 
15 #ifndef MAIN_ENTRY
16 #define MAIN_ENTRY main
17 #endif
18 extern int MAIN_ENTRY(void);
19 
_clean_up(void)20 __attribute__((weak)) void _clean_up(void)
21 {
22     /* clean up plic, it will help while debugging */
23     disable_irq_from_intc();
24     intc_m_set_threshold(0);
25     for (uint32_t irq = 0; irq < 128; irq++) {
26         intc_m_complete_irq(irq);
27     }
28     /* clear any bits left in plic enable register */
29     for (uint32_t i = 0; i < 4; i++) {
30         *(volatile uint32_t *)(HPM_PLIC_BASE + HPM_PLIC_ENABLE_OFFSET + (i << 2)) = 0;
31     }
32 }
33 
c_startup(void)34 __attribute__((weak)) void c_startup(void)
35 {
36     uint32_t i, size;
37     extern uint8_t __bss_start__[], __bss_end__[];
38     extern uint8_t __tdata_start__[], __tdata_end__[];
39     extern uint8_t __data_start__[], __data_end__[];
40     extern uint8_t __ramfunc_start__[], __ramfunc_end__[];
41     extern uint8_t __noncacheable_bss_start__[], __noncacheable_bss_end__[];
42     extern uint8_t __noncacheable_init_start__[], __noncacheable_init_end__[];
43     extern uint8_t __data_load_addr__[], __tdata_load_addr__[];
44     extern uint8_t __fast_load_addr__[], __noncacheable_init_load_addr__[];
45     extern uint8_t __fast_ram_bss_start__[], __fast_ram_bss_end__[];
46     extern uint8_t __fast_ram_init_start__[], __fast_ram_init_end__[], __fast_ram_init_load_addr__[];
47 
48 #if defined(FLASH_XIP) || defined(FLASH_UF2)
49     extern uint8_t __vector_ram_start__[], __vector_ram_end__[], __vector_load_addr__[];
50     size = __vector_ram_end__ - __vector_ram_start__;
51     for (i = 0; i < size; i++) {
52         *(__vector_ram_start__ + i) = *(__vector_load_addr__ + i);
53     }
54 #endif
55 
56     /* bss section */
57     size = __bss_end__ - __bss_start__;
58     for (i = 0; i < size; i++) {
59         *(__bss_start__ + i) = 0;
60     }
61 
62     /* noncacheable bss section */
63     size = __noncacheable_bss_end__ - __noncacheable_bss_start__;
64     for (i = 0; i < size; i++) {
65         *(__noncacheable_bss_start__ + i) = 0;
66     }
67 
68     /* fast_ram bss section */
69     size = __fast_ram_bss_end__ - __fast_ram_bss_start__;
70     for (i = 0; i < size; i++) {
71         *(__fast_ram_bss_start__ + i) = 0;
72     }
73 
74     /* data section LMA: etext */
75     size = __data_end__ - __data_start__;
76     for (i = 0; i < size; i++) {
77         *(__data_start__ + i) = *(__data_load_addr__ + i);
78     }
79 
80     /* ramfunc section LMA: etext + data length */
81     size = __ramfunc_end__ - __ramfunc_start__;
82     for (i = 0; i < size; i++) {
83         *(__ramfunc_start__ + i) = *(__fast_load_addr__ + i);
84     }
85 
86     /* tdata section LMA: etext + data length + ramfunc length */
87     size = __tdata_end__ - __tdata_start__;
88     for (i = 0; i < size; i++) {
89         *(__tdata_start__ + i) = *(__tdata_load_addr__ + i);
90     }
91 
92     /* noncacheable init section LMA: etext + data length + ramfunc legnth + tdata length*/
93     size = __noncacheable_init_end__ - __noncacheable_init_start__;
94     for (i = 0; i < size; i++) {
95         *(__noncacheable_init_start__ + i) = *(__noncacheable_init_load_addr__ + i);
96     }
97 
98     /* fast_ram init section LMA: etext + data length + ramfunc legnth + tdata length*/
99     size = __fast_ram_init_end__ - __fast_ram_init_start__;
100     for (i = 0; i < size; i++) {
101         *(__fast_ram_init_start__ + i) = *(__fast_ram_init_load_addr__ + i);
102     }
103 }
104 
main(void)105 __attribute__((weak)) int main(void)
106 {
107     while (1) {
108         ;
109     }
110 }
111 
reset_handler(void)112 __attribute__((weak)) void reset_handler(void)
113 {
114     fencei();
115 
116     /* Call platform specific hardware initialization */
117     system_init();
118 
119     /* Entry function */
120     MAIN_ENTRY();
121 }
122 
123 /*
124  * When compiling C++ code with static objects, the compiler inserts
125  * a call to __cxa_atexit() with __dso_handle as one of the arguments.
126  * The dummy versions of these symbols should be provided.
127  */
__cxa_atexit(void (* arg1)(void *),void * arg2,void * arg3)128 __attribute__((weak)) void __cxa_atexit(void (*arg1)(void *), void *arg2, void *arg3)
129 {
130     (void) arg1;
131     (void) arg2;
132     (void) arg3;
133 }
134 
135 #if (!defined(__SEGGER_RTL_VERSION) || defined(__riscv_xandes)) && !defined(__ICCRISCV__)
136 void *__dso_handle = (void *) &__dso_handle;
137 #endif
138 
_init(void)139 __attribute__((weak)) void _init(void)
140 {
141 }
142 
143 
144 #ifdef __ICCRISCV__
__low_level_init(void)145 int __low_level_init(void)
146 {
147 #ifdef IAR_MANUAL_COPY /* Enable this code snippet if the .isr_vector and .vector_table need to be copied to RAM manually */
148 #pragma section = ".isr_vector"
149 #pragma section = ".isr_vector_init"
150 #pragma section = ".vector_table"
151 #pragma section = ".vector_table_init"
152     /* Initialize section .isr_vector, section .vector_table */
153     uint8_t *__isr_vector_ram_start = __section_begin(".isr_vector");
154     uint32_t __isr_vector_ram_size = __section_size(".isr_vector");
155     uint8_t *__isr_vector_rom_start = __section_begin(".isr_vector_init");
156 
157     for (uint32_t i = 0; i < __isr_vector_ram_size; i++) {
158         __isr_vector_ram_start[i] = __isr_vector_rom_start[i];
159     }
160 
161     uint8_t *__vector_table_ram_start = __section_begin(".vector_table");
162     uint32_t __vector_table_ram_size = __section_size(".vector_table");
163     uint8_t *__vector_rom_start = __section_begin(".vector_table_init");
164 
165     for (uint32_t i = 0; i < __vector_table_ram_size; i++) {
166         __vector_table_ram_start[i] = __vector_rom_start[i];
167     }
168 #endif
169 
170     return 1;
171 }
172 #endif
173