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

Subversion Repositories neorv32

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

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 42 zero_gravi
// # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
7 2 zero_gravi
// #                                                                                               #
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 40 zero_gravi
static uint32_t __neorv32_rte_vector_lut[17] __attribute__((unused)); // trap handler vector table
49 14 zero_gravi
 
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 40 zero_gravi
      (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) || (id == RTE_TRAP_UENV_CALL) ||
99 14 zero_gravi
      (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 40 zero_gravi
      (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) || (id == RTE_TRAP_UENV_CALL) ||
126 14 zero_gravi
      (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 40 zero_gravi
    case TRAP_CODE_UENV_CALL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_UENV_CALL]; break;
181 14 zero_gravi
    case TRAP_CODE_MENV_CALL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
182
    case TRAP_CODE_MSI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
183
    case TRAP_CODE_MTI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
184
    case TRAP_CODE_MEI:          rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
185
    case TRAP_CODE_FIRQ_0:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_0]; break;
186
    case TRAP_CODE_FIRQ_1:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_1]; break;
187
    case TRAP_CODE_FIRQ_2:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_2]; break;
188
    case TRAP_CODE_FIRQ_3:       rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_3]; break;
189
    default: break;
190
  }
191
 
192
  // execute handler
193
  void (*handler_pnt)(void);
194
  handler_pnt = (void*)rte_handler;
195
  (*handler_pnt)();
196 2 zero_gravi
}
197
 
198
 
199
/**********************************************************************//**
200
 * NEORV32 runtime environment: Debug exception handler, printing various exception/interrupt information via UART.
201 14 zero_gravi
 * @note This function is used by neorv32_rte_exception_uninstall(void) only.
202 2 zero_gravi
 **************************************************************************/
203
static void __neorv32_rte_debug_exc_handler(void) {
204
 
205 15 zero_gravi
  // intro
206 33 zero_gravi
  neorv32_uart_print("<RTE> ");
207 2 zero_gravi
 
208 15 zero_gravi
  // cause
209 7 zero_gravi
  register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
210
  switch (trap_cause) {
211 33 zero_gravi
    case TRAP_CODE_I_MISALIGNED: neorv32_uart_print("Instruction address misaligned"); break;
212
    case TRAP_CODE_I_ACCESS:     neorv32_uart_print("Instruction access fault"); break;
213
    case TRAP_CODE_I_ILLEGAL:    neorv32_uart_print("Illegal instruction"); break;
214
    case TRAP_CODE_BREAKPOINT:   neorv32_uart_print("Breakpoint"); break;
215
    case TRAP_CODE_L_MISALIGNED: neorv32_uart_print("Load address misaligned"); break;
216
    case TRAP_CODE_L_ACCESS:     neorv32_uart_print("Load access fault"); break;
217
    case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
218
    case TRAP_CODE_S_ACCESS:     neorv32_uart_print("Store access fault"); break;
219 40 zero_gravi
    case TRAP_CODE_UENV_CALL:    neorv32_uart_print("Environment call from U-mode"); break;
220
    case TRAP_CODE_MENV_CALL:    neorv32_uart_print("Environment call from M-mode"); break;
221 33 zero_gravi
    case TRAP_CODE_MSI:          neorv32_uart_print("Machine software interrupt"); break;
222
    case TRAP_CODE_MTI:          neorv32_uart_print("Machine timer interrupt"); break;
223
    case TRAP_CODE_MEI:          neorv32_uart_print("Machine external interrupt"); break;
224
    case TRAP_CODE_FIRQ_0:       neorv32_uart_print("Fast interrupt 0"); break;
225
    case TRAP_CODE_FIRQ_1:       neorv32_uart_print("Fast interrupt 1"); break;
226
    case TRAP_CODE_FIRQ_2:       neorv32_uart_print("Fast interrupt 2"); break;
227
    case TRAP_CODE_FIRQ_3:       neorv32_uart_print("Fast interrupt 3"); break;
228
    default:                     neorv32_uart_print("Unknown trap cause: "); __neorv32_rte_print_hex_word(trap_cause); break;
229 2 zero_gravi
  }
230
 
231 33 zero_gravi
  // instruction address
232 35 zero_gravi
  neorv32_uart_print(" @ PC=");
233 33 zero_gravi
  __neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MSCRATCH)); // rte core stores actual mepc to mscratch
