Misc patches queue

hw/sd/sdhci: Default I/O ops to little endian
 hw/mips/loongson3-virt: Only use default USB if available
 hw/char/escc: Implement loopback mode to allow self-testing
 target/mips: Avoid overruns and shifts by negative number
 target/sparc: Handle FPRS correctly on big-endian hosts
 target/tricore: Rename tricore_feature to avoid clash with libcapstone
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmS/4ksACgkQ4+MsLN6t
 wN6OSg//cZY9C6fRXNNaIqkmnhjbaV6KLtjE7mOKp0RUyh3aN0dtTwWIjdJc0O5C
 iipHESYhcbHTiN/TxK0zXg4KgtKmtwqGsa3QTXGdTlSkTY/dMNioSpb7p82becu0
 fhCvGRLJ97j7/mhebiBNT/urrcG5h3n7CjA5IoFMMA4f+cajsGZHwmq5TTzc2ehy
 4FuchjFUw+cgqU1peNYoqt2dfnxFg0EgKBSRikl8MyPf9lFzTlXOKbgd+qppG6hI
 2fAUHyMqBkU22sAoK0eB0077LjgjPPQfmn8UPGkpGD5QZQcvBRNArg4fyHxCKTS7
 zOsO1Qc+4D2l2RJlIHgct2pmcHdT29TlTn2T4Lg900Hm09KelZh1XF+1BemCC13z
 cGWjPcYozvGFFiHlhazINtbGpB6XaP/Z3OwroRHRn+Mn3ss+FaU+j/p+4YlEVyFi
 4yoEyjhNma6/hssmstifSQsaOf6XthzpS+XdKNB6G1b2WuRSc1Z59b2gcPBTwbXY
 B52lfI61nzSrP9pLuS8c/6hQXQvADIEndeWEcWZ50h3WW2Cemj9jTDVgfjWC4Vg9
 wV2U6NeTr+g54cSU5vcKiZrqsQHUoLiKbZFRJkXF7EEMbOErIQnyIS5l8xf71Pay
 YPxuPf1VprRiR07d+ZaA+wmEaBxLCUPEl1CEuu5NPVA9S4yIIWE=
 =F+Wb
 -----END PGP SIGNATURE-----

Merge tag 'misc-fixes-20230725' of https://github.com/philmd/qemu into staging

Misc patches queue

hw/sd/sdhci: Default I/O ops to little endian
hw/mips/loongson3-virt: Only use default USB if available
hw/char/escc: Implement loopback mode to allow self-testing
target/mips: Avoid overruns and shifts by negative number
target/sparc: Handle FPRS correctly on big-endian hosts
target/tricore: Rename tricore_feature to avoid clash with libcapstone

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmS/4ksACgkQ4+MsLN6t
# wN6OSg//cZY9C6fRXNNaIqkmnhjbaV6KLtjE7mOKp0RUyh3aN0dtTwWIjdJc0O5C
# iipHESYhcbHTiN/TxK0zXg4KgtKmtwqGsa3QTXGdTlSkTY/dMNioSpb7p82becu0
# fhCvGRLJ97j7/mhebiBNT/urrcG5h3n7CjA5IoFMMA4f+cajsGZHwmq5TTzc2ehy
# 4FuchjFUw+cgqU1peNYoqt2dfnxFg0EgKBSRikl8MyPf9lFzTlXOKbgd+qppG6hI
# 2fAUHyMqBkU22sAoK0eB0077LjgjPPQfmn8UPGkpGD5QZQcvBRNArg4fyHxCKTS7
# zOsO1Qc+4D2l2RJlIHgct2pmcHdT29TlTn2T4Lg900Hm09KelZh1XF+1BemCC13z
# cGWjPcYozvGFFiHlhazINtbGpB6XaP/Z3OwroRHRn+Mn3ss+FaU+j/p+4YlEVyFi
# 4yoEyjhNma6/hssmstifSQsaOf6XthzpS+XdKNB6G1b2WuRSc1Z59b2gcPBTwbXY
# B52lfI61nzSrP9pLuS8c/6hQXQvADIEndeWEcWZ50h3WW2Cemj9jTDVgfjWC4Vg9
# wV2U6NeTr+g54cSU5vcKiZrqsQHUoLiKbZFRJkXF7EEMbOErIQnyIS5l8xf71Pay
# YPxuPf1VprRiR07d+ZaA+wmEaBxLCUPEl1CEuu5NPVA9S4yIIWE=
# =F+Wb
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 25 Jul 2023 15:55:07 BST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'misc-fixes-20230725' of https://github.com/philmd/qemu:
  target/tricore: Rename tricore_feature
  target/sparc: Handle FPRS correctly on big-endian hosts
  target/mips: Avoid shift by negative number in page_table_walk_refill()
  target/mips: Pass directory/leaf shift values to walk_directory()
  target/mips/mxu: Avoid overrun in gen_mxu_q8adde()
  target/mips/mxu: Avoid overrun in gen_mxu_S32SLT()
  target/mips/mxu: Replace magic array size by its definition
  hw/char/escc: Implement loopback mode
  hw/mips: Improve the default USB settings in the loongson3-virt machine
  hw/sd/sdhci: Do not force sdhci_mmio_*_ops onto all SD controllers

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2023-07-25 16:30:39 +01:00
commit d59f0c9214
13 changed files with 75 additions and 52 deletions

