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

Subversion Repositories neorv32

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

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 12 zero_gravi
  neorv32_uart_printf("Hart ID:          %u\n", neorv32_cpu_csr_read(CSR_MHARTID));
258 6 zero_gravi
 
259 23 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
  neorv32_uart_printf("Architecture ID:  0x%x", tmp);
263
 
264
  // Custom user code/ID
265
  neorv32_uart_printf("\nUser ID:          0x%x\n", SYSINFO_USER_CODE);
266
 
267 6 zero_gravi
  // HW version
268
  neorv32_uart_printf("Hardware version: ");
269 12 zero_gravi
  neorv32_rte_print_hw_version();
270 6 zero_gravi
 
271
  // CPU architecture
272 23 zero_gravi
  neorv32_uart_printf("\nArchitecture:     ");
273 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
274
  tmp = (tmp >> 30) & 0x03;
275
  if (tmp == 0) {
276
    neorv32_uart_printf("unknown");
277
  }
278
  if (tmp == 1) {
279
    neorv32_uart_printf("RV32");
280
  }
281
  if (tmp == 2) {
282
    neorv32_uart_printf("RV64");
283
  }
284
  if (tmp == 3) {
285
    neorv32_uart_printf("RV128");
286
  }
287
 
288
  // CPU extensions
289 23 zero_gravi
  neorv32_uart_printf("\nExtensions:       ");
290 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
291
  for (i=0; i<26; i++) {
292
    if (tmp & (1 << i)) {
293
      c = (char)('A' + i);
294
      neorv32_uart_putc(c);
295
      neorv32_uart_putc(' ');
296
    }
297
  }
298 22 zero_gravi
 
299 23 zero_gravi
  // Z* CPU extensions (from custom CSR "mzext")
300 22 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MZEXT);
301
  if (tmp & (1<<0)) {
302
    neorv32_uart_printf("Zicsr ");
303
  }
304
  if (tmp & (1<<1)) {
305
    neorv32_uart_printf("Zifencei ");
306
  }
307 6 zero_gravi
 
308
 
309 15 zero_gravi
  // Misc
310 22 zero_gravi
  neorv32_uart_printf("\n\n-- System --\n");
311 15 zero_gravi
  neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
312
 
313
 
314 6 zero_gravi
  // Memory configuration
315 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
316 6 zero_gravi
 
317 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
318 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
319 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
320 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
321 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
322 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
323 6 zero_gravi
 
324 23 zero_gravi
  neorv32_uart_printf("Data base address:    0x%x\n", SYSINFO_DSPACE_BASE);
325 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
326 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
327 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
328 6 zero_gravi
 
329
  neorv32_uart_printf("Bootloader:           ");
330 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
331 6 zero_gravi
 
332
  neorv32_uart_printf("External interface:   ");
333 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
334 6 zero_gravi
 
335
  // peripherals
336 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Peripherals --\n");
337
 
338 12 zero_gravi
  tmp = SYSINFO_FEATURES;
339 6 zero_gravi
 
340
  neorv32_uart_printf("GPIO:    ");
341 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
342 6 zero_gravi
 
343
  neorv32_uart_printf("MTIME:   ");
344 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
345 6 zero_gravi
 
346
  neorv32_uart_printf("UART:    ");
347 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
348 6 zero_gravi
 
349
  neorv32_uart_printf("SPI:     ");
350 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
351 6 zero_gravi
 
352
  neorv32_uart_printf("TWI:     ");
353 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
354 6 zero_gravi
 
355
  neorv32_uart_printf("PWM:     ");
356 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
357 6 zero_gravi
 
358
  neorv32_uart_printf("WDT:     ");
359 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
360 6 zero_gravi
 
361
  neorv32_uart_printf("TRNG:    ");
362 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
363 6 zero_gravi
 
364
  neorv32_uart_printf("DEVNULL: ");
365 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_DEVNULL));
366 23 zero_gravi
 
