Skip to content

Commit

Permalink
success
Browse files Browse the repository at this point in the history
  • Loading branch information
ChinYikMing committed Nov 26, 2024
1 parent f47eb81 commit 5d7049d
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 69 deletions.
Binary file added .Makefile.swp
Binary file not shown.
Binary file added .test.sh.swp
Binary file not shown.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ BIN := $(OUT)/rv32emu
CONFIG_FILE := $(OUT)/.config
-include $(CONFIG_FILE)

CFLAGS = -std=gnu99 -O2 -Wall -Wextra
CFLAGS = -std=gnu99 -Wall -Wextra
CFLAGS += -Wno-unused-label
CFLAGS += -include src/common.h

Expand Down
35 changes: 32 additions & 3 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extern struct target_ops gdbstub_ops;
static uint32_t reloc_enable_mmu_jalr_addr;
static bool reloc_enable_mmu = false;
bool need_retranslate = false;
bool need_refetch = false;
#endif

static void rv_trap_default_handler(riscv_t *rv)
Expand Down Expand Up @@ -176,6 +177,7 @@ static uint32_t *csr_get_ptr(riscv_t *rv, uint32_t csr)
* If rd == x0, then the instruction shall not read the CSR and shall not cause
* any of the side effects that might occur on a CSR read.
*/
static need_clear_map = false;
static uint32_t csr_csrrw(riscv_t *rv, uint32_t csr, uint32_t val)
{
uint32_t *c = csr_get_ptr(rv, csr);
Expand All @@ -195,8 +197,9 @@ static uint32_t csr_csrrw(riscv_t *rv, uint32_t csr, uint32_t val)
* guestOS's process might have same VA,
* so block_map cannot be reused
*/
if (c == &rv->csr_satp)
block_map_clear(rv);
if (c == &rv->csr_satp){
need_clear_map = true;
}
#endif

return out;
Expand Down Expand Up @@ -313,6 +316,7 @@ static void block_insert(block_map_t *map, const block_t *block)
/* try to locate an already translated block in the block map */
static block_t *block_find(const block_map_t *map, const uint32_t addr)
{
//return NULL;
assert(map);
uint32_t index = map_hash(addr);
const uint32_t mask = map->block_capacity - 1;
Expand Down Expand Up @@ -385,6 +389,11 @@ static uint32_t peripheral_update_ctr = 64;
code; \
nextop: \
PC += __rv_insn_##inst##_len; \
if (unlikely(need_clear_map)) { \
rv->csr_cycle = cycle; \
rv->PC = PC; \
return false; \
} \
if (unlikely(RVOP_NO_NEXT(ir))) { \
goto end_op; \
} \
Expand Down Expand Up @@ -564,10 +573,17 @@ FORCE_INLINE bool insn_is_unconditional_branch(uint8_t opcode)
return false;
}

static bool use_orig_pc = false;
static uint32_t orig_pc;
static void block_translate(riscv_t *rv, block_t *block)
{
retranslate:
block->pc_start = block->pc_end = rv->PC;
if(use_orig_pc)
block->pc_start = block->pc_end = orig_pc;
else
block->pc_start = block->pc_end = rv->PC;

use_orig_pc = false;

rv_insn_t *prev_ir = NULL;
rv_insn_t *ir = mpool_calloc(rv->block_ir_mp);
Expand All @@ -587,6 +603,14 @@ static void block_translate(riscv_t *rv, block_t *block)
need_retranslate = false;
goto retranslate;
}

if (!insn && need_refetch) {
memset(block, 0, sizeof(block_t));
need_refetch = false;
block_map_clear(rv);
use_orig_pc = true;
goto retranslate;
}
#endif

assert(insn);
Expand Down Expand Up @@ -809,6 +833,10 @@ static block_t *block_find_or_translate(riscv_t *rv)
{
#if !RV32_HAS(JIT)
block_map_t *map = &rv->block_map;
if(need_clear_map){
block_map_clear(rv);
need_clear_map = false;
}
/* lookup the next block in the block map */
block_t *next = block_find(map, rv->PC);
#else
Expand All @@ -825,6 +853,7 @@ static block_t *block_find_or_translate(riscv_t *rv)
#endif
/* allocate a new block */
next = block_alloc(rv);
orig_pc = rv->PC;
block_translate(rv, next);

//optimize_constant(rv, next);
Expand Down
32 changes: 0 additions & 32 deletions src/rv32_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,44 +317,12 @@ RVOP(
IIF(RV32_HAS(EXT_C))(, const uint32_t pc = PC;); \
if (BRANCH_COND(type, rv->X[ir->rs1], rv->X[ir->rs2], cond)) { \
is_branch_taken = false; \
struct rv_insn *untaken = ir->branch_untaken; \
if (!untaken) \
goto nextop; \
IIF(RV32_HAS(JIT)) \
( \
{ \
cache_get(rv->block_cache, PC + 4, true); \
if (!set_add(&pc_set, PC + 4)) \
has_loops = true; \
if (cache_hot(rv->block_cache, PC + 4)) \
goto nextop; \
}, ); \
PC += 4; \
last_pc = PC; \
IIF(RV32_HAS(SYSTEM)(if (!rv->is_trapped), )) \
MUST_TAIL return untaken->impl(rv, untaken, cycle, PC); \
goto end_op; \
} \
is_branch_taken = true; \
PC += ir->imm; \
/* check instruction misaligned */ \
IIF(RV32_HAS(EXT_C)) \
(, RV_EXC_MISALIGN_HANDLER(pc, INSN, false, 0);); \
struct rv_insn *taken = ir->branch_taken; \
if (taken) { \
IIF(RV32_HAS(JIT)) \
( \
{ \
cache_get(rv->block_cache, PC, true); \
if (!set_add(&pc_set, PC)) \
has_loops = true; \
if (cache_hot(rv->block_cache, PC)) \
goto end_op; \
}, ); \
last_pc = PC; \
IIF(RV32_HAS(SYSTEM)(if (!rv->is_trapped), )) \
MUST_TAIL return taken->impl(rv, taken, cycle, PC); \
} \
goto end_op;

/* In RV32I and RV64I, if the branch is taken, set pc = pc + offset, where
Expand Down
56 changes: 24 additions & 32 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,16 @@ static uint32_t *mmu_walk(riscv_t *rv, const uint32_t addr, uint32_t *level, pte
ppn = (*pte >> (RV_PG_SHIFT - 2));
if (*level == 1 &&
unlikely(ppn & MASK(10))){ /* misaligned superpage */
*pte_ref = NULL;
return NULL;
}
return pte; /* leaf PTE */
case RESRV_PAGE1:
case RESRV_PAGE2:
default:
*pte_ref = NULL;
return NULL;
}
}

