diff --git a/CHANGELOG.md b/CHANGELOG.md index 35d45f146..e054bcaea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) | diff --git a/docs/datasheet/cpu.adoc b/docs/datasheet/cpu.adoc index 65da9551a..1c8b251ac 100644 --- a/docs/datasheet/cpu.adoc +++ b/docs/datasheet/cpu.adoc @@ -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] ---- diff --git a/docs/datasheet/cpu_csr.adoc b/docs/datasheet/cpu_csr.adoc index 1b16f9632..5e63f2e99 100644 --- a/docs/datasheet/cpu_csr.adoc +++ b/docs/datasheet/cpu_csr.adoc @@ -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,58 +10,26 @@ 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. - - -<<< -// #################################################################################################################### -**CSR Listing Notes** - -CSRs with the following notes ... +.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. -* `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"] @@ -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.** diff --git a/docs/datasheet/on_chip_debugger.adoc b/docs/datasheet/on_chip_debugger.adoc index 297d530ff..bd763df0d 100644 --- a/docs/datasheet/on_chip_debugger.adoc +++ b/docs/datasheet/on_chip_debugger.adoc @@ -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. |====== diff --git a/rtl/core/neorv32_application_image.vhd b/rtl/core/neorv32_application_image.vhd index 838fda5bb..7acc2c000 100644 --- a/rtl/core/neorv32_application_image.vhd +++ b/rtl/core/neorv32_application_image.vhd @@ -1,8 +1,8 @@ -- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32 -- Auto-generated memory initialization file (for APPLICATION) from source file --- 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", diff --git a/rtl/core/neorv32_bootloader_image.vhd b/rtl/core/neorv32_bootloader_image.vhd index 7443cb12f..ff6da4b04 100644 --- a/rtl/core/neorv32_bootloader_image.vhd +++ b/rtl/core/neorv32_bootloader_image.vhd @@ -1,8 +1,8 @@ -- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32 -- Auto-generated memory initialization file (for BOOTLOADER) from source file --- 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", diff --git a/rtl/core/neorv32_cpu_control.vhd b/rtl/core/neorv32_cpu_control.vhd index 6817e4261..ab0a84f63 100644 --- a/rtl/core/neorv32_cpu_control.vhd +++ b/rtl/core/neorv32_cpu_control.vhd @@ -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 = true then evaluates to '-'. Registers that # --- # reset to 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? -- diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index b9633172b..a86119970 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -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 ------------------------------------------------------- diff --git a/sw/common/crt0.S b/sw/common/crt0.S index bf21a8c7e..8714efe66 100644 --- a/sw/common/crt0.S +++ b/sw/common/crt0.S @@ -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)