234 15 zero_gravi
 
235 33 zero_gravi
  // additional info
236
  neorv32_uart_print(", MTVAL=");
237
  __neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MTVAL));
238
  neorv32_uart_print(" </RTE>");
239 6 zero_gravi
}
240
 
241
 
242
/**********************************************************************//**
243
 * NEORV32 runtime environment: Print hardware configuration information via UART
244
 **************************************************************************/
245
void neorv32_rte_print_hw_config(void) {
246
 
247
  uint32_t tmp;
248
  int i;
249
  char c;
250
 
251 32 zero_gravi
  neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
252 6 zero_gravi
 
253
  // CPU configuration
254 40 zero_gravi
  neorv32_uart_printf("\n---- Central Processing Unit ----\n");
255 6 zero_gravi
 
256 23 zero_gravi
  // ID
257 30 zero_gravi
  neorv32_uart_printf("Hart ID:           0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
258 6 zero_gravi
 
259 30 zero_gravi
  neorv32_uart_printf("Vendor ID:         0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
260 12 zero_gravi
 
261 23 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MARCHID);
262 30 zero_gravi
  neorv32_uart_printf("Architecture ID:   0x%x", tmp);
263 32 zero_gravi
  if (tmp == NEORV32_ARCHID) {
264
    neorv32_uart_printf(" (NEORV32)");
265
  }
266 23 zero_gravi
 
267 6 zero_gravi
  // HW version
268 30 zero_gravi
  neorv32_uart_printf("\nImplementation ID: 0x%x (", neorv32_cpu_csr_read(CSR_MIMPID));
269 12 zero_gravi
  neorv32_rte_print_hw_version();
270 30 zero_gravi
  neorv32_uart_printf(")\n");
271 6 zero_gravi
 
272
  // CPU architecture
273 30 zero_gravi
  neorv32_uart_printf("Architecture:      ");
274 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
275
  tmp = (tmp >> 30) & 0x03;
276
  if (tmp == 0) {
277
    neorv32_uart_printf("unknown");
278
  }
279
  if (tmp == 1) {
280 41 zero_gravi
    neorv32_uart_printf("rv32");
281 6 zero_gravi
  }
282
  if (tmp == 2) {
283 41 zero_gravi
    neorv32_uart_printf("rv64");
284 6 zero_gravi
  }
285
  if (tmp == 3) {
286 41 zero_gravi
    neorv32_uart_printf("rv128");
287 6 zero_gravi
  }
288
 
289
  // CPU extensions
290 40 zero_gravi
  neorv32_uart_printf("\nEndianness:        ");
291 42 zero_gravi
  if (neorv32_cpu_csr_read(CSR_MSTATUSH) & (1<<CSR_MSTATUSH_MBE)) {
292 40 zero_gravi
    neorv32_uart_printf("big\n");
293
  }
294
  else {
295
    neorv32_uart_printf("little\n");
296
  }
297
 
298
  // CPU extensions
299 42 zero_gravi
  neorv32_uart_printf("Extensions:        ");
300 6 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MISA);
301
  for (i=0; i<26; i++) {
302
    if (tmp & (1 << i)) {
303
      c = (char)('A' + i);
304
      neorv32_uart_putc(c);
305
      neorv32_uart_putc(' ');
306
    }
307
  }
308 22 zero_gravi
 
309 40 zero_gravi
  // Z* CPU extensions (from custom "mzext" CSR)
310 22 zero_gravi
  tmp = neorv32_cpu_csr_read(CSR_MZEXT);
311 42 zero_gravi
  if (tmp & (1<<CSR_MZEXT_ZICSR)) {
312 22 zero_gravi
    neorv32_uart_printf("Zicsr ");
313
  }
314 42 zero_gravi
  if (tmp & (1<<CSR_MZEXT_ZIFENCEI)) {
315 22 zero_gravi
    neorv32_uart_printf("Zifencei ");
316
  }
317 6 zero_gravi
 
318 34 zero_gravi
  // check physical memory protection
319 42 zero_gravi
  neorv32_uart_printf("\nPMP:               ");
320
  uint32_t pmp_num_regions = neorv32_cpu_pmp_get_num_regions();
321
  if (pmp_num_regions != 0)  {
322 43 zero_gravi
    neorv32_uart_printf("%u regions, %u bytes minimal granularity\n", pmp_num_regions, neorv32_cpu_pmp_get_granularity());
323 34 zero_gravi
  }
324
  else {
325
    neorv32_uart_printf("not implemented\n");
326
  }
327
 
328 43 zero_gravi
  // check hardware performance monitors
329 42 zero_gravi
  neorv32_uart_printf("HPM Counters:      %u\n", neorv32_cpu_hpm_get_counters());
330 34 zero_gravi
 
331 42 zero_gravi
 
332 34 zero_gravi
  // Misc - system
333 40 zero_gravi
  neorv32_uart_printf("\n\n---- Processor - General ----\n");
334 30 zero_gravi
  neorv32_uart_printf("Clock:   %u Hz\n", SYSINFO_CLK);
335
  neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
336 15 zero_gravi
 
337
 
338 6 zero_gravi
  // Memory configuration
339 40 zero_gravi
  neorv32_uart_printf("\n---- Processor - Memory Configuration ----\n");
340 6 zero_gravi
 
341 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
342 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
343 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
344 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
345 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
346 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
347 6 zero_gravi
 
348 42 zero_gravi
  neorv32_uart_printf("Data base address:    0x%x\n", SYSINFO_DSPACE_BASE);
349 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
350 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
351 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
352 6 zero_gravi
 
353 42 zero_gravi
  neorv32_uart_printf("Internal i-cache:     ");
354 41 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE));
355
  if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE)) {
356
    neorv32_uart_printf("- ");
357
 
358
    uint32_t ic_block_size = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F;
359
    if (ic_block_size) {
360
      ic_block_size = 1 << ic_block_size;
361
    }
362
    else {
363
      ic_block_size = 0;
364
    }
365
 
366
    uint32_t ic_num_blocks = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_NUM_BLOCKS_0) & 0x0F;
