Misc HW patches queue

- Silent unuseful DTC warnings (Philippe)
 - Unify QDev hotplug decision logic (Akihiko)
 - Rework XilinX EthLite RAM buffers (Philippe)
 - Convert vmcoreinfo to 3-phase reset (Philippe)
 - Convert HPPA CPUs to 3-phase reset (Helge)
 - Fix UFS endianness issue (Keoseong)
 - Introduce pci_set_enabled (Akihiko)
 - Clarify Enclave and Firecracker relationship (Alexander)
 - Set SDHCI DMA interrupt status bit in correct place (Bernhard)
 - Fix leak in cryptodev-vhost-user backend (Gabriel)
 - Fixes on PCI USB XHCI (Phil)
 - Convert DPRINTF to trace events (Nikita, Bernhard)
 - Remove &first_cpu in TriCore machine (Philippe)
 - Checkpatch style cleanups (Bibo)
 - MAINTAINERS updates (Marcin, Gustavo, Akihiko)
 - Add default configuration for b4 tool (Jiaxun)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmeFTq0ACgkQ4+MsLN6t
 wN6F2RAA0hhgXYf1BAn0DQI5O/oOzt6WzkwL/yQhKff1piWMcCZbHCOn8JHETE4R
 QTqg+OMGuw4Q55YSwqwHW98JIQI/lRbSUX9Vc3km4QxED5owHiqu9wk//KSLv3TY
 y86CRbibb0Uy6vEM4J1WK6ATiLePWZ6qzePQX59f9YEagTLM2XO2DasRu+wGDbt+
 96fPnT7Tx2Bu5jU8+sZ36mw3wWSJo/pLQBE9siH4N33v2I5ntmMs1Lbe7QscDDsw
 1+OOti3lB4q5chNMYNQyPxvz75QIi9et7wREJM9Vt03OpEpj+vWMGzwZFNLfOmeu
 eApgcQP/k6z1+pAGjEo5mwNOZcZtR9I/3Uf/sONvO0N5FlJq9CSOTs7L2EddcFzM
 lVDZjwEHIoU1xCohqNy2A0Q1s20dNfBEjPEUCuh+tIvFk9cy1L8uZtBVFNUCb33J
 Jq8KAkqXAaVj2tHGa27DwFjSTo4olU/G0WO4AQZNwdxvMQwX88gHOGMJkRmJPRVi
 ErKD0/bBfVa6orEAorWYwQSnTP1H/2fGfF6rLtI5GvQtPc/jBG3+KpEOS+vc2nzG
 1fq+Kty8kWsU4Fpw3EUHvflnzG4Ujhuc/nJ+FyQhn89Erb49jxBlu25lQOLVRVa4
 gP+jsgi46+4goYzj1vrpTpBgFPFWKGCl1gGz17ij5WyvVXroRzA=
 =+uup
 -----END PGP SIGNATURE-----

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

Misc HW patches queue

- Silent unuseful DTC warnings (Philippe)
- Unify QDev hotplug decision logic (Akihiko)
- Rework XilinX EthLite RAM buffers (Philippe)
- Convert vmcoreinfo to 3-phase reset (Philippe)
- Convert HPPA CPUs to 3-phase reset (Helge)
- Fix UFS endianness issue (Keoseong)
- Introduce pci_set_enabled (Akihiko)
- Clarify Enclave and Firecracker relationship (Alexander)
- Set SDHCI DMA interrupt status bit in correct place (Bernhard)
- Fix leak in cryptodev-vhost-user backend (Gabriel)
- Fixes on PCI USB XHCI (Phil)
- Convert DPRINTF to trace events (Nikita, Bernhard)
- Remove &first_cpu in TriCore machine (Philippe)
- Checkpatch style cleanups (Bibo)
- MAINTAINERS updates (Marcin, Gustavo, Akihiko)
- Add default configuration for b4 tool (Jiaxun)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmeFTq0ACgkQ4+MsLN6t
# wN6F2RAA0hhgXYf1BAn0DQI5O/oOzt6WzkwL/yQhKff1piWMcCZbHCOn8JHETE4R
# QTqg+OMGuw4Q55YSwqwHW98JIQI/lRbSUX9Vc3km4QxED5owHiqu9wk//KSLv3TY
# y86CRbibb0Uy6vEM4J1WK6ATiLePWZ6qzePQX59f9YEagTLM2XO2DasRu+wGDbt+
# 96fPnT7Tx2Bu5jU8+sZ36mw3wWSJo/pLQBE9siH4N33v2I5ntmMs1Lbe7QscDDsw
# 1+OOti3lB4q5chNMYNQyPxvz75QIi9et7wREJM9Vt03OpEpj+vWMGzwZFNLfOmeu
# eApgcQP/k6z1+pAGjEo5mwNOZcZtR9I/3Uf/sONvO0N5FlJq9CSOTs7L2EddcFzM
# lVDZjwEHIoU1xCohqNy2A0Q1s20dNfBEjPEUCuh+tIvFk9cy1L8uZtBVFNUCb33J
# Jq8KAkqXAaVj2tHGa27DwFjSTo4olU/G0WO4AQZNwdxvMQwX88gHOGMJkRmJPRVi
# ErKD0/bBfVa6orEAorWYwQSnTP1H/2fGfF6rLtI5GvQtPc/jBG3+KpEOS+vc2nzG
# 1fq+Kty8kWsU4Fpw3EUHvflnzG4Ujhuc/nJ+FyQhn89Erb49jxBlu25lQOLVRVa4
# gP+jsgi46+4goYzj1vrpTpBgFPFWKGCl1gGz17ij5WyvVXroRzA=
# =+uup
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 13 Jan 2025 12:34:37 EST
# 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 'hw-misc-20250113' of https://github.com/philmd/qemu: (55 commits)
  Add a b4 configuration file
  MAINTAINERS: Update path to coreaudio.m
  MAINTAINERS: Add me as the maintainer for ivshmem-flat
  MAINTAINERS: remove myself from sbsa-ref
  hw/tricore/triboard: Remove unnecessary use of &first_cpu
  hw/usb/hcd-xhci-pci: Use event ring 0 if mapping unsupported
  hw/usb/hcd-xhci-pci: Use modulo to select MSI vector as per spec
  backends/cryptodev-vhost-user: Fix local_error leaks
  hw/loongarch/virt: Checkpatch cleanup
  target/hppa: Speed up hppa_is_pa20()
  target/hppa: Set PC on vCPU reset
  target/hppa: Only set PSW 'M' bit on reset
  hw/hppa: Reset vCPUs calling resettable_reset()
  target/hppa: Convert hppa_cpu_init() to ResetHold handler
  tests: Add functional tests for HPPA machines
  tests/qtest/boot-serial-test: Correct HPPA machine name
  hw/gpio/imx_gpio: Turn DPRINTF() into trace events
  hw/i2c/imx_i2c: Convert DPRINTF() to trace events
  hw/char/imx_serial: Turn some DPRINTF() statements into trace events
  hw/misc/imx6_src: Convert DPRINTF() to trace events
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-01-14 12:46:56 -05:00
commit 7433709a14
52 changed files with 558 additions and 310 deletions

14
.b4-config Normal file
View File

@ -0,0 +1,14 @@
#
# Common b4 settings that can be used to send patches to QEMU upstream.
# https://b4.docs.kernel.org/
#
[b4]
send-series-to = qemu-devel@nongnu.org
send-auto-to-cmd = echo
send-auto-cc-cmd = scripts/get_maintainer.pl --noroles --norolestats --nogit --nogit-fallback
am-perpatch-check-cmd = scripts/checkpatch.pl -q --terse --no-summary --mailback -
prep-perpatch-check-cmd = scripts/checkpatch.pl -q --terse --no-summary --mailback -
searchmask = https://lore.kernel.org/qemu-devel/?x=m&t=1&q=%s
linkmask = https://lore.kernel.org/qemu-devel/%s
linktrailermask = Message-ID: <%s>

