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

Subversion Repositories neorv32

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

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 33 zero_gravi
static void __neorv32_rte_print_hex_word(uint32_t num);
55 2 zero_gravi
 
56
 
57
/**********************************************************************//**
58 14 zero_gravi
 * Setup NEORV32 runtime environment.
59 2 zero_gravi
 *
60
 * @note This function installs a debug handler for ALL exception and interrupt sources, which
61 14 zero_gravi
 * gives detailed information about the exception/interrupt. Actual handler can be installed afterwards
62
 * via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
63 2 zero_gravi
 **************************************************************************/
64 14 zero_gravi
void neorv32_rte_setup(void) {
65 2 zero_gravi
 
66 24 zero_gravi
  // check if CSR system is available at all
67
  if (neorv32_cpu_csr_read(CSR_MISA) == 0) {
68 33 zero_gravi
    neorv32_uart_print("<RTE> WARNING! CPU CSR system not available! </RTE>");
69 24 zero_gravi
  }
70
 
71 14 zero_gravi
  // configure trap handler base address
72
  uint32_t mtvec_base = (uint32_t)(&__neorv32_rte_core);
73
  neorv32_cpu_csr_write(CSR_MTVEC, mtvec_base);
74 2 zero_gravi
 
75
  // install debug handler for all sources
76 14 zero_gravi
  uint8_t id;
77
  for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) {
78
    neorv32_rte_exception_uninstall(id); // this will configure the debug handler
79 2 zero_gravi
  }
80
}
81
 
82
 
83
/**********************************************************************//**
84
 * Install exception handler function to NEORV32 runtime environment.
85
 *
86 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)
87
 * and the global interrupt enable bit mstatus.mie via neorv32_cpu_eint(void).
88 2 zero_gravi
 *
89 14 zero_gravi
 * @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum.
90
 * @param[in] handler The actual handler function for the specified exception (function MUST be of type "void function(void);").
91 18 zero_gravi
 * @return 0 if success, 1 if error (invalid id or targeted exception not supported).
92 2 zero_gravi
 **************************************************************************/
93 14 zero_gravi
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void)) {
94 2 zero_gravi
 
95
  // id valid?
96 14 zero_gravi
  if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS)     || (id == RTE_TRAP_I_ILLEGAL) ||
97
      (id == RTE_TRAP_BREAKPOINT)   || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS)  ||
98
      (id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS)     || (id == RTE_TRAP_MENV_CALL) ||
99
      (id == RTE_TRAP_MSI)          || (id == RTE_TRAP_MTI)          || (id == RTE_TRAP_MEI)       ||
100
      (id == RTE_TRAP_FIRQ_0)       || (id == RTE_TRAP_FIRQ_1)       || (id == RTE_TRAP_FIRQ_2)    || (id == RTE_TRAP_FIRQ_3)) {
101 2 zero_gravi
 
102 24 zero_gravi
    __neorv32_rte_vector_lut[id] = (uint32_t)handler; // install handler
103 14 zero_gravi
 
104 2 zero_gravi
    return 0;
105
  }
106
  return 1;
107
}
108
 
109
 
110
/**********************************************************************//**
111
 * Uninstall exception handler function from NEORV32 runtime environment, which was
112 14 zero_gravi
 * previously installed via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
113 2 zero_gravi
 *
114 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)
115
 * and/or the global interrupt enable bit mstatus.mie via neorv32_cpu_dint(void).
116 2 zero_gravi
 *
117 14 zero_gravi
 * @param[in] id Identifier (type) of the targeted exception. See #NEORV32_RTE_TRAP_enum.
118 18 zero_gravi
 * @return 0 if success, 1 if error (invalid id or targeted exception not supported).
119 2 zero_gravi
 **************************************************************************/
120 14 zero_gravi
int neorv32_rte_exception_uninstall(uint8_t id) {
121 2 zero_gravi
 
122
  // id valid?
123 14 zero_gravi
  if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS)     || (id == RTE_TRAP_I_ILLEGAL) ||
124
      (id == RTE_TRAP_BREAKPOINT)   || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS)  ||
125
      (id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS)     || (id == RTE_TRAP_MENV_CALL) ||
126
      (id == RTE_TRAP_MSI)          || (id == RTE_TRAP_MTI)          || (id == RTE_TRAP_MEI)       ||
127
      (id == RTE_TRAP_FIRQ_0)       || (id == RTE_TRAP_FIRQ_1)       || (id == RTE_TRAP_FIRQ_2)    || (id == RTE_TRAP_FIRQ_3)) {
128 2 zero_gravi
 
129 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
130 2 zero_gravi
 
131
    return 0;
132
  }