View File

@ -653,7 +653,9 @@ static void escc_mem_write(void *opaque, hwaddr addr,
escc_update_irq(s);
s->tx = val;
if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { /* tx enabled */
if (qemu_chr_fe_backend_connected(&s->chr)) {
if (s->wregs[W_MISC2] & MISC2_LCL_LOOP) {
serial_receive_byte(s, s->tx);
} else if (qemu_chr_fe_backend_connected(&s->chr)) {
/*
* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks

View File

@ -447,7 +447,7 @@ static inline void loongson3_virt_devices_init(MachineState *machine,
pci_vga_init(pci_bus);
if (defaults_enabled()) {
if (defaults_enabled() && object_class_by_name("pci-ohci")) {
pci_create_simple(pci_bus, -1, "pci-ohci");
usb_create_simple(usb_bus_find(-1), "usb-kbd");
usb_create_simple(usb_bus_find(-1), "usb-tablet");

View File

@ -1382,6 +1382,8 @@ void sdhci_initfn(SDHCIState *s)
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
s->io_ops = &sdhci_mmio_le_ops;
}
void sdhci_uninitfn(SDHCIState *s)
@ -1399,9 +1401,13 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
switch (s->endianness) {
case DEVICE_LITTLE_ENDIAN:
s->io_ops = &sdhci_mmio_le_ops;
/* s->io_ops is little endian by default */
break;
case DEVICE_BIG_ENDIAN:
if (s->io_ops != &sdhci_mmio_le_ops) {
error_setg(errp, "SD controller doesn't support big endianness");
return;
}
s->io_ops = &sdhci_mmio_be_ops;
break;
default:

View File

@ -609,7 +609,7 @@ enum {
static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
static TCGv mxu_CR;
static const char mxuregnames[][4] = {
static const char mxuregnames[NUMBER_OF_MXU_REGISTERS][4] = {
"XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
"XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "XCR",
};
@ -644,6 +644,16 @@ static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
}
}
static inline void gen_extract_mxu_gpr(TCGv t, unsigned int reg,
unsigned int ofs, unsigned int len)
{
if (reg == 0) {
tcg_gen_movi_tl(t, 0);
} else if (reg <= 15) {
tcg_gen_extract_tl(t, mxu_gpr[reg - 1], ofs, len);
}
}
/* MXU control register moves. */
static inline void gen_load_mxu_cr(TCGv t)
{
@ -2434,8 +2444,12 @@ static void gen_mxu_S32SLT(DisasContext *ctx)
tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
} else {
/* the most general case */
tcg_gen_setcond_tl(TCG_COND_LT, mxu_gpr[XRa - 1],
mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
gen_load_mxu_gpr(t0, XRb);
gen_load_mxu_gpr(t1, XRc);
tcg_gen_setcond_tl(TCG_COND_LT, mxu_gpr[XRa - 1], t0, t1);
}
}
@ -3000,10 +3014,10 @@ static void gen_mxu_q8adde(DisasContext *ctx, bool accumulate)
TCGv t5 = tcg_temp_new();
if (XRa != 0) {
tcg_gen_extract_tl(t0, mxu_gpr[XRb - 1], 16, 8);
tcg_gen_extract_tl(t1, mxu_gpr[XRc - 1], 16, 8);
tcg_gen_extract_tl(t2, mxu_gpr[XRb - 1], 24, 8);
tcg_gen_extract_tl(t3, mxu_gpr[XRc - 1], 24, 8);
gen_extract_mxu_gpr(t0, XRb, 16, 8);
gen_extract_mxu_gpr(t1, XRc, 16, 8);
gen_extract_mxu_gpr(t2, XRb, 24, 8);
gen_extract_mxu_gpr(t3, XRc, 24, 8);
if (aptn2 & 2) {
tcg_gen_sub_tl(t0, t0, t1);
tcg_gen_sub_tl(t2, t2, t3);
@ -3023,10 +3037,10 @@ static void gen_mxu_q8adde(DisasContext *ctx, bool accumulate)
tcg_gen_or_tl(t4, t2, t0);
}
if (XRd != 0) {
tcg_gen_extract_tl(t0, mxu_gpr[XRb - 1], 0, 8);
tcg_gen_extract_tl(t1, mxu_gpr[XRc - 1], 0, 8);
tcg_gen_extract_tl(t2, mxu_gpr[XRb - 1], 8, 8);
tcg_gen_extract_tl(t3, mxu_gpr[XRc - 1], 8, 8);
gen_extract_mxu_gpr(t0, XRb, 0, 8);
gen_extract_mxu_gpr(t1, XRc, 0, 8);
gen_extract_mxu_gpr(t2, XRb, 8, 8);
gen_extract_mxu_gpr(t3, XRc, 8, 8);
if (aptn2 & 1) {
tcg_gen_sub_tl(t0, t0, t1);
tcg_gen_sub_tl(t2, t2, t3);

View File

@ -623,18 +623,13 @@ static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
int directory_index, bool *huge_page, bool *hgpg_directory_hit,
uint64_t *pw_entrylo0, uint64_t *pw_entrylo1)
uint64_t *pw_entrylo0, uint64_t *pw_entrylo1,
unsigned directory_shift, unsigned leaf_shift)
{
int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1;
int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F;
int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F;
int native_shift = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? 2 : 3;
int directory_shift = (ptew > 1) ? -1 :
(hugepg && (ptew == 1)) ? native_shift + 1 : native_shift;
int leaf_shift = (ptew > 1) ? -1 :
(ptew == 1) ? native_shift + 1 : native_shift;
uint32_t direntry_size = 1 << (directory_shift + 3);
uint32_t leafentry_size = 1 << (leaf_shift + 3);
uint64_t entry;
@ -735,21 +730,11 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
/* Other HTW configs */
int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
/* HTW Shift values (depend on entry size) */
int directory_shift = (ptew > 1) ? -1 :
(hugepg && (ptew == 1)) ? native_shift + 1 : native_shift;
int leaf_shift = (ptew > 1) ? -1 :
(ptew == 1) ? native_shift + 1 : native_shift;
unsigned directory_shift, leaf_shift;
/* Offsets into tables */
int goffset = gindex << directory_shift;
int uoffset = uindex << directory_shift;
int moffset = mindex << directory_shift;
int ptoffset0 = (ptindex >> 1) << (leaf_shift + 1);
int ptoffset1 = ptoffset0 | (1 << (leaf_shift));
uint32_t leafentry_size = 1 << (leaf_shift + 3);
unsigned goffset, uoffset, moffset, ptoffset0, ptoffset1;
uint32_t leafentry_size;
/* Starting address - Page Table Base */
uint64_t vaddr = env->CP0_PWBase;
@ -771,15 +756,28 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
/* no structure to walk */
return false;
}
if ((directory_shift == -1) || (leaf_shift == -1)) {
if (ptew > 1) {
return false;
}
/* HTW Shift values (depend on entry size) */
directory_shift = (hugepg && (ptew == 1)) ? native_shift + 1 : native_shift;
leaf_shift = (ptew == 1) ? native_shift + 1 : native_shift;
goffset = gindex << directory_shift;
uoffset = uindex << directory_shift;
moffset = mindex << directory_shift;
ptoffset0 = (ptindex >> 1) << (leaf_shift + 1);
ptoffset1 = ptoffset0 | (1 << (leaf_shift));
leafentry_size = 1 << (leaf_shift + 3);
/* Global Directory */
if (gdw > 0) {
vaddr |= goffset;
switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit,
&pw_entrylo0, &pw_entrylo1))
&pw_entrylo0, &pw_entrylo1,
directory_shift, leaf_shift))
{
case 0:
return false;
@ -795,7 +793,8 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
if (udw > 0) {
vaddr |= uoffset;
switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit,
&pw_entrylo0, &pw_entrylo1))
&pw_entrylo0, &pw_entrylo1,
directory_shift, leaf_shift))
{
case 0:
return false;
@ -811,7 +810,8 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
if (mdw > 0) {
vaddr |= moffset;
switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit,
&pw_entrylo0, &pw_entrylo1))
&pw_entrylo0, &pw_entrylo1,
directory_shift, leaf_shift))
{
case 0:
return false;

View File

@ -673,8 +673,8 @@ static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
"cleanwin: %d cwp: %d\n",
env->cansave, env->canrestore, env->otherwin, env->wstate,
env->cleanwin, env->nwindows - 1 - env->cwp);
qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: %016x\n",
env->fsr, env->y, env->fprs);
#else
qemu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));