View File

@ -923,7 +923,6 @@ SBSA-REF
M: Radoslaw Biernacki <rad@semihalf.com>
M: Peter Maydell <peter.maydell@linaro.org>
R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/sbsa-ref.c
@ -1203,6 +1202,7 @@ F: include/hw/pci-host/astro.h
F: include/hw/pci-host/dino.h
F: pc-bios/hppa-firmware.img
F: roms/seabios-hppa/
F: tests/functional/test_hppa_seabios.py
LoongArch Machines
------------------
@ -2786,6 +2786,13 @@ F: hw/hyperv/hv-balloon*.h
F: include/hw/hyperv/dynmem-proto.h
F: include/hw/hyperv/hv-balloon.h
ivshmem-flat
M: Gustavo Romero <gustavo.romero@linaro.org>
S: Maintained
F: hw/misc/ivshmem-flat.c
F: include/hw/misc/ivshmem-flat.h
F: docs/system/devices/ivshmem-flat.rst
Subsystems
----------
Overall Audio backends
@ -2794,7 +2801,7 @@ M: Marc-André Lureau <marcandre.lureau@redhat.com>
S: Odd Fixes
F: audio/
X: audio/alsaaudio.c
X: audio/coreaudio.c
X: audio/coreaudio.m
X: audio/dsound*
X: audio/jackaudio.c
X: audio/ossaudio.c
@ -2816,7 +2823,7 @@ M: Philippe Mathieu-Daudé <philmd@linaro.org>
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
R: Akihiko Odaki <akihiko.odaki@daynix.com>
S: Odd Fixes
F: audio/coreaudio.c
F: audio/coreaudio.m
DSound Audio backend
M: Gerd Hoffmann <kraxel@redhat.com>

View File

@ -281,8 +281,7 @@ static int cryptodev_vhost_user_create_session(
break;
default:
error_setg(&local_error, "Unsupported opcode :%" PRIu32 "",
sess_info->op_code);
error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code);
return -VIRTIO_CRYPTO_NOTSUPP;
}

View File

@ -13,7 +13,7 @@ the enclave VM gets a dynamic CID. Enclaves use an EIF (`Enclave Image Format`_)
file which contains the necessary kernel, cmdline and ramdisk(s) to boot.
In QEMU, ``nitro-enclave`` is a machine type based on ``microvm`` similar to how
AWS nitro enclaves are based on `Firecracker`_ microvm. This is useful for
AWS nitro enclaves look like a `Firecracker`_ microvm. This is useful for
local testing of EIF files using QEMU instead of running real AWS Nitro Enclaves
which can be difficult for debugging due to its roots in security. The vsock
device emulation is done using vhost-user-vsock which means another process that

View File