133
  return 1;
134
}
135
 
136
 
137
/**********************************************************************//**
138 14 zero_gravi
 * This is the core of the NEORV32 RTE.
139
 *
140
 * @note This function must no be explicitly used by the user.
141 33 zero_gravi
 * @note The RTE core uses mscratch CSR to store the trap-causing mepc for further (user-defined) processing.
142
 *
143 14 zero_gravi
 * @warning When using the the RTE, this function is the ONLY function that can use the 'interrupt' attribute!
144 2 zero_gravi
 **************************************************************************/
145 14 zero_gravi
static void __attribute__((__interrupt__)) __attribute__((aligned(16)))  __neorv32_rte_core(void) {
146 2 zero_gravi
 
147 33 zero_gravi
  register uint32_t rte_mepc = neorv32_cpu_csr_read(CSR_MEPC);
148
  neorv32_cpu_csr_write(CSR_MSCRATCH, rte_mepc); // store for later
149 14 zero_gravi
  register uint32_t rte_mcause = neorv32_cpu_csr_read(CSR_MCAUSE);
150
 
151
  // compute return address
152
  if ((rte_mcause & 0x80000000) == 0) { // modify pc only if exception
153
 
154
    // get low half word of faulting instruction
155
    register uint32_t rte_trap_inst;
156
    asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (rte_trap_inst) : [input_i] "r" (rte_mepc));
157
 
158
    if ((rte_trap_inst & 3) == 3) { // faulting instruction is uncompressed instruction
159
      rte_mepc += 4;
160
    }
161
    else { // faulting instruction is compressed instruction
162
      rte_mepc += 2;
163
    }
164
 
165
    // store new return address
166
    neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
167
  }
168
 
169
  // find according trap handler
170
  register uint32_t rte_handler = (uint32_t)(&__neorv32_rte_debug_exc_handler);
171
  switch (rte_mcause) {
172
    case TRAP_CODE_I_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_MISALIGNED]; break;
173
    case TRAP_CODE_I_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ACCESS]; break;
174
    case TRAP_CODE_I_ILLEGAL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ILLEGAL]; break;
175
    case TRAP_CODE_BREAKPOINT:   rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
176
    case TRAP_CODE_L_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_MISALIGNED]; break;
177
    case TRAP_CODE_L_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
178
    case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
179
    case TRAP_CODE_S_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
180
    case TRAP_CODE_MENV_CALL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
181
    case TRAP_CODE_MSI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
182
    case TRAP_CODE_MTI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
183
    case TRAP_CODE_MEI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
184
    case TRAP_CODE_FIRQ_0:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_0]; break;
185
    case TRAP_CODE_FIRQ_1:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_1]; break;
186
    case TRAP_CODE_FIRQ_2:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_2]; break;
187
    case TRAP_CODE_FIRQ_3:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_3]; break;
188
    default: break;
189
  }
190
 
191
  // execute handler
192
  void (*handler_pnt)(void);
193
  handler_pnt = (void*)rte_handler;
194
  (*handler_pnt)();
195 2 zero_gravi
}
196
 
197
 
198
/**********************************************************************//**
199
 * NEORV32 runtime environment: Debug exception handler, printing various exception/interrupt information via UART.
200 14 zero_gravi
 * @note This function is used by neorv32_rte_exception_uninstall(void) only.
201 2 zero_gravi
 **************************************************************************/