367
    if (ic_num_blocks) {
368
      ic_num_blocks = 1 << ic_num_blocks;
369
    }
370
    else {
371
      ic_num_blocks = 0;
372
    }
373
 
374
    uint32_t ic_associativity = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_ASSOCIATIVITY_0) & 0x0F;
375
    ic_associativity = 1 << ic_associativity;
376
 
377
    neorv32_uart_printf("%u bytes (%u set(s), %u block(s) per set, %u bytes per block), ", ic_associativity*ic_num_blocks*ic_block_size, ic_associativity, ic_num_blocks, ic_block_size);
378
    if (ic_associativity == 0) {
379
      neorv32_uart_printf("direct-mapped\n");
380
    }
381
    else if (ic_associativity == ic_num_blocks) {
382
      neorv32_uart_printf("%u-way set-associative\n", ic_associativity);
383
    }
384
    else {
385
      neorv32_uart_printf("fully-associative\n");
386
    }
387
  }
388
 
389 42 zero_gravi
  neorv32_uart_printf("Bootloader:           ");
390 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
391 6 zero_gravi
 
392 42 zero_gravi
  neorv32_uart_printf("Ext. bus interface:   ");
393 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
394 42 zero_gravi
  neorv32_uart_printf("Ext. bus Endianness:  ");
395 40 zero_gravi
  if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) {
396
    neorv32_uart_printf("big\n");
397
  }
398
  else {
399
    neorv32_uart_printf("little\n");
400
  }
401 6 zero_gravi
 
402
  // peripherals
403 40 zero_gravi
  neorv32_uart_printf("\n\n---- Processor - Peripherals ----\n");
404 15 zero_gravi
 
