OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_rte.c] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zero_gravi
// #################################################################################################
2
// # << NEORV32: neorv32_rte.c - NEORV32 Runtime Environment >>                                    #
3
// # ********************************************************************************************* #
4
// # BSD 3-Clause License                                                                          #
5
// #                                                                                               #
6
// # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
7
// #                                                                                               #
8
// # Redistribution and use in source and binary forms, with or without modification, are          #
9
// # permitted provided that the following conditions are met:                                     #
10
// #                                                                                               #
11
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
// #    conditions and the following disclaimer.                                                   #
13
// #                                                                                               #
14
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
// #    conditions and the following disclaimer in the documentation and/or other materials        #
16
// #    provided with the distribution.                                                            #
17
// #                                                                                               #
18
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
// #    endorse or promote products derived from this software without specific prior written      #
20
// #    permission.                                                                                #
21
// #                                                                                               #
22
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
// # ********************************************************************************************* #
32
// # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
// #################################################################################################
34
 
35
 
36
/**********************************************************************//**
37
 * @file neorv32_rte.c
38
 * @author Stephan Nolting
39
 * @brief NEORV32 Runtime Environment.
40
 **************************************************************************/
41
 
42
#include "neorv32.h"
43
#include "neorv32_rte.h"
44
 
45 14 zero_gravi
/**********************************************************************//**
46
 * The >private< trap vector look-up table of the NEORV32 RTE.
47
 **************************************************************************/
48
static uint32_t __neorv32_rte_vector_lut[16] __attribute__((unused)); // trap handler vector table
49
 
50
// private functions
51
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused));
52 6 zero_gravi
static void __neorv32_rte_debug_exc_handler(void)     __attribute__((unused));
53
static void __neorv32_rte_print_true_false(int state) __attribute__((unused));
54 2 zero_gravi
 
55
 
56
/**********************************************************************//**
57 14 zero_gravi
 * Setup NEORV32 runtime environment.
58 2 zero_gravi
 *
59
 * @note This function installs a debug handler for ALL exception and interrupt sources, which
60 14 zero_gravi
 * gives detailed information about the exception/interrupt. Actual handler can be installed afterwards
61
 * via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
62 2 zero_gravi
 **************************************************************************/
63 14 zero_gravi
void neorv32_rte_setup(void) {
64 2 zero_gravi
 
65 24 zero_gravi
  // check if CSR system is available at all
66
  if (neorv32_cpu_csr_read(CSR_MISA) == 0) {
67
    neorv32_uart_printf("<RTE> WARNING! CPU CSR system not available! </RTE>");
68
  }
69
 
70 14 zero_gravi
  // configure trap handler base address
71
  uint32_t mtvec_base = (uint32_t)(&__neorv32_rte_core);
72
  neorv32_cpu_csr_write(CSR_MTVEC, mtvec_base);
73 2 zero_gravi
 
74
  // install debug handler for all sources
75 14 zero_gravi
  uint8_t id;
76
  for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) {
77
    neorv32_rte_exception_uninstall(id); // this will configure the debug handler
78 2 zero_gravi
  }
79
}
80
 
81
 
82
/**********************************************************************//**
83
 * Install exception handler function to NEORV32 runtime environment.
84
 *
85 17 zero_gravi
 * @note Interrupt sources have to be explicitly enabled by the user via the CSR.mie bits via neorv32_cpu_irq_enable(uint8_t irq_sel)
86
 * and the global interrupt enable bit mstatus.mie via neorv32_cpu_eint(void).
87 2 zero_gravi
 *
88 14 zero_gravi
 * @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum.
89
 * @param[in] handler The actual handler function for the specified exception (function MUST be of type "void function(void);").
90 18 zero_gravi
 * @return 0 if success, 1 if error (invalid id or targeted exception not supported).
91 2 zero_gravi
 **************************************************************************/
92 14 zero_gravi
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void)) {
93 2 zero_gravi
 
94
  // id valid?
95 14 zero_gravi
  if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS)     || (id == RTE_TRAP_I_ILLEGAL) ||
96
      (id == RTE_TRAP_BREAKPOINT)   || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS)  ||
97
      (id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS)     || (id == RTE_TRAP_MENV_CALL) ||
98
      (id == RTE_TRAP_MSI)          || (id == RTE_TRAP_MTI)          || (id == RTE_TRAP_MEI)       ||
