1 /*
2 * Copyright (c) 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
_clean_up(void)16 __attribute__((weak)) void _clean_up(void)
17 {
18 /* clean up plic, it will help while debugging */
19 disable_irq_from_intc();
20 intc_m_set_threshold(0);
21 for (uint32_t irq = 0; irq < 128; irq++) {
22 intc_m_complete_irq(irq);
23 }
24 /* clear any bits left in plic enable register */
25 for (uint32_t i = 0; i < 4; i++) {
26 *(volatile uint32_t *)(HPM_PLIC_BASE + HPM_PLIC_ENABLE_OFFSET + (i << 2)) = 0;
27 }
28 }
29
c_startup(void)30 __attribute__((weak)) void c_startup(void)
31 {
32 uint32_t i, size;
33 extern uint8_t __bss_start__[], __bss_end__[];
34 extern uint8_t __tdata_start__[], __tdata_end__[];
35 extern uint8_t __data_start__[], __data_end__[];
36 extern uint8_t __ramfunc_start__[], __ramfunc_end__[];
37 extern uint8_t __noncacheable_bss_start__[], __noncacheable_bss_end__[];
38 extern uint8_t __noncacheable_init_start__[], __noncacheable_init_end__[];
39 extern uint8_t __data_load_addr__[], __tdata_load_addr__[];
40 extern uint8_t __fast_load_addr__[], __noncacheable_init_load_addr__[];
41
42 #if defined(FLASH_XIP) || defined(FLASH_UF2)
43 extern uint8_t __vector_ram_start__[], __vector_ram_end__[], __vector_load_addr__[];
44 size = __vector_ram_end__ - __vector_ram_start__;
45 for (i = 0; i < size; i++) {
46 *(__vector_ram_start__ + i) = *(__vector_load_addr__ + i);
47 }
48 #endif
49
50 /* bss section */
51 size = __bss_end__ - __bss_start__;
52 for (i = 0; i < size; i++) {
53 *(__bss_start__ + i) = 0;
54 }
55
56 /* noncacheable bss section */
57 size = __noncacheable_bss_end__ - __noncacheable_bss_start__;
58 for (i = 0; i < size; i++) {
59 *(__noncacheable_bss_start__ + i) = 0;
60 }
61
62 /* data section LMA: etext */
63 size = __data_end__ - __data_start__;
64 for (i = 0; i < size; i++) {
65 *(__data_start__ + i) = *(__data_load_addr__ + i);
66 }
67
68 /* ramfunc section LMA: etext + data length */
69 size = __ramfunc_end__ - __ramfunc_start__;
70 for (i = 0; i < size; i++) {
71 *(__ramfunc_start__ + i) = *(__fast_load_addr__ + i);
72 }
73
74 /* tdata section LMA: etext + data length + ramfunc length */
75 size = __tdata_end__ - __tdata_start__;
76 for (i = 0; i < size; i++) {
77 *(__tdata_start__ + i) = *(__tdata_load_addr__ + i);
78 }
79
80 /* noncacheable init section LMA: etext + data length + ramfunc legnth + tdata length*/
81 size = __noncacheable_init_end__ - __noncacheable_init_start__;
82 for (i = 0; i < size; i++) {
83 *(__noncacheable_init_start__ + i) = *(__noncacheable_init_load_addr__ + i);
84 }
85 }
86
main(void)87 __attribute__((weak)) int main(void)
88 {
89 while (1) {
90 ;
91 }
92 }
93
reset_handler(void)94 __attribute__((weak)) void reset_handler(void)
95 {
96 fencei();
97
98 /* Call platform specific hardware initialization */
99 system_init();
100
101 /* Entry function */
102 main();
103 }
104
105 /*
106 * When compiling C++ code with static objects, the compiler inserts
107 * a call to __cxa_atexit() with __dso_handle as one of the arguments.
108 * The dummy versions of these symbols should be provided.
109 */
__cxa_atexit(void (* arg1)(void *),void * arg2,void * arg3)110 __attribute__((weak)) void __cxa_atexit(void (*arg1)(void *), void *arg2, void *arg3)
111 {
112 (void) arg1;
113 (void) arg2;
114 (void) arg3;
115 }
116
117 #if !defined(__SEGGER_RTL_VERSION) || defined(__riscv_xandes)
118 void *__dso_handle = (void *) &__dso_handle;
119 #endif
120
_init(void)121 __attribute__((weak)) void _init(void)
122 {
123 }
124