405 12 zero_gravi
  tmp = SYSINFO_FEATURES;
406 6 zero_gravi
 
407 39 zero_gravi
  neorv32_uart_printf("GPIO  - ");
408 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
409 6 zero_gravi
 
410 39 zero_gravi
  neorv32_uart_printf("MTIME - ");
411 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
412 6 zero_gravi
 
413 39 zero_gravi
  neorv32_uart_printf("UART  - ");
414 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
415 6 zero_gravi
 
416 39 zero_gravi
  neorv32_uart_printf("SPI   - ");
417 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
418 6 zero_gravi
 
419 39 zero_gravi
  neorv32_uart_printf("TWI   - ");
420 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
421 6 zero_gravi
 
422 39 zero_gravi
  neorv32_uart_printf("PWM   - ");
423 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
424 6 zero_gravi
 
425 39 zero_gravi
  neorv32_uart_printf("WDT   - ");
426 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
427 6 zero_gravi
 
428 39 zero_gravi
  neorv32_uart_printf("TRNG  - ");
429 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
430 6 zero_gravi
 
431 39 zero_gravi
  neorv32_uart_printf("CFU0  - ");
432 34 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU0));
433
 
434 39 zero_gravi
  neorv32_uart_printf("CFU1  - ");
435 34 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU1));
436 6 zero_gravi
}
437
 
438
 
439
/**********************************************************************//**
440
 * NEORV32 runtime environment: Private function to print true or false.
441
 * @note This function is used by neorv32_rte_print_hw_config(void) only.
442
 *
443
 * @param[in] state Print TRUE when !=0, print FALSE when 0
444
 **************************************************************************/
445
static void __neorv32_rte_print_true_false(int state) {
446
 
447
  if (state) {
448 33 zero_gravi
    neorv32_uart_print("True\n");
449 6 zero_gravi
  }
450 2 zero_gravi
  else {
451 33 zero_gravi
    neorv32_uart_print("False\n");
452 2 zero_gravi
  }
453 6 zero_gravi
}
454 2 zero_gravi
 
455
 
456 6 zero_gravi
/**********************************************************************//**
457 33 zero_gravi
 * NEORV32 runtime environment: Private function to print 32-bit number
458
 * as 8-digit hexadecimal value (with "0x" suffix).
459
 *
460
 * @param[in] num Number to print as hexadecimal.
461
 **************************************************************************/
462
void __neorv32_rte_print_hex_word(uint32_t num) {
463
 
464
  static const char hex_symbols[16] = "0123456789ABCDEF";
465
 
466
  neorv32_uart_print("0x");
467
 
468
  int i;
469
  for (i=0; i<8; i++) {
470
    uint32_t index = (num >> (28 - 4*i)) & 0xF;
471
    neorv32_uart_putc(hex_symbols[index]);
472
  }
473
}
474
 
475
 
476
 
477
/**********************************************************************//**
478 41 zero_gravi
 * NEORV32 runtime environment: Print the processor version in human-readable format.
479 6 zero_gravi
 **************************************************************************/
480 12 zero_gravi
void neorv32_rte_print_hw_version(void) {
481 6 zero_gravi
 
482
  uint32_t i;
483
  char tmp, cnt;
484
 
485
  for (i=0; i<4; i++) {
486
 
487 33 zero_gravi
    tmp = (char)(neorv32_cpu_csr_read(CSR_MIMPID) >> (24 - 8*i));
488 6 zero_gravi
 
489
    // serial division
490
    cnt = 0;
491 35 zero_gravi
    while (tmp >= 16) {
492
      tmp = tmp - 16;
493 6 zero_gravi
      cnt++;
494
    }
495
 
496
    if (cnt) {
497
      neorv32_uart_putc('0' + cnt);
498
    }
499
    neorv32_uart_putc('0' + tmp);
500
    if (i < 3) {
501
      neorv32_uart_putc('.');
502
    }
503
  }
504 2 zero_gravi
}
505 11 zero_gravi
 
506
 
507
/**********************************************************************//**
508
 * NEORV32 runtime environment: Print project credits
509
 **************************************************************************/