@ -1238,7 +1238,7 @@ static void musicpal_init(MachineState *machine)
qdev_get_gpio_in(pic, MP_TIMER4_IRQ), NULL);
/* Logically OR both UART IRQs together */
uart_orgate = DEVICE(object_new(TYPE_OR_IRQ));
uart_orgate = qdev_new(TYPE_OR_IRQ);
object_property_set_int(OBJECT(uart_orgate), "num-lines", 2, &error_fatal);
qdev_realize_and_unref(uart_orgate, NULL, &error_fatal);
qdev_connect_gpio_out(uart_orgate, 0,

View File

@ -27,6 +27,7 @@
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/fifo32.h"
#include "trace.h"
#ifndef DEBUG_IMX_UART
#define DEBUG_IMX_UART 0
@ -184,10 +185,10 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
unsigned size)
{
IMXSerialState *s = (IMXSerialState *)opaque;
Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
uint32_t c, rx_used;
uint8_t rxtl = s->ufcr & TL_MASK;
DPRINTF("read(offset=0x%" HWADDR_PRIx ")\n", offset);
uint64_t value;
switch (offset >> 2) {
case 0x0: /* URXD */
@ -208,49 +209,67 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
imx_serial_rx_fifo_ageing_timer_restart(s);
qemu_chr_fe_accept_input(&s->chr);
}
return c;
value = c;
break;
case 0x20: /* UCR1 */
return s->ucr1;
value = s->ucr1;
break;
case 0x21: /* UCR2 */
return s->ucr2;
value = s->ucr2;
break;
case 0x25: /* USR1 */
return s->usr1;
value = s->usr1;
break;
case 0x26: /* USR2 */
return s->usr2;
value = s->usr2;
break;
case 0x2A: /* BRM Modulator */
return s->ubmr;
value = s->ubmr;
break;
case 0x2B: /* Baud Rate Count */
return s->ubrc;
value = s->ubrc;
break;
case 0x2d: /* Test register */
return s->uts1;
value = s->uts1;
break;
case 0x24: /* UFCR */
return s->ufcr;
value = s->ufcr;
break;
case 0x2c:
return s->onems;
value = s->onems;
break;
case 0x22: /* UCR3 */
return s->ucr3;
value = s->ucr3;
break;
case 0x23: /* UCR4 */
return s->ucr4;
value = s->ucr4;
break;
case 0x29: /* BRM Incremental */
return 0x0; /* TODO */
value = 0x0; /* TODO */
break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
return 0;
value = 0;
break;
}
trace_imx_serial_read(chr ? chr->label : "NODEV", offset, value);
return value;
}
static void imx_serial_write(void *opaque, hwaddr offset,
@ -260,8 +279,7 @@ static void imx_serial_write(void *opaque, hwaddr offset,
Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
unsigned char ch;
DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n",
offset, (unsigned int)value, chr ? chr->label : "NODEV");
trace_imx_serial_write(chr ? chr->label : "NODEV", offset, value);
switch (offset >> 2) {
case 0x10: /* UTXD */
@ -373,9 +391,11 @@ static int imx_can_receive(void *opaque)
static void imx_put_data(void *opaque, uint32_t value)
{
IMXSerialState *s = (IMXSerialState *)opaque;
Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
uint8_t rxtl = s->ufcr & TL_MASK;
DPRINTF("received char\n");
trace_imx_serial_put_data(chr ? chr->label : "NODEV", value);
imx_serial_rx_fifo_push(s, value);
if (fifo32_num_used(&s->rx_fifo) >= rxtl) {
s->usr1 |= USR1_RRDY;

View File

@ -30,17 +30,7 @@
#include "qemu/log.h"
#include "qemu/module.h"
#ifndef STM_USART_ERR_DEBUG
#define STM_USART_ERR_DEBUG 0
#endif
#define DB_PRINT_L(lvl, fmt, args...) do { \
if (STM_USART_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
#include "trace.h"
static int stm32f2xx_usart_can_receive(void *opaque)
{
@ -67,10 +57,11 @@ static void stm32f2xx_update_irq(STM32F2XXUsartState *s)
static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
{
STM32F2XXUsartState *s = opaque;
DeviceState *d = DEVICE(s);
if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
/* USART not enabled - drop the chars */
DB_PRINT("Dropping the chars\n");
trace_stm32f2xx_usart_drop(d->id);
return;
}
@ -79,7 +70,7 @@ static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
stm32f2xx_update_irq(s);
DB_PRINT("Receiving: %c\n", s->usart_dr);
trace_stm32f2xx_usart_receive(d->id, *buf);
}
static void stm32f2xx_usart_reset(DeviceState *dev)
@ -101,49 +92,55 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
unsigned int size)
{
STM32F2XXUsartState *s = opaque;
uint64_t retvalue;
DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr);
DeviceState *d = DEVICE(s);
uint64_t retvalue = 0;
switch (addr) {
case USART_SR:
retvalue = s->usart_sr;
qemu_chr_fe_accept_input(&s->chr);
return retvalue;
break;
case USART_DR:
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
retvalue = s->usart_dr & 0x3FF;
s->usart_sr &= ~USART_SR_RXNE;
qemu_chr_fe_accept_input(&s->chr);
stm32f2xx_update_irq(s);
return retvalue;
break;
case USART_BRR:
return s->usart_brr;
retvalue = s->usart_brr;
break;
case USART_CR1:
return s->usart_cr1;
retvalue = s->usart_cr1;
break;
case USART_CR2:
return s->usart_cr2;
retvalue = s->usart_cr2;
break;
case USART_CR3:
return s->usart_cr3;
retvalue = s->usart_cr3;
break;
case USART_GTPR:
return s->usart_gtpr;
retvalue = s->usart_gtpr;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
return 0;
}
return 0;
trace_stm32f2xx_usart_read(d->id, size, addr, retvalue);
return retvalue;
}
static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
{
STM32F2XXUsartState *s = opaque;
DeviceState *d = DEVICE(s);
uint32_t value = val64;
unsigned char ch;
DB_PRINT("Write 0x%" PRIx32 ", 0x%"HWADDR_PRIx"\n", value, addr);
trace_stm32f2xx_usart_write(d->id, size, addr, val64);
switch (addr) {
case USART_SR:

View File

@ -52,6 +52,11 @@ escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x"
escc_kbd_command(int val) "Command %d"
escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=0x%01x"
# imx_serial.c
imx_serial_read(const char *chrname, uint64_t addr, uint64_t value) "%s:[0x%03" PRIu64 "] -> 0x%08" PRIx64
imx_serial_write(const char *chrname, uint64_t addr, uint64_t value) "%s:[0x%03" PRIu64 "] <- 0x%08" PRIx64
imx_serial_put_data(const char *chrname, uint32_t value) "%s: 0x%" PRIx32
# pl011.c
pl011_irq_state(int level) "irq state %d"
pl011_read(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s"
@ -125,3 +130,9 @@ xen_console_unrealize(unsigned int idx) "idx %u"
xen_console_realize(unsigned int idx, const char *chrdev) "idx %u chrdev %s"
xen_console_device_create(unsigned int idx) "idx %u"
xen_console_device_destroy(unsigned int idx) "idx %u"
# stm32f2xx_usart.c
stm32f2xx_usart_read(char *id, unsigned size, uint64_t ofs, uint64_t val) " %s size %d ofs 0x%02" PRIx64 " -> 0x%02" PRIx64
stm32f2xx_usart_write(char *id, unsigned size, uint64_t ofs, uint64_t val) "%s size %d ofs 0x%02" PRIx64 " <- 0x%02" PRIx64
stm32f2xx_usart_drop(char *id) " %s dropping the chars"
stm32f2xx_usart_receive(char *id, uint8_t chr) " %s receiving '%c'"

View File

@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "hw/qdev-core.h"
#include "hw/boards.h"
#include "qapi/error.h"
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
{
@ -30,12 +31,48 @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
return NULL;
}
bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus,
Error **errp)
{
DeviceClass *dc = DEVICE_GET_CLASS(dev);
if (!dc->hotpluggable) {
error_setg(errp, "Device '%s' does not support hotplugging",
object_get_typename(OBJECT(dev)));
return false;
}
if (bus) {
if (!qbus_is_hotpluggable(bus)) {
error_setg(errp, "Bus '%s' does not support hotplugging",
bus->name);
return false;
}
} else {
if (!qdev_get_machine_hotplug_handler(dev)) {
/*
* No bus, no machine hotplug handler --> device is not hotpluggable
*/
error_setg(errp,
"Device '%s' can not be hotplugged on this machine",
object_get_typename(OBJECT(dev)));
return false;
}
}
return true;
}
bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp)
{
MachineState *machine;
MachineClass *mc;
Object *m_obj = qdev_get_machine();
if (!qdev_hotplug_unplug_allowed_common(dev, bus, errp)) {
return false;
}
if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
machine = MACHINE(m_obj);
mc = MACHINE_GET_CLASS(machine);
@ -47,6 +84,12 @@ bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
return true;
}
bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp)
{
return !qdev_unplug_blocked(dev, errp) &&
qdev_hotplug_unplug_allowed_common(dev, dev->parent_bus, errp);
}
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
{
if (dev->parent_bus) {

View File

@ -24,6 +24,7 @@
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
#ifndef DEBUG_IMX_GPIO
#define DEBUG_IMX_GPIO 0
@ -34,14 +35,6 @@ typedef enum IMXGPIOLevel {
IMX_GPIO_LEVEL_HIGH = 1,
} IMXGPIOLevel;
#define DPRINTF(fmt, args...) \
do { \
if (DEBUG_IMX_GPIO) { \
fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPIO, \
__func__, ##args); \
} \
} while (0)
static const char *imx_gpio_reg_name(uint32_t reg)
{
switch (reg) {
@ -111,6 +104,8 @@ static void imx_gpio_set(void *opaque, int line, int level)
IMXGPIOState *s = IMX_GPIO(opaque);
IMXGPIOLevel imx_level = level ? IMX_GPIO_LEVEL_HIGH : IMX_GPIO_LEVEL_LOW;
trace_imx_gpio_set(DEVICE(s)->canonical_path, line, imx_level);
imx_gpio_set_int_line(s, line, imx_level);
/* this is an input signal, so set PSR */
@ -200,7 +195,8 @@ static uint64_t imx_gpio_read(void *opaque, hwaddr offset, unsigned size)
break;
}
DPRINTF("(%s) = 0x%" PRIx32 "\n", imx_gpio_reg_name(offset), reg_value);
trace_imx_gpio_read(DEVICE(s)->canonical_path, imx_gpio_reg_name(offset),
reg_value);
return reg_value;
}
@ -210,8 +206,8 @@ static void imx_gpio_write(void *opaque, hwaddr offset, uint64_t value,
{
IMXGPIOState *s = IMX_GPIO(opaque);
DPRINTF("(%s, value = 0x%" PRIx32 ")\n", imx_gpio_reg_name(offset),
(uint32_t)value);
trace_imx_gpio_write(DEVICE(s)->canonical_path, imx_gpio_reg_name(offset),
value);
switch (offset) {
case DR_ADDR:

View File

@ -1,5 +1,10 @@
# See docs/devel/tracing.rst for syntax documentation.
# imx_gpio.c
imx_gpio_read(const char *id, const char *reg, uint32_t value) "%s:[%s] -> 0x%" PRIx32
imx_gpio_write(const char *id, const char *reg, uint32_t value) "%s:[%s] <- 0x%" PRIx32
imx_gpio_set(const char *id, int line, int level) "%s:[%d] <- %d"
# npcm7xx_gpio.c
npcm7xx_gpio_read(const char *id, uint64_t offset, uint64_t value) " %s offset: 0x%04" PRIx64 " value 0x%08" PRIx64
npcm7xx_gpio_write(const char *id, uint64_t offset, uint64_t value) "%s offset: 0x%04" PRIx64 " value 0x%08" PRIx64

View File

@ -655,12 +655,12 @@ static void hppa_machine_reset(MachineState *ms, ResetType type)
for (i = 0; i < smp_cpus; i++) {
CPUState *cs = CPU(cpu[i]);
/* reset CPU */
resettable_reset(OBJECT(cs), RESET_TYPE_COLD);
cpu_set_pc(cs, firmware_entry);
cpu[i]->env.psw = PSW_Q;
cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000;
cs->exception_index = -1;
cs->halted = 0;
}
/* already initialized by machine_hppa_init()? */

View File

@ -25,18 +25,7 @@
#include "hw/i2c/i2c.h"
#include "qemu/log.h"
#include "qemu/module.h"
#ifndef DEBUG_IMX_I2C
#define DEBUG_IMX_I2C 0
#endif
#define DPRINTF(fmt, args...) \
do { \
if (DEBUG_IMX_I2C) { \
fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_I2C, \
__func__, ##args); \
} \
} while (0)
#include "trace.h"
static const char *imx_i2c_get_regname(unsigned offset)
{
@ -152,8 +141,8 @@ static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
break;
}
DPRINTF("read %s [0x%" HWADDR_PRIx "] -> 0x%02x\n",
imx_i2c_get_regname(offset), offset, value);
trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset),
offset, value);
return (uint64_t)value;
}
@ -163,8 +152,8 @@ static void imx_i2c_write(void *opaque, hwaddr offset,
{
IMXI2CState *s = IMX_I2C(opaque);
DPRINTF("write %s [0x%" HWADDR_PRIx "] <- 0x%02x\n",
imx_i2c_get_regname(offset), offset, (int)value);
trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset),
offset, value);
value &= 0xff;

View File

@ -56,3 +56,8 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s
pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
# imx_i2c.c
imx_i2c_read(const char *id, const char *reg, uint64_t ofs, uint64_t value) "%s:[%s (0x%" PRIx64 ")] -> 0x%02" PRIx64
imx_i2c_write(const char *id, const char *reg, uint64_t ofs, uint64_t value) "%s:[%s (0x%" PRIx64 ")] <- 0x%02" PRIx64

View File

@ -144,6 +144,10 @@ static const MemoryRegionOps pic_ops = {
.read = pic_read,
.write = pic_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.valid = {
.min_access_size = 4,
.max_access_size = 4

View File

@ -456,8 +456,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
acpi_table_begin(&table, table_data);
dsdt = init_aml_allocator();
for (i = 0; i < VIRT_UART_COUNT; i++)
for (i = 0; i < VIRT_UART_COUNT; i++) {
build_uart_device_aml(dsdt, i);
}
build_pci_device_aml(dsdt, lvms);
build_la_ged_aml(dsdt, machine);
build_flash_aml(dsdt, lvms);

View File

@ -331,8 +331,9 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
if (chosen)
if (chosen) {
qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
}
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4);
qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
*pch_pic_phandle);
@ -1175,9 +1176,10 @@ static void fw_cfg_add_memory(MachineState *ms)
size = ram_size - numa_info[0].node_mem;
}
if (size)
if (size) {
memmap_add_entry(base, size, 1);
}
}
static void virt_init(MachineState *machine)
{

View File

@ -17,18 +17,7 @@
#include "qemu/module.h"
#include "target/arm/arm-powerctl.h"
#include "hw/core/cpu.h"
#ifndef DEBUG_IMX6_SRC
#define DEBUG_IMX6_SRC 0
#endif
#define DPRINTF(fmt, args...) \
do { \
if (DEBUG_IMX6_SRC) { \
fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
__func__, ##args); \
} \
} while (0)
#include "trace.h"
static const char *imx6_src_reg_name(uint32_t reg)
{
@ -87,7 +76,7 @@ static void imx6_src_reset(DeviceState *dev)
{
IMX6SRCState *s = IMX6_SRC(dev);
DPRINTF("\n");
trace_imx6_src_reset();
memset(s->regs, 0, sizeof(s->regs));
@ -111,7 +100,7 @@ static uint64_t imx6_src_read(void *opaque, hwaddr offset, unsigned size)
}
DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_src_reg_name(index), value);
trace_imx6_src_read(imx6_src_reg_name(index), value);
return value;
}
@ -134,8 +123,7 @@ static void imx6_clear_reset_bit(CPUState *cpu, run_on_cpu_data data)
assert(bql_locked());
s->regs[SRC_SCR] = deposit32(s->regs[SRC_SCR], ri->reset_bit, 1, 0);
DPRINTF("reg[%s] <= 0x%" PRIx32 "\n",
imx6_src_reg_name(SRC_SCR), s->regs[SRC_SCR]);
trace_imx6_clear_reset_bit(imx6_src_reg_name(SRC_SCR), s->regs[SRC_SCR]);
g_free(ri);
}
@ -173,8 +161,7 @@ static void imx6_src_write(void *opaque, hwaddr offset, uint64_t value,
return;
}
DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_src_reg_name(index),
(uint32_t)current_value);
trace_imx6_src_write(imx6_src_reg_name(index), value);
change_mask = s->regs[index] ^ (uint32_t)current_value;

View File

@ -253,6 +253,12 @@ ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d"
ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
# imx6_src.c
imx6_src_read(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
imx6_src_write(const char *reg_name, uint64_t value) "reg[%s] <= 0x%" PRIx64
imx6_clear_reset_bit(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
imx6_src_reset(void) ""
# imx7_src.c
imx7_src_read(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
imx7_src_write(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32

View File

@ -26,9 +26,9 @@ static void fw_cfg_vmci_write(void *opaque, off_t offset, size_t len)
&& s->vmcoreinfo.guest_format != FW_CFG_VMCOREINFO_FORMAT_NONE;
}
static void vmcoreinfo_reset(void *opaque)
static void vmcoreinfo_reset_hold(Object *obj, ResetType type)
{
VMCoreInfoState *s = opaque;
VMCoreInfoState *s = VMCOREINFO(obj);
s->has_vmcoreinfo = false;
memset(&s->vmcoreinfo, 0, sizeof(s->vmcoreinfo));
@ -47,13 +47,13 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
*/
if (!vmcoreinfo_find()) {
error_setg(errp, "at most one %s device is permitted",
VMCOREINFO_DEVICE);
TYPE_VMCOREINFO);
return;
}
if (!fw_cfg || !fw_cfg->dma_enabled) {
error_setg(errp, "%s device requires fw_cfg with DMA",
VMCOREINFO_DEVICE);
TYPE_VMCOREINFO);
return;
}
@ -65,7 +65,7 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
* This device requires to register a global reset because it is
* not plugged to a bus (which, as its QOM parent, would reset it).
*/
qemu_register_reset(vmcoreinfo_reset, s);
qemu_register_resettable(OBJECT(s));
vmcoreinfo_state = s;
}
@ -86,16 +86,18 @@ static const VMStateDescription vmstate_vmcoreinfo = {
static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->vmsd = &vmstate_vmcoreinfo;
dc->realize = vmcoreinfo_realize;
dc->hotpluggable = false;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
rc->phases.hold = vmcoreinfo_reset_hold;
}
static const TypeInfo vmcoreinfo_types[] = {
{
.name = VMCOREINFO_DEVICE,
.name = TYPE_VMCOREINFO,
.parent = TYPE_DEVICE,
.instance_size = sizeof(VMCoreInfoState),
.class_init = vmcoreinfo_device_class_init,

View File

@ -2,6 +2,7 @@
* QEMU model of the Xilinx Ethernet Lite MAC.
*
* Copyright (c) 2009 Edgar E. Iglesias.
* Copyright (c) 2024 Linaro, Ltd
*
* DS580: https://docs.amd.com/v/u/en-US/xps_ethernetlite
* LogiCORE IP XPS Ethernet Lite Media Access Controller
@ -27,28 +28,34 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/bitops.h"
#include "qom/object.h"
#include "exec/tswap.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/misc/unimp.h"
#include "net/net.h"
#include "trace.h"
#define R_TX_BUF0 0
#define BUFSZ_MAX 0x07e4
#define R_TX_LEN0 (0x07f4 / 4)
#define R_TX_GIE0 (0x07f8 / 4)
#define R_TX_CTRL0 (0x07fc / 4)
#define R_TX_BUF1 (0x0800 / 4)
#define R_TX_LEN1 (0x0ff4 / 4)
#define R_TX_CTRL1 (0x0ffc / 4)
#define A_MDIO_BASE 0x07e4
#define A_TX_BASE0 0x07f4
#define A_TX_BASE1 0x0ff4
#define A_RX_BASE0 0x17fc
#define A_RX_BASE1 0x1ffc
#define R_RX_BUF0 (0x1000 / 4)
#define R_RX_CTRL0 (0x17fc / 4)
#define R_RX_BUF1 (0x1800 / 4)
#define R_RX_CTRL1 (0x1ffc / 4)
#define R_MAX (0x2000 / 4)
enum {
TX_LEN = 0,
TX_GIE = 1,
TX_CTRL = 2,
TX_MAX
};
enum {
RX_CTRL = 0,
RX_MAX
};
#define GIE_GIE 0x80000000
@ -56,6 +63,21 @@
#define CTRL_P 0x2
#define CTRL_S 0x1
typedef struct XlnxXpsEthLitePort {
MemoryRegion txio;
MemoryRegion rxio;
MemoryRegion txbuf;
MemoryRegion rxbuf;
struct {
uint32_t tx_len;
uint32_t tx_gie;
uint32_t tx_ctrl;
uint32_t rx_ctrl;
} reg;
} XlnxXpsEthLitePort;
#define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite"
OBJECT_DECLARE_SIMPLE_TYPE(XlnxXpsEthLite, XILINX_ETHLITE)
@ -63,7 +85,7 @@ struct XlnxXpsEthLite
{
SysBusDevice parent_obj;
MemoryRegion mmio;
MemoryRegion container;
qemu_irq irq;
NICState *nic;
NICConf conf;
@ -72,125 +94,176 @@ struct XlnxXpsEthLite
uint32_t c_rx_pingpong;
unsigned int port_index; /* dual port RAM index */
uint32_t regs[R_MAX];
UnimplementedDeviceState rsvd;
UnimplementedDeviceState mdio;
XlnxXpsEthLitePort port[2];
};
static inline void eth_pulse_irq(XlnxXpsEthLite *s)
{
/* Only the first gie reg is active. */
if (s->regs[R_TX_GIE0] & GIE_GIE) {
if (s->port[0].reg.tx_gie & GIE_GIE) {
qemu_irq_pulse(s->irq);
}
}
static uint64_t
eth_read(void *opaque, hwaddr addr, unsigned int size)
static unsigned addr_to_port_index(hwaddr addr)
{
return extract64(addr, 11, 1);
}
static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index)
{
return memory_region_get_ram_ptr(&s->port[port_index].txbuf);
}
static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index)
{
return memory_region_get_ram_ptr(&s->port[port_index].rxbuf);
}
static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size)
{
XlnxXpsEthLite *s = opaque;
unsigned port_index = addr_to_port_index(addr);
uint32_t r = 0;
addr >>= 2;
switch (addr)
{
case R_TX_GIE0:
case R_TX_LEN0:
case R_TX_LEN1:
case R_TX_CTRL1:
case R_TX_CTRL0:
case R_RX_CTRL1:
case R_RX_CTRL0:
r = s->regs[addr];
switch (addr >> 2) {
case TX_LEN:
r = s->port[port_index].reg.tx_len;
break;
case TX_GIE:
r = s->port[port_index].reg.tx_gie;
break;
case TX_CTRL:
r = s->port[port_index].reg.tx_ctrl;
break;
default:
r = tswap32(s->regs[addr]);
break;
g_assert_not_reached();
}
return r;
}
static void
eth_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
static void port_tx_write(void *opaque, hwaddr addr, uint64_t value,
unsigned int size)
{
XlnxXpsEthLite *s = opaque;
unsigned int base = 0;
uint32_t value = val64;
addr >>= 2;
switch (addr)
{
case R_TX_CTRL0:
case R_TX_CTRL1:
if (addr == R_TX_CTRL1)
base = 0x800 / 4;
unsigned port_index = addr_to_port_index(addr);
switch (addr >> 2) {
case TX_LEN:
s->port[port_index].reg.tx_len = value;
break;
case TX_GIE:
s->port[port_index].reg.tx_gie = value;
break;
case TX_CTRL:
if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
qemu_send_packet(qemu_get_queue(s->nic),
(void *) &s->regs[base],
s->regs[base + R_TX_LEN0]);
if (s->regs[base + R_TX_CTRL0] & CTRL_I)
eth_pulse_irq(s);
} else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
memcpy(&s->conf.macaddr.a[0], &s->regs[base], 6);
if (s->regs[base + R_TX_CTRL0] & CTRL_I)
txbuf_ptr(s, port_index),
s->port[port_index].reg.tx_len);
if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
eth_pulse_irq(s);
}
/* We are fast and get ready pretty much immediately so
we actually never flip the S nor P bits to one. */
s->regs[addr] = value & ~(CTRL_P | CTRL_S);
} else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6);
if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
eth_pulse_irq(s);
}
}
/*
* We are fast and get ready pretty much immediately
* so we actually never flip the S nor P bits to one.
*/
s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S);
break;
default:
g_assert_not_reached();
}
}
/* Keep these native. */
case R_RX_CTRL0:
case R_RX_CTRL1:
static const MemoryRegionOps eth_porttx_ops = {
.read = port_tx_read,
.write = port_tx_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.valid = {
.min_access_size = 4,
.max_access_size = 4,
},
};
static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size)
{
XlnxXpsEthLite *s = opaque;
unsigned port_index = addr_to_port_index(addr);
uint32_t r = 0;
switch (addr >> 2) {
case RX_CTRL:
r = s->port[port_index].reg.rx_ctrl;
break;
default:
g_assert_not_reached();
}
return r;
}
static void port_rx_write(void *opaque, hwaddr addr, uint64_t value,
unsigned int size)
{
XlnxXpsEthLite *s = opaque;
unsigned port_index = addr_to_port_index(addr);
switch (addr >> 2) {
case RX_CTRL:
if (!(value & CTRL_S)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
/* fall through */
case R_TX_LEN0:
case R_TX_LEN1:
case R_TX_GIE0:
s->regs[addr] = value;
s->port[port_index].reg.rx_ctrl = value;
break;
default:
s->regs[addr] = tswap32(value);
break;
g_assert_not_reached();
}
}
static const MemoryRegionOps eth_ops = {
.read = eth_read,
.write = eth_write,
static const MemoryRegionOps eth_portrx_ops = {
.read = port_rx_read,
.write = port_rx_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.valid = {
.min_access_size = 4,
.max_access_size = 4
}
.max_access_size = 4,
},
};
static bool eth_can_rx(NetClientState *nc)
{
XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
unsigned int rxbase = s->port_index * (0x800 / 4);
return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S);
return !(s->port[s->port_index].reg.rx_ctrl & CTRL_S);
}
static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
{
XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
unsigned int rxbase = s->port_index * (0x800 / 4);
unsigned int port_index = s->port_index;
/* DA filter. */
if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6))
return size;
if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) {
trace_ethlite_pkt_lost(s->regs[R_RX_CTRL0]);
if (s->port[port_index].reg.rx_ctrl & CTRL_S) {
trace_ethlite_pkt_lost(s->port[port_index].reg.rx_ctrl);
return -1;
}
@ -198,10 +271,10 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
trace_ethlite_pkt_size_too_big(size);
return -1;
}
memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size);
memcpy(rxbuf_ptr(s, port_index), buf, size);
s->regs[rxbase + R_RX_CTRL0] |= CTRL_S;
if (s->regs[R_RX_CTRL0] & CTRL_I) {
s->port[port_index].reg.rx_ctrl |= CTRL_S;
if (s->port[port_index].reg.rx_ctrl & CTRL_I) {
eth_pulse_irq(s);
}
@ -228,6 +301,52 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp)
{
XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
memory_region_init(&s->container, OBJECT(dev),
"xlnx.xps-ethernetlite", 0x2000);
object_initialize_child(OBJECT(dev), "ethlite.reserved", &s->rsvd,
TYPE_UNIMPLEMENTED_DEVICE);
qdev_prop_set_string(DEVICE(&s->rsvd), "name", "ethlite.reserved");
qdev_prop_set_uint64(DEVICE(&s->rsvd), "size",
memory_region_size(&s->container));
sysbus_realize(SYS_BUS_DEVICE(&s->rsvd), &error_fatal);
memory_region_add_subregion_overlap(&s->container, 0,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rsvd), 0),
-1);
object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio,
TYPE_UNIMPLEMENTED_DEVICE);
qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio");
qdev_prop_set_uint64(DEVICE(&s->mdio), "size", 4 * 4);
sysbus_realize(SYS_BUS_DEVICE(&s->mdio), &error_fatal);
memory_region_add_subregion(&s->container, A_MDIO_BASE,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 0));
for (unsigned i = 0; i < 2; i++) {
memory_region_init_ram(&s->port[i].txbuf, OBJECT(dev),
i ? "ethlite.tx[1]buf" : "ethlite.tx[0]buf",
BUFSZ_MAX, &error_abort);
memory_region_add_subregion(&s->container, 0x0800 * i, &s->port[i].txbuf);
memory_region_init_io(&s->port[i].txio, OBJECT(dev),
&eth_porttx_ops, s,
i ? "ethlite.tx[1]io" : "ethlite.tx[0]io",
4 * TX_MAX);
memory_region_add_subregion(&s->container, i ? A_TX_BASE1 : A_TX_BASE0,
&s->port[i].txio);
memory_region_init_ram(&s->port[i].rxbuf, OBJECT(dev),
i ? "ethlite.rx[1]buf" : "ethlite.rx[0]buf",
BUFSZ_MAX, &error_abort);
memory_region_add_subregion(&s->container, 0x1000 + 0x0800 * i,
&s->port[i].rxbuf);
memory_region_init_io(&s->port[i].rxio, OBJECT(dev),
&eth_portrx_ops, s,
i ? "ethlite.rx[1]io" : "ethlite.rx[0]io",
4 * RX_MAX);
memory_region_add_subregion(&s->container, i ? A_RX_BASE1 : A_RX_BASE0,
&s->port[i].rxio);
}
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id,
@ -240,10 +359,7 @@ static void xilinx_ethlite_init(Object *obj)
XlnxXpsEthLite *s = XILINX_ETHLITE(obj);
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
memory_region_init_io(&s->mmio, obj, &eth_ops, s,
"xlnx.xps-ethernetlite", R_MAX * 4);
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
}
static const Property xilinx_ethlite_properties[] = {

View File

@ -1598,7 +1598,7 @@ static void pci_update_mappings(PCIDevice *d)
continue;
new_addr = pci_bar_address(d, i, r->type, r->size);
if (!d->has_power) {
if (!d->enabled) {
new_addr = PCI_BAR_UNMAPPED;
}
@ -1686,7 +1686,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int
pci_update_irq_disabled(d, was_irq_disabled);
memory_region_set_enabled(&d->bus_master_enable_region,
(pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER) && d->has_power);
& PCI_COMMAND_MASTER) && d->enabled);
}
msi_write_config(d, addr, val_in, l);
@ -2963,16 +2963,21 @@ MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
void pci_set_power(PCIDevice *d, bool state)
{
if (d->has_power == state) {
pci_set_enabled(d, state);
}
void pci_set_enabled(PCIDevice *d, bool state)
{
if (d->enabled == state) {
return;
}
d->has_power = state;
d->enabled = state;
pci_update_mappings(d);
memory_region_set_enabled(&d->bus_master_enable_region,
(pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER) && d->has_power);
if (!d->has_power) {
& PCI_COMMAND_MASTER) && d->enabled);
if (!d->enabled) {
pci_device_reset(d);
}
}

