Merge pull request #366 from stnolting/csr_reset

[rtl] reset all "core" CSRs to zero
This commit is contained in:
Stephan Nolting 2022-07-14 16:04:56 +02:00 committed by GitHub
commit fc4f14c91e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 175 additions and 231 deletions

View file

@ -32,6 +32,7 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12
| Date (*dd.mm.yyyy*) | Version | Comment |
|:-------------------:|:-------:|:--------|
| 14.07.2022 | 1.7.3.11 | reset all "core" CSRs to all-zero; [#366](https://github.com/stnolting/neorv32/pull/366) |
| 13.07.2022 | 1.7.3.10 | :bug: reworked/fixed **physical memory protection**; :sparkles: added `mstatus.MPRV` flag; [#365](https://github.com/stnolting/neorv32/pull/365) |
| 12.07.2022 | 1.7.3.9 | clean-up and rework **bootloader**; :sparkles: add "boot via XIP" option; [#364](https://github.com/stnolting/neorv32/pull/364) |
| 11.07.2022 | 1.7.3.8 | **physical memory protection(PMP)**: locking entry `i` in TOR mode will now also prevent write access to `pmpaddr(i-1)` (RISC-V compatibility); [#363](https://github.com/stnolting/neorv32/pull/363) |

View file

@ -999,7 +999,7 @@ memory system to perform the necessary operations (for example a cache flush and
In order to reduce routing constraints (and by this the actual hardware requirements), most uncritical
registers of the NEORV32 CPU as well as most register of the whole NEORV32 Processor do not use **a
dedicated hardware reset**. "Uncritical registers" in this context means that the initial value of these registers
after power-up is not relevant for a defined CPU boot process.
after power-up/reset is not relevant for a defined CPU boot process.
**Rationale**
@ -1016,26 +1016,19 @@ this example "uncritical registers".
**NEORV32 CPU Reset**
In terms of the NEORV32 CPU, there are several pipeline registers, state machine registers and even status
In terms of the NEORV32 CPU, there are several pipeline registers, state machine registers and even some status
and control registers (CSRs) that do not require a defined initial state to ensure a correct boot process. The
pipeline register will get initialized by the CPU's internal state machines, which are initialized from the main
control engine that actually features a defined reset. The initialization of most of the CPU's core CSRs (like
interrupt control) is done by the software (to be more specific, this is done by the `crt0.S` start-up code).
During the very early boot process (where `crt0.S` is running) there is no chance for undefined behavior due to
the lack of dedicated hardware resets of certain CSRs. For example the machine interrupt-enable CSR <<_mie>>
does not provide a dedicated reset. The value after reset of this register is uncritical as interrupts cannot fire
because the global interrupt enabled flag in the status register (`mstatsus(mie)`) _do_ provide a dedicated
hardware reset setting this bit to low (globally disabling interrupts).
control engine that actually features a defined reset.
**Reset Configuration**
Most CPU-internal register do provide an asynchronous reset in the VHDL code, but the "don't care" value
(VHDL `'-'`) is used for initialization of all uncritical registers, effectively generating a flip-flop without a
(VHDL `'-'`) is used for initialization of all uncritical registers - effectively generating a flip-flop without a
reset. However, certain applications or situations (like advanced gate-level / timing simulations) might
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of all CPU registers can
be enabled by enabling a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`):
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of most CPU registers can
be configured by enabling a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`):
[source,vhdl]
----

View file

@ -2,7 +2,7 @@
:sectnums:
=== Control and Status Registers (CSRs)
The following table shows a summary of all available CSRs. The address field defines the CSR address for
The following table shows a summary of all available NEORV32 CSRs. The address field defines the CSR address for
the CSR access instructions. The *[ASM]* name can be used for (inline) assembly code and is directly
understood by the assembler/compiler. The *[C]* names are defined by the NEORV32 core library and can be
used as immediate in plain C code. The *R/W* column shows whether the CSR can be read and/or written.
@ -10,59 +10,27 @@ The NEORV32-specific CSRs are mapped to the official "custom CSRs" CSR address s
.Mandatory `Zicsr` Extension
[IMPORTANT]
The CSRs, the CSR-related instructions and the complete exception/interrupt processing
system are only available when the <<_cpu_extension_riscv_zicsr>> generic is _true_.
.CSR Access Exception
[IMPORTANT]
When trying to write to a read-only CSR (like the `time` CSR) or when trying to access a nonexistent
CSR or when trying to access a machine-mode CSR from less-privileged user-mode an
illegal instruction exception is raised.
The CSRs, the CSR-related instructions and the complete privileged architecture including interrupts and exceptions
are only available when the <<_cpu_extension_riscv_zicsr>> generic is enabled.
.CSR Reset Value
[IMPORTANT]
Please note that most of the CSRs do *NOT* provide a dedicated reset. Hence,
these CSRs are not initialized by a hardware reset and provide an *UNDEFINED* value until they are
explicitly initialized by the software (normally, this is done by the NEORV32-specific
`crt0.S` start-up code). For more information see section <<_cpu_hardware_reset>>.
**CSR Listing**
The description of each single CSR provides the following summary:
.CSR description
[cols="4,27,>7"]
[frame="topbot",grid="none"]
|=======================
| _Address_ | _Description_ | _ASM alias_
3+| Reset value: _CSR content after hardware reset_ (also see <<_cpu_hardware_reset>>)
3+| _Detailed description_
|=======================
Please note that some CSRs do *not* provide a dedicated reset. Hence, these CSRs are not initialized by a
hardware reset and provide an **UNDEFINED** after reset. In general, all CSRs should be explicitly initialized
by software before being used.
.Not Implemented CSRs / CSR Bits
[IMPORTANT]
All CSR bits that are unused / not implemented / not shown are _hardwired to zero_. All CSRs that are not
implemented at all (and are not "disabled" using certain configuration generics) will trigger an exception on
access. The CSR that are implemented within the NEORV32 might cause an exception if they are disabled.
See the according CSR description for more information.
implemented (not supported or disabled) will raise an illegal instruction exception if accessed.
.Debug Mode CSRs
[IMPORTANT]
The _debug mode_ CSRs are not listed here since they are accessible only in debug mode and not during _normal_ CPU operation.
See section <<_cpu_debug_mode_csrs>> for more information.
.Debug-Mode CSRs
[NOTE]
The CSRs related to the CPU's debug mode (used by the <<_on_chip_debugger_ocd>>) are not listed here as they are
not accessible by "normal" software. See sections <<_cpu_debug_mode_csrs>> and <<_trigger_module_csrs>> for more
information about those CSRs.
<<<
// ####################################################################################################################
**CSR Listing Notes**
CSRs with the following notes ...
* `X`: _custom_ - have or are a custom CPU-specific extension (which is allowed by the RISC-V specs)
* `R`: _read-only_ - are read-only (in contrast to the originally specified r/w capability)
* `C`: _constrained_ - have a constrained compatibility, not all specified bits are implemented
.NEORV32 Control and Status Registers (CSRs)
[cols="<6,<11,<16,^3,<25,^3"]
[options="header"]
@ -118,10 +86,11 @@ CSRs with the following notes ...
| 0xfc0 | <<_mxisa>> | _CSR_MXISA_ | r/- | NEORV32-specific "extended" machine CPU ISA and extensions | `X`
|=======================
.Debug-Mode CSRs
[NOTE]
The CSRs related to the CPU's debug mode (used by the on-chip debugger) are not listed here as they are not accessible by
normal software. See sections <<_cpu_debug_mode_csrs>> and <<_trigger_module_csrs>> for more information about those CSRs.
**CSR Annotations**
* `X`: _custom_ - have or are a custom CPU-specific extension (which is allowed by the RISC-V specs)
* `R`: _read-only_ - are read-only (in contrast to the originally specified r/w capability)
* `C`: _constrained_ - have a constrained compatibility, not all specified bits are implemented
<<<
@ -140,7 +109,7 @@ Otherwise any access to the floating-point CSRs will raise an illegal instructio
[frame="topbot",grid="none"]
|=======================
| 0x001 | **Floating-point accrued exceptions** | `fflags`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `fflags` CSR is compatible to the RISC-V specifications. It shows the accrued ("accumulated")
exception flags in the lowest 5 bits. This CSR is only available if a floating-point CPU extension is enabled.
See the RISC-V ISA spec for more information.
@ -154,7 +123,7 @@ See the RISC-V ISA spec for more information.
[frame="topbot",grid="none"]
|=======================
| 0x002 | **Floating-point dynamic rounding mode** | `frm`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `frm` CSR is compatible to the RISC-V specifications and is used to configure the rounding modes using
the lowest 3 bits. This CSR is only available if a floating-point CPU extension is enabled. See the RISC-V
ISA spec for more information.
@ -168,7 +137,7 @@ ISA spec for more information.
[frame="topbot",grid="none"]
|=======================
| 0x003 | **Floating-point control and status register** | `fcsr`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `fcsr` CSR is compatible to the RISC-V specifications. It provides combined read/write access to the
`fflags` and `frm` CSRs. This CSR is only available if a floating-point CPU extension is enabled. See the
RISC-V ISA spec for more information.
@ -187,7 +156,7 @@ RISC-V ISA spec for more information.
[frame="topbot",grid="none"]
|=======================
| 0x30a | **Machine environment configuration register** | `menvcfg`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The features of this CSR are not implemented yet. The register is read-only. NOTE: This register
only exists if the `U` ISA extensions is enabled.
|=======================
@ -200,7 +169,7 @@ only exists if the `U` ISA extensions is enabled.
[frame="topbot",grid="none"]
|=======================
| 0x31a | **Machine environment configuration register - high word** | `menvcfgh`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The features of this CSR are not implemented yet. The register is read-only. NOTE: This register
only exists if the `U` ISA extensions is enabled.
|=======================
@ -218,7 +187,7 @@ only exists if the `U` ISA extensions is enabled.
[frame="topbot",grid="none"]
|=======================
| 0x300 | **Machine status register** | `mstatus`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mstatus` CSR is compatible to the RISC-V specifications. It shows the CPU's current execution state.
The following bits are implemented (all remaining bits are always zero and are read-only).
|=======================
@ -279,7 +248,7 @@ Machine-mode software can discover available `Z*` _sub-extensions_ (like `Zicsr`
[frame="topbot",grid="none"]
|=======================
| 0x304 | **Machine interrupt-enable register** | `mie`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mie` CSR is compatible to the RISC-V specifications and features custom extensions for the fast
interrupt channels. It is used to enabled specific interrupts sources. Please note that interrupts also have to be
globally enabled via the `CSR_MSTATUS_MIE` flag of the `mstatus` CSR. The following bits are implemented
@ -305,7 +274,7 @@ globally enabled via the `CSR_MSTATUS_MIE` flag of the `mstatus` CSR. The follow
[frame="topbot",grid="none"]
|=======================
| 0x305 | **Machine trap-handler base address** | `mtvec`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `mtvec` CSR is compatible to the RISC-V specifications. It stores the base address for ALL machine
traps. Thus, it defines the main entry point for exception/interrupt handling regardless of the actual trap
source. The lowest two bits of this register are always zero and cannot be modified (= address mode only).
@ -329,7 +298,7 @@ Hence, the trap handler's base address has to be aligned to a 4-byte boundary.
[frame="topbot",grid="none"]
|=======================
| 0x306 | **Machine counter enable** | `mcounteren`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mcounteren` CSR is compatible to the RISC-V specifications. The bits of this CSR define which
counter/timer CSR can be accessed (read) from code running in a less-privileged modes. For example,
if user-level code tries to read from a counter/timer CSR without enabled access, an illegal instruction
@ -361,7 +330,7 @@ CPU these bits are hardwired to zero. Hence, user-level software cannot access t
[frame="topbot",grid="none"]
|=======================
| 0x310 | **Machine status register - high word** | `mstatush`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mstatush` CSR is compatible to the RISC-V specifications. In combination with <<_mstatus>> it shows additional
execution state information. The NEORV32 `mstatush` CSR is read-only and all bits are hardwired to zero.
|=======================
@ -392,7 +361,7 @@ can be used by the exception/interrupt handler. The content pf this register aft
[frame="topbot",grid="none"]
|=======================
| 0x341 | **Machine exception program counter** | `mepc`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `mepc` CSR is compatible to the RISC-V specifications. For exceptions (like an illegal instruction) this
register provides the address of the exception-causing instruction. For Interrupt (like a machine timer
interrupt) this register provides the address of the next not-yet-executed instruction.
@ -405,7 +374,7 @@ interrupt) this register provides the address of the next not-yet-executed instr
[frame="topbot",grid="none"]
|=======================
| 0x342 | **Machine trap cause** | `mcause`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `mcause` CSR is compatible to the RISC-V specifications. It show the cause ID for a taken exception.
|=======================
@ -426,7 +395,7 @@ interrupt) this register provides the address of the next not-yet-executed instr
[frame="topbot",grid="none"]
|=======================
| 0x343 | **Machine bad address or instruction** | `mtval`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `mtval` CSR is compatible to the RISC-V specifications. When a trap is triggered, the CSR shows either
the faulting address (for misaligned/faulting load/store/fetch) or the faulting (decompressed) instruction word itself (for illegal
instructions). For all other exceptions (including interrupts) the CSR is set to zero.
@ -458,7 +427,7 @@ perform a memory load using the address stored in <<_mepc>>.
[frame="topbot",grid="none"]
|=======================
| 0x344 | **Machine interrupt Pending** | `mip`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mip` CSR is compatible to the RISC-V specifications and also provides custom extensions. It shows currently _pending_ interrupts.
The bits for the standard RISC-V interrupts are read-only. Hence, these interrupts cannot be cleared using the `mip` register and must
be cleared/acknowledged within the according interrupt-generating device.
@ -515,7 +484,7 @@ However, any access beyond `pmpcfg3` or `pmpaddr15`, which are the last physical
[frame="topbot",grid="none"]
|=======================
| 0x3a0 - 0x3a3| **Physical memory protection configuration registers** | `pmpcfg0` - `pmpcfg3`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `pmpcfg*` CSRs are compatible to the RISC-V specifications. They are used to configure the protected
regions, where each `pmpcfg*` CSR provides configuration bits for four regions (8-bit per region).
The actual number of available `pmpcfg` CSRs and CSR entries is defined by the <<_pmp_num_regions>> generic.
@ -548,7 +517,7 @@ See the RISC-V specs. for more information.
[frame="topbot",grid="none"]
|=======================
| 0x3b0 - 0x3bf| **Physical memory protection address registers** | `pmpaddr0` - `pmpaddr15`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| The `pmpaddr*` CSRs are compatible to the RISC-V specifications. They are used to configure bits 33:2 of the PMP region's
physical memory address. The actual number of available `pmpaddr` CSRs is defined by the <<_pmp_num_regions>> generic.
|=======================
@ -600,7 +569,7 @@ See section <<_cpu_debug_mode>> for more information.
|=======================
| 0xc00 | **Cycle counter - low word** | `cycle`
| 0xc80 | **Cycle counter - high word** | `cycleh`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| The `cycle[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit cycle
counter. The `cycle[h]` CSR is a read-only shadowed copy of the `mcycle[h]` CSR.
|=======================
@ -614,7 +583,7 @@ counter. The `cycle[h]` CSR is a read-only shadowed copy of the `mcycle[h]` CSR.
|=======================
| 0xc01 | **System time - low word** | `time`
| 0xc81 | **System time - high word** | `timeh`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `time[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit system
time. The system time is either generated by the processor-internal _MTIME_ system timer unit (if _IO_MTIME_EN_ = _true_) or can be provided by an
external timer unit via the processor's `mtime_i` signal (if _IO_MTIME_EN_ = _false_).
@ -630,7 +599,7 @@ CSR is read-only. Change the system time via the _MTIME_ unit.
|=======================
| 0xc02 | **Instructions-retired counter - low word** | `instret`
| 0xc82 | **Instructions-retired counter - high word** | `instreth`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| The `instret[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit retired
instructions counter. The `instret[h]` CSR is a read-only shadowed copy of the `minstret[h]` CSR.
|=======================
@ -644,7 +613,7 @@ instructions counter. The `instret[h]` CSR is a read-only shadowed copy of the `
|=======================
| 0xb00 | **Machine cycle counter - low word** | `mcycle`
| 0xb80 | **Machine cycle counter - high word** | `mcycleh`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| The `mcycle[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit cycle
counter. The `mcycle[h]` CSR can also be written when in machine mode and is mirrored to the `cycle[h]` CSR.
|=======================
@ -658,7 +627,7 @@ counter. The `mcycle[h]` CSR can also be written when in machine mode and is mir
|=======================
| 0xb02 | **Machine instructions-retired counter - low word** | `minstret`
| 0xb82 | **Machine instructions-retired counter - high word** | `minstreth`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| The `minstret[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit retired
instructions counter. The `minstret[h]` CSR also be written when in machine mode and is mirrored to the `instret[h]` CSR.
|=======================
@ -706,7 +675,7 @@ information) or when the CPU is in sleep-mode.
[frame="topbot",grid="none"]
|=======================
| 0x232 -0x33f | **Machine hardware performance monitor event selector** | `mhpmevent3` - `mhpmevent31`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mhpmevent*` CSRs are compatible to the RISC-V specifications. The value in these CSRs define
the architectural events that cause an increment of the according `mhpmcounter*[h]` counter(s). All available events are
listed in the table below. If more than one event is selected, the according counter will increment if _any_ of
@ -753,7 +722,7 @@ wait cycles (_HPMCNT_EVENT_WAIT_II_) as the CPU execution core is waiting for ne
|=======================
| 0xb03 - 0xb1f | **Machine hardware performance monitor - counter low** | `mhpmcounter3` - `mhpmcounter31`
| 0xb83 - 0xb9f | **Machine hardware performance monitor - counter high** | `mhpmcounter3h` - `mhpmcounter31h`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| The `mhpmcounter*[h]` CSRs are compatible to the RISC-V specifications. These CSRs provide the lower/upper 32-
bit of arbitrary event counters. The event(s) that trigger an increment of theses counters are selected via the according
`mhpmevent*` CSRs bits.
@ -772,7 +741,7 @@ bit of arbitrary event counters. The event(s) that trigger an increment of these
[frame="topbot",grid="none"]
|=======================
| 0x320 | **Machine counter-inhibit register** | `mcountinhibit`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mcountinhibit` CSR is compatible to the RISC-V specifications. The bits in this register define which
counter/timer CSR are allowed to perform an automatic increment. Automatic update is enabled if the
according bit in `mcountinhibit` is cleared. The following bits are implemented (all remaining bits are
@ -805,7 +774,7 @@ All machine information registers can only be accessed in machine mode and are r
[frame="topbot",grid="none"]
|=======================
| 0xf11 | **Machine vendor ID** | `mvendorid`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| The `mvendorid` CSR is compatible to the RISC-V specifications. It is read-only and always reads zero.
|=======================
@ -817,7 +786,7 @@ All machine information registers can only be accessed in machine mode and are r
[frame="topbot",grid="none"]
|=======================
| 0xf12 | **Machine architecture ID** | `marchid`
3+| Reset value: _0x00000013_
3+| Reset value: `0x00000013`
3+| The `marchid` CSR is compatible to the RISC-V specifications. It is read-only and shows the NEORV32
official _RISC-V open-source architecture ID_ (decimal: 19, 32-bit hexadecimal: 0x00000013).
|=======================
@ -845,7 +814,7 @@ NEORV32 as BCD-coded number (example: `mimpid` = _0x01020312_ → 01.02.03.12
| 0xf14 | **Machine hardware thread ID** | `mhartid`
3+| Reset value: _defined_
3+| The `mhartid` CSR is compatible to the RISC-V specifications. It is read-only and shows the core's hart ID,
which is assigned via the CPU's _HW_THREAD_ID_ generic.
which is assigned via the CPU's <<_hw_thread_id>> generic.
|=======================
@ -856,7 +825,7 @@ which is assigned via the CPU's _HW_THREAD_ID_ generic.
[frame="topbot",grid="none"]
|=======================
| 0xf15 | **Machine configuration pointer register** | `mconfigptr`
3+| Reset value: _0x00000000_
3+| Reset value: `0x00000000`
3+| This register holds a physical address (if not zero) that points to the base address of an architecture configuration structure.
Software can traverse this data structure to discover information about the harts, the platform, and their configuration.
**NOTE: Not assigned yet.**

View file

@ -214,7 +214,7 @@ their functionality.
[frame="topbot",grid="none"]
|======
| 0x04 | **Abstract data 0** | `data0`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| Basic read/write registers to be used with abstract command (for example to read/write data from/to CPU GPRs).
|======
@ -226,7 +226,7 @@ their functionality.
[frame="topbot",grid="none"]
|======
| 0x10 | **Debug module control register** | `dmcontrol`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| Control of the overall debug module and the hart. The following table shows all implemented bits. All remaining bits/bit-fields are configures as "zero" and are
read-only. Writing '1' to these bits/fields will be ignored.
|======
@ -251,7 +251,7 @@ read-only. Writing '1' to these bits/fields will be ignored.
[frame="topbot",grid="none"]
|======
| 0x11 | **Debug module status register** | `dmstatus`
3+| Reset value: 0x00000000
3+| Reset value: `0x00400082`
3+| Current status of the overall debug module and the hart. The entire register is read-only.
|======
@ -290,7 +290,7 @@ read-only. Writing '1' to these bits/fields will be ignored.
[frame="topbot",grid="none"]
|======
| 0x12 | **Hart information** | `hartinfo`
3+| Reset value: see below
3+| Reset value: _see below_
3+| This register gives information about the hart. The entire register is read-only.
|======
@ -315,7 +315,7 @@ read-only. Writing '1' to these bits/fields will be ignored.
[frame="topbot",grid="none"]
|======
| 0x16 | **Abstract control and status** | `abstracts`
3+| Reset value: see below
3+| Reset value: _see below_
3+| Command execution info and status.
|======
@ -350,7 +350,7 @@ Error codes in `cmderr` (highest priority first):
[frame="topbot",grid="none"]
|======
| 0x17 | **Abstract command** | `command`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| Writing this register will trigger the execution of an abstract command. New command can only be executed if
`cmderr` is zero. The entire register in write-only (reads will return zero).
|======
@ -382,7 +382,7 @@ hart's GPRs (abstract command register index `0x1000` - `0x101f`).
[frame="topbot",grid="none"]
|======
| 0x18 | **Abstract command auto-execution** | `abstractauto`
3+| Reset value: 0x00000000s
3+| Reset value: `0x00000000`
3+| Register to configure when a read/write access to a DM repeats execution of the last abstract command.
|======
@ -417,7 +417,7 @@ hart's GPRs (abstract command register index `0x1000` - `0x101f`).
[frame="topbot",grid="none"]
|======
| 0x40 | **Halt summary 0** | `haltsum0`
3+| Reset value: _UNDEFINED_
3+| Reset value: `UNDEFINED`
3+| Bit 0 of this register is set if the hart is halted (all remaining bits are always zero). The entire register is read-only.
|======
@ -578,7 +578,7 @@ is raised.
[frame="topbot",grid="none"]
|======
| 0x7b0 | **Debug control and status register** | `dcsr`
3+| Reset value: 0x40000000
3+| Reset value: `0x40000403`
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to configure debug mode and provides additional status information.
The following bits are implemented. The reaming bits are read-only and always read as zero.
|======
@ -620,7 +620,7 @@ Cause codes in `dcsr.cause` (highest priority first):
[frame="topbot",grid="none"]
|======
| 0x7b1 | **Debug program counter** | `dpc`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to store the current program counter when
debug mode is entered. The `dret` instruction will return to `dpc` by moving `dpc` to `pc`.
|======
@ -633,7 +633,7 @@ debug mode is entered. The `dret` instruction will return to `dpc` by moving `dp
[frame="topbot",grid="none"]
|======
| 0x7b2 | **Debug scratch register 0** | `dscratch0`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| The `dscratch0` CSR is compatible to the RISC-V debug spec. It provides a general purpose debug mode-only scratch register.
|======
@ -674,7 +674,7 @@ Hence, the CSRs of this module are only relevant for the debugger.
[frame="topbot",grid="none"]
|======
| 0x7a0 | **Trigger select register** | `tselect`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| This CSR is hardwired to zero indicating there is only one trigger available. Any write access is ignored.
|======
@ -686,7 +686,7 @@ Hence, the CSRs of this module are only relevant for the debugger.
[frame="topbot",grid="none"]
|======
| 0x7a1 | **Trigger data register 1 / match control register** | `tdata1` / `mcontrol`
3+| Reset value: 0x28041048
3+| Reset value: `0x28041048`
3+| This CSR is used to configure the address match trigger. Only one bit is writable, the remaining bits are hardwired (see table below).
Write attempts to the hardwired bits are ignored.
|======
@ -723,7 +723,7 @@ Write attempts to the hardwired bits are ignored.
[frame="topbot",grid="none"]
|======
| 0x7a2 | **Trigger data register 2** | `tdata2`
3+| Reset value: _UNDEFINED_
3+| Reset value: `0x00000000`
3+| Since only the "address match trigger" type is supported, this r/w CSR is used to store the address of the triggering instruction.
|======
@ -735,7 +735,7 @@ Write attempts to the hardwired bits are ignored.
[frame="topbot",grid="none"]
|======
| 0x7a3 | **Trigger data register 3** | `tdata3`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======
@ -747,7 +747,7 @@ Write attempts to the hardwired bits are ignored.
[frame="topbot",grid="none"]
|======
| 0x7a4 | **Trigger information register** | `tinfo`
3+| Reset value: 0x00000004
3+| Reset value: `0x00000004`
3+| This CSR is hardwired to "4" indicating there is only an "address match trigger" available. Any write access is ignored.
|======
@ -759,7 +759,7 @@ Write attempts to the hardwired bits are ignored.
[frame="topbot",grid="none"]
|======
| 0x7a5 | **Trigger control register** | `tcontrol`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======
@ -771,7 +771,7 @@ Write attempts to the hardwired bits are ignored.
[frame="topbot",grid="none"]
|======
| 0x7a8 | **Machine context register** | `mcontext`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======
@ -783,7 +783,7 @@ Write attempts to the hardwired bits are ignored.
[frame="topbot",grid="none"]
|======
| 0x7aa | **Supervisor context register** | `scontext`
3+| Reset value: 0x00000000
3+| Reset value: `0x00000000`
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======

View file

@ -1,8 +1,8 @@
-- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32
-- Auto-generated memory initialization file (for APPLICATION) from source file <blink_led/main.bin>
-- Size: 1032 bytes
-- Size: 1020 bytes
-- MARCH: default
-- Built: 08.07.2022 14:57:32
-- Built: 14.07.2022 15:09:04
-- prototype defined in 'neorv32_package.vhd'
package body neorv32_application_image is
@ -14,12 +14,9 @@ x"ff810113",
x"80000197",
x"7f418193",
x"00000517",
x"13c50513",
x"13050513",
x"30551073",
x"34151073",
x"000023b7",
x"80038393",
x"30039073",
x"30001073",
x"30401073",
x"34401073",
x"32001073",
@ -28,10 +25,10 @@ x"b0001073",
x"b8001073",
x"b0201073",
x"b8201073",
x"00000093",
x"00000213",
x"00000293",
x"00000313",
x"00000393",
x"00000813",
x"00000893",
x"00000913",
@ -48,11 +45,11 @@ x"00000e13",
x"00000e93",
x"00000f13",
x"00000f93",
x"40800593",
x"3fc00593",
x"80000617",
x"f5c60613",
x"f6860613",
x"80000697",
x"f5468693",
x"f6068693",
x"00c58e63",
x"00d65c63",
x"0005a703",
@ -61,15 +58,15 @@ x"00458593",
x"00460613",
x"fedff06f",
x"80000717",
x"f3070713",
x"f3c70713",
x"80000797",
x"f2878793",
x"f3478793",
x"00f75863",
x"00072023",
x"00470713",
x"ff5ff06f",
x"40800413",
x"40800493",
x"3fc00413",
x"3fc00493",
x"00945a63",
x"0009a083",
x"000080e7",
@ -80,12 +77,12 @@ x"00000593",
x"088000ef",
x"30047073",
x"34051073",
x"40800993",
x"40800a13",
x"0149da63",
x"0009a303",
x"000300e7",
x"00498993",
x"3fc00413",
x"3fc00493",
x"00945a63",
x"00042083",
x"000080e7",
x"00440413",
x"ff1ff06f",
x"00000093",
x"00008463",
@ -116,14 +113,14 @@ x"00000513",
x"00000593",
x"00112623",
x"00812423",
x"03c000ef",
x"0e0000ef",
x"00000513",
x"00150413",
x"00000593",
x"0ff57513",
x"028000ef",
x"0cc000ef",
x"10000513",
x"030000ef",
x"020000ef",
x"00040513",
x"fe5ff06f",
x"f9402583",
@ -131,10 +128,6 @@ x"f9002503",
x"f9402783",
x"fef59ae3",
x"00008067",
x"fc000793",
x"00a7a423",
x"00b7a623",
x"00008067",
x"fe010113",
x"00a12623",
x"fe002503",
@ -142,23 +135,23 @@ x"3e800593",
x"00112e23",
x"00812c23",
x"00912a23",
x"144000ef",
x"154000ef",
x"00c12603",
x"00000693",
x"00000593",
x"09c000ef",
x"0ac000ef",
x"fe802783",
x"00020737",
x"00050413",
x"00e7f7b3",
x"00058493",
x"02078e63",
x"f95ff0ef",
x"fa5ff0ef",
x"00850433",
x"00a43533",
x"009584b3",
x"009504b3",
x"f81ff0ef",
x"f91ff0ef",
x"fe95eee3",
x"00b49463",
x"fe856ae3",
@ -176,6 +169,10 @@ x"fff50513",
x"00000013",
x"ff1ff06f",
x"fcdff06f",
x"fc000793",
x"00a7a423",
x"00b7a623",
x"00008067",
x"00050613",
x"00000513",
x"0015f693",

View file

@ -1,8 +1,8 @@
-- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32
-- Auto-generated memory initialization file (for BOOTLOADER) from source file <bootloader/main.bin>
-- Size: 4048 bytes
-- Size: 4036 bytes
-- MARCH: default
-- Built: 12.07.2022 13:48:34
-- Built: 14.07.2022 15:12:45
-- prototype defined in 'neorv32_package.vhd'
package body neorv32_bootloader_image is
@ -14,12 +14,9 @@ x"1f810113",
x"80010197",
x"7f418193",
x"00000517",
x"0f850513",
x"0ec50513",
x"30551073",
x"34151073",
x"000023b7",
x"80038393",
x"30039073",
x"30001073",
x"30401073",
x"34401073",
x"32001073",
@ -28,10 +25,10 @@ x"b0001073",
x"b8001073",
x"b0201073",
x"b8201073",
x"00000093",
x"00000213",
x"00000293",
x"00000313",
x"00000393",
x"00000813",
x"00000893",
x"00000913",
@ -51,9 +48,9 @@ x"00000f93",
x"00001597",
x"f3058593",
x"80010617",
x"f5860613",
x"f6460613",
x"80010697",
x"f5068693",
x"f5c68693",
x"00c58e63",
x"00d65c63",
x"0005a703",
@ -62,7 +59,7 @@ x"00458593",
x"00460613",
x"fedff06f",
x"80010717",
x"f2c70713",
x"f3870713",
x"80818793",
x"00f75863",
x"00072023",
@ -114,7 +111,7 @@ x"0007a023",
x"800007b7",
x"0007a223",
x"ffff07b7",
x"7b478793",
x"7a878793",
x"30579073",
x"fe802783",
x"00080737",
@ -193,46 +190,46 @@ x"08000793",
x"30479073",
x"30046073",
x"ffff1537",
x"dd450513",
x"dc850513",
x"41c000ef",
x"f1302573",
x"3a0000ef",
x"ffff1537",
x"e0c50513",
x"e0050513",
x"408000ef",
x"fe002503",
x"38c000ef",
x"ffff1537",
x"e1450513",
x"e0850513",
x"3f4000ef",
x"30102573",
x"378000ef",
x"ffff1537",
x"e1c50513",
x"e1050513",
x"3e0000ef",
x"fc002573",
x"364000ef",
x"ffff1537",
x"e2050513",
x"e1450513",
x"3cc000ef",
x"fe802503",
x"ffff14b7",
x"34c000ef",
x"ffff1537",
x"e2850513",
x"e1c50513",
x"3b4000ef",
x"ff802503",
x"338000ef",
x"e3048513",
x"e2448513",
x"3a4000ef",
x"ff002503",
x"328000ef",
x"ffff1537",
x"e3c50513",
x"e3050513",
x"390000ef",
x"ffc02503",
x"314000ef",
x"e3048513",
x"e2448513",
x"380000ef",
x"ff402503",
x"304000ef",
@ -241,7 +238,7 @@ x"00020737",
x"00e7f7b3",
x"04078663",
x"ffff1537",
x"e4450513",
x"e3850513",
x"35c000ef",
x"2b8000ef",
x"fe002483",
@ -256,10 +253,10 @@ x"0a078663",
x"fa402783",
x"0a07d263",
x"ffff1537",
x"e7050513",
x"e6450513",
x"320000ef",
x"ffff1937",
x"e7c90513",
x"e7090513",
x"314000ef",
x"ffff1ab7",
x"ffff1b37",
@ -267,7 +264,7 @@ x"ffff1bb7",
x"ffff1c37",
x"ffff1cb7",
x"ffff17b7",
x"efc78513",
x"ef078513",
x"2f4000ef",
x"fa402483",
x"fe04dee3",
@ -275,7 +272,7 @@ x"0ff4f493",
x"00048513",
x"254000ef",
x"ffff17b7",
x"dd078513",
x"dc478513",
x"2d4000ef",
x"07200793",
x"06f49863",
@ -302,12 +299,12 @@ x"f52560e3",
x"00100513",
x"680000ef",
x"ffff1537",
x"dd050513",
x"dc450513",
x"268000ef",
x"00000513",
x"079000ef",
x"06800793",
x"e7c90513",
x"e7090513",
x"02f48463",
x"07500793",
x"00000513",
@ -317,18 +314,18 @@ x"14f49663",
x"00042483",
x"00049a63",
x"ffff1537",
x"f0450513",
x"ef850513",
x"22c000ef",
x"f2dff06f",
x"f20b8513",
x"f14b8513",
x"220000ef",
x"00048513",
x"1a4000ef",
x"f28c0513",
x"f1cc0513",
x"210000ef",
x"00400537",
x"194000ef",
x"f40c8513",
x"f34c8513",
x"200000ef",
x"fa402983",
x"fe09dee3",
@ -342,7 +339,7 @@ x"00050663",
x"00300513",
x"22c000ef",
x"ffff1537",
x"f4c50513",
x"f4050513",
x"1c8000ef",
x"0104d793",
x"00178a13",
@ -378,7 +375,7 @@ x"00898513",
x"41b005b3",
x"6b8000ef",
x"ffff1537",
x"db850513",
x"dac50513",
x"f0dff06f",
x"374000ef",
x"fa802703",
@ -405,17 +402,17 @@ x"06500793",
x"00f49a63",
x"00042783",
x"e60798e3",
x"f5cb0513",
x"f50b0513",
x"ea1ff06f",
x"07800793",
x"00f49663",
x"00100513",
x"e5dff06f",
x"03f00793",
x"f6ca8513",
x"f60a8513",
x"e8f482e3",
x"ffff17b7",
x"fa078513",
x"f9478513",
x"e79ff06f",
x"f9402583",
x"f9002503",
@ -441,7 +438,7 @@ x"07800513",
x"ffff14b7",
x"fbdff0ef",
x"01c00413",
x"fc048493",
x"fb448493",
x"ffc00993",
x"008957b3",
x"00f7f793",
@ -483,13 +480,13 @@ x"ff010113",
x"00812423",
x"00050413",
x"ffff1537",
x"d7050513",
x"d6450513",
x"00112623",
x"f91ff0ef",
x"00241513",
x"00850433",
x"ffff1537",
x"fac50513",
x"fa050513",
x"00850533",
x"f79ff0ef",
x"30047073",
@ -578,7 +575,7 @@ x"00040737",
x"00e7f7b3",
x"04078263",
x"ffff1537",
x"d7850513",
x"d6c50513",
x"e19ff0ef",
x"00048513",
x"d9dff0ef",
@ -591,7 +588,7 @@ x"d6dff0ef",
x"34302573",
x"d7dff0ef",
x"ffff1537",
x"dd050513",
x"dc450513",
x"de5ff0ef",
x"00440413",
x"34141073",
@ -735,7 +732,7 @@ x"00050413",
x"004a0a13",
x"02051863",
x"ffff1537",
x"d8450513",
x"d7850513",
x"ba5ff0ef",
x"004005b7",
x"00040513",
@ -746,12 +743,12 @@ x"04f50863",
x"00000513",
x"0380006f",
x"ffff1537",
x"da450513",
x"d9850513",
x"b79ff0ef",
x"00400537",
x"afdff0ef",
x"ffff1537",
x"db050513",
x"da450513",
x"b65ff0ef",
x"fe802783",
x"00080737",
@ -782,7 +779,7 @@ x"016484b3",
x"00200513",
x"fa0494e3",
x"ffff1537",
x"db850513",
x"dac50513",
x"ae9ff0ef",
x"02c12083",
x"02812403",
@ -855,12 +852,12 @@ x"ff002403",
x"00050463",
x"40400437",
x"ffff1537",
x"dbc50513",
x"db050513",
x"9c5ff0ef",
x"00040513",
x"949ff0ef",
x"ffff1537",
x"dcc50513",
x"dc050513",
x"9b1ff0ef",
x"00010737",
x"fa002783",
@ -903,7 +900,7 @@ x"0a3e3e20",
x"444c420a",
x"4a203a56",
x"31206c75",
x"30322032",
x"30322034",
x"480a3232",
x"203a5657",
x"00000020",

View file

@ -10,11 +10,6 @@
-- # + CSR module: Read/write access to control and status registers #
-- # + Debug module: CPU debug mode handling (on-chip debugger) #
-- # + Trigger module: Hardware-assisted breakpoints (on-chip debugger) #
-- # #
-- # NOTE: If <dedicated_reset_c> = true then <def_rst_val_c> evaluates to '-'. Registers that #
-- # reset to <def_rst_val_c> do NOT actually have a real reset by default and have to be #
-- # explicitly initialized by software! This is only used for "uncritical" registers. Many #
-- # of them will be initialized by the default crt0 start-up code. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
@ -394,7 +389,7 @@ begin
fetch_engine.state_prev <= S_RESTART;
fetch_engine.restart <= '1'; -- set to reset IPB
fetch_engine.unaligned <= '0'; -- always start at aligned address after reset
fetch_engine.pc <= (others => def_rst_val_c);
fetch_engine.pc <= (others => '0');
fetch_engine.pmp_err <= '0';
elsif rising_edge(clk_i) then
-- previous state (for HPM) --
@ -675,8 +670,8 @@ begin
execute_engine.is_ici <= def_rst_val_c;
execute_engine.i_reg_last <= (others => def_rst_val_c);
execute_engine.next_pc <= (others => def_rst_val_c);
ctrl <= (others => def_rst_val_c);
-- registers that DO require a specific RESET state --
ctrl <= (others => '0');
execute_engine.pc <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00"; -- 32-bit aligned!
execute_engine.pc_last <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00";
execute_engine.state <= BRANCHED; -- reset is a branch from "somewhere"
@ -684,8 +679,6 @@ begin
execute_engine.state_prev2 <= BRANCHED; -- actual reset value is not relevant
execute_engine.sleep <= '0';
execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
ctrl(ctrl_bus_rd_c) <= '0';
ctrl(ctrl_bus_wr_c) <= '0';
elsif rising_edge(clk_i) then
-- PC update --
if (execute_engine.pc_we = '1') then
@ -1761,11 +1754,11 @@ begin
csr.mie_meie <= '0';
csr.mie_mtie <= '0';
csr.mie_firqe <= (others => '0');
csr.mtvec <= (others => def_rst_val_c);
csr.mtvec <= (others => '0');
csr.mscratch <= x"19880704";
csr.mepc <= (others => def_rst_val_c);
csr.mcause <= (others => def_rst_val_c);
csr.mtval <= (others => def_rst_val_c);
csr.mepc <= (others => '0');
csr.mcause <= (others => '0');
csr.mtval <= (others => '0');
csr.mip_firq_nclr <= (others => '-');
--
csr.pmpcfg <= (others => (others => '0'));
@ -1788,12 +1781,12 @@ begin
csr.dcsr_ebreaku <= '0';
csr.dcsr_step <= '0';
csr.dcsr_prv <= priv_mode_m_c;
csr.dcsr_cause <= (others => def_rst_val_c);
csr.dpc <= (others => def_rst_val_c);
csr.dscratch0 <= (others => def_rst_val_c);
csr.dcsr_cause <= (others => '0');
csr.dpc <= (others => '0');
csr.dscratch0 <= (others => '0');
--
csr.tdata1_exe <= '0';
csr.tdata2 <= (others => def_rst_val_c);
csr.tdata2 <= (others => '0');
elsif rising_edge(clk_i) then
-- write access? --

View file

@ -63,7 +63,7 @@ package neorv32_package is
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070310"; -- NEORV32 version - no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070311"; -- NEORV32 version - no touchy!
constant archid_c : natural := 19; -- official RISC-V architecture ID - hands off!
-- Check if we're inside the Matrix -------------------------------------------------------

View file

@ -67,20 +67,15 @@ __crt0_pointer_init:
// ************************************************************************************************
// Setup CPU core CSRs (some of them DO NOT have a dedicated
// reset and need to be explicitly initialized)
// Setup CPU core CSRs (some of them DO NOT have a dedicated reset and need to be explicitly initialized)
// ************************************************************************************************
__crt0_cpu_csr_init:
la x10, __crt0_trap_handler // configure early-boot trap handler
csrw mtvec, x10
csrw mepc, x10 // just to init mepc
li x7, (3 << 11) // set mpp=11 => machine-mode, clear all remaining bits,
csrw mstatus, x7 // also disable IRQs globally
csrw mie, zero // disable all interrupt lines
csrw mip, zero // clear all pending interrupts
csrw mstatus, zero // also disables IRQs globally
csrw mie, zero // disable all interrupt sources
csrw mip, zero // clear all pending interrupts
csrw 0x320, zero // stop all counters; use "mcountinhibit" literal address for lagacy toolchain compatibility
csrw mcounteren, zero // no access from less-privileged modes to counter CSRs
@ -96,13 +91,13 @@ __crt0_cpu_csr_init:
// ************************************************************************************************
__crt0_reg_file_init:
//addi x0, x0, 0 // hardwired to zero
addi x1, x0, 0
//addi x1, x0, 0 // return address; implicitly initialized within crt0
//addi x2, x0, 0 // stack pointer sp
//addi x3, x0, 0 // global pointer gp
addi x4, x0, 0
addi x5, x0, 0
addi x6, x0, 0
//addi x7, x0, 0 // implicitly initialized within crt0
addi x7, x0, 0
//addi x8, x0, 0 // implicitly initialized within crt0
//addi x9, x0, 0 // implicitly initialized within crt0
//addi x10, x0, 0 // implicitly initialized within crt0
@ -178,8 +173,8 @@ __crt0_call_constructors:
__crt0_call_constructors_loop:
bge x8, x9, __crt0_call_constructors_loop_end
lw ra, 0(s3)
jalr ra, 0(ra)
lw x1, 0(s3)
jalr x1, 0(x1)
addi x8, x8, 4
j __crt0_call_constructors_loop
@ -191,9 +186,9 @@ __crt0_call_constructors_loop_end:
// Setup arguments and call main function
// ************************************************************************************************
__crt0_main_entry:
addi a0, zero, 0 // a0 = argc = 0
addi a1, zero, 0 // a1 = argv = 0
jal ra, main // call actual app's main function
addi x10, zero, 0 // x10 = a0 = argc = 0
addi x11, zero, 0 // x11 = a1 = argv = 0
jal x1, main // call actual app's main function
__crt0_main_exit: // main's "return" and "exit" will arrive here
csrci mstatus, (1 << 3) // disable global IRQs (clear mstatus.mie)
@ -205,14 +200,14 @@ __crt0_main_exit: // main's "return" and "exit" will arrive here
// ************************************************************************************************
#ifndef make_bootloader // destructors are not supported for bootloader
__crt0_call_destructors:
la s3, __fini_array_start
la s4, __fini_array_end
la x8, __fini_array_start
la x9, __fini_array_end
__crt0_call_destructors_loop:
bge s3, s4, __crt0_call_destructors_loop_end
lw t1, 0(s3)
jalr ra, 0(t1)
addi s3, s3, 4
bge x8, x9, __crt0_call_destructors_loop_end
lw x1, 0(x8)
jalr x1, 0(x1)
addi x8, x8, 4
j __crt0_call_destructors_loop
__crt0_call_destructors_loop_end:
@ -255,9 +250,8 @@ __crt0_trap_handler:
csrr x8, mcause
blt x8, zero, __crt0_trap_handler_end // skip mepc modification if interrupt
// update mepc
csrr x8, mepc
__crt0_trap_handler_exc_mepc_update:
lh x9, 0(x8) // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
andi x9, x9, 3 // mask: isolate lowest 2 opcode bits (= 11 for uncompressed instructions)