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

Subversion Repositories neorv32

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

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 34 zero_gravi
  // check physical memory protection
312
  neorv32_uart_printf("\n\nPhysical memory protection: ");
313
  if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP))  {
314
 
315
    // check granulartiy
316
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
317
    neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
318
    uint32_t pmp_test_g = neorv32_cpu_csr_read(0x3b0);
319
 
320
    // find least-significat set bit
321
    for (i=31; i!=0; i--) {
322
      if (((pmp_test_g >> i) & 1) == 0) {
323
        break;
324
      }
325
    }
326
 
327
    neorv32_uart_printf("\n- Min granularity: ");
328
    if (i < 29) {
329
      neorv32_uart_printf("%u bytes per region (0x%x)\n", (uint32_t)(1 << (i+1+2)), pmp_test_g);
330
    }
331
    else {
332
      neorv32_uart_printf("2^%u bytes per region\n", i+1+2);
333
    }
334
 
335
 
336
    // test available modes
337
    neorv32_uart_printf("- Mode TOR:   ");
338
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
339
    if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x08) {
340
      neorv32_uart_printf("available\n");
341
    }
342
    else {
343
      neorv32_uart_printf("not implemented\n");
344
    }
345
 
346
    neorv32_uart_printf("- Mode NA4:   ");
347
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0x10);
348
    if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x10) {
349
      neorv32_uart_printf("available\n");
350
    }
351
    else {
352
      neorv32_uart_printf("not implemented\n");
353
    }
354
 
355
    neorv32_uart_printf("- Mode NAPOT: ");
356
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0x18);
357
    if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x18) {
358
      neorv32_uart_printf("available\n");
359
    }
360
    else {
361
      neorv32_uart_printf("not implemented\n");
362
    }
363
 
364
    // deactivate entry
365
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
366
  }
367
  else {
368
    neorv32_uart_printf("not implemented\n");
369
  }
370
 
371
 
372
  // Misc - system
373
  neorv32_uart_printf("\n\n-- Processor --\n");
374 30 zero_gravi
  neorv32_uart_printf("Clock:   %u Hz\n", SYSINFO_CLK);
375
  neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
376 15 zero_gravi
 
377
 
378 6 zero_gravi
  // Memory configuration
379 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
380 6 zero_gravi
 
381 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
382 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
383 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
384 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
385 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
386 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
387 6 zero_gravi
 
388 23 zero_gravi
  neorv32_uart_printf("Data base address:    0x%x\n", SYSINFO_DSPACE_BASE);
389 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
390 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
391 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
392 6 zero_gravi
 
393
  neorv32_uart_printf("Bootloader:           ");
394 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
395 6 zero_gravi
 
396 30 zero_gravi
  neorv32_uart_printf("External M interface: ");
397 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
398 6 zero_gravi
 
399
  // peripherals
400 15 zero_gravi
  neorv32_uart_printf("\n-- Processor Peripherals --\n");
401
 
402 12 zero_gravi
  tmp = SYSINFO_FEATURES;
403 6 zero_gravi
 
404 30 zero_gravi
  neorv32_uart_printf("GPIO:  ");
405 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
406 6 zero_gravi
 
407 30 zero_gravi
  neorv32_uart_printf("MTIME: ");
408 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
409 6 zero_gravi
 
410 30 zero_gravi
  neorv32_uart_printf("UART:  ");
411 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
412 6 zero_gravi
 
413 30 zero_gravi
  neorv32_uart_printf("SPI:   ");
414 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
415 6 zero_gravi
 
416 30 zero_gravi
  neorv32_uart_printf("TWI:   ");
417 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
418 6 zero_gravi
 
419 30 zero_gravi
  neorv32_uart_printf("PWM:   ");
420 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
421 6 zero_gravi
 
422 30 zero_gravi
  neorv32_uart_printf("WDT:   ");
423 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
424 6 zero_gravi
 
425 30 zero_gravi
  neorv32_uart_printf("TRNG:  ");
426 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
427 6 zero_gravi
 
428 34 zero_gravi
  neorv32_uart_printf("CFU0:  ");
429
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU0));
430
 
431
  neorv32_uart_printf("CFU1:  ");
432
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU1));
433 6 zero_gravi
}
434
 
435
 
436
/**********************************************************************//**
437
 * NEORV32 runtime environment: Private function to print true or false.
438
 * @note This function is used by neorv32_rte_print_hw_config(void) only.
439
 *
440
 * @param[in] state Print TRUE when !=0, print FALSE when 0
441
 **************************************************************************/
