Skip to content

Commit d0ee6c4

Browse files
committed
Allow JIT compilation for system simulation
This commit introduces "satp" field to the block structure in JIT mode to ensure the block cache is replaced correctly. The MOP fusion and T2C are disabled temporarily. Use the following commands to boot the Linux Kernel: $ make ENABLE_SYSTEM=1 ENABLE_MOP_FUSION=0 ENABLE_JIT=1 ENABLE_T2C=0 $ ./build/rv32emu -k <image> -i <rootfs> -b <dtb>
1 parent 12c9dbe commit d0ee6c4

File tree

9 files changed

+922
-215
lines changed

9 files changed

+922
-215
lines changed

src/decode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ typedef struct {
332332
struct rv_insn *target[HISTORY_SIZE];
333333
#else
334334
uint32_t times[HISTORY_SIZE];
335+
#if RV32_HAS(SYSTEM)
336+
uint32_t satp[HISTORY_SIZE];
337+
#endif
335338
#endif
336339
} branch_history_table_t;
337340

src/emulate.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -863,12 +863,12 @@ static block_t *block_find_or_translate(riscv_t *rv)
863863
block_t *next_blk = block_find(map, rv->PC);
864864
#else
865865
/* lookup the next block in the block cache */
866-
/*
867-
* The function "cache_get()" gets the cached block by the given "key (PC)".
868-
* In system simulation, the returned block might be dropped because it is
869-
* not the one from the current process (by checking SATP CSR register).
870-
*/
871866
block_t *next_blk = (block_t *) cache_get(rv->block_cache, rv->PC, true);
867+
#if RV32_HAS(SYSTEM)
868+
/* discard cache if satp is not matched */
869+
if (next_blk && next_blk->satp != rv->csr_satp)
870+
next_blk = NULL;
871+
#endif
872872
#endif
873873

874874
if (next_blk)
@@ -886,6 +886,14 @@ static block_t *block_find_or_translate(riscv_t *rv)
886886

887887
block_translate(rv, next_blk);
888888

889+
#if RV32_HAS(JIT) && RV32_HAS(SYSTEM)
890+
/*
891+
* May be an ifetch fault which changes satp, Do not do this
892+
* in "block_alloc()"
893+
*/
894+
next_blk->satp = rv->csr_satp;
895+
#endif
896+
889897
optimize_constant(rv, next_blk);
890898
#if RV32_HAS(MOP_FUSION)
891899
/* macro operation fusion */
@@ -912,8 +920,6 @@ static block_t *block_find_or_translate(riscv_t *rv)
912920
return next_blk;
913921
}
914922

915-
list_del_init(&replaced_blk->list);
916-
917923
if (prev == replaced_blk)
918924
prev = NULL;
919925

@@ -932,6 +938,16 @@ static block_t *block_find_or_translate(riscv_t *rv)
932938
if (untaken == replaced_blk_entry) {
933939
entry->ir_tail->branch_untaken = NULL;
934940
}
941+
942+
/* upadte JALR LUT */
943+
if (!entry->ir_tail->branch_table) {
944+
continue;
945+
}
946+
947+
/**
948+
* TODO: upadate all JALR instructions which references to this
949+
* basic block as the destination.
950+
*/
935951
}
936952

937953
/* free IRs in replaced block */
@@ -945,6 +961,7 @@ static block_t *block_find_or_translate(riscv_t *rv)
945961
mpool_free(rv->block_ir_mp, ir);
946962
}
947963

964+
list_del_init(&replaced_blk->list);
948965
mpool_free(rv->block_mp, replaced_blk);
949966
#if RV32_HAS(T2C)
950967
pthread_mutex_unlock(&rv->cache_lock);
@@ -961,6 +978,10 @@ static block_t *block_find_or_translate(riscv_t *rv)
961978
#if RV32_HAS(JIT) && !RV32_HAS(ARCH_TEST)
962979
static bool runtime_profiler(riscv_t *rv, block_t *block)
963980
{
981+
#if RV32_HAS(SYSTEM)
982+
if (block->satp != rv->csr_satp)
983+
return false;
984+
#endif
964985
/* Based on our observations, a significant number of true hotspots are
965986
* characterized by high usage frequency and including loop. Consequently,
966987
* we posit that our profiler could effectively identify hotspots using
@@ -1053,14 +1074,22 @@ void rv_step(void *arg)
10531074
/* by now, a block should be available */
10541075
assert(block);
10551076

1077+
#if RV32_HAS(JIT) && RV32_HAS(SYSTEM)
1078+
assert(block->satp == rv->csr_satp);
1079+
#endif
1080+
10561081
/* After emulating the previous block, it is determined whether the
10571082
* branch is taken or not. The IR array of the current block is then
10581083
* assigned to either the branch_taken or branch_untaken pointer of
10591084
* the previous block.
10601085
*/
10611086

10621087
#if RV32_HAS(BLOCK_CHAINING)
1063-
if (prev) {
1088+
if (prev
1089+
#if RV32_HAS(JIT) && RV32_HAS(SYSTEM)
1090+
&& prev->satp == rv->csr_satp
1091+
#endif
1092+
) {
10641093
rv_insn_t *last_ir = prev->ir_tail;
10651094
/* chain block */
10661095
if (!insn_is_unconditional_branch(last_ir->opcode)) {

0 commit comments

Comments
 (0)