99
      (id == RTE_TRAP_FIRQ_0)       || (id == RTE_TRAP_FIRQ_1)       || (id == RTE_TRAP_FIRQ_2)    || (id == RTE_TRAP_FIRQ_3)) {
100 2 zero_gravi
 
101 24 zero_gravi
    __neorv32_rte_vector_lut[id] = (uint32_t)handler; // install handler
102 14 zero_gravi
 
103 2 zero_gravi
    return 0;
104
  }
105
  return 1;
106
}
107
 
108
 
109
/**********************************************************************//**
110
 * Uninstall exception handler function from NEORV32 runtime environment, which was
111 14 zero_gravi
 * previously installed via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
112 2 zero_gravi
 *
113 17 zero_gravi
 * @note Interrupt sources have to be explicitly disabled by the user via the CSR.mie bits via neorv32_cpu_irq_disable(uint8_t irq_sel)
114
 * and/or the global interrupt enable bit mstatus.mie via neorv32_cpu_dint(void).
115 2 zero_gravi
 *
116 14 zero_gravi
 * @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum.
117 18 zero_gravi
 * @return 0 if success, 1 if error (invalid id or targeted exception not supported).
118 2 zero_gravi
 **************************************************************************/
119 14 zero_gravi
int neorv32_rte_exception_uninstall(uint8_t id) {
120 2 zero_gravi
 
121
  // id valid?
122 14 zero_gravi
  if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS)     || (id == RTE_TRAP_I_ILLEGAL) ||
123
      (id == RTE_TRAP_BREAKPOINT)   || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS)  ||
124
      (id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS)     || (id == RTE_TRAP_MENV_CALL) ||
125
      (id == RTE_TRAP_MSI)          || (id == RTE_TRAP_MTI)          || (id == RTE_TRAP_MEI)       ||
126
      (id == RTE_TRAP_FIRQ_0)       || (id == RTE_TRAP_FIRQ_1)       || (id == RTE_TRAP_FIRQ_2)    || (id == RTE_TRAP_FIRQ_3)) {
127 2 zero_gravi
 
128 14 zero_gravi
    __neorv32_rte_vector_lut[id] = (uint32_t)(&__neorv32_rte_debug_exc_handler); // use dummy handler in case the exception is accidently triggered
129 2 zero_gravi
 
130
    return 0;
131
  }
132
  return 1;
133
}
134
 
135
 
136
/**********************************************************************//**
137 14 zero_gravi
 * This is the core of the NEORV32 RTE.
138
 *
139
 * @note This function must no be explicitly used by the user.
140
 * @warning When using the the RTE, this function is the ONLY function that can use the 'interrupt' attribute!
141 2 zero_gravi
 **************************************************************************/
142 14 zero_gravi
static void __attribute__((__interrupt__)) __attribute__((aligned(16)))  __neorv32_rte_core(void) {
143 2 zero_gravi
 
144 14 zero_gravi
  register uint32_t rte_mepc   = neorv32_cpu_csr_read(CSR_MEPC);
145
  register uint32_t rte_mcause = neorv32_cpu_csr_read(CSR_MCAUSE);
146
 
147
  // compute return address
148
  if ((rte_mcause & 0x80000000) == 0) { // modify pc only if exception
149
 
150
    // get low half word of faulting instruction
151
    register uint32_t rte_trap_inst;
152
    asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (rte_trap_inst) : [input_i] "r" (rte_mepc));
153
 
154
    if ((rte_trap_inst & 3) == 3) { // faulting instruction is uncompressed instruction
155
      rte_mepc += 4;
156
    }
157
    else { // faulting instruction is compressed instruction
158
      rte_mepc += 2;
159
    }
160
 
161
    // store new return address
162
    neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
163
  }
164
 
165
  // find according trap handler
166
  register uint32_t rte_handler = (uint32_t)(&__neorv32_rte_debug_exc_handler);
167
  switch (rte_mcause) {
168
    case TRAP_CODE_I_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_MISALIGNED]; break;
169
    case TRAP_CODE_I_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ACCESS]; break;
170
    case TRAP_CODE_I_ILLEGAL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ILLEGAL]; break;
171
    case TRAP_CODE_BREAKPOINT:   rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
172
    case TRAP_CODE_L_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_MISALIGNED]; break;
