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

Subversion Repositories neorv32

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

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 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
  if (neorv32_cpu_csr_read(CSR_MSTATUSH) & (1<<CPU_MSTATUSH_MBE)) {
292
    neorv32_uart_printf("big\n");
293
  }
294
  else {
295
    neorv32_uart_printf("little\n");
296
  }
297
 
298
  // CPU extensions
299 30 zero_gravi
  neorv32_uart_printf("\nExtensions:        ");
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 33 zero_gravi
  if (tmp & (1<<CPU_MZEXT_ZICSR)) {
312 22 zero_gravi
    neorv32_uart_printf("Zicsr ");
313
  }
314 33 zero_gravi
  if (tmp & (1<<CPU_MZEXT_ZIFENCEI)) {
315 22 zero_gravi
    neorv32_uart_printf("Zifencei ");
316
  }
317 33 zero_gravi
  if (tmp & (1<<CPU_MZEXT_PMP)) {
318
    neorv32_uart_printf("PMP ");
319
  }
320 6 zero_gravi
 
321
 
322 34 zero_gravi
  // check physical memory protection
323
  neorv32_uart_printf("\n\nPhysical memory protection: ");
324
  if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP))  {
325
 
326 40 zero_gravi
    // get minimal region siz (granulartiy)
327
    neorv32_uart_printf("\n- Minimal granularity: %u bytes per region\n", neorv32_cpu_pmp_get_granularity());
328 34 zero_gravi
 
329
    // test available modes
330
    neorv32_uart_printf("- Mode TOR:   ");
331
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
332
    if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x08) {
333
      neorv32_uart_printf("available\n");
334
    }
335
    else {
336
      neorv32_uart_printf("not implemented\n");
337
    }
338
 
339
    neorv32_uart_printf("- Mode NA4:   ");
340
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0x10);
341
    if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x10) {
342
      neorv32_uart_printf("available\n");
343
    }
344
    else {
345
      neorv32_uart_printf("not implemented\n");
346
    }
347
 
348
    neorv32_uart_printf("- Mode NAPOT: ");
349
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0x18);
350
    if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x18) {
351
      neorv32_uart_printf("available\n");
352
    }
353
    else {
354
      neorv32_uart_printf("not implemented\n");
355
    }
356
 
357
    // deactivate entry
358
    neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
359
  }
360
  else {
361
    neorv32_uart_printf("not implemented\n");
362
  }
363
 
364
 
365
  // Misc - system
366 40 zero_gravi
  neorv32_uart_printf("\n\n---- Processor - General ----\n");
367 30 zero_gravi
  neorv32_uart_printf("Clock:   %u Hz\n", SYSINFO_CLK);
368
  neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
369 15 zero_gravi
 
370
 
371 6 zero_gravi
  // Memory configuration
372 40 zero_gravi
  neorv32_uart_printf("\n---- Processor - Memory Configuration ----\n");
373 6 zero_gravi
 
374 23 zero_gravi
  neorv32_uart_printf("Instr. base address:  0x%x\n", SYSINFO_ISPACE_BASE);
375 6 zero_gravi
  neorv32_uart_printf("Internal IMEM:        ");
376 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
377 23 zero_gravi
  neorv32_uart_printf("IMEM size:            %u bytes\n", SYSINFO_IMEM_SIZE);
378 6 zero_gravi
  neorv32_uart_printf("Internal IMEM as ROM: ");
379 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
380 6 zero_gravi
 
381 40 zero_gravi
  neorv32_uart_printf("\nData base address:    0x%x\n", SYSINFO_DSPACE_BASE);
382 6 zero_gravi
  neorv32_uart_printf("Internal DMEM:        ");
383 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
384 23 zero_gravi
  neorv32_uart_printf("DMEM size:            %u bytes\n", SYSINFO_DMEM_SIZE);
385 6 zero_gravi
 
386 41 zero_gravi
  neorv32_uart_printf("\nInternal i-cache:     ");
387
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE));
388
  if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE)) {
389
    neorv32_uart_printf("- ");
390
 
391
    uint32_t ic_block_size = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F;
392
    if (ic_block_size) {
393
      ic_block_size = 1 << ic_block_size;
394
    }
395
    else {
396
      ic_block_size = 0;
397
    }
398
 
399
    uint32_t ic_num_blocks = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_NUM_BLOCKS_0) & 0x0F;
400
    if (ic_num_blocks) {
401
      ic_num_blocks = 1 << ic_num_blocks;
402
    }
403
    else {
404
      ic_num_blocks = 0;
405
    }
406
 
407
    uint32_t ic_associativity = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_ASSOCIATIVITY_0) & 0x0F;
