- uint32_t reset_vec[] = {
- 0x297 + DRAM_BASE - DEFAULT_RSTVEC, // auipc t0, DRAM_BASE
- 0x597, // auipc a1, 0
- 0x58593, // addi a1, a1, 0
- 0xf1402573, // csrr a0,mhartid
- 0x00028067 // jalr zero, t0, 0 (jump straight to DRAM_BASE)
+ const int reset_vec_size = 8;
+
+ reg_t pc_delta = start_pc - DEFAULT_RSTVEC;
+ reg_t pc_delta_hi = (pc_delta + 0x800U) & ~reg_t(0xfffU);
+ reg_t pc_delta_lo = pc_delta - pc_delta_hi;
+ if ((pc_delta_hi >> 31) != 0 && (pc_delta_hi >> 31) != reg_t(-1) >> 31) {
+ fprintf(stderr, "initial pc %" PRIx64 " out of range\n", pc_delta);
+ abort();
+ }
+
+ uint32_t reset_vec[reset_vec_size] = {
+ 0x297 + uint32_t(pc_delta_hi), // auipc t0, &pc
+ 0x597, // auipc a1, &dtb
+ 0x58593 + ((reset_vec_size - 1) * 4 << 20), // addi a1, a1, &dtb
+ 0xf1402573, // csrr a0, mhartid
+ 0x28067 + uint32_t(pc_delta_lo << 20) // jalr zero, t0, &pc