510
void neorv32_rte_print_credits(void) {
511
 
512 42 zero_gravi
  neorv32_uart_print("The NEORV32 Processor Project\n"
513
                     "Copyright 2021, Stephan Nolting\n"
514
                     "BSD 3-Clause License\n"
515 39 zero_gravi
                     "https://github.com/stnolting/neorv32\n\n");
516 11 zero_gravi
}
517
 
518 22 zero_gravi
 
519
/**********************************************************************//**
520 41 zero_gravi
 * NEORV32 runtime environment: Print project logo
521 37 zero_gravi
 **************************************************************************/
522
void neorv32_rte_print_logo(void) {
523
 
524 40 zero_gravi
  const uint32_t logo_data_c[11][4] =
525
  {
526
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000},
527
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
528
    {0b01100000110001111111110001111111,0b10000111111110001100000011000111,0b11111000011111111000000110000000,0b11111111111111110000000000000000},
529
    {0b11110000110011000000000011000000,0b11001100000011001100000011001100,0b00001100110000001100000110000011,0b11000000000000111100000000000000},
530
    {0b11011000110011000000000011000000,0b11001100000011001100000011000000,0b00001100000000011000000110000000,0b11000111111000110000000000000000},
531
    {0b11001100110011111111100011000000,0b11001111111110001100000011000000,0b11111000000001100000000110000011,0b11000111111000111100000000000000},
532
    {0b11000110110011000000000011000000,0b11001100001100000110000110000000,0b00001100000110000000000110000000,0b11000111111000110000000000000000},
533
    {0b11000011110011000000000011000000,0b11001100000110000011001100001100,0b00001100011000000000000110000011,0b11000000000000111100000000000000},
534
    {0b11000001100001111111110001111111,0b10001100000011000000110000000111,0b11111000111111111100000110000000,0b11111111111111110000000000000000},
535
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
536
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000}
537
  };
538
 
539
  int u,v,w;
540
  uint32_t tmp;
541
 
542
  for (u=0; u<11; u++) {
543
    neorv32_uart_print("\n");
544
    for (v=0; v<4; v++) {
545
      tmp = logo_data_c[u][v];
546
      for (w=0; w<32; w++){
547
        if (tmp & (1 << (31-w))) {
548
          neorv32_uart_putc('#');
549
        }
550
        else {
551
          neorv32_uart_putc(' ');
552
        }
553
      }
554
    }
555
  }
556
  neorv32_uart_print("\n");
557 37 zero_gravi
}
558
 
559
 
560
/**********************************************************************//**
561 22 zero_gravi
 * NEORV32 runtime environment: Print project license
562
 **************************************************************************/
563
void neorv32_rte_print_license(void) {
564
 
565
  neorv32_uart_print(
566
  "\n"
567
  "BSD 3-Clause License\n"
568
  "\n"
569 42 zero_gravi
  "Copyright (c) 2021, Stephan Nolting. All rights reserved.\n"
570 22 zero_gravi
  "\n"
571
  "Redistribution and use in source and binary forms, with or without modification, are\n"
572
  "permitted provided that the following conditions are met:\n"
573
  "\n"
574
  "1. Redistributions of source code must retain the above copyright notice, this list of\n"
575
  "   conditions and the following disclaimer.\n"
576
  "\n"
577
  "2. Redistributions in binary form must reproduce the above copyright notice, this list of\n"
578
  "   conditions and the following disclaimer in the documentation and/or other materials\n"
579
  "   provided with the distribution.\n"
580
  "\n"
581
  "3. Neither the name of the copyright holder nor the names of its contributors may be used to\n"
582
  "   endorse or promote products derived from this software without specific prior written\n"
583
  "   permission.\n"
584
  "\n"
585
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n"
586
  "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
587
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
588
  "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n"
589
  "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
590
  "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
591
  "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
592
  "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"
593
  "OF THE POSSIBILITY OF SUCH DAMAGE.\n"
594
  "\n"
595
  "\n"
596
  );
597
}
598
 

powered by: WebSVN 2.1.0

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