I would like to get a clear understanding of how ESP32 RISC-V implementations handle misaligned load/store memory accesses.
The RISC-V specification states that the behavior of misaligned accesses is implementation-specific (The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture, Section 2.6 "Load and Store Instructions", page 34).
When reviewing the technical reference manuals for various ESP32 RISC-V devices (ESP32-P4, ESP32-C5, ESP32-C6, ESP32-C3, ESP32-C2, etc.), I could not find a clear statement describing how `lw`/`sw` instructions handle misaligned accesses. However, when examining the documented values of the `mcause` register, exceptions with IDs `0x4` (Load address misaligned) and `0x6` (Store/AMO address misaligned) are not listed. This seems to suggest that these exceptions are not generated by the implementation, but instead handled transparently.
The only explicit mention I found is that a Store/AMO address misaligned exception can be generated when `lr.w` or `sc.w` accesses are not properly aligned.
My questions are:
- How do ESP32 RISC-V implementations handle misaligned memory accesses?
- Is there any ESP32 RISC-V implementation that does not support misaligned memory accesses and instead generates a misaligned address exception for `lw/`sw` instructions?
- The ESP-IDF documentation mentions the errors "Load Address Misaligned" and "Store Address Misaligned" https://docs.espressif.com/projects/esp ... misaligned. Can these exceptions actually occur on ESP32 RISC-V devices?
Code: Select all
void __attribute__((noreturn)) call_start_cpu0(void)
{
volatile uint8_t buf[8] = {
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08
};
uint32_t aligned;
uint32_t unaligned;
// Use inline assembly to ensure the compiler does not optimize the accesses away.
asm volatile("lw %0, 0(%1)" : "=r"(aligned) : "r"(buf));
asm volatile("lw %0, 0(%1)" : "=r"(unaligned) : "r"(buf + 1));
ESP_EARLY_LOGE(TAG, "Aligned address: 0x%x", buf);
ESP_EARLY_LOGE(TAG, "Aligned read: 0x%x", aligned);
ESP_EARLY_LOGE(TAG, "Unaligned address: 0x%x", (buf + 1));
ESP_EARLY_LOGE(TAG, "Unaligned read: 0x%x", unaligned);
while (1) {
// Test complete.
}
}
Code: Select all
ESP-ROM:esp32c3-api1-20210207
Build:Feb 7 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x403cbfb2
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5710,len:0x168
load:0x403cbf10,len:0xb4
load:0x403ce710,len:0x74
entry 0x403cbf10
E (23) boot: Aligned address: aligned = 0x3fcde538
E (27) boot: Aligned read: *(aligned) = 0x4030201
E (32) boot: Unaligned address: unaligned = 0x3fcde539
E (36) boot: Unaligned read: *(unaligned) = 0x5040302