View File

@ -86,7 +86,7 @@ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
* allowing direct removal of unexposed functions.
*/
if ((pci_dev->qdev.hotplugged && !pci_get_function_0(pci_dev)) ||
!pci_dev->has_power || is_pci_dev_ejected(pci_dev)) {
!pci_dev->enabled || is_pci_dev_ejected(pci_dev)) {
return;
}
@ -111,7 +111,7 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
* allowing direct removal of unexposed functions.
*/
if ((pci_dev->qdev.hotplugged && !pci_get_function_0(pci_dev)) ||
!pci_dev->has_power || is_pci_dev_ejected(pci_dev)) {
!pci_dev->enabled || is_pci_dev_ejected(pci_dev)) {
return ~0x0;
}

View File

@ -665,12 +665,13 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
}
}
if (s->blkcnt == 0) {
sdhci_end_transfer(s);
} else {
if (s->norintstsen & SDHC_NISEN_DMA) {
s->norintsts |= SDHC_NIS_DMA;
}
if (s->blkcnt == 0) {
sdhci_end_transfer(s);
} else {
sdhci_update_irq(s);
}
}
@ -691,9 +692,22 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s)
}
s->blkcnt--;
if (s->norintstsen & SDHC_NISEN_DMA) {
s->norintsts |= SDHC_NIS_DMA;
}
sdhci_end_transfer(s);
}
static void sdhci_sdma_transfer(SDHCIState *s)
{
if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {
sdhci_sdma_transfer_single_block(s);
} else {
sdhci_sdma_transfer_multi_blocks(s);
}
}
typedef struct ADMADescr {
hwaddr addr;
uint16_t length;
@ -925,12 +939,7 @@ static void sdhci_data_transfer(void *opaque)
if (s->trnmod & SDHC_TRNS_DMA) {
switch (SDHC_DMA_TYPE(s->hostctl1)) {
case SDHC_CTRL_SDMA:
if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {
sdhci_sdma_transfer_single_block(s);
} else {
sdhci_sdma_transfer_multi_blocks(s);
}
sdhci_sdma_transfer(s);
break;
case SDHC_CTRL_ADMA1_32:
if (!(s->capareg & R_SDHC_CAPAB_ADMA1_MASK)) {
@ -1174,11 +1183,7 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
if (!(mask & 0xFF000000) && s->blkcnt &&
(s->blksize & BLOCK_SIZE_MASK) &&
SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) {
if (s->trnmod & SDHC_TRNS_MULTI) {
sdhci_sdma_transfer_multi_blocks(s);
} else {
sdhci_sdma_transfer_single_block(s);
}
sdhci_sdma_transfer(s);
}
}
break;

View File

@ -974,7 +974,7 @@ static void sun4m_hw_init(MachineState *machine)
sysbus_mmio_map(s, 0, hwdef->ms_kb_base);
/* Logically OR both its IRQs together */
ms_kb_orgate = DEVICE(object_new(TYPE_OR_IRQ));
ms_kb_orgate = qdev_new(TYPE_OR_IRQ);
object_property_set_int(OBJECT(ms_kb_orgate), "num-lines", 2, &error_fatal);
qdev_realize_and_unref(ms_kb_orgate, NULL, &error_fatal);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(ms_kb_orgate, 0));
@ -995,7 +995,7 @@ static void sun4m_hw_init(MachineState *machine)
sysbus_mmio_map(s, 0, hwdef->serial_base);
/* Logically OR both its IRQs together */
serial_orgate = DEVICE(object_new(TYPE_OR_IRQ));
serial_orgate = qdev_new(TYPE_OR_IRQ);
object_property_set_int(OBJECT(serial_orgate), "num-lines", 2,
&error_fatal);
qdev_realize_and_unref(serial_orgate, NULL, &error_fatal);

View File

@ -20,10 +20,6 @@
#include "qemu/log.h"
#include "trace.h"
#ifndef DEBUG_IMX_GPT
#define DEBUG_IMX_GPT 0
#endif
static const char *imx_gpt_reg_name(uint32_t reg)
{
switch (reg) {

View File

@ -193,6 +193,10 @@ static const MemoryRegionOps timer_ops = {
.read = timer_read,
.write = timer_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
.valid = {
.min_access_size = 4,
.max_access_size = 4

View File

@ -31,11 +31,10 @@
#include "hw/tricore/triboard.h"
#include "hw/tricore/tc27x_soc.h"
static void tricore_load_kernel(const char *kernel_filename)
static void tricore_load_kernel(TriCoreCPU *cpu, const char *kernel_filename)
{
uint64_t entry;
long kernel_size;
TriCoreCPU *cpu;
CPUTriCoreState *env;
kernel_size = load_elf(kernel_filename, NULL,
@ -46,7 +45,6 @@ static void tricore_load_kernel(const char *kernel_filename)
error_report("no kernel file '%s'", kernel_filename);
exit(1);
}
cpu = TRICORE_CPU(first_cpu);
env = &cpu->env;
env->PC = entry;
}
@ -62,7 +60,7 @@ static void triboard_machine_init(MachineState *machine)
sysbus_realize(SYS_BUS_DEVICE(&ms->tc27x_soc), &error_fatal);
if (machine->kernel_filename) {
tricore_load_kernel(machine->kernel_filename);
tricore_load_kernel(&ms->tc27x_soc.cpu, machine->kernel_filename);
}
}

View File

@ -1164,7 +1164,7 @@ static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
value = ufs_read_attr_value(u, idn);
ret = UFS_QUERY_RESULT_SUCCESS;
} else {
value = req->req_upiu.qr.value;
value = be32_to_cpu(req->req_upiu.qr.value);
ret = ufs_write_attr_value(u, idn, value);
}
req->rsp_upiu.qr.value = cpu_to_be32(value);

View File

@ -411,7 +411,7 @@ void usb_claim_port(USBDevice *dev, Error **errp)
} else {
if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
/* Create a new hub and chain it on */
hub = usb_try_new("usb-hub");
hub = USB_DEVICE(qdev_try_new("usb-hub"));
if (hub) {
usb_realize_and_unref(hub, bus, NULL);
}
@ -662,7 +662,8 @@ USBDevice *usbdevice_create(const char *driver)
return NULL;
}
dev = f->usbdevice_init ? f->usbdevice_init() : usb_new(f->name);
dev = f->usbdevice_init ? f->usbdevice_init()
: USB_DEVICE(qdev_new(f->name));
if (!dev) {
error_report("Failed to create USB device '%s'", f->name);
return NULL;

View File

@ -624,7 +624,7 @@ static USBDevice *usb_braille_init(void)
return NULL;
}
dev = usb_new("usb-braille");
dev = USB_DEVICE(qdev_new("usb-braille"));
qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
return dev;
}

View File

@ -74,6 +74,7 @@ static bool xhci_pci_intr_raise(XHCIState *xhci, int n, bool level)
}
if (msi_enabled(pci_dev) && level) {
n %= msi_nr_vectors_allocated(pci_dev);
msi_notify(pci_dev, n);
return true;
}

View File

@ -644,6 +644,10 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
dma_addr_t erdp;
unsigned int dp_idx;
if (xhci->numintrs == 1) {
v = 0;
}
if (v >= xhci->numintrs) {
DPRINTF("intr nr out of range (%d >= %d)\n", v, xhci->numintrs);
return;

View File

@ -16,10 +16,9 @@
#include "standard-headers/linux/qemu_fw_cfg.h"
#include "qom/object.h"
#define VMCOREINFO_DEVICE "vmcoreinfo"
#define TYPE_VMCOREINFO "vmcoreinfo"
typedef struct VMCoreInfoState VMCoreInfoState;
DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO,
VMCOREINFO_DEVICE)
DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO, TYPE_VMCOREINFO)
typedef struct fw_cfg_vmcoreinfo FWCfgVMCoreInfo;
@ -33,7 +32,7 @@ struct VMCoreInfoState {
/* returns NULL unless there is exactly one device */
static inline VMCoreInfoState *vmcoreinfo_find(void)
{
Object *o = object_resolve_path_type("", VMCOREINFO_DEVICE, NULL);
Object *o = object_resolve_path_type("", TYPE_VMCOREINFO, NULL);
return o ? VMCOREINFO(o) : NULL;
}

View File

@ -674,6 +674,7 @@ static inline void pci_irq_deassert(PCIDevice *pci_dev)
}
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
void pci_set_enabled(PCIDevice *pci_dev, bool state);
void pci_set_power(PCIDevice *pci_dev, bool state);
#endif