View File

@ -521,7 +521,7 @@ struct CPUArchState {
uint64_t igregs[8]; /* interrupt general registers */
uint64_t mgregs[8]; /* mmu general registers */
uint64_t glregs[8 * MAXTL_MAX];
uint64_t fprs;
uint32_t fprs;
uint64_t tick_cmpr, stick_cmpr;
CPUTimer *tick, *stick;
#define TICK_NPT_MASK 0x8000000000000000ULL

View File

@ -168,7 +168,8 @@ const VMStateDescription vmstate_sparc_cpu = {
VMSTATE_UINT64_ARRAY(env.bgregs, SPARCCPU, 8),
VMSTATE_UINT64_ARRAY(env.igregs, SPARCCPU, 8),
VMSTATE_UINT64_ARRAY(env.mgregs, SPARCCPU, 8),
VMSTATE_UINT64(env.fprs, SPARCCPU),
VMSTATE_UNUSED(4), /* was unused high half of uint64_t fprs */
VMSTATE_UINT32(env.fprs, SPARCCPU),
VMSTATE_UINT64(env.tick_cmpr, SPARCCPU),
VMSTATE_UINT64(env.stick_cmpr, SPARCCPU),
VMSTATE_CPU_TIMER(env.tick, SPARCCPU),

View File

@ -154,7 +154,7 @@ const MonitorDef monitor_defs[] = {
{ "otherwin", offsetof(CPUSPARCState, otherwin) },
{ "wstate", offsetof(CPUSPARCState, wstate) },
{ "cleanwin", offsetof(CPUSPARCState, cleanwin) },
{ "fprs", offsetof(CPUSPARCState, fprs) },
{ "fprs", offsetof(CPUSPARCState, fprs), NULL, MD_I32 },
#endif
{ NULL },
};

View File

@ -104,18 +104,18 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
}
/* Some features automatically imply others */
if (tricore_feature(env, TRICORE_FEATURE_162)) {
if (tricore_has_feature(env, TRICORE_FEATURE_162)) {
set_feature(env, TRICORE_FEATURE_161);
}
if (tricore_feature(env, TRICORE_FEATURE_161)) {
if (tricore_has_feature(env, TRICORE_FEATURE_161)) {
set_feature(env, TRICORE_FEATURE_16);
}
if (tricore_feature(env, TRICORE_FEATURE_16)) {
if (tricore_has_feature(env, TRICORE_FEATURE_16)) {
set_feature(env, TRICORE_FEATURE_131);
}
if (tricore_feature(env, TRICORE_FEATURE_131)) {
if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
set_feature(env, TRICORE_FEATURE_13);
}
cpu_reset(cs);

View File

@ -277,7 +277,7 @@ enum tricore_features {
TRICORE_FEATURE_162,
};
static inline int tricore_feature(CPUTriCoreState *env, int feature)
static inline int tricore_has_feature(CPUTriCoreState *env, int feature)
{
return (env->features & (1ULL << feature)) != 0;
}

View File

@ -155,7 +155,7 @@ void psw_write(CPUTriCoreState *env, uint32_t val)
#define FIELD_GETTER_WITH_FEATURE(NAME, REG, FIELD, FEATURE) \
uint32_t NAME(CPUTriCoreState *env) \
{ \
if (tricore_feature(env, TRICORE_FEATURE_##FEATURE)) { \
if (tricore_has_feature(env, TRICORE_FEATURE_##FEATURE)) { \
return FIELD_EX32(env->REG, REG, FIELD ## _ ## FEATURE); \
} \
return FIELD_EX32(env->REG, REG, FIELD ## _13); \
@ -170,7 +170,7 @@ uint32_t NAME(CPUTriCoreState *env) \
#define FIELD_SETTER_WITH_FEATURE(NAME, REG, FIELD, FEATURE) \
void NAME(CPUTriCoreState *env, uint32_t val) \
{ \
if (tricore_feature(env, TRICORE_FEATURE_##FEATURE)) { \
if (tricore_has_feature(env, TRICORE_FEATURE_##FEATURE)) { \
env->REG = FIELD_DP32(env->REG, REG, FIELD ## _ ## FEATURE, val); \
} \
env->REG = FIELD_DP32(env->REG, REG, FIELD ## _13, val); \

View File

@ -2584,7 +2584,7 @@ void helper_ret(CPUTriCoreState *env)
/* PCXI = new_PCXI; */
env->PCXI = new_PCXI;
if (tricore_feature(env, TRICORE_FEATURE_131)) {
if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
/* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
} else { /* TRICORE_FEATURE_13 only */
@ -2695,7 +2695,7 @@ void helper_rfm(CPUTriCoreState *env)
env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
if (tricore_feature(env, TRICORE_FEATURE_131)) {
if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
env->DBGTCR = 0;
}
}