408
    ic_associativity = 1 << ic_associativity;
409
 
410
    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);
411
    if (ic_associativity == 0) {
412
      neorv32_uart_printf("direct-mapped\n");
413
    }
414
    else if (ic_associativity == ic_num_blocks) {
415
      neorv32_uart_printf("%u-way set-associative\n", ic_associativity);
416
    }
417
    else {
418
      neorv32_uart_printf("fully-associative\n");
419
    }
420
  }
421
 
422
  neorv32_uart_printf("\nBootloader:           ");
423 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
424 6 zero_gravi
 
425 40 zero_gravi
  neorv32_uart_printf("\nExternal memory bus interface:  ");
426 12 zero_gravi
  __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
427 40 zero_gravi
  neorv32_uart_printf("External memory bus Endianness: ");
428
  if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) {
429
    neorv32_uart_printf("big\n");
430
  }
431
  else {
432
    neorv32_uart_printf("little\n");
433
  }
434 6 zero_gravi
 
435
  // peripherals
436 40 zero_gravi
  neorv32_uart_printf("\n\n---- Processor - Peripherals ----\n");
437 15 zero_gravi
 
438 12 zero_gravi
  tmp = SYSINFO_FEATURES;
439 6 zero_gravi
 
440 39 zero_gravi
  neorv32_uart_printf("GPIO  - ");
441 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
442 6 zero_gravi
 
443 39 zero_gravi
  neorv32_uart_printf("MTIME - ");
444 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
445 6 zero_gravi
 
446 39 zero_gravi
  neorv32_uart_printf("UART  - ");
447 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
448 6 zero_gravi
 
449 39 zero_gravi
  neorv32_uart_printf("SPI   - ");
450 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
451 6 zero_gravi
 
452 39 zero_gravi
  neorv32_uart_printf("TWI   - ");
453 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
454 6 zero_gravi
 
455 39 zero_gravi
  neorv32_uart_printf("PWM   - ");
456 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
457 6 zero_gravi
 
458 39 zero_gravi
  neorv32_uart_printf("WDT   - ");
459 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
460 6 zero_gravi
 
461 39 zero_gravi
  neorv32_uart_printf("TRNG  - ");
462 12 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
463 6 zero_gravi
 
464 39 zero_gravi
  neorv32_uart_printf("CFU0  - ");
465 34 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU0));
466
 
467 39 zero_gravi
  neorv32_uart_printf("CFU1  - ");
468 34 zero_gravi
  __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU1));
469 6 zero_gravi
}
470
 
471
 
472
/**********************************************************************//**
473
 * NEORV32 runtime environment: Private function to print true or false.
474
 * @note This function is used by neorv32_rte_print_hw_config(void) only.
475
 *
476
 * @param[in] state Print TRUE when !=0, print FALSE when 0
477
 **************************************************************************/
478
static void __neorv32_rte_print_true_false(int state) {
479
 
480
  if (state) {
481 33 zero_gravi
    neorv32_uart_print("True\n");
482 6 zero_gravi
  }
483 2 zero_gravi
  else {
484 33 zero_gravi
    neorv32_uart_print("False\n");
485 2 zero_gravi
  }
486 6 zero_gravi
}
487 2 zero_gravi
 
488
 
489 6 zero_gravi
/**********************************************************************//**
490 33 zero_gravi
 * NEORV32 runtime environment: Private function to print 32-bit number
491
 * as 8-digit hexadecimal value (with "0x" suffix).
492
 *
493
 * @param[in] num Number to print as hexadecimal.
494
 **************************************************************************/
495
void __neorv32_rte_print_hex_word(uint32_t num) {
496
 
497
  static const char hex_symbols[16] = "0123456789ABCDEF";
498
 
499
  neorv32_uart_print("0x");
500
 
501
  int i;
502
  for (i=0; i<8; i++) {
503
    uint32_t index = (num >> (28 - 4*i)) & 0xF;
504
    neorv32_uart_putc(hex_symbols[index]);
505
  }
506
}
507
 
508
 
509
 
510
/**********************************************************************//**
511 41 zero_gravi
 * NEORV32 runtime environment: Print the processor version in human-readable format.
512 6 zero_gravi
 **************************************************************************/