View File

@ -57,7 +57,7 @@ typedef struct PCIReqIDCache PCIReqIDCache;
struct PCIDevice {
DeviceState qdev;
bool partially_hotplugged;
bool has_power;
bool enabled;
/* PCI config space */
uint8_t *config;

View File

@ -540,7 +540,8 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
int required_for_version);
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev);
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
bool qdev_hotplug_allowed(DeviceState *dev, Error **errp);
bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp);
bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp);
/**
* qdev_get_hotplug_handler() - Get handler responsible for device wiring

View File

@ -579,16 +579,6 @@ void usb_pcap_init(FILE *fp);
void usb_pcap_ctrl(USBPacket *p, bool setup);
void usb_pcap_data(USBPacket *p, bool setup);
static inline USBDevice *usb_new(const char *name)
{
return USB_DEVICE(qdev_new(name));
}
static inline USBDevice *usb_try_new(const char *name)
{
return USB_DEVICE(qdev_try_new(name));
}
static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **errp)
{
return qdev_realize_and_unref(&dev->qdev, &bus->qbus, errp);
@ -596,7 +586,7 @@ static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **er
static inline USBDevice *usb_create_simple(USBBus *bus, const char *name)
{
USBDevice *dev = usb_new(name);
USBDevice *dev = USB_DEVICE(qdev_new(name));
usb_realize_and_unref(dev, bus, &error_abort);
return dev;

View File

@ -99,7 +99,8 @@ foreach f : [
output: out,
install: get_option('install_blobs'),
install_dir: qemu_datadir,
command: [ dtc, '-I', 'dts', '-O', 'dtb', '-o', '@OUTPUT@', '@INPUT0@' ])
command: [ dtc, '-q', '-I', 'dts', '-O', 'dtb',
'-o', '@OUTPUT@', '@INPUT0@' ])
else
blobs += out
endif

View File

@ -263,8 +263,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
}
dc = DEVICE_CLASS(oc);
if (!dc->user_creatable ||
(phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) {
if (!dc->user_creatable) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
"a pluggable device type");
return NULL;
@ -676,11 +675,6 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
return NULL;
}
if (phase_check(PHASE_MACHINE_READY) && bus && !qbus_is_hotpluggable(bus)) {
error_setg(errp, "Bus '%s' does not support hotplugging", bus->name);
return NULL;
}
if (migration_is_running()) {
error_setg(errp, "device_add not allowed while migrating");
return NULL;
@ -690,19 +684,11 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
dev = qdev_new(driver);
/* Check whether the hotplug is allowed by the machine */
if (phase_check(PHASE_MACHINE_READY)) {
if (!qdev_hotplug_allowed(dev, errp)) {
if (phase_check(PHASE_MACHINE_READY) &&
!qdev_hotplug_allowed(dev, bus, errp)) {
goto err_del_dev;
}
if (!bus && !qdev_get_machine_hotplug_handler(dev)) {
/* No bus, no machine hotplug handler --> device is not hotpluggable */
error_setg(errp, "Device '%s' can not be hotplugged on this machine",
driver);
goto err_del_dev;
}
}
/*
* set dev's parent and register its id.
* If it fails it means the id is already taken.
@ -904,24 +890,11 @@ static DeviceState *find_device_state(const char *id, bool use_generic_error,
void qdev_unplug(DeviceState *dev, Error **errp)
{
DeviceClass *dc = DEVICE_GET_CLASS(dev);
HotplugHandler *hotplug_ctrl;
HotplugHandlerClass *hdc;
Error *local_err = NULL;
if (qdev_unplug_blocked(dev, errp)) {
return;
}
if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
error_setg(errp, "Bus '%s' does not support hotplugging",
dev->parent_bus->name);
return;
}
if (!dc->hotpluggable) {
error_setg(errp, "Device '%s' does not support hotplugging",
object_get_typename(OBJECT(dev)));
if (!qdev_hotunplug_allowed(dev, errp)) {
return;
}

View File

@ -195,13 +195,29 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
static void hppa_cpu_initfn(Object *obj)
{
CPUHPPAState *env = cpu_env(CPU(obj));
env->is_pa20 = !!object_dynamic_cast(obj, TYPE_HPPA64_CPU);
}
static void hppa_cpu_reset_hold(Object *obj, ResetType type)
{
HPPACPUClass *scc = HPPA_CPU_GET_CLASS(obj);
CPUState *cs = CPU(obj);
HPPACPU *cpu = HPPA_CPU(obj);
CPUHPPAState *env = &cpu->env;
if (scc->parent_phases.hold) {
scc->parent_phases.hold(obj, type);
}
cs->exception_index = -1;
cs->halted = 0;
cpu_set_pc(cs, 0xf0000004);
memset(env, 0, offsetof(CPUHPPAState, end_reset_fields));
cpu_hppa_loaded_fr0(env);
cpu_hppa_put_psw(env, PSW_W);
cpu_hppa_put_psw(env, PSW_M);
}
static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model)
@ -242,10 +258,14 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
HPPACPUClass *acc = HPPA_CPU_CLASS(oc);
ResettableClass *rc = RESETTABLE_CLASS(oc);
device_class_set_parent_realize(dc, hppa_cpu_realizefn,
&acc->parent_realize);
resettable_class_set_parent_phases(rc, NULL, hppa_cpu_reset_hold, NULL,
&acc->parent_phases);
cc->class_by_name = hppa_cpu_class_by_name;
cc->has_work = hppa_cpu_has_work;
cc->mmu_index = hppa_cpu_mmu_index;

View File

@ -263,6 +263,11 @@ typedef struct CPUArchState {
IntervalTreeRoot tlb_root;
HPPATLBEntry tlb[HPPA_TLB_ENTRIES];
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
bool is_pa20;
} CPUHPPAState;
/**
@ -281,6 +286,7 @@ struct ArchCPU {
/**
* HPPACPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_phases: The parent class' reset phase handlers.
*
* An HPPA CPU model.
*/
@ -288,13 +294,14 @@ struct HPPACPUClass {
CPUClass parent_class;
DeviceRealize parent_realize;
ResettablePhases parent_phases;
};
#include "exec/cpu-all.h"
static inline bool hppa_is_pa20(CPUHPPAState *env)
static inline bool hppa_is_pa20(const CPUHPPAState *env)
{
return object_dynamic_cast(OBJECT(env_cpu(env)), TYPE_HPPA64_CPU) != NULL;
return env->is_pa20;
}
static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)