202
static void __neorv32_rte_debug_exc_handler(void) {
203
 
204 15 zero_gravi
  // intro
205 33 zero_gravi
  neorv32_uart_print("<RTE> ");
206 2 zero_gravi
 
207 15 zero_gravi
  // cause
208 7 zero_gravi
  register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
209
  switch (trap_cause) {
210 33 zero_gravi
    case TRAP_CODE_I_MISALIGNED: neorv32_uart_print("Instruction address misaligned"); break;
211
    case TRAP_CODE_I_ACCESS:     neorv32_uart_print("Instruction access fault"); break;
212
    case TRAP_CODE_I_ILLEGAL:    neorv32_uart_print("Illegal instruction"); break;
213
    case TRAP_CODE_BREAKPOINT:   neorv32_uart_print("Breakpoint"); break;
214
    case TRAP_CODE_L_MISALIGNED: neorv32_uart_print("Load address misaligned"); break;
215
    case TRAP_CODE_L_ACCESS:     neorv32_uart_print("Load access fault"); break;
216
    case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
217
    case TRAP_CODE_S_ACCESS:     neorv32_uart_print("Store access fault"); break;
218
    case TRAP_CODE_MENV_CALL:    neorv32_uart_print("Environment call"); break;
219
    case TRAP_CODE_MSI:          neorv32_uart_print("Machine software interrupt"); break;
220
    case TRAP_CODE_MTI:          neorv32_uart_print("Machine timer interrupt"); break;
221
    case TRAP_CODE_MEI:          neorv32_uart_print("Machine external interrupt"); break;
222
    case TRAP_CODE_FIRQ_0:       neorv32_uart_print("Fast interrupt 0"); break;
223
    case TRAP_CODE_FIRQ_1:       neorv32_uart_print("Fast interrupt 1"); break;
224
    case TRAP_CODE_FIRQ_2:       neorv32_uart_print("Fast interrupt 2"); break;
225
    case TRAP_CODE_FIRQ_3:       neorv32_uart_print("Fast interrupt 3"); break;
226
    default:                     neorv32_uart_print("Unknown trap cause: "); __neorv32_rte_print_hex_word(trap_cause); break;
227 2 zero_gravi
  }
228
 
229 33 zero_gravi
  // instruction address
230
  neorv32_uart_print(" @ ");
231
  __neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MSCRATCH)); // rte core stores actual mepc to mscratch
232 15 zero_gravi
 
233 33 zero_gravi
  // additional info
234
  neorv32_uart_print(", MTVAL=");
235
  __neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MTVAL));
236
  neorv32_uart_print(" </RTE>");
237 6 zero_gravi
}
238
 
239
 
240
/**********************************************************************//**
241
 * NEORV32 runtime environment: Print hardware configuration information via UART
242
 **************************************************************************/
243
void neorv32_rte_print_hw_config(void) {
244
 
245
  uint32_t tmp;
246
  int i;
247
  char c;
248
 
249 32 zero_gravi
  neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
250 6 zero_gravi
 
251
  // CPU configuration
252
  neorv32_uart_printf("\n-- Central Processing Unit --\n");
253
 
254 23 zero_gravi
  // ID
255 30 zero_gravi
  neorv32_uart_printf("Hart ID:           0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
256 6 zero_gravi
 
257 30 zero_gravi
  neorv32_uart_printf("Vendor ID:         0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
258 12 zero_gravi
 
259 23 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MARCHID);
260 30 zero_gravi
  neorv32_uart_printf("Architecture ID:   0x%x", tmp);
261 32 zero_gravi
  if (tmp == NEORV32_ARCHID) {
262
    neorv32_uart_printf(" (NEORV32)");
263
  }
264 23 zero_gravi
 
265 6 zero_gravi
  // HW version
266 30 zero_gravi
  neorv32_uart_printf("\nImplementation ID: 0x%x (", neorv32_cpu_csr_read(CSR_MIMPID));
267 12 zero_gravi
  neorv32_rte_print_hw_version();
268 30 zero_gravi
  neorv32_uart_printf(")\n");
269 6 zero_gravi
 
270
  // CPU architecture
271 30 zero_gravi
  neorv32_uart_printf("Architecture:      ");
272 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
273
  tmp = (tmp >> 30) & 0x03;
274
  if (tmp == 0) {
275
    neorv32_uart_printf("unknown");
276
  }
277
  if (tmp == 1) {
278
    neorv32_uart_printf("RV32");
279
  }
280
  if (tmp == 2) {
281
    neorv32_uart_printf("RV64");
282
  }
283
  if (tmp == 3) {
284
    neorv32_uart_printf("RV128");
285
  }
286
 
287
  // CPU extensions
288 30 zero_gravi
  neorv32_uart_printf("\nExtensions:        ");
289 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
290
  for (i=0; i<26; i++) {
291
    if (tmp & (1 << i)) {
292
      c = (char)('A' + i);
293
      neorv32_uart_putc(c);
294
      neorv32_uart_putc(' ');
295
    }
296
  }
297 22 zero_gravi
 
298 23 zero_gravi
  // Z* CPU extensions (from custom CSR "mzext")
299 22 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MZEXT);
300 33 zero_gravi
  if (tmp & (1<<CPU_MZEXT_ZICSR)) {
301 22 zero_gravi
    neorv32_uart_printf("Zicsr ");
302
  }
303 33 zero_gravi
  if (tmp & (1<<CPU_MZEXT_ZIFENCEI)) {
304 22 zero_gravi
    neorv32_uart_printf("Zifencei ");
305
  }
306 33 zero_gravi
  if (tmp & (1<<CPU_MZEXT_PMP)) {
307
    neorv32_uart_printf("PMP ");
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 33 zero_gravi
    neorv32_uart_print("True\n");
382 6 zero_gravi
  }
383 2 zero_gravi
  else {
384 33 zero_gravi
    neorv32_uart_print("False\n");
385 2 zero_gravi
  }
386 6 zero_gravi
}
387 2 zero_gravi
 