173
    case TRAP_CODE_L_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
174
    case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
175
    case TRAP_CODE_S_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
176
    case TRAP_CODE_MENV_CALL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
177
    case TRAP_CODE_MSI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
178
    case TRAP_CODE_MTI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
179
    case TRAP_CODE_MEI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
180
    case TRAP_CODE_FIRQ_0:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_0]; break;
181
    case TRAP_CODE_FIRQ_1:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_1]; break;
182
    case TRAP_CODE_FIRQ_2:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_2]; break;
183
    case TRAP_CODE_FIRQ_3:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_3]; break;
184
    default: break;
185
  }
186
 
187
  // execute handler
188
  void (*handler_pnt)(void);
189
  handler_pnt = (void*)rte_handler;
190
  (*handler_pnt)();
191 2 zero_gravi
}
192
 
193
 
194
/**********************************************************************//**
195
 * NEORV32 runtime environment: Debug exception handler, printing various exception/interrupt information via UART.
196 14 zero_gravi
 * @note This function is used by neorv32_rte_exception_uninstall(void) only.
197 2 zero_gravi
 **************************************************************************/
198
static void __neorv32_rte_debug_exc_handler(void) {
199
 
200 15 zero_gravi
  // intro
201
  neorv32_uart_printf("<RTE> ");
202 2 zero_gravi
 
203 15 zero_gravi
  // cause
204 7 zero_gravi
  register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
205
  switch (trap_cause) {
206 14 zero_gravi
    case TRAP_CODE_I_MISALIGNED: neorv32_uart_printf("Instruction address misaligned"); break;
207
    case TRAP_CODE_I_ACCESS:     neorv32_uart_printf("Instruction access fault"); break;
208
    case TRAP_CODE_I_ILLEGAL:    neorv32_uart_printf("Illegal instruction"); break;
209 18 zero_gravi
    case TRAP_CODE_BREAKPOINT:   neorv32_uart_printf("Breakpoint"); break;
210 14 zero_gravi
    case TRAP_CODE_L_MISALIGNED: neorv32_uart_printf("Load address misaligned"); break;
211
    case TRAP_CODE_L_ACCESS:     neorv32_uart_printf("Load access fault"); break;
212
    case TRAP_CODE_S_MISALIGNED: neorv32_uart_printf("Store address misaligned"); break;
213
    case TRAP_CODE_S_ACCESS:     neorv32_uart_printf("Store access fault"); break;
214 18 zero_gravi
    case TRAP_CODE_MENV_CALL:    neorv32_uart_printf("Environment call"); break;
215 14 zero_gravi
    case TRAP_CODE_MSI:          neorv32_uart_printf("Machine software interrupt"); break;
216
    case TRAP_CODE_MTI:          neorv32_uart_printf("Machine timer interrupt"); break;
217
    case TRAP_CODE_MEI:          neorv32_uart_printf("Machine external interrupt"); break;
218 24 zero_gravi
    case TRAP_CODE_FIRQ_0:       neorv32_uart_printf("Fast interrupt 0"); break;
219
    case TRAP_CODE_FIRQ_1:       neorv32_uart_printf("Fast interrupt 1"); break;
220
    case TRAP_CODE_FIRQ_2:       neorv32_uart_printf("Fast interrupt 2"); break;
221
    case TRAP_CODE_FIRQ_3:       neorv32_uart_printf("Fast interrupt 3"); break;
222 14 zero_gravi
    default:                     neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
223 2 zero_gravi
  }
224
 
225 15 zero_gravi
  // address
226 24 zero_gravi
  register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC);
227 15 zero_gravi
  register uint32_t trap_inst;
228
  asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
229
 
230 24 zero_gravi
  if ((trap_cause & 0x80000000) == 0) { // is exception?
231
    if ((trap_inst & 3) == 3) { // is uncompressed instruction?
232 15 zero_gravi
      trap_addr -= 4;
233
    }
234
    else {
235
      trap_addr -= 2;
236
    }
237 2 zero_gravi
  }
238 18 zero_gravi
  neorv32_uart_printf(" @ 0x%x, MTVAL=0x%x </RTE>", trap_addr, neorv32_cpu_csr_read(CSR_MTVAL));
239 6 zero_gravi
}
240
 
241
 