442
static void __neorv32_rte_print_true_false(int state) {
443
 
444
  if (state) {
445 33 zero_gravi
    neorv32_uart_print("True\n");
446 6 zero_gravi
  }
447 2 zero_gravi
  else {
448 33 zero_gravi
    neorv32_uart_print("False\n");
449 2 zero_gravi
  }
450 6 zero_gravi
}
451 2 zero_gravi
 
452
 
453 6 zero_gravi
/**********************************************************************//**
454 33 zero_gravi
 * NEORV32 runtime environment: Private function to print 32-bit number
455
 * as 8-digit hexadecimal value (with "0x" suffix).
456
 *
457
 * @param[in] num Number to print as hexadecimal.
458
 **************************************************************************/
459
void __neorv32_rte_print_hex_word(uint32_t num) {
460
 
461
  static const char hex_symbols[16] = "0123456789ABCDEF";
462
 
463
  neorv32_uart_print("0x");
464
 
465
  int i;
466
  for (i=0; i<8; i++) {
467
    uint32_t index = (num >> (28 - 4*i)) & 0xF;
468
    neorv32_uart_putc(hex_symbols[index]);
469
  }
470
}
471
 
472
 
473
 
474
/**********************************************************************//**
475 12 zero_gravi
 * NEORV32 runtime environment: Function to show the processor version in human-readable format.
476 6 zero_gravi
 **************************************************************************/
477 12 zero_gravi
void neorv32_rte_print_hw_version(void) {
478 6 zero_gravi
 
479
  uint32_t i;
480
  char tmp, cnt;
481
 
482
  for (i=0; i<4; i++) {
483
 
484 33 zero_gravi
    tmp = (char)(neorv32_cpu_csr_read(CSR_MIMPID) >> (24 - 8*i));
485 6 zero_gravi
 
486
    // serial division
487
    cnt = 0;
488
    while (tmp >= 10) {
489
      tmp = tmp - 10;
490
      cnt++;
491
    }
492
 
493
    if (cnt) {
494
      neorv32_uart_putc('0' + cnt);
495
    }
496
    neorv32_uart_putc('0' + tmp);
497
    if (i < 3) {
498
      neorv32_uart_putc('.');
499
    }
500
  }
501 2 zero_gravi
}
502 11 zero_gravi
 
503
 
504
/**********************************************************************//**
505
 * NEORV32 runtime environment: Print project credits
506
 **************************************************************************/
507
void neorv32_rte_print_credits(void) {
508
 
509
  neorv32_uart_print("\n\nThe NEORV32 Processor Project\n"
510
                     "by Stephan Nolting\n"
511
                     "https://github.com/stnolting/neorv32\n"
512
                     "made in Hannover, Germany\n\n");
513
}
514
 
515 22 zero_gravi
 
516
/**********************************************************************//**
517
 * NEORV32 runtime environment: Print project license
518
 **************************************************************************/
519
void neorv32_rte_print_license(void) {
520
 
521
  neorv32_uart_print(
522
  "\n"
523
  "\n"
524
  "BSD 3-Clause License\n"
525
  "\n"
526
  "Copyright (c) 2020, Stephan Nolting. All rights reserved.\n"
527
  "\n"
528
  "Redistribution and use in source and binary forms, with or without modification, are\n"
529
  "permitted provided that the following conditions are met:\n"
530
  "\n"
531
  "1. Redistributions of source code must retain the above copyright notice, this list of\n"
532
  "   conditions and the following disclaimer.\n"
533
  "\n"
534
  "2. Redistributions in binary form must reproduce the above copyright notice, this list of\n"
535
  "   conditions and the following disclaimer in the documentation and/or other materials\n"
536
  "   provided with the distribution.\n"
537
  "\n"
538
  "3. Neither the name of the copyright holder nor the names of its contributors may be used to\n"
539
  "   endorse or promote products derived from this software without specific prior written\n"
540
  "   permission.\n"
541
  "\n"
542
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n"
543
  "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
544
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
545
  "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n"
546
  "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
547
  "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
548
  "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
549
  "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"
550
  "OF THE POSSIBILITY OF SUCH DAMAGE.\n"
551
  "\n"
552
  "The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting\n"
553
  "\n"
554
  "\n"
555
  );
556
}
557
 

powered by: WebSVN 2.1.0

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