*pte_ref = NULL;
return NULL;
}

Expand All @@ -170,6 +167,7 @@ static uint32_t *mmu_walk(riscv_t *rv, const uint32_t addr, uint32_t *level, pte
* access permission else true
*/
/* FIXME: handle access fault, addr out of range check */
extern bool need_refetch;
#define MMU_FAULT_CHECK(op, rv, pte, addr, access_bits) \
mmu_##op##_fault_check(rv, pte, addr, access_bits)
#define MMU_FAULT_CHECK_IMPL(op, pgfault) \
Expand All @@ -192,11 +190,17 @@ static uint32_t *mmu_walk(riscv_t *rv, const uint32_t addr, uint32_t *level, pte
__UNREACHABLE; \
break; \
} \
if (pte && (!(*pte & PTE_V))) { \
if (!pte) { \
if(scause == PAGEFAULT_INSN){\
need_refetch = true;\
}\
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, scause, stval); \
return false; \
} \
if (!(pte && (*pte & access_bits))) { \
if(scause == PAGEFAULT_INSN){\
need_refetch = true;\
}\
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, scause, stval); \
return false; \
} \
Expand All @@ -207,29 +211,9 @@ static uint32_t *mmu_walk(riscv_t *rv, const uint32_t addr, uint32_t *level, pte
* (2) When MXR=1, loads from pages marked either readable or \
* executable (R=1 or X=1) will succeed. \
*/ \
if (pte && ((!(SSTATUS_MXR & rv->csr_sstatus) && !(*pte & PTE_R) && \
(access_bits == PTE_R)) || \
((SSTATUS_MXR & rv->csr_sstatus) && \
!((*pte & PTE_R) | (*pte & PTE_X)) && \
(access_bits == PTE_R)))) { \
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, scause, stval); \
return false; \
} \
/* \
* When SUM=0, S-mode memory accesses to pages that are accessible by \
* U-mode will fault. \
*/ \
if (pte && rv->priv_mode == RV_PRIV_S_MODE && \
!(SSTATUS_SUM & rv->csr_sstatus) && (*pte & PTE_U)) { \
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, scause, stval); \
return false; \
} \
/* PTE not found, map it in handler */ \
if (!pte) { \
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, scause, stval); \
return false; \
} \
/* valid PTE */ \
need_refetch = false;\
return true; \
}

