lowRISC / lowRISC/opentitan

[verilator] simulation hangs when running buggy firmware

Open
#22,012 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
SystemVerilog
Stars
3.6k
Forks
1.1k
Avg merge
2d 22h
Merged PRs (30d)
141

Description

### Description

Discovered during zephyr bringup on earlgrey. The default board config was using a stale value for the number of interrupts supported by the PLIC (`184` instead of `182`). This number then translates to zephyr's initialization sequence for the PLIC, where all interrupts are initialized. What's observed is that when the `sys_write32()` walks off the end of the PLIC config space (index @183), verilator "hangs".

I didn't look too closely at the verilator thread stacks, but the symptoms are that all the verilator threads get stuck in event handling at this point (corresponding CPU cores are pegged).

from `drivers/interrupt_controller/intc_plic.c` in the zephyr repo. Verilator gets stuck at line 23, a graceful crash / test fail would be preferable behavior.

```
1 static int plic_init(const struct device *dev)
2 {
3 const struct plic_config *config = dev->config;
4 mem_addr_t en_addr, thres_prio_addr;
5 mem_addr_t prio_addr = config->prio;
6
7 /* Iterate through each of the contexts, HART + PRIV */
8 for (uint32_t cpu_num = 0; cpu_num < arch_num_cpus(); cpu_num++) {
9 en_addr = get_context_en_addr(dev, cpu_num);
10 thres_prio_addr = get_threshold_priority_addr(dev, cpu_num);
11
12 /* Ensure that all interrupts are disabled initially */
13 for (uint32_t i = 0; i < get_plic_enabled_size(dev); i++) {
14 sys_write32(0U, en_addr + (i * sizeof(uint32_t)));
15 }
16
17 /* Set threshold priority to 0 */
18 sys_write32(0U, thres_prio_addr);
19 }
20
21 /* Set priority of each interrupt line to 0 initially */
22 for (uint32_t i = 0; i < config->num_irqs; i++) {
23 sys_write32(0U, prio_addr + (i * sizeof(uint32_t)));
24 }
25
26 /* Configure IRQ for PLIC driver */
27 config->irq_config_func();
28
29 return 0;
30 }
```

Fixing the PLIC device configuration makes boot work again: https://github.com/zephyrproject-rtos/zephyr/pull/70123/commits/0c007a705de72698f1843d32ec5591195fdb1ad0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the earlgrey Zephyr bringup with the PLIC configuration mismatch, starting from drivers/interrupt_controller/intc_plic.c and its sys_write32() at line 23. Trace how Verilator handles the out-of-range PLIC access at index 183. Done means the simulation fails or crashes gracefully instead of hanging, while valid PLIC configuration still boots.

Written by the indexing model from the issue text.

Assessment

Domain
testing, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.