mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-riscv-to-apply-20220108' of github.com:alistair23/qemu into staging
Second RISC-V PR for QEMU 7.0 - Fix illegal instruction when PMP is disabled - SiFive PDMA 64-bit support - SiFive PLIC cleanups - Mark Hypervisor extension as non experimental - Enable Hypervisor extension by default - Support 32 cores on the virt machine - Corrections for the Vector extension - Experimental support for 128-bit CPUs - stval and mtval support for illegal instructions # gpg: Signature made Fri 07 Jan 2022 09:50:11 PM PST # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * tag 'pull-riscv-to-apply-20220108' of github.com:alistair23/qemu: (37 commits) target/riscv: Implement the stval/mtval illegal instruction target/riscv: Fixup setting GVA target/riscv: Set the opcode in DisasContext target/riscv: actual functions to realize crs 128-bit insns target/riscv: modification of the trans_csrxx for 128-bit support target/riscv: helper functions to wrap calls to 128-bit csr insns target/riscv: adding high part of some csrs target/riscv: support for 128-bit M extension target/riscv: support for 128-bit arithmetic instructions target/riscv: support for 128-bit shift instructions target/riscv: support for 128-bit U-type instructions target/riscv: support for 128-bit bitwise instructions target/riscv: accessors to registers upper part and 128-bit load/store target/riscv: moving some insns close to similar insns target/riscv: setup everything for rv64 to support rv128 execution target/riscv: array for the 64 upper bits of 128-bit registers target/riscv: separation of bitwise logic and arithmetic helpers target/riscv: additional macros to check instruction support qemu/int128: addition of div/rem 128-bit operations exec/memop: Adding signed quad and octo defines ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
+15
-15
@@ -1885,9 +1885,9 @@ load_memop(const void *haddr, MemOp op)
|
||||
return (uint32_t)ldl_be_p(haddr);
|
||||
case MO_LEUL:
|
||||
return (uint32_t)ldl_le_p(haddr);
|
||||
case MO_BEQ:
|
||||
case MO_BEUQ:
|
||||
return ldq_be_p(haddr);
|
||||
case MO_LEQ:
|
||||
case MO_LEUQ:
|
||||
return ldq_le_p(haddr);
|
||||
default:
|
||||
qemu_build_not_reached();
|
||||
@@ -2081,16 +2081,16 @@ tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
|
||||
uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_LEQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_LEQ, false,
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_LEUQ, false,
|
||||
helper_le_ldq_mmu);
|
||||
}
|
||||
|
||||
uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_BEQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_BEQ, false,
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_BEUQ, false,
|
||||
helper_be_ldq_mmu);
|
||||
}
|
||||
|
||||
@@ -2166,7 +2166,7 @@ uint32_t cpu_ldl_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
return cpu_load_helper(env, addr, oi, MO_BEQ, helper_be_ldq_mmu);
|
||||
return cpu_load_helper(env, addr, oi, MO_BEUQ, helper_be_ldq_mmu);
|
||||
}
|
||||
|
||||
uint16_t cpu_ldw_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
@@ -2210,10 +2210,10 @@ store_memop(void *haddr, uint64_t val, MemOp op)
|
||||
case MO_LEUL:
|
||||
stl_le_p(haddr, val);
|
||||
break;
|
||||
case MO_BEQ:
|
||||
case MO_BEUQ:
|
||||
stq_be_p(haddr, val);
|
||||
break;
|
||||
case MO_LEQ:
|
||||
case MO_LEUQ:
|
||||
stq_le_p(haddr, val);
|
||||
break;
|
||||
default:
|
||||
@@ -2465,15 +2465,15 @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
||||
void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_LEQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_LEQ);
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_LEUQ);
|
||||
}
|
||||
|
||||
void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_BEQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_BEQ);
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_BEUQ);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2609,11 +2609,11 @@ uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
|
||||
static uint64_t full_ldq_code(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
return load_helper(env, addr, oi, retaddr, MO_TEQ, true, full_ldq_code);
|
||||
return load_helper(env, addr, oi, retaddr, MO_TEUQ, true, full_ldq_code);
|
||||
}
|
||||
|
||||
uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_TEQ, cpu_mmu_index(env, true));
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true));
|
||||
return full_ldq_code(env, addr, oi, 0);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_BEQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
|
||||
return cpu_ldq_be_mmu(env, addr, oi, ra);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_LEQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
|
||||
return cpu_ldq_le_mmu(env, addr, oi, ra);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_BEQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
|
||||
cpu_stq_be_mmu(env, addr, val, oi, ra);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_LEQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
|
||||
cpu_stq_le_mmu(env, addr, val, oi, ra);
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
void *haddr;
|
||||
uint64_t ret;
|
||||
|
||||
validate_memop(oi, MO_BEQ);
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldq_be_p(haddr);
|
||||
@@ -339,7 +339,7 @@ uint64_t cpu_ldq_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
void *haddr;
|
||||
uint64_t ret;
|
||||
|
||||
validate_memop(oi, MO_LEQ);
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldq_le_p(haddr);
|
||||
@@ -392,7 +392,7 @@ void cpu_stq_be_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
{
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_BEQ);
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stq_be_p(haddr, val);
|
||||
@@ -431,7 +431,7 @@ void cpu_stq_le_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
{
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_LEQ);
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stq_le_p(haddr, val);
|
||||
|
||||
@@ -3090,3 +3090,8 @@ int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info)
|
||||
{
|
||||
return print_insn_riscv(memaddr, info, rv64);
|
||||
}
|
||||
|
||||
int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info)
|
||||
{
|
||||
return print_insn_riscv(memaddr, info, rv128);
|
||||
}
|
||||
|
||||
+181
-44
@@ -177,6 +177,101 @@ static inline void sifive_pdma_update_irq(SiFivePDMAState *s, int ch)
|
||||
s->chan[ch].state = DMA_CHAN_STATE_IDLE;
|
||||
}
|
||||
|
||||
static uint64_t sifive_pdma_readq(SiFivePDMAState *s, int ch, hwaddr offset)
|
||||
{
|
||||
uint64_t val = 0;
|
||||
|
||||
offset &= 0xfff;
|
||||
switch (offset) {
|
||||
case DMA_NEXT_BYTES:
|
||||
val = s->chan[ch].next_bytes;
|
||||
break;
|
||||
case DMA_NEXT_DST:
|
||||
val = s->chan[ch].next_dst;
|
||||
break;
|
||||
case DMA_NEXT_SRC:
|
||||
val = s->chan[ch].next_src;
|
||||
break;
|
||||
case DMA_EXEC_BYTES:
|
||||
val = s->chan[ch].exec_bytes;
|
||||
break;
|
||||
case DMA_EXEC_DST:
|
||||
val = s->chan[ch].exec_dst;
|
||||
break;
|
||||
case DMA_EXEC_SRC:
|
||||
val = s->chan[ch].exec_src;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint32_t sifive_pdma_readl(SiFivePDMAState *s, int ch, hwaddr offset)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
offset &= 0xfff;
|
||||
switch (offset) {
|
||||
case DMA_CONTROL:
|
||||
val = s->chan[ch].control;
|
||||
break;
|
||||
case DMA_NEXT_CONFIG:
|
||||
val = s->chan[ch].next_config;
|
||||
break;
|
||||
case DMA_NEXT_BYTES:
|
||||
val = extract64(s->chan[ch].next_bytes, 0, 32);
|
||||
break;
|
||||
case DMA_NEXT_BYTES + 4:
|
||||
val = extract64(s->chan[ch].next_bytes, 32, 32);
|
||||
break;
|
||||
case DMA_NEXT_DST:
|
||||
val = extract64(s->chan[ch].next_dst, 0, 32);
|
||||
break;
|
||||
case DMA_NEXT_DST + 4:
|
||||
val = extract64(s->chan[ch].next_dst, 32, 32);
|
||||
break;
|
||||
case DMA_NEXT_SRC:
|
||||
val = extract64(s->chan[ch].next_src, 0, 32);
|
||||
break;
|
||||
case DMA_NEXT_SRC + 4:
|
||||
val = extract64(s->chan[ch].next_src, 32, 32);
|
||||
break;
|
||||
case DMA_EXEC_CONFIG:
|
||||
val = s->chan[ch].exec_config;
|
||||
break;
|
||||
case DMA_EXEC_BYTES:
|
||||
val = extract64(s->chan[ch].exec_bytes, 0, 32);
|
||||
break;
|
||||
case DMA_EXEC_BYTES + 4:
|
||||
val = extract64(s->chan[ch].exec_bytes, 32, 32);
|
||||
break;
|
||||
case DMA_EXEC_DST:
|
||||
val = extract64(s->chan[ch].exec_dst, 0, 32);
|
||||
break;
|
||||
case DMA_EXEC_DST + 4:
|
||||
val = extract64(s->chan[ch].exec_dst, 32, 32);
|
||||
break;
|
||||
case DMA_EXEC_SRC:
|
||||
val = extract64(s->chan[ch].exec_src, 0, 32);
|
||||
break;
|
||||
case DMA_EXEC_SRC + 4:
|
||||
val = extract64(s->chan[ch].exec_src, 32, 32);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Unexpected 32-bit access to 0x%" HWADDR_PRIX "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
SiFivePDMAState *s = opaque;
|
||||
@@ -189,56 +284,53 @@ static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset &= 0xfff;
|
||||
switch (offset) {
|
||||
case DMA_CONTROL:
|
||||
val = s->chan[ch].control;
|
||||
switch (size) {
|
||||
case 8:
|
||||
val = sifive_pdma_readq(s, ch, offset);
|
||||
break;
|
||||
case DMA_NEXT_CONFIG:
|
||||
val = s->chan[ch].next_config;
|
||||
break;
|
||||
case DMA_NEXT_BYTES:
|
||||
val = s->chan[ch].next_bytes;
|
||||
break;
|
||||
case DMA_NEXT_DST:
|
||||
val = s->chan[ch].next_dst;
|
||||
break;
|
||||
case DMA_NEXT_SRC:
|
||||
val = s->chan[ch].next_src;
|
||||
break;
|
||||
case DMA_EXEC_CONFIG:
|
||||
val = s->chan[ch].exec_config;
|
||||
break;
|
||||
case DMA_EXEC_BYTES:
|
||||
val = s->chan[ch].exec_bytes;
|
||||
break;
|
||||
case DMA_EXEC_DST:
|
||||
val = s->chan[ch].exec_dst;
|
||||
break;
|
||||
case DMA_EXEC_SRC:
|
||||
val = s->chan[ch].exec_src;
|
||||
case 4:
|
||||
val = sifive_pdma_readl(s, ch, offset);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid read size %u to PDMA\n",
|
||||
__func__, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void sifive_pdma_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
static void sifive_pdma_writeq(SiFivePDMAState *s, int ch,
|
||||
hwaddr offset, uint64_t value)
|
||||
{
|
||||
SiFivePDMAState *s = opaque;
|
||||
int ch = SIFIVE_PDMA_CHAN_NO(offset);
|
||||
bool claimed, run;
|
||||
|
||||
if (ch >= SIFIVE_PDMA_CHANS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n",
|
||||
__func__, ch);
|
||||
return;
|
||||
offset &= 0xfff;
|
||||
switch (offset) {
|
||||
case DMA_NEXT_BYTES:
|
||||
s->chan[ch].next_bytes = value;
|
||||
break;
|
||||
case DMA_NEXT_DST:
|
||||
s->chan[ch].next_dst = value;
|
||||
break;
|
||||
case DMA_NEXT_SRC:
|
||||
s->chan[ch].next_src = value;
|
||||
break;
|
||||
case DMA_EXEC_BYTES:
|
||||
case DMA_EXEC_DST:
|
||||
case DMA_EXEC_SRC:
|
||||
/* these are read-only registers */
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sifive_pdma_writel(SiFivePDMAState *s, int ch,
|
||||
hwaddr offset, uint32_t value)
|
||||
{
|
||||
bool claimed, run;
|
||||
|
||||
offset &= 0xfff;
|
||||
switch (offset) {
|
||||
@@ -282,27 +374,68 @@ static void sifive_pdma_write(void *opaque, hwaddr offset,
|
||||
s->chan[ch].next_config = value;
|
||||
break;
|
||||
case DMA_NEXT_BYTES:
|
||||
s->chan[ch].next_bytes = value;
|
||||
s->chan[ch].next_bytes =
|
||||
deposit64(s->chan[ch].next_bytes, 0, 32, value);
|
||||
break;
|
||||
case DMA_NEXT_BYTES + 4:
|
||||
s->chan[ch].next_bytes =
|
||||
deposit64(s->chan[ch].next_bytes, 32, 32, value);
|
||||
break;
|
||||
case DMA_NEXT_DST:
|
||||
s->chan[ch].next_dst = value;
|
||||
s->chan[ch].next_dst = deposit64(s->chan[ch].next_dst, 0, 32, value);
|
||||
break;
|
||||
case DMA_NEXT_DST + 4:
|
||||
s->chan[ch].next_dst = deposit64(s->chan[ch].next_dst, 32, 32, value);
|
||||
break;
|
||||
case DMA_NEXT_SRC:
|
||||
s->chan[ch].next_src = value;
|
||||
s->chan[ch].next_src = deposit64(s->chan[ch].next_src, 0, 32, value);
|
||||
break;
|
||||
case DMA_NEXT_SRC + 4:
|
||||
s->chan[ch].next_src = deposit64(s->chan[ch].next_src, 32, 32, value);
|
||||
break;
|
||||
case DMA_EXEC_CONFIG:
|
||||
case DMA_EXEC_BYTES:
|
||||
case DMA_EXEC_BYTES + 4:
|
||||
case DMA_EXEC_DST:
|
||||
case DMA_EXEC_DST + 4:
|
||||
case DMA_EXEC_SRC:
|
||||
case DMA_EXEC_SRC + 4:
|
||||
/* these are read-only registers */
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Unexpected 32-bit access to 0x%" HWADDR_PRIX "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sifive_pdma_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
SiFivePDMAState *s = opaque;
|
||||
int ch = SIFIVE_PDMA_CHAN_NO(offset);
|
||||
|
||||
if (ch >= SIFIVE_PDMA_CHANS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n",
|
||||
__func__, ch);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 8:
|
||||
sifive_pdma_writeq(s, ch, offset, value);
|
||||
break;
|
||||
case 4:
|
||||
sifive_pdma_writel(s, ch, offset, (uint32_t) value);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid write size %u to PDMA\n",
|
||||
__func__, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps sifive_pdma_ops = {
|
||||
.read = sifive_pdma_read,
|
||||
.write = sifive_pdma_write,
|
||||
@@ -311,6 +444,10 @@ static const MemoryRegionOps sifive_pdma_ops = {
|
||||
.impl = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 8,
|
||||
},
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 8,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+76
-178
@@ -31,7 +31,10 @@
|
||||
#include "migration/vmstate.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
#define RISCV_DEBUG_PLIC 0
|
||||
static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
|
||||
{
|
||||
return addr >= base && addr - base < num;
|
||||
}
|
||||
|
||||
static PLICMode char_to_mode(char c)
|
||||
{
|
||||
@@ -46,47 +49,6 @@ static PLICMode char_to_mode(char c)
|
||||
}
|
||||
}
|
||||
|
||||
static char mode_to_char(PLICMode m)
|
||||
{
|
||||
switch (m) {
|
||||
case PLICMode_U: return 'U';
|
||||
case PLICMode_S: return 'S';
|
||||
case PLICMode_H: return 'H';
|
||||
case PLICMode_M: return 'M';
|
||||
default: return '?';
|
||||
}
|
||||
}
|
||||
|
||||
static void sifive_plic_print_state(SiFivePLICState *plic)
|
||||
{
|
||||
int i;
|
||||
int addrid;
|
||||
|
||||
/* pending */
|
||||
qemu_log("pending : ");
|
||||
for (i = plic->bitfield_words - 1; i >= 0; i--) {
|
||||
qemu_log("%08x", plic->pending[i]);
|
||||
}
|
||||
qemu_log("\n");
|
||||
|
||||
/* pending */
|
||||
qemu_log("claimed : ");
|
||||
for (i = plic->bitfield_words - 1; i >= 0; i--) {
|
||||
qemu_log("%08x", plic->claimed[i]);
|
||||
}
|
||||
qemu_log("\n");
|
||||
|
||||
for (addrid = 0; addrid < plic->num_addrs; addrid++) {
|
||||
qemu_log("hart%d-%c enable: ",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode));
|
||||
for (i = plic->bitfield_words - 1; i >= 0; i--) {
|
||||
qemu_log("%08x", plic->enable[addrid * plic->bitfield_words + i]);
|
||||
}
|
||||
qemu_log("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value)
|
||||
{
|
||||
uint32_t old, new, cmp = qatomic_read(a);
|
||||
@@ -110,26 +72,34 @@ static void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool level)
|
||||
atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level);
|
||||
}
|
||||
|
||||
static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
|
||||
static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
|
||||
{
|
||||
uint32_t max_irq = 0;
|
||||
uint32_t max_prio = plic->target_priority[addrid];
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < plic->bitfield_words; i++) {
|
||||
uint32_t pending_enabled_not_claimed =
|
||||
(plic->pending[i] & ~plic->claimed[i]) &
|
||||
plic->enable[addrid * plic->bitfield_words + i];
|
||||
(plic->pending[i] & ~plic->claimed[i]) &
|
||||
plic->enable[addrid * plic->bitfield_words + i];
|
||||
|
||||
if (!pending_enabled_not_claimed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
int irq = (i << 5) + j;
|
||||
uint32_t prio = plic->source_priority[irq];
|
||||
int enabled = pending_enabled_not_claimed & (1 << j);
|
||||
if (enabled && prio > plic->target_priority[addrid]) {
|
||||
return 1;
|
||||
|
||||
if (enabled && prio > max_prio) {
|
||||
max_irq = irq;
|
||||
max_prio = prio;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
return max_irq;
|
||||
}
|
||||
|
||||
static void sifive_plic_update(SiFivePLICState *plic)
|
||||
@@ -140,7 +110,7 @@ static void sifive_plic_update(SiFivePLICState *plic)
|
||||
for (addrid = 0; addrid < plic->num_addrs; addrid++) {
|
||||
uint32_t hartid = plic->addr_config[addrid].hartid;
|
||||
PLICMode mode = plic->addr_config[addrid].mode;
|
||||
int level = sifive_plic_irqs_pending(plic, addrid);
|
||||
bool level = !!sifive_plic_claimed(plic, addrid);
|
||||
|
||||
switch (mode) {
|
||||
case PLICMode_M:
|
||||
@@ -153,111 +123,48 @@ static void sifive_plic_update(SiFivePLICState *plic)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
sifive_plic_print_state(plic);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid)
|
||||
{
|
||||
int i, j;
|
||||
uint32_t max_irq = 0;
|
||||
uint32_t max_prio = plic->target_priority[addrid];
|
||||
|
||||
for (i = 0; i < plic->bitfield_words; i++) {
|
||||
uint32_t pending_enabled_not_claimed =
|
||||
(plic->pending[i] & ~plic->claimed[i]) &
|
||||
plic->enable[addrid * plic->bitfield_words + i];
|
||||
if (!pending_enabled_not_claimed) {
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < 32; j++) {
|
||||
int irq = (i << 5) + j;
|
||||
uint32_t prio = plic->source_priority[irq];
|
||||
int enabled = pending_enabled_not_claimed & (1 << j);
|
||||
if (enabled && prio > max_prio) {
|
||||
max_irq = irq;
|
||||
max_prio = prio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (max_irq) {
|
||||
sifive_plic_set_pending(plic, max_irq, false);
|
||||
sifive_plic_set_claimed(plic, max_irq, true);
|
||||
}
|
||||
return max_irq;
|
||||
}
|
||||
|
||||
static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
SiFivePLICState *plic = opaque;
|
||||
|
||||
/* writes must be 4 byte words */
|
||||
if ((addr & 0x3) != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (addr >= plic->priority_base && /* 4 bytes per source */
|
||||
addr < plic->priority_base + (plic->num_sources << 2))
|
||||
{
|
||||
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
|
||||
uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: read priority: irq=%d priority=%d\n",
|
||||
irq, plic->source_priority[irq]);
|
||||
}
|
||||
|
||||
return plic->source_priority[irq];
|
||||
} else if (addr >= plic->pending_base && /* 1 bit per source */
|
||||
addr < plic->pending_base + (plic->num_sources >> 3))
|
||||
{
|
||||
} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
|
||||
uint32_t word = (addr - plic->pending_base) >> 2;
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: read pending: word=%d value=%d\n",
|
||||
word, plic->pending[word]);
|
||||
}
|
||||
|
||||
return plic->pending[word];
|
||||
} else if (addr >= plic->enable_base && /* 1 bit per source */
|
||||
addr < plic->enable_base + plic->num_addrs * plic->enable_stride)
|
||||
{
|
||||
} else if (addr_between(addr, plic->enable_base,
|
||||
plic->num_addrs * plic->enable_stride)) {
|
||||
uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride;
|
||||
uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2;
|
||||
|
||||
if (wordid < plic->bitfield_words) {
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: read enable: hart%d-%c word=%d value=%x\n",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode), wordid,
|
||||
plic->enable[addrid * plic->bitfield_words + wordid]);
|
||||
}
|
||||
return plic->enable[addrid * plic->bitfield_words + wordid];
|
||||
}
|
||||
} else if (addr >= plic->context_base && /* 1 bit per source */
|
||||
addr < plic->context_base + plic->num_addrs * plic->context_stride)
|
||||
{
|
||||
} else if (addr_between(addr, plic->context_base,
|
||||
plic->num_addrs * plic->context_stride)) {
|
||||
uint32_t addrid = (addr - plic->context_base) / plic->context_stride;
|
||||
uint32_t contextid = (addr & (plic->context_stride - 1));
|
||||
|
||||
if (contextid == 0) {
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: read priority: hart%d-%c priority=%x\n",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode),
|
||||
plic->target_priority[addrid]);
|
||||
}
|
||||
return plic->target_priority[addrid];
|
||||
} else if (contextid == 4) {
|
||||
uint32_t value = sifive_plic_claim(plic, addrid);
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: read claim: hart%d-%c irq=%x\n",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode),
|
||||
value);
|
||||
uint32_t max_irq = sifive_plic_claimed(plic, addrid);
|
||||
|
||||
if (max_irq) {
|
||||
sifive_plic_set_pending(plic, max_irq, false);
|
||||
sifive_plic_set_claimed(plic, max_irq, true);
|
||||
}
|
||||
|
||||
sifive_plic_update(plic);
|
||||
return value;
|
||||
return max_irq;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Invalid register read 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
@@ -269,80 +176,53 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
|
||||
{
|
||||
SiFivePLICState *plic = opaque;
|
||||
|
||||
/* writes must be 4 byte words */
|
||||
if ((addr & 0x3) != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (addr >= plic->priority_base && /* 4 bytes per source */
|
||||
addr < plic->priority_base + (plic->num_sources << 2))
|
||||
{
|
||||
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
|
||||
uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
|
||||
|
||||
plic->source_priority[irq] = value & 7;
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: write priority: irq=%d priority=%d\n",
|
||||
irq, plic->source_priority[irq]);
|
||||
}
|
||||
sifive_plic_update(plic);
|
||||
return;
|
||||
} else if (addr >= plic->pending_base && /* 1 bit per source */
|
||||
addr < plic->pending_base + (plic->num_sources >> 3))
|
||||
{
|
||||
} else if (addr_between(addr, plic->pending_base,
|
||||
plic->num_sources >> 3)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid pending write: 0x%" HWADDR_PRIx "",
|
||||
__func__, addr);
|
||||
return;
|
||||
} else if (addr >= plic->enable_base && /* 1 bit per source */
|
||||
addr < plic->enable_base + plic->num_addrs * plic->enable_stride)
|
||||
{
|
||||
} else if (addr_between(addr, plic->enable_base,
|
||||
plic->num_addrs * plic->enable_stride)) {
|
||||
uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride;
|
||||
uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2;
|
||||
|
||||
if (wordid < plic->bitfield_words) {
|
||||
plic->enable[addrid * plic->bitfield_words + wordid] = value;
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: write enable: hart%d-%c word=%d value=%x\n",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode), wordid,
|
||||
plic->enable[addrid * plic->bitfield_words + wordid]);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Invalid enable write 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
}
|
||||
} else if (addr >= plic->context_base && /* 4 bytes per reg */
|
||||
addr < plic->context_base + plic->num_addrs * plic->context_stride)
|
||||
{
|
||||
} else if (addr_between(addr, plic->context_base,
|
||||
plic->num_addrs * plic->context_stride)) {
|
||||
uint32_t addrid = (addr - plic->context_base) / plic->context_stride;
|
||||
uint32_t contextid = (addr & (plic->context_stride - 1));
|
||||
|
||||
if (contextid == 0) {
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: write priority: hart%d-%c priority=%x\n",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode),
|
||||
plic->target_priority[addrid]);
|
||||
}
|
||||
if (value <= plic->num_priorities) {
|
||||
plic->target_priority[addrid] = value;
|
||||
sifive_plic_update(plic);
|
||||
}
|
||||
return;
|
||||
} else if (contextid == 4) {
|
||||
if (RISCV_DEBUG_PLIC) {
|
||||
qemu_log("plic: write claim: hart%d-%c irq=%x\n",
|
||||
plic->addr_config[addrid].hartid,
|
||||
mode_to_char(plic->addr_config[addrid].mode),
|
||||
(uint32_t)value);
|
||||
}
|
||||
if (value < plic->num_sources) {
|
||||
sifive_plic_set_claimed(plic, value, false);
|
||||
sifive_plic_update(plic);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Invalid context write 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
}
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Invalid register write 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
}
|
||||
|
||||
err:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Invalid register write 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps sifive_plic_ops = {
|
||||
@@ -355,6 +235,23 @@ static const MemoryRegionOps sifive_plic_ops = {
|
||||
}
|
||||
};
|
||||
|
||||
static void sifive_plic_reset(DeviceState *dev)
|
||||
{
|
||||
SiFivePLICState *s = SIFIVE_PLIC(dev);
|
||||
int i;
|
||||
|
||||
memset(s->source_priority, 0, sizeof(uint32_t) * s->num_sources);
|
||||
memset(s->target_priority, 0, sizeof(uint32_t) * s->num_addrs);
|
||||
memset(s->pending, 0, sizeof(uint32_t) * s->bitfield_words);
|
||||
memset(s->claimed, 0, sizeof(uint32_t) * s->bitfield_words);
|
||||
memset(s->enable, 0, sizeof(uint32_t) * s->num_enables);
|
||||
|
||||
for (i = 0; i < s->num_harts; i++) {
|
||||
qemu_set_irq(s->m_external_irqs[i], 0);
|
||||
qemu_set_irq(s->s_external_irqs[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse PLIC hart/mode address offset config
|
||||
*
|
||||
@@ -501,6 +398,7 @@ static void sifive_plic_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = sifive_plic_reset;
|
||||
device_class_set_props(dc, sifive_plic_properties);
|
||||
dc->realize = sifive_plic_realize;
|
||||
dc->vmsd = &vmstate_sifive_plic;
|
||||
|
||||
@@ -471,7 +471,7 @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
|
||||
/* Initialize SoC */
|
||||
object_initialize_child(OBJECT(machine), "soc", &s->soc,
|
||||
TYPE_MICROCHIP_PFSOC);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
|
||||
|
||||
/* Split RAM into low and high regions using aliases to machine->ram */
|
||||
mem_low_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size;
|
||||
|
||||
@@ -80,7 +80,7 @@ static void opentitan_board_init(MachineState *machine)
|
||||
/* Initialize SoC */
|
||||
object_initialize_child(OBJECT(machine), "soc", &s->soc,
|
||||
TYPE_RISCV_IBEX_SOC);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
|
||||
|
||||
memory_region_add_subregion(sys_mem,
|
||||
memmap[IBEX_DEV_RAM].base, machine->ram);
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ static void sifive_e_machine_init(MachineState *machine)
|
||||
|
||||
/* Initialize SoC */
|
||||
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_E_SOC);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
|
||||
|
||||
/* Data Tightly Integrated Memory */
|
||||
memory_region_add_subregion(sys_mem,
|
||||
|
||||
+1
-1
@@ -547,7 +547,7 @@ static void sifive_u_machine_init(MachineState *machine)
|
||||
&error_abort);
|
||||
object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
|
||||
&error_abort);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
|
||||
|
||||
/* register RAM */
|
||||
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_DRAM].base,
|
||||
|
||||
@@ -459,6 +459,7 @@ int print_insn_nios2(bfd_vma, disassemble_info*);
|
||||
int print_insn_xtensa (bfd_vma, disassemble_info*);
|
||||
int print_insn_riscv32 (bfd_vma, disassemble_info*);
|
||||
int print_insn_riscv64 (bfd_vma, disassemble_info*);
|
||||
int print_insn_riscv128 (bfd_vma, disassemble_info*);
|
||||
int print_insn_rx(bfd_vma, disassemble_info *);
|
||||
int print_insn_hexagon(bfd_vma, disassemble_info *);
|
||||
|
||||
|
||||
+11
-4
@@ -85,29 +85,36 @@ typedef enum MemOp {
|
||||
MO_UB = MO_8,
|
||||
MO_UW = MO_16,
|
||||
MO_UL = MO_32,
|
||||
MO_UQ = MO_64,
|
||||
MO_UO = MO_128,
|
||||
MO_SB = MO_SIGN | MO_8,
|
||||
MO_SW = MO_SIGN | MO_16,
|
||||
MO_SL = MO_SIGN | MO_32,
|
||||
MO_Q = MO_64,
|
||||
MO_SQ = MO_SIGN | MO_64,
|
||||
MO_SO = MO_SIGN | MO_128,
|
||||
|
||||
MO_LEUW = MO_LE | MO_UW,
|
||||
MO_LEUL = MO_LE | MO_UL,
|
||||
MO_LEUQ = MO_LE | MO_UQ,
|
||||
MO_LESW = MO_LE | MO_SW,
|
||||
MO_LESL = MO_LE | MO_SL,
|
||||
MO_LEQ = MO_LE | MO_Q,
|
||||
MO_LESQ = MO_LE | MO_SQ,
|
||||
|
||||
MO_BEUW = MO_BE | MO_UW,
|
||||
MO_BEUL = MO_BE | MO_UL,
|
||||
MO_BEUQ = MO_BE | MO_UQ,
|
||||
MO_BESW = MO_BE | MO_SW,
|
||||
MO_BESL = MO_BE | MO_SL,
|
||||
MO_BEQ = MO_BE | MO_Q,
|
||||
MO_BESQ = MO_BE | MO_SQ,
|
||||
|
||||
#ifdef NEED_CPU_H
|
||||
MO_TEUW = MO_TE | MO_UW,
|
||||
MO_TEUL = MO_TE | MO_UL,
|
||||
MO_TEUQ = MO_TE | MO_UQ,
|
||||
MO_TEUO = MO_TE | MO_UO,
|
||||
MO_TESW = MO_TE | MO_SW,
|
||||
MO_TESL = MO_TE | MO_SL,
|
||||
MO_TEQ = MO_TE | MO_Q,
|
||||
MO_TESQ = MO_TE | MO_SQ,
|
||||
#endif
|
||||
|
||||
MO_SSIZE = MO_SIZE | MO_SIGN,
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "hw/block/flash.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define VIRT_CPUS_MAX 8
|
||||
#define VIRT_CPUS_MAX 32
|
||||
#define VIRT_SOCKETS_MAX 8
|
||||
|
||||
#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
|
||||
@@ -172,6 +172,26 @@ static inline Int128 bswap128(Int128 a)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline Int128 int128_divu(Int128 a, Int128 b)
|
||||
{
|
||||
return (__uint128_t)a / (__uint128_t)b;
|
||||
}
|
||||
|
||||
static inline Int128 int128_remu(Int128 a, Int128 b)
|
||||
{
|
||||
return (__uint128_t)a % (__uint128_t)b;
|
||||
}
|
||||
|
||||
static inline Int128 int128_divs(Int128 a, Int128 b)
|
||||
{
|
||||
return a / b;
|
||||
}
|
||||
|
||||
static inline Int128 int128_rems(Int128 a, Int128 b)
|
||||
{
|
||||
return a % b;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_INT128 */
|
||||
|
||||
typedef struct Int128 Int128;
|
||||
@@ -379,6 +399,11 @@ static inline Int128 bswap128(Int128 a)
|
||||
return int128_make128(bswap64(a.hi), bswap64(a.lo));
|
||||
}
|
||||
|
||||
Int128 int128_divu(Int128, Int128);
|
||||
Int128 int128_remu(Int128, Int128);
|
||||
Int128 int128_divs(Int128, Int128);
|
||||
Int128 int128_rems(Int128, Int128);
|
||||
|
||||
#endif /* CONFIG_INT128 */
|
||||
|
||||
static inline void bswap128s(Int128 *s)
|
||||
@@ -386,4 +411,6 @@ static inline void bswap128s(Int128 *s)
|
||||
*s = bswap128(*s);
|
||||
}
|
||||
|
||||
#define UINT128_MAX int128_make128(~0LL, ~0LL)
|
||||
|
||||
#endif /* INT128_H */
|
||||
|
||||
@@ -894,7 +894,7 @@ static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
|
||||
|
||||
static inline void tcg_gen_qemu_ld64(TCGv_i64 ret, TCGv addr, int mem_index)
|
||||
{
|
||||
tcg_gen_qemu_ld_i64(ret, addr, mem_index, MO_TEQ);
|
||||
tcg_gen_qemu_ld_i64(ret, addr, mem_index, MO_TEUQ);
|
||||
}
|
||||
|
||||
static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
|
||||
@@ -914,7 +914,7 @@ static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
|
||||
|
||||
static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
|
||||
{
|
||||
tcg_gen_qemu_st_i64(arg, addr, mem_index, MO_TEQ);
|
||||
tcg_gen_qemu_st_i64(arg, addr, mem_index, MO_TEUQ);
|
||||
}
|
||||
|
||||
void tcg_gen_atomic_cmpxchg_i32(TCGv_i32, TCGv, TCGv_i32, TCGv_i32,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
Submodule roms/opensbi updated: 234ed8e427...48f91ee9c9
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user