Expand All @@ -241,10 +225,14 @@ MMU_FAULT_CHECK_IMPL(write, pagefault_store)
uint32_t ppn; \
uint32_t offset; \
do { \
if(pte){\
assert(pte);\
ppn = *pte >> (RV_PG_SHIFT - 2) << RV_PG_SHIFT; \
offset = level == 1 ? addr & MASK((RV_PG_SHIFT + 10)) \
: addr & MASK(RV_PG_SHIFT); \
} else {\
ppn = offset = 0;\
}\
} while (0)

/* The IO handler that operates when the Memory Management Unit (MMU)
Expand Down Expand Up @@ -276,12 +264,16 @@ static uint32_t mmu_ifetch(riscv_t *rv, const uint32_t addr)
bool ok = MMU_FAULT_CHECK(ifetch, rv, pte, addr, PTE_X);
if (unlikely(!ok))
pte = mmu_walk(rv, addr, &level, &pte_ref);
pte = pte_ref;
//pte = pte_ref;

if (need_retranslate) {
return 0;
}

if (!rv->is_trapped && need_refetch) {
return 0;
}

assert(pte);

get_ppn_and_offset();
Expand All @@ -304,7 +296,7 @@ static uint32_t mmu_read_w(riscv_t *rv, const uint32_t addr)
printf("addr is zero here\n");
}
}
pte = pte_ref;
//pte = pte_ref;

assert(pte);

Expand Down Expand Up @@ -341,7 +333,7 @@ static uint16_t mmu_read_s(riscv_t *rv, const uint32_t addr)
bool ok = MMU_FAULT_CHECK(read, rv, pte, addr, PTE_R);
if (unlikely(!ok))
pte = mmu_walk(rv, addr, &level, &pte_ref);
pte = pte_ref;
//pte = pte_ref;
assert(pte);

get_ppn_and_offset();
Expand All @@ -360,7 +352,7 @@ static uint8_t mmu_read_b(riscv_t *rv, const uint32_t addr)
bool ok = MMU_FAULT_CHECK(read, rv, pte, addr, PTE_R);
if (unlikely(!ok))
pte = mmu_walk(rv, addr, &level, &pte_ref);
pte = pte_ref;
//pte = pte_ref;
assert(pte);

{
Expand Down Expand Up @@ -388,7 +380,7 @@ static void mmu_write_w(riscv_t *rv, const uint32_t addr, const uint32_t val)
bool ok = MMU_FAULT_CHECK(write, rv, pte, addr, PTE_W);
if (unlikely(!ok))
pte = mmu_walk(rv, addr, &level, &pte_ref);
pte = pte_ref;
//pte = pte_ref;
assert(pte);

{
Expand Down Expand Up @@ -416,7 +408,7 @@ static void mmu_write_s(riscv_t *rv, const uint32_t addr, const uint16_t val)
bool ok = MMU_FAULT_CHECK(write, rv, pte, addr, PTE_W);
if (unlikely(!ok))
pte = mmu_walk(rv, addr, &level, &pte_ref);
pte = pte_ref;
//pte = pte_ref;
assert(pte);

get_ppn_and_offset();
Expand All @@ -435,7 +427,7 @@ static void mmu_write_b(riscv_t *rv, const uint32_t addr, const uint8_t val)
bool ok = MMU_FAULT_CHECK(write, rv, pte, addr, PTE_W);
if (unlikely(!ok))
pte = mmu_walk(rv, addr, &level, &pte_ref);
pte = pte_ref;
//pte = pte_ref;
assert(pte);

{
Expand Down
3 changes: 2 additions & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ else # Linux
TIMEOUT=90
fi

for i in {1..20}; do
for i in {1..100}; do
echo ${i}
ASSERT expect <<DONE
set timeout ${TIMEOUT}
spawn build/rv32emu -k ./build/linux-image/Image -i ./build/linux-image/rootfs.cpio -b build/minimal.dtb
Expand Down

0 comments on commit 5d7049d

Please sign in to comment.