242
/**********************************************************************//**
243
 * NEORV32 runtime environment: Print hardware configuration information via UART
244
 **************************************************************************/
245
void neorv32_rte_print_hw_config(void) {
246
 
247
  uint32_t tmp;
248
  int i;
249
  char c;
250
 
251
  neorv32_uart_printf("\n\n<< NEORV32 Hardware Configuration Overview >>\n");
252
 
253
  // CPU configuration
254
  neorv32_uart_printf("\n-- Central Processing Unit --\n");
255
 
256 23 zero_gravi
  // ID
257 30 zero_gravi
  neorv32_uart_printf("Hart ID:           0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
258 6 zero_gravi
 
259 30 zero_gravi
  neorv32_uart_printf("Vendor ID:         0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
260 12 zero_gravi
 
261 23 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MARCHID);
262 30 zero_gravi
  neorv32_uart_printf("Architecture ID:   0x%x", tmp);
263 23 zero_gravi
 
264 6 zero_gravi
  // HW version
265 30 zero_gravi
  neorv32_uart_printf("\nImplementation ID: 0x%x (", neorv32_cpu_csr_read(CSR_MIMPID));
266 12 zero_gravi
  neorv32_rte_print_hw_version();
267 30 zero_gravi
  neorv32_uart_printf(")\n");
268 6 zero_gravi
 
269
  // CPU architecture
270 30 zero_gravi
  neorv32_uart_printf("Architecture:      ");
271 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
272
  tmp = (tmp >> 30) & 0x03;
273
  if (tmp == 0) {
274
    neorv32_uart_printf("unknown");
275
  }
276
  if (tmp == 1) {
277
    neorv32_uart_printf("RV32");
278
  }
279
  if (tmp == 2) {
280
    neorv32_uart_printf("RV64");
281
  }
282
  if (tmp == 3) {
283
    neorv32_uart_printf("RV128");
284
  }
285
 
286
  // CPU extensions
287 30 zero_gravi
  neorv32_uart_printf("\nExtensions:        ");
288 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
289
  for (i=0; i<26; i++) {
290
    if (tmp & (1 << i)) {
291
      c = (char)('A' + i);
292
      neorv32_uart_putc(c);
293
      neorv32_uart_putc(' ');
294
    }
295
  }
296 22 zero_gravi
 
297 23 zero_gravi
  // Z* CPU extensions (from custom CSR "mzext")
298 22 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MZEXT);
299
  if (tmp & (1<<0)) {
300
    neorv32_uart_printf("Zicsr ");
301
  }
302
  if (tmp & (1<<1)) {
303
    neorv32_uart_printf("Zifencei ");
304
  }
305 6 zero_gravi
 
306
 
307 15 zero_gravi
  // Misc
308 30 zero_gravi
  neorv32_uart_printf("\n\n\n-- Processor --\n");
309
  neorv32_uart_printf("Clock:   %u Hz\n", SYSINFO_CLK);
310
  neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
311 15 zero_gravi
 
312
 
313 6 zero_gravi
  // Memory configuration
314 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
315 6 zero_gravi
 
316 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
317 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
318 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
319 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
320 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
321 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
322 6 zero_gravi
 
323 23 zero_gravi
  neorv32_uart_printf("Data base address:    0x%x\n", SYSINFO_DSPACE_BASE);
324 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
325 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
326 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
327 6 zero_gravi
 
328
  neorv32_uart_printf("Bootloader:           ");
329 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
330 6 zero_gravi
 
331 30 zero_gravi
  neorv32_uart_printf("External M interface: ");
332 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
333 6 zero_gravi
 
334
  // peripherals
335 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Peripherals --\n");
336
 
337 12 zero_gravi
  tmp = SYSINFO_FEATURES;
338 6 zero_gravi
 
339 30 zero_gravi
  neorv32_uart_printf("GPIO:  ");
340 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
341 6 zero_gravi
 
342 30 zero_gravi
  neorv32_uart_printf("MTIME: ");
343 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
344 6 zero_gravi
 
345 30 zero_gravi
  neorv32_uart_printf("UART:  ");
346 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
347 6 zero_gravi
 
348 30 zero_gravi
  neorv32_uart_printf("SPI:   ");
349 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
350 6 zero_gravi
 
351 30 zero_gravi
  neorv32_uart_printf("TWI:   ");
352 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
353 6 zero_gravi
 
354 30 zero_gravi
  neorv32_uart_printf("PWM:   ");
355 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
356 6 zero_gravi
 
357 30 zero_gravi
  neorv32_uart_printf("WDT:   ");
358 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
359 6 zero_gravi
 
360 30 zero_gravi
  neorv32_uart_printf("TRNG:  ");
361 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
362 6 zero_gravi
 
363 30 zero_gravi
  neorv32_uart_printf("CFU:   ");
364 23 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU));
365 6 zero_gravi
}
366
 
