pull-loongarch-20240712
-----BEGIN PGP SIGNATURE----- iLMEAAEKAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZpCKgwAKCRBAov/yOSY+ 3yuEBADmzjhomzzTnTHvOTPcK8Ugrru1QY9gT+5m7+I3cdbSRsYxEZLOdnjDAPBJ aVO+ZOkNFHspOOAo5A55QRC0PA4YGDGMg+ZcB7AVhzbdmra7SKdzMzrrVfYJYpk5 CtcrI+4OPt+U6mh/eTKuaXaWgjuoZ+TOjZqhL+rrpIFjcN78Rw== =vhZy -----END PGP SIGNATURE----- Merge tag 'pull-loongarch-20240712' of https://gitlab.com/gaosong/qemu into staging pull-loongarch-20240712 # -----BEGIN PGP SIGNATURE----- # # iLMEAAEKAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZpCKgwAKCRBAov/yOSY+ # 3yuEBADmzjhomzzTnTHvOTPcK8Ugrru1QY9gT+5m7+I3cdbSRsYxEZLOdnjDAPBJ # aVO+ZOkNFHspOOAo5A55QRC0PA4YGDGMg+ZcB7AVhzbdmra7SKdzMzrrVfYJYpk5 # CtcrI+4OPt+U6mh/eTKuaXaWgjuoZ+TOjZqhL+rrpIFjcN78Rw== # =vhZy # -----END PGP SIGNATURE----- # gpg: Signature made Thu 11 Jul 2024 06:44:35 PM PDT # gpg: using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF # gpg: Good signature from "Song Gao <m17746591750@163.com>" [unknown] # 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: B8FF 1DA0 D2FD CB2D A09C 6C2C 40A2 FFF2 3926 3EDF * tag 'pull-loongarch-20240712' of https://gitlab.com/gaosong/qemu: target/loongarch: Fix cpu_reset set wrong CSR_CRMD target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values target/loongarch: Remove avail_64 in trans_srai_w() and simplify it target/loongarch/kvm: Add software breakpoint support MAINTAINERS: Add myself as a reviewer of LoongArch virt machine hw/loongarch/virt: Remove unused assignment hw/loongarch: Change the tpm support by default hw/loongarch/boot.c: fix out-of-bound reading Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
ba79ef143f
@ -1240,6 +1240,7 @@ LoongArch Machines
|
||||
------------------
|
||||
Virt
|
||||
M: Song Gao <gaosong@loongson.cn>
|
||||
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
S: Maintained
|
||||
F: docs/system/loongarch/virt.rst
|
||||
F: configs/targets/loongarch64-softmmu.mak
|
||||
|
@ -1,5 +1,6 @@
|
||||
TARGET_ARCH=loongarch64
|
||||
TARGET_BASE_ARCH=loongarch
|
||||
TARGET_KVM_HAVE_GUEST_DEBUG=y
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
|
||||
# all boards require libfdt
|
||||
|
@ -8,6 +8,7 @@ config LOONGARCH_VIRT
|
||||
imply VIRTIO_VGA
|
||||
imply PCI_DEVICES
|
||||
imply NVDIMM
|
||||
imply TPM_TIS_SYSBUS
|
||||
select SERIAL
|
||||
select VIRTIO_PCI
|
||||
select PLATFORM_BUS
|
||||
|
@ -646,6 +646,9 @@ void loongarch_acpi_setup(LoongArchVirtMachineState *lvms)
|
||||
build_state, tables.rsdp,
|
||||
ACPI_BUILD_RSDP_FILE);
|
||||
|
||||
fw_cfg_add_file(lvms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
|
||||
acpi_data_len(tables.tcpalog));
|
||||
|
||||
qemu_register_reset(acpi_build_reset, build_state);
|
||||
acpi_build_reset(build_state);
|
||||
vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);
|
||||
|
@ -163,7 +163,7 @@ static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
|
||||
info->a0 = 1;
|
||||
info->a1 = cmdline_addr;
|
||||
|
||||
memcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE);
|
||||
g_strlcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE);
|
||||
}
|
||||
|
||||
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
||||
|
@ -1054,7 +1054,6 @@ static void fw_cfg_add_memory(MachineState *ms)
|
||||
memmap_add_entry(base, gap, 1);
|
||||
size -= gap;
|
||||
base = VIRT_HIGHMEM_BASE;
|
||||
gap = ram_size - VIRT_LOWMEM_SIZE;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
@ -1067,17 +1066,17 @@ static void fw_cfg_add_memory(MachineState *ms)
|
||||
}
|
||||
|
||||
/* add fw_cfg memory map of other nodes */
|
||||
size = ram_size - numa_info[0].node_mem;
|
||||
gap = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE;
|
||||
if (base < gap && (base + size) > gap) {
|
||||
if (numa_info[0].node_mem < gap && ram_size > gap) {
|
||||
/*
|
||||
* memory map for the maining nodes splited into two part
|
||||
* lowram: [base, +(gap - base))
|
||||
* highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base)))
|
||||
* lowram: [base, +(gap - numa_info[0].node_mem))
|
||||
* highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap))
|
||||
*/
|
||||
memmap_add_entry(base, gap - base, 1);
|
||||
size -= gap - base;
|
||||
memmap_add_entry(base, gap - numa_info[0].node_mem, 1);
|
||||
size = ram_size - gap;
|
||||
base = VIRT_HIGHMEM_BASE;
|
||||
} else {
|
||||
size = ram_size - numa_info[0].node_mem;
|
||||
}
|
||||
|
||||
if (size)
|
||||
|
@ -457,6 +457,18 @@ static void loongarch_la464_initfn(Object *obj)
|
||||
env->cpucfg[20] = data;
|
||||
|
||||
env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
|
||||
|
||||
env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8);
|
||||
env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f);
|
||||
env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
|
||||
|
||||
env->CSR_PRCFG2 = 0x3ffff000;
|
||||
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
|
||||
|
||||
loongarch_cpu_post_init(obj);
|
||||
}
|
||||
|
||||
@ -511,13 +523,13 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
|
||||
env->fcsr0 = 0x0;
|
||||
|
||||
int n;
|
||||
/* Set csr registers value after reset */
|
||||
/* Set csr registers value after reset, see the manual 6.4. */
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 1);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 1);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0);
|
||||
|
||||
env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0);
|
||||
env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0);
|
||||
@ -538,11 +550,6 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
|
||||
env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
|
||||
env->CSR_TID = cs->cpu_index;
|
||||
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
|
||||
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
|
||||
|
||||
for (n = 0; n < 4; n++) {
|
||||
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
|
||||
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "trace.h"
|
||||
|
||||
static bool cap_has_mp_state;
|
||||
static unsigned int brk_insn;
|
||||
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
||||
KVM_CAP_LAST_INFO
|
||||
};
|
||||
@ -664,7 +665,14 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
|
||||
|
||||
if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
|
||||
brk_insn = val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -739,6 +747,67 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
|
||||
return true;
|
||||
}
|
||||
|
||||
void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
|
||||
{
|
||||
if (kvm_sw_breakpoints_active(cpu)) {
|
||||
dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||
{
|
||||
if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
|
||||
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
|
||||
error_report("%s failed", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||
{
|
||||
static uint32_t brk;
|
||||
|
||||
if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
|
||||
brk != brk_insn ||
|
||||
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
|
||||
error_report("%s failed", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
void kvm_arch_remove_all_hw_breakpoints(void)
|
||||
{
|
||||
}
|
||||
|
||||
static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
CPULoongArchState *env = &cpu->env;
|
||||
|
||||
kvm_cpu_synchronize_state(cs);
|
||||
if (cs->singlestep_enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (kvm_find_sw_breakpoint(cs, env->pc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -757,6 +826,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
run->iocsr_io.len,
|
||||
run->iocsr_io.is_write);
|
||||
break;
|
||||
|
||||
case KVM_EXIT_DEBUG:
|
||||
if (kvm_loongarch_handle_debug(cs, run)) {
|
||||
ret = EXCP_DEBUG;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -1;
|
||||
warn_report("KVM: unknown exit reason %d", run->exit_reason);
|
||||
|
@ -67,19 +67,9 @@ static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2)
|
||||
tcg_gen_rotr_tl(dest, src1, t0);
|
||||
}
|
||||
|
||||
static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a)
|
||||
static void gen_sari_w(TCGv dest, TCGv src1, target_long imm)
|
||||
{
|
||||
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO);
|
||||
|
||||
if (!avail_64(ctx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm);
|
||||
gen_set_gpr(a->rd, dest, EXT_NONE);
|
||||
|
||||
return true;
|
||||
tcg_gen_sextract_tl(dest, src1, imm, 32 - imm);
|
||||
}
|
||||
|
||||
TRANS(sll_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w)
|
||||
@ -94,6 +84,7 @@ TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl)
|
||||
TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl)
|
||||
TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl)
|
||||
TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl)
|
||||
TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w)
|
||||
TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl)
|
||||
TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
|
||||
TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl)
|
||||
|
Loading…
Reference in New Issue
Block a user