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

Subversion Repositories neorv32

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

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 14 zero_gravi
  // configure trap handler base address
66
  uint32_t mtvec_base = (uint32_t)(&__neorv32_rte_core);
67
  neorv32_cpu_csr_write(CSR_MTVEC, mtvec_base);
68 2 zero_gravi
 
69
  // install debug handler for all sources
70 14 zero_gravi
  uint8_t id;
71
  for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) {
72
    neorv32_rte_exception_uninstall(id); // this will configure the debug handler
73 2 zero_gravi
  }
74
}
75
 
76
 
77
/**********************************************************************//**
78
 * Install exception handler function to NEORV32 runtime environment.
79
 *
80 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)
81
 * and the global interrupt enable bit mstatus.mie via neorv32_cpu_eint(void).
82 2 zero_gravi
 *
83 14 zero_gravi
 * @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum.
84
 * @param[in] handler The actual handler function for the specified exception (function MUST be of type "void function(void);").
85 18 zero_gravi
 * @return 0 if success, 1 if error (invalid id or targeted exception not supported).
86 2 zero_gravi
 **************************************************************************/
87 14 zero_gravi
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void)) {
88 2 zero_gravi
 
89
  // id valid?
90 14 zero_gravi
  if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS)     || (id == RTE_TRAP_I_ILLEGAL) ||
91
      (id == RTE_TRAP_BREAKPOINT)   || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS)  ||
92
      (id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS)     || (id == RTE_TRAP_MENV_CALL) ||
93
      (id == RTE_TRAP_MSI)          || (id == RTE_TRAP_MTI)          || (id == RTE_TRAP_MEI)       ||
94
      (id == RTE_TRAP_FIRQ_0)       || (id == RTE_TRAP_FIRQ_1)       || (id == RTE_TRAP_FIRQ_2)    || (id == RTE_TRAP_FIRQ_3)) {
95 2 zero_gravi
 
96 14 zero_gravi
    __neorv32_rte_vector_lut[id]  = (uint32_t)handler; // install handler
97
 
98 2 zero_gravi
    return 0;
99
  }
100
  return 1;
101
}
102
 
103
 
104
/**********************************************************************//**
105
 * Uninstall exception handler function from NEORV32 runtime environment, which was
106 14 zero_gravi
 * previously installed via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
107 2 zero_gravi
 *
108 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)
109
 * and/or the global interrupt enable bit mstatus.mie via neorv32_cpu_dint(void).
110 2 zero_gravi
 *
111 14 zero_gravi
 * @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum.
112 18 zero_gravi
 * @return 0 if success, 1 if error (invalid id or targeted exception not supported).
113 2 zero_gravi
 **************************************************************************/
114 14 zero_gravi
int neorv32_rte_exception_uninstall(uint8_t id) {
115 2 zero_gravi
 
116
  // id valid?
117 14 zero_gravi
  if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS)     || (id == RTE_TRAP_I_ILLEGAL) ||
118
      (id == RTE_TRAP_BREAKPOINT)   || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS)  ||
119
      (id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS)     || (id == RTE_TRAP_MENV_CALL) ||
120
      (id == RTE_TRAP_MSI)          || (id == RTE_TRAP_MTI)          || (id == RTE_TRAP_MEI)       ||
121
      (id == RTE_TRAP_FIRQ_0)       || (id == RTE_TRAP_FIRQ_1)       || (id == RTE_TRAP_FIRQ_2)    || (id == RTE_TRAP_FIRQ_3)) {
122 2 zero_gravi
 
123 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
124 2 zero_gravi
 
125
    return 0;
126
  }
127
  return 1;
128
}
129
 
130
 
131
/**********************************************************************//**
132 14 zero_gravi
 * This is the core of the NEORV32 RTE.
133
 *
134
 * @note This function must no be explicitly used by the user.
135
 * @warning When using the the RTE, this function is the ONLY function that can use the 'interrupt' attribute!
136 2 zero_gravi
 **************************************************************************/
137 14 zero_gravi
static void __attribute__((__interrupt__)) __attribute__((aligned(16)))  __neorv32_rte_core(void) {
138 2 zero_gravi
 
139 14 zero_gravi
  register uint32_t rte_mepc   = neorv32_cpu_csr_read(CSR_MEPC);
140
  register uint32_t rte_mcause = neorv32_cpu_csr_read(CSR_MCAUSE);
141
 
142
  // compute return address
143
  if ((rte_mcause & 0x80000000) == 0) { // modify pc only if exception
144
 
145
    // get low half word of faulting instruction
146
    register uint32_t rte_trap_inst;
147
    asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (rte_trap_inst) : [input_i] "r" (rte_mepc));
148
 
149
    if ((rte_trap_inst & 3) == 3) { // faulting instruction is uncompressed instruction
150
      rte_mepc += 4;
151
    }
152
    else { // faulting instruction is compressed instruction
153
      rte_mepc += 2;
154
    }
155
 
156
    // store new return address
157
    neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
158
  }