View File

@ -644,7 +644,7 @@ MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk,
{
DeviceState *cpu;
cpu = DEVICE(object_new(cpu_type));
cpu = qdev_new(cpu_type);
qdev_connect_clock_in(cpu, "clk-in", cpu_refclk);
object_property_set_bool(OBJECT(cpu), "big-endian", is_big_endian,
&error_abort);

View File

@ -208,7 +208,7 @@ XtensaCPU *xtensa_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk)
{
DeviceState *cpu;
cpu = DEVICE(object_new(cpu_type));
cpu = qdev_new(cpu_type);
qdev_connect_clock_in(cpu, "clk-in", cpu_refclk);
qdev_realize(cpu, NULL, &error_abort);

View File

@ -108,6 +108,10 @@ tests_avr_system_thorough = [
'avr_mega2560',
]
tests_hppa_system_quick = [
'hppa_seabios',
]
tests_i386_system_thorough = [
'i386_tuxrun',
]

View File

@ -0,0 +1,35 @@
#!/usr/bin/env python3
#
# SeaBIOS boot test for HPPA machines
#
# Copyright (c) 2024 Linaro, Ltd
#
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import QemuSystemTest
from qemu_test import wait_for_console_pattern
class HppaSeabios(QemuSystemTest):
timeout = 5
MACH_BITS = {'B160L': 32, 'C3700': 64}
def boot_seabios(self):
mach = self.machine
bits = self.MACH_BITS[mach]
self.vm.set_console()
self.vm.launch()
self.machine
wait_for_console_pattern(self, f'SeaBIOS PA-RISC {bits}-bit Firmware')
wait_for_console_pattern(self, f'Emulated machine: HP {mach} ({bits}-bit')
def test_hppa_32(self):
self.set_machine('B160L')
self.boot_seabios()
def test_hppa_64(self):
self.set_machine('C3700')
self.boot_seabios()
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -189,8 +189,6 @@ static const testdef_t tests[] = {
{ "microblazeel", "petalogix-ml605", "", "TT",
sizeof(kernel_plml605), kernel_plml605 },
{ "arm", "raspi2b", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
/* For hppa, force bios to output to serial by disabling graphics. */
{ "hppa", "hppa", "-vga none", "SeaBIOS wants SYSTEM HALT" },
{ "aarch64", "virt", "-cpu max", "TT", sizeof(kernel_aarch64),
kernel_aarch64 },
{ "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 },

View File

@ -23,6 +23,7 @@
#include "libqos-malloc.h"
#include "qgraph.h"
#include "i2c.h"
#include "hw/i2c/imx_i2c.h"
#define ARM_PAGE_SIZE 4096
#define IMX25_PDK_RAM_START 0x80000000
@ -50,7 +51,7 @@ static void *imx25_pdk_get_driver(void *object, const char *interface)
static QOSGraphObject *imx25_pdk_get_device(void *obj, const char *device)
{
QIMX25PDKMachine *machine = obj;
if (!g_strcmp0(device, "imx.i2c")) {
if (!g_strcmp0(device, TYPE_IMX_I2C)) {
return &machine->i2c_1.obj;
}
@ -86,7 +87,7 @@ static void imx25_pdk_register_nodes(void)
.extra_device_opts = "bus=i2c-bus.0"
};
qos_node_create_machine("arm/imx25-pdk", qos_create_machine_arm_imx25_pdk);
qos_node_contains("arm/imx25-pdk", "imx.i2c", &edge, NULL);
qos_node_contains("arm/imx25-pdk", TYPE_IMX_I2C, &edge, NULL);
}
libqos_init(imx25_pdk_register_nodes);

View File

@ -209,8 +209,8 @@ void imx_i2c_init(IMXI2C *s, QTestState *qts, uint64_t addr)
static void imx_i2c_register_nodes(void)
{
qos_node_create_driver("imx.i2c", NULL);
qos_node_produces("imx.i2c", "i2c-bus");
qos_node_create_driver(TYPE_IMX_I2C, NULL);
qos_node_produces(TYPE_IMX_I2C, "i2c-bus");
}
libqos_init(imx_i2c_register_nodes);

View File

@ -140,7 +140,7 @@ qtests_alpha = ['boot-serial-test'] + \
qtests_avr = [ 'boot-serial-test' ]
qtests_hppa = ['boot-serial-test'] + \
qtests_hppa = \
qtests_filter + \
(config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : [])

View File

@ -145,7 +145,7 @@ static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function,
req_upiu.qr.idn = idn;
req_upiu.qr.index = index;
req_upiu.qr.selector = selector;
req_upiu.qr.value = attr_value;
req_upiu.qr.value = cpu_to_be32(attr_value);
req_upiu.qr.length = UFS_QUERY_DESC_MAX_SIZE;
qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu,
sizeof(req_upiu));