388
 
389 6 zero_gravi
/**********************************************************************//**
390 33 zero_gravi
 * NEORV32 runtime environment: Private function to print 32-bit number
391
 * as 8-digit hexadecimal value (with "0x" suffix).
392
 *
393
 * @param[in] num Number to print as hexadecimal.
394
 **************************************************************************/
395
void __neorv32_rte_print_hex_word(uint32_t num) {
396
 
397
  static const char hex_symbols[16] = "0123456789ABCDEF";
398
 
399
  neorv32_uart_print("0x");
400
 
401
  int i;
402
  for (i=0; i<8; i++) {
403
    uint32_t index = (num >> (28 - 4*i)) & 0xF;
404
    neorv32_uart_putc(hex_symbols[index]);
405
  }
406
}
407
 
408
 
409
 
410
/**********************************************************************//**
411 12 zero_gravi
 * NEORV32 runtime environment: Function to show the processor version in human-readable format.
412 6 zero_gravi
 **************************************************************************/
413 12 zero_gravi
void neorv32_rte_print_hw_version(void) {
414 6 zero_gravi
 
415
  uint32_t i;
416
  char tmp, cnt;
417
 
418
  for (i=0; i<4; i++) {
419
 
420 33 zero_gravi
    tmp = (char)(neorv32_cpu_csr_read(CSR_MIMPID) >> (24 - 8*i));
421 6 zero_gravi
 
422
    // serial division
423
    cnt = 0;
424
    while (tmp >= 10) {
425
      tmp = tmp - 10;
426
      cnt++;
427
    }
428
 
429
    if (cnt) {
430
      neorv32_uart_putc('0' + cnt);
431
    }
432
    neorv32_uart_putc('0' + tmp);
433
    if (i < 3) {
434
      neorv32_uart_putc('.');
435
    }
436
  }
437 2 zero_gravi
}
438 11 zero_gravi
 
439
 
440
/**********************************************************************//**
441
 * NEORV32 runtime environment: Print project credits
442
 **************************************************************************/
443
void neorv32_rte_print_credits(void) {
444
 
445
  neorv32_uart_print("\n\nThe NEORV32 Processor Project\n"
446
                     "by Stephan Nolting\n"
447
                     "https://github.com/stnolting/neorv32\n"
448
                     "made in Hannover, Germany\n\n");
449
}
450
 
451 22 zero_gravi
 
452
/**********************************************************************//**
453
 * NEORV32 runtime environment: Print project license
454
 **************************************************************************/
455
void neorv32_rte_print_license(void) {
456
 
457
  neorv32_uart_print(
458
  "\n"
459
  "\n"
460
  "BSD 3-Clause License\n"
461
  "\n"
462
  "Copyright (c) 2020, Stephan Nolting. All rights reserved.\n"
463
  "\n"
464
  "Redistribution and use in source and binary forms, with or without modification, are\n"
465
  "permitted provided that the following conditions are met:\n"
466
  "\n"
467
  "1. Redistributions of source code must retain the above copyright notice, this list of\n"
468
  "   conditions and the following disclaimer.\n"
469
  "\n"
470
  "2. Redistributions in binary form must reproduce the above copyright notice, this list of\n"
471
  "   conditions and the following disclaimer in the documentation and/or other materials\n"
472
  "   provided with the distribution.\n"
473
  "\n"
474
  "3. Neither the name of the copyright holder nor the names of its contributors may be used to\n"
475
  "   endorse or promote products derived from this software without specific prior written\n"
476
  "   permission.\n"
477
  "\n"
478
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n"
479
  "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
480
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
481
  "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n"
482
  "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
483
  "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
484
  "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
485
  "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"
486
  "OF THE POSSIBILITY OF SUCH DAMAGE.\n"
487
  "\n"
488
  "The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting\n"
489
  "\n"
490
  "\n"
491
  );
492
}
493
 

powered by: WebSVN 2.1.0

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