159
 
160
  // find according trap handler
161
  register uint32_t rte_handler = (uint32_t)(&__neorv32_rte_debug_exc_handler);
162
  switch (rte_mcause) {
163
    case TRAP_CODE_I_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_MISALIGNED]; break;
164
    case TRAP_CODE_I_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ACCESS]; break;
165
    case TRAP_CODE_I_ILLEGAL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ILLEGAL]; break;
166
    case TRAP_CODE_BREAKPOINT:   rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
167
    case TRAP_CODE_L_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_MISALIGNED]; break;
168
    case TRAP_CODE_L_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
169
    case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
170
    case TRAP_CODE_S_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
171
    case TRAP_CODE_MENV_CALL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
172
    case TRAP_CODE_MSI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
173
    case TRAP_CODE_MTI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
174
    case TRAP_CODE_MEI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
175
    case TRAP_CODE_FIRQ_0:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_0]; break;
176
    case TRAP_CODE_FIRQ_1:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_1]; break;
177
    case TRAP_CODE_FIRQ_2:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_2]; break;
178
    case TRAP_CODE_FIRQ_3:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_3]; break;
179
    default: break;
180
  }
181
 
182
  // execute handler
183
  void (*handler_pnt)(void);
184
  handler_pnt = (void*)rte_handler;
185
  (*handler_pnt)();
186 2 zero_gravi
}
187
 
188
 
189
/**********************************************************************//**
190
 * NEORV32 runtime environment: Debug exception handler, printing various exception/interrupt information via UART.
191 14 zero_gravi
 * @note This function is used by neorv32_rte_exception_uninstall(void) only.
192 2 zero_gravi
 **************************************************************************/
193
static void __neorv32_rte_debug_exc_handler(void) {
194
 
195 15 zero_gravi
  // intro
196
  neorv32_uart_printf("<RTE> ");
197 2 zero_gravi
 
198 15 zero_gravi
  // cause
199 7 zero_gravi
  register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
200
  switch (trap_cause) {
201 14 zero_gravi
    case TRAP_CODE_I_MISALIGNED: neorv32_uart_printf("Instruction address misaligned"); break;
202
    case TRAP_CODE_I_ACCESS:     neorv32_uart_printf("Instruction access fault"); break;
203
    case TRAP_CODE_I_ILLEGAL:    neorv32_uart_printf("Illegal instruction"); break;
204 18 zero_gravi
    case TRAP_CODE_BREAKPOINT:   neorv32_uart_printf("Breakpoint"); break;
205 14 zero_gravi
    case TRAP_CODE_L_MISALIGNED: neorv32_uart_printf("Load address misaligned"); break;
206
    case TRAP_CODE_L_ACCESS:     neorv32_uart_printf("Load access fault"); break;
207
    case TRAP_CODE_S_MISALIGNED: neorv32_uart_printf("Store address misaligned"); break;
208
    case TRAP_CODE_S_ACCESS:     neorv32_uart_printf("Store access fault"); break;
209 18 zero_gravi
    case TRAP_CODE_MENV_CALL:    neorv32_uart_printf("Environment call"); break;
210 14 zero_gravi
    case TRAP_CODE_MSI:          neorv32_uart_printf("Machine software interrupt"); break;
211
    case TRAP_CODE_MTI:          neorv32_uart_printf("Machine timer interrupt"); break;
212
    case TRAP_CODE_MEI:          neorv32_uart_printf("Machine external interrupt"); break;
213 23 zero_gravi
    case TRAP_CODE_FIRQ_0:       neorv32_uart_printf("Fast interrupt 0 (WDT)"); break;
214
    case TRAP_CODE_FIRQ_1:       neorv32_uart_printf("Fast interrupt 1 (GPIO)"); break;
215
    case TRAP_CODE_FIRQ_2:       neorv32_uart_printf("Fast interrupt 2 (UART)"); break;
216
    case TRAP_CODE_FIRQ_3:       neorv32_uart_printf("Fast interrupt 3 (SPI/TWI)"); break;
217 14 zero_gravi
    default:                     neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
218 2 zero_gravi
  }
219
 
220 15 zero_gravi
  // address
221
  register uint32_t trap_addr  = neorv32_cpu_csr_read(CSR_MEPC);
222
  register uint32_t trap_inst;
223 2 zero_gravi
 
224 15 zero_gravi
  asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
225
 
226
  if ((trap_cause & 0x80000000) == 0) {
227
    if ((trap_inst & 3) == 3) {
228
      trap_addr -= 4;
229
    }
230
    else {
231
      trap_addr -= 2;
232
    }
233 2 zero_gravi
  }
234 18 zero_gravi
  neorv32_uart_printf(" @ 0x%x, MTVAL=0x%x </RTE>", trap_addr, neorv32_cpu_csr_read(CSR_MTVAL));
235 6 zero_gravi
}
236
 