367
 
368
/**********************************************************************//**
369
 * NEORV32 runtime environment: Private function to print true or false.
370
 * @note This function is used by neorv32_rte_print_hw_config(void) only.
371
 *
372
 * @param[in] state Print TRUE when !=0, print FALSE when 0
373
 **************************************************************************/
374
static void __neorv32_rte_print_true_false(int state) {
375
 
376
  if (state) {
377
    neorv32_uart_printf("True\n");
378
  }
379 2 zero_gravi
  else {
380 6 zero_gravi
    neorv32_uart_printf("False\n");
381 2 zero_gravi
  }
382 6 zero_gravi
}
383 2 zero_gravi
 
384
 
385 6 zero_gravi
/**********************************************************************//**
386 12 zero_gravi
 * NEORV32 runtime environment: Function to show the processor version in human-readable format.
387 6 zero_gravi
 **************************************************************************/
388 12 zero_gravi
void neorv32_rte_print_hw_version(void) {
389 6 zero_gravi
 
390
  uint32_t i;
391
  char tmp, cnt;
392
  uint32_t version = neorv32_cpu_csr_read(CSR_MIMPID);
393
 
394
  for (i=0; i<4; i++) {
395
 
396
    tmp = (char)(version >> (24 - 8*i));
397
 
398
    // serial division
399
    cnt = 0;
400
    while (tmp >= 10) {
401
      tmp = tmp - 10;
402
      cnt++;
403
    }
404
 
405
    if (cnt) {
406
      neorv32_uart_putc('0' + cnt);
407
    }
408
    neorv32_uart_putc('0' + tmp);
409
    if (i < 3) {
410
      neorv32_uart_putc('.');
411
    }
412
  }
413 2 zero_gravi
}
414 11 zero_gravi
 
415
 
416
/**********************************************************************//**
417
 * NEORV32 runtime environment: Print project credits
418
 **************************************************************************/
419
void neorv32_rte_print_credits(void) {
420
 
421
  neorv32_uart_print("\n\nThe NEORV32 Processor Project\n"
422
                     "by Stephan Nolting\n"
423
                     "https://github.com/stnolting/neorv32\n"
424
                     "made in Hannover, Germany\n\n");
425
}
426
 
427 22 zero_gravi
 
428
/**********************************************************************//**
429
 * NEORV32 runtime environment: Print project license
430
 **************************************************************************/
431
void neorv32_rte_print_license(void) {
432
 
433
  neorv32_uart_print(
434
  "\n"
435
  "\n"
436
  "BSD 3-Clause License\n"
437
  "\n"
438
  "Copyright (c) 2020, Stephan Nolting. All rights reserved.\n"
439
  "\n"
440
  "Redistribution and use in source and binary forms, with or without modification, are\n"
441
  "permitted provided that the following conditions are met:\n"
442
  "\n"
443
  "1. Redistributions of source code must retain the above copyright notice, this list of\n"
444
  "   conditions and the following disclaimer.\n"
445
  "\n"
446
  "2. Redistributions in binary form must reproduce the above copyright notice, this list of\n"
447
  "   conditions and the following disclaimer in the documentation and/or other materials\n"
448
  "   provided with the distribution.\n"
449
  "\n"
450
  "3. Neither the name of the copyright holder nor the names of its contributors may be used to\n"
451
  "   endorse or promote products derived from this software without specific prior written\n"
452
  "   permission.\n"
453
  "\n"
454
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n"
455
  "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
456
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
457
  "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n"
458
  "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
459
  "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
460
  "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
461
  "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"
462
  "OF THE POSSIBILITY OF SUCH DAMAGE.\n"
463
  "\n"
464
  "The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting\n"
465
  "\n"
466
  "\n"
467
  );
468
}
469
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.