367
  neorv32_uart_printf("CFU:     ");
368
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU));
369 6 zero_gravi
}
370
 
371
 
372
/**********************************************************************//**
373
 * NEORV32 runtime environment: Private function to print true or false.
374
 * @note This function is used by neorv32_rte_print_hw_config(void) only.
375
 *
376
 * @param[in] state Print TRUE when !=0, print FALSE when 0
377
 **************************************************************************/
378
static void __neorv32_rte_print_true_false(int state) {
379
 
380
  if (state) {
381
    neorv32_uart_printf("True\n");
382
  }
383 2 zero_gravi
  else {
384 6 zero_gravi
    neorv32_uart_printf("False\n");
385 2 zero_gravi
  }
386 6 zero_gravi
}
387 2 zero_gravi
 
388
 
389 6 zero_gravi
/**********************************************************************//**
390 12 zero_gravi
 * NEORV32 runtime environment: Function to show the processor version in human-readable format.
391 6 zero_gravi
 **************************************************************************/
392 12 zero_gravi
void neorv32_rte_print_hw_version(void) {
393 6 zero_gravi
 
394
  uint32_t i;
395
  char tmp, cnt;
396
  uint32_t version = neorv32_cpu_csr_read(CSR_MIMPID);
397
 
398
  for (i=0; i<4; i++) {
399
 
400
    tmp = (char)(version >> (24 - 8*i));
401
 
402
    // serial division
403
    cnt = 0;
404
    while (tmp >= 10) {
405
      tmp = tmp - 10;
406
      cnt++;
407
    }
408
 
409
    if (cnt) {
410
      neorv32_uart_putc('0' + cnt);
411
    }
412
    neorv32_uart_putc('0' + tmp);
413
    if (i < 3) {
414
      neorv32_uart_putc('.');
415
    }
416
  }
417 2 zero_gravi
}
418 11 zero_gravi
 
419
 
420
/**********************************************************************//**
421
 * NEORV32 runtime environment: Print project credits
422
 **************************************************************************/
423
void neorv32_rte_print_credits(void) {
424
 
425
  neorv32_uart_print("\n\nThe NEORV32 Processor Project\n"
426
                     "by Stephan Nolting\n"
427
                     "https://github.com/stnolting/neorv32\n"
428
                     "made in Hannover, Germany\n\n");
429
}
430
 
431 22 zero_gravi
 
432
/**********************************************************************//**
433
 * NEORV32 runtime environment: Print project license
434
 **************************************************************************/
435
void neorv32_rte_print_license(void) {
436
 
437
  neorv32_uart_print(
438
  "\n"
439
  "\n"
440
  "BSD 3-Clause License\n"
441
  "\n"
442
  "Copyright (c) 2020, Stephan Nolting. All rights reserved.\n"
443
  "\n"
444
  "Redistribution and use in source and binary forms, with or without modification, are\n"
445
  "permitted provided that the following conditions are met:\n"
446
  "\n"
447
  "1. Redistributions of source code must retain the above copyright notice, this list of\n"
448
  "   conditions and the following disclaimer.\n"
449
  "\n"
450
  "2. Redistributions in binary form must reproduce the above copyright notice, this list of\n"
451
  "   conditions and the following disclaimer in the documentation and/or other materials\n"
452
  "   provided with the distribution.\n"
453
  "\n"
454
  "3. Neither the name of the copyright holder nor the names of its contributors may be used to\n"
455
  "   endorse or promote products derived from this software without specific prior written\n"
456
  "   permission.\n"
457
  "\n"
458
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n"
459
  "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
460
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
461
  "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n"
462
  "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
463
  "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
464
  "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
465
  "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"
466
  "OF THE POSSIBILITY OF SUCH DAMAGE.\n"
467
  "\n"
468
  "The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting\n"
469
  "\n"
470
  "\n"
471
  );
472
}
473
 

powered by: WebSVN 2.1.0

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