237
 
238
/**********************************************************************//**
239
 * NEORV32 runtime environment: Print hardware configuration information via UART
240
 **************************************************************************/
241
void neorv32_rte_print_hw_config(void) {
242
 
243
  uint32_t tmp;
244
  int i;
245
  char c;
246
 
247
  neorv32_uart_printf("\n\n<< NEORV32 Hardware Configuration Overview >>\n");
248
 
249
  // CPU configuration
250
  neorv32_uart_printf("\n-- Central Processing Unit --\n");
251
 
252 23 zero_gravi
  // ID
253 12 zero_gravi
  neorv32_uart_printf("Hart ID:          %u\n", neorv32_cpu_csr_read(CSR_MHARTID));
254 6 zero_gravi
 
255 23 zero_gravi
  neorv32_uart_printf("Vendor ID:        0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
256 12 zero_gravi
 
257 23 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MARCHID);
258
  neorv32_uart_printf("Architecture ID:  0x%x", tmp);
259
 
260
  // Custom user code/ID
261
  neorv32_uart_printf("\nUser ID:          0x%x\n", SYSINFO_USER_CODE);
262
 
263 6 zero_gravi
  // HW version
264
  neorv32_uart_printf("Hardware version: ");
265 12 zero_gravi
  neorv32_rte_print_hw_version();
266 6 zero_gravi
 
267
  // CPU architecture
268 23 zero_gravi
  neorv32_uart_printf("\nArchitecture:     ");
269 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
270
  tmp = (tmp >> 30) & 0x03;
271
  if (tmp == 0) {
272
    neorv32_uart_printf("unknown");
273
  }
274
  if (tmp == 1) {
275
    neorv32_uart_printf("RV32");
276
  }
277
  if (tmp == 2) {
278
    neorv32_uart_printf("RV64");
279
  }
280
  if (tmp == 3) {
281
    neorv32_uart_printf("RV128");
282
  }
283
 
284
  // CPU extensions
285 23 zero_gravi
  neorv32_uart_printf("\nExtensions:       ");
286 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
287
  for (i=0; i<26; i++) {
288
    if (tmp & (1 << i)) {
289
      c = (char)('A' + i);
290
      neorv32_uart_putc(c);
291
      neorv32_uart_putc(' ');
292
    }
293
  }
294 22 zero_gravi
 
295 23 zero_gravi
  // Z* CPU extensions (from custom CSR "mzext")
296 22 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MZEXT);
297
  if (tmp & (1<<0)) {
298
    neorv32_uart_printf("Zicsr ");
299
  }
300
  if (tmp & (1<<1)) {
301
    neorv32_uart_printf("Zifencei ");
302
  }
303 6 zero_gravi
 
304
 
305 15 zero_gravi
  // Misc
306 22 zero_gravi
  neorv32_uart_printf("\n\n-- System --\n");
307 15 zero_gravi
  neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
308
 
309
 
310 6 zero_gravi
  // Memory configuration
311 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
312 6 zero_gravi
 
313 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
314 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
315 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
316 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
317 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
318 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
319 6 zero_gravi
 
320 23 zero_gravi
  neorv32_uart_printf("Data base address:    0x%x\n", SYSINFO_DSPACE_BASE);
321 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
322 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
323 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
324 6 zero_gravi
 
325
  neorv32_uart_printf("Bootloader:           ");
326 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
327 6 zero_gravi
 
328
  neorv32_uart_printf("External interface:   ");
329 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
330 6 zero_gravi
 
331
  // peripherals
332 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Peripherals --\n");
333
 
334 12 zero_gravi
  tmp = SYSINFO_FEATURES;
335 6 zero_gravi
 
336
  neorv32_uart_printf("GPIO:    ");
337 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
338 6 zero_gravi
 
339
  neorv32_uart_printf("MTIME:   ");
340 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
341 6 zero_gravi
 
342
  neorv32_uart_printf("UART:    ");
343 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
344 6 zero_gravi
 
345
  neorv32_uart_printf("SPI:     ");
346 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
347 6 zero_gravi
 
348
  neorv32_uart_printf("TWI:     ");
349 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
350 6 zero_gravi
 
351
  neorv32_uart_printf("PWM:     ");
352 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
353 6 zero_gravi
 
354
  neorv32_uart_printf("WDT:     ");
355 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
356 6 zero_gravi
 
357
  neorv32_uart_printf("TRNG:    ");
358 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
359 6 zero_gravi
 
360
  neorv32_uart_printf("DEVNULL: ");
361 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_DEVNULL));
362 23 zero_gravi
 
363
  neorv32_uart_printf("CFU:     ");
364
  __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.