513 12 zero_gravi
void neorv32_rte_print_hw_version(void) {
514 6 zero_gravi
 
515
  uint32_t i;
516
  char tmp, cnt;
517
 
518
  for (i=0; i<4; i++) {
519
 
520 33 zero_gravi
    tmp = (char)(neorv32_cpu_csr_read(CSR_MIMPID) >> (24 - 8*i));
521 6 zero_gravi
 
522
    // serial division
523
    cnt = 0;
524 35 zero_gravi
    while (tmp >= 16) {
525
      tmp = tmp - 16;
526 6 zero_gravi
      cnt++;
527
    }
528
 
529
    if (cnt) {
530
      neorv32_uart_putc('0' + cnt);
531
    }
532
    neorv32_uart_putc('0' + tmp);
533
    if (i < 3) {
534
      neorv32_uart_putc('.');
535
    }
536
  }
537 2 zero_gravi
}
538 11 zero_gravi
 
539
 
540
/**********************************************************************//**
541
 * NEORV32 runtime environment: Print project credits
542
 **************************************************************************/
543
void neorv32_rte_print_credits(void) {
544
 
545 39 zero_gravi
  neorv32_uart_print("The NEORV32 Processor Project by Stephan Nolting\n"
546
                     "https://github.com/stnolting/neorv32\n\n");
547 11 zero_gravi
}
548
 
549 22 zero_gravi
 
550
/**********************************************************************//**
551 41 zero_gravi
 * NEORV32 runtime environment: Print project logo
552 37 zero_gravi
 **************************************************************************/
553
void neorv32_rte_print_logo(void) {
554
 
555 40 zero_gravi
  const uint32_t logo_data_c[11][4] =
556
  {
557
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000},
558
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
559
    {0b01100000110001111111110001111111,0b10000111111110001100000011000111,0b11111000011111111000000110000000,0b11111111111111110000000000000000},
560
    {0b11110000110011000000000011000000,0b11001100000011001100000011001100,0b00001100110000001100000110000011,0b11000000000000111100000000000000},
561
    {0b11011000110011000000000011000000,0b11001100000011001100000011000000,0b00001100000000011000000110000000,0b11000111111000110000000000000000},
562
    {0b11001100110011111111100011000000,0b11001111111110001100000011000000,0b11111000000001100000000110000011,0b11000111111000111100000000000000},
563
    {0b11000110110011000000000011000000,0b11001100001100000110000110000000,0b00001100000110000000000110000000,0b11000111111000110000000000000000},
564
    {0b11000011110011000000000011000000,0b11001100000110000011001100001100,0b00001100011000000000000110000011,0b11000000000000111100000000000000},
565
    {0b11000001100001111111110001111111,0b10001100000011000000110000000111,0b11111000111111111100000110000000,0b11111111111111110000000000000000},
566
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
567
    {0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000}
568
  };
569
 
570
  int u,v,w;
571
  uint32_t tmp;
572
 
573
  for (u=0; u<11; u++) {
574
    neorv32_uart_print("\n");
575
    for (v=0; v<4; v++) {
576
      tmp = logo_data_c[u][v];
577
      for (w=0; w<32; w++){
578
        if (tmp & (1 << (31-w))) {
579
          neorv32_uart_putc('#');
580
        }
581
        else {
582
          neorv32_uart_putc(' ');
583
        }
584
      }
585
    }
586
  }
587
  neorv32_uart_print("\n");
588 37 zero_gravi
}
589
 
590
 
591
/**********************************************************************//**
592 22 zero_gravi
 * NEORV32 runtime environment: Print project license
593
 **************************************************************************/
594
void neorv32_rte_print_license(void) {
595
 
596
  neorv32_uart_print(
597
  "\n"
598
  "BSD 3-Clause License\n"
599
  "\n"
600
  "Copyright (c) 2020, Stephan Nolting. All rights reserved.\n"
601
  "\n"
602
  "Redistribution and use in source and binary forms, with or without modification, are\n"
603
  "permitted provided that the following conditions are met:\n"
604
  "\n"
605
  "1. Redistributions of source code must retain the above copyright notice, this list of\n"
606
  "   conditions and the following disclaimer.\n"
607
  "\n"
608
  "2. Redistributions in binary form must reproduce the above copyright notice, this list of\n"
609
  "   conditions and the following disclaimer in the documentation and/or other materials\n"
610
  "   provided with the distribution.\n"
611
  "\n"
612
  "3. Neither the name of the copyright holder nor the names of its contributors may be used to\n"
613
  "   endorse or promote products derived from this software without specific prior written\n"
614
  "   permission.\n"
615
  "\n"
616
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n"
617
  "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
618
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
619
  "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n"
620
  "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
621
  "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n"
622
  "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
623
  "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n"
624
  "OF THE POSSIBILITY OF SUCH DAMAGE.\n"
625
  "\n"
626
  "\n"
627
  );
628
}
629
 

powered by: WebSVN 2.1.0

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