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

Subversion Repositories neorv32

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

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 32 zero_gravi
  // modify return address only if exception (NOT for interrupts)
231 24 zero_gravi
  if ((trap_cause & 0x80000000) == 0) { // is exception?
232
    if ((trap_inst & 3) == 3) { // is uncompressed instruction?
233 15 zero_gravi
      trap_addr -= 4;
234
    }
235
    else {
236
      trap_addr -= 2;
237
    }
238 2 zero_gravi
  }
239 18 zero_gravi
  neorv32_uart_printf(" @ 0x%x, MTVAL=0x%x </RTE>", trap_addr, neorv32_cpu_csr_read(CSR_MTVAL));
240 6 zero_gravi
}
241
 
242
 
243
/**********************************************************************//**
244
 * NEORV32 runtime environment: Print hardware configuration information via UART
245
 **************************************************************************/
246
void neorv32_rte_print_hw_config(void) {
247
 
248
  uint32_t tmp;
249
  int i;
250
  char c;
251
 
252 32 zero_gravi
  neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
253 6 zero_gravi
 
254
  // CPU configuration
255
  neorv32_uart_printf("\n-- Central Processing Unit --\n");
256
 
257 23 zero_gravi
  // ID
258 30 zero_gravi
  neorv32_uart_printf("Hart ID:           0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
259 6 zero_gravi
 
260 30 zero_gravi
  neorv32_uart_printf("Vendor ID:         0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
261 12 zero_gravi
 
262 23 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MARCHID);
263 30 zero_gravi
  neorv32_uart_printf("Architecture ID:   0x%x", tmp);
264 32 zero_gravi
  if (tmp == NEORV32_ARCHID) {
265
    neorv32_uart_printf(" (NEORV32)");
266
  }
267 23 zero_gravi
 
268 6 zero_gravi
  // HW version
269 30 zero_gravi
  neorv32_uart_printf("\nImplementation ID: 0x%x (", neorv32_cpu_csr_read(CSR_MIMPID));
270 12 zero_gravi
  neorv32_rte_print_hw_version();
271 30 zero_gravi
  neorv32_uart_printf(")\n");
272 6 zero_gravi
 
273
  // CPU architecture
274 30 zero_gravi
  neorv32_uart_printf("Architecture:      ");
275 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
276
  tmp = (tmp >> 30) & 0x03;
277
  if (tmp == 0) {
278
    neorv32_uart_printf("unknown");
279
  }
280
  if (tmp == 1) {
281
    neorv32_uart_printf("RV32");
282
  }
283
  if (tmp == 2) {
284
    neorv32_uart_printf("RV64");
285
  }
286
  if (tmp == 3) {
287
    neorv32_uart_printf("RV128");
288
  }
289
 
290
  // CPU extensions
291 30 zero_gravi
  neorv32_uart_printf("\nExtensions:        ");
292 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
293
  for (i=0; i<26; i++) {
294
    if (tmp & (1 << i)) {
295
      c = (char)('A' + i);
296
      neorv32_uart_putc(c);
297
      neorv32_uart_putc(' ');
298
    }
299
  }
300 22 zero_gravi
 
301 23 zero_gravi
  // Z* CPU extensions (from custom CSR "mzext")
302 22 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MZEXT);
303
  if (tmp & (1<<0)) {
304
    neorv32_uart_printf("Zicsr ");
305
  }
306
  if (tmp & (1<<1)) {
307
    neorv32_uart_printf("Zifencei ");
308
  }
309 6 zero_gravi
 
310
 
311 15 zero_gravi
  // Misc
312 30 zero_gravi
  neorv32_uart_printf("\n\n\n-- Processor --\n");
313
  neorv32_uart_printf("Clock:   %u Hz\n", SYSINFO_CLK);
314
  neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
315 15 zero_gravi
 
316
 
317 6 zero_gravi
  // Memory configuration
318 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
319 6 zero_gravi
 
320 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
321 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
322 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
323 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
324 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
325 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
326 6 zero_gravi
 
327 23 zero_gravi
  neorv32_uart_printf("Data base address:    0x%x\n", SYSINFO_DSPACE_BASE);
328 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
329 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
330 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
331 6 zero_gravi
 
332
  neorv32_uart_printf("Bootloader:           ");
333 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
334 6 zero_gravi
 
335 30 zero_gravi
  neorv32_uart_printf("External M interface: ");
336 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
337 6 zero_gravi
 
338
  // peripherals
339 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Peripherals --\n");
340
 
341 12 zero_gravi
  tmp = SYSINFO_FEATURES;
342 6 zero_gravi
 
343 30 zero_gravi
  neorv32_uart_printf("GPIO:  ");
344 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
345 6 zero_gravi
 
346 30 zero_gravi
  neorv32_uart_printf("MTIME: ");
347 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
348 6 zero_gravi
 
349 30 zero_gravi
  neorv32_uart_printf("UART:  ");
350 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
351 6 zero_gravi
 
352 30 zero_gravi
  neorv32_uart_printf("SPI:   ");
353 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
354 6 zero_gravi
 
355 30 zero_gravi
  neorv32_uart_printf("TWI:   ");
356 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
357 6 zero_gravi
 
358 30 zero_gravi
  neorv32_uart_printf("PWM:   ");
359 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
360 6 zero_gravi
 
361 30 zero_gravi
  neorv32_uart_printf("WDT:   ");
362 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
363 6 zero_gravi
 
364 30 zero_gravi
  neorv32_uart_printf("TRNG:  ");
365 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
366 6 zero_gravi
 
367 30 zero_gravi
  neorv32_uart_printf("CFU:   ");
368 23 zero_gravi
  __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.