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

Misc HW patches

- Remove TCG dependency on ARM_GICV3 (Philippe)
- Add MMIO interface to PVPanic device (Alexander)
- Add vmapple machine (Alexander & Phil)
- Restrict part of sPAPR PAGE_INIT hypercall to TCG (Philippe)
- Make ghes_record_cper_errors() scope static (Gavin)
- Do not expose the ARM virt machines on Xen-only binary (Philippe)
- Xen header cleanups (Philippe)
- Set Freescale eTSEC network device description & category (Zoltan)
- Improve RX FIFO depth for various UARTs (Philippe)
- Prevent TX FIFO memory leak in SiFive UART (Alistair)
- Cleanups in MacIO and AT24C EEPROM (Zoltan)
- Add UFS temperature event notification support & test (Keoseong)
- Remove printf() calls in hw/arm/ (Peter)

 # -----BEGIN PGP SIGNATURE-----
 #
 # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmfHpagACgkQ4+MsLN6t
 # wN4dTg//Z2neoENdnZglRp6q66LLxSTHJnHUMNHe2Bp+KKfhce+//j+CFYgOnJjV
 # P5eExzvHvtYFL6lNXOR7MTM/i/4pixcLYh8anyrnUWkEiufGXI4/30QePbwAAdkZ
 # kQ1CpLI43ZdnMLTh18JswLo/JMkl/jJGvCGNjhtQVnobqam+ATgAbjmcnwA8esJS
 # cCQVFzno9TNvsCnUtMe3IdOfIs9K3atCARbXpA3i3wd52P+NHvGO1jU0QPFBm2Lr
 # 4kcFLI1Sg2vYWD3FujDPeCcfI7kcRDIjHS6vVplK1VlCjjdaQmxx6XKO72PnZZOG
 # 7sra8xJpW8mZS2jfN2AxKMVlNndZMYzAJoS2UBMp1YX8KBEzlcmI2uSjGas6bcmQ
 # XIaP7/mggx7yBU3nspUl8rqY/3Z3wVjwepf1l8KOn9Z13wo+APv4aj6W+zkK96A5
 # NGq6EpoKquINGLBBMkZAdfBOKk97NhwHh1Op04VgJNnPESpLnb5hENtZW1ksg92r
 # tijWdDWnC/JtWMU2dAnmT/9Vaxk4fukGqqncXqQJzGBw0OylzWh5b2Zer02WFyxz
 # oplISEwU3uFcg0OLa9aUHgs7lVWBUbEW3pSk1CtKuqgPtwxm/Gr2KbAVgAbFiyzr
 # 6YPQsfFP5z6CjreOWMELPWmsYV+jtTj/KoIek2QlYt7Ex6uiA6c=
 # =TcY9
 # -----END PGP SIGNATURE-----
 # gpg: Signature made Wed 05 Mar 2025 09:15:20 HKT
 # 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-20250305' of https://github.com/philmd/qemu: (41 commits)
  hw/nvram/eeprom_at24c: Reorganise init to avoid overwriting values
  hw/nvram/eeprom_at24c: Remove memset after g_malloc0
  hw/nvram/eeprom_at24c: Remove ERR macro that calls fprintf to stderr
  hw/nvram/eeprom_at24c: Use OBJECT_DECLARE_SIMPLE_TYPE
  hw/arm/versatilepb: Convert printfs to LOG_GUEST_ERROR
  hw/arm/omap_sx1: Remove ifdeffed out debug printf
  hw/arm/omap1: Convert information printfs to tracepoints
  hw/arm/omap1: Drop ALMDEBUG ifdeffed out code
  hw/arm/omap1: Convert raw printfs to qemu_log_mask()
  tests/qtest/ufs-test: Add test code for the temperature feature
  hw/ufs: Add temperature event notification support
  hw/misc/macio/gpio: Add constants for register bits
  hw/misc/macio: Improve trace logs
  hw/char/sifive_uart: Free fifo on unrealize
  hw/char/sh_serial: Return correct number of empty RX FIFO elements
  hw/char/mcf_uart: Really use RX FIFO depth
  hw/char/mcf_uart: Use FIFO_DEPTH definition instead of magic values
  hw/char/imx_serial: Really use RX FIFO depth
  hw/char/bcm2835_aux: Really use RX FIFO depth
  hw/char/pl011: Really use RX FIFO depth
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2025-03-05 21:54:58 +08:00
68 changed files with 2558 additions and 204 deletions
+8
View File
@@ -2826,6 +2826,14 @@ S: Maintained
F: hw/uefi/
F: include/hw/uefi/
VMapple
M: Alexander Graf <agraf@csgraf.de>
M: Phil Dennis-Jordan <phil@philjordan.eu>
S: Maintained
F: hw/vmapple/*
F: include/hw/vmapple/*
F: docs/system/arm/vmapple.rst
Subsystems
----------
Overall Audio backends
+1
View File
@@ -16,4 +16,5 @@ config KVM
config XEN
bool
select FSDEV_9P if VIRTFS
select PCI_EXPRESS_GENERIC_BRIDGE
select XEN_BUS
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
#
# Used for converting a guest provisioned using Virtualization.framework
# for use with the QEMU 'vmapple' aarch64 machine type.
#
# Extracts the Machine UUID from Virtualization.framework VM JSON file.
# (as produced by 'macosvm', passed as command line argument)
#
# SPDX-License-Identifier: GPL-2.0-or-later
plutil -extract machineId raw "$1" | base64 -d | plutil -extract ECID raw -
+65
View File
@@ -0,0 +1,65 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
VMApple machine emulation
========================================================================================
VMApple is the device model that the macOS built-in hypervisor called "Virtualization.framework"
exposes to Apple Silicon macOS guests. The "vmapple" machine model in QEMU implements the same
device model, but does not use any code from Virtualization.Framework.
Prerequisites
-------------
To run the vmapple machine model, you need to
* Run on Apple Silicon
* Run on macOS 12.0 or above
* Have an already installed copy of a Virtualization.Framework macOS 12 virtual
machine. Note that newer versions than 12.x are currently NOT supported on
the guest side. I will assume that you installed it using the
`macosvm <https://github.com/s-u/macosvm>`__ CLI.
First, we need to extract the UUID from the virtual machine that you installed. You can do this
by running the shell script in contrib/vmapple/uuid.sh on the macosvm.json file.
.. code-block:: bash
:caption: uuid.sh script to extract the UUID from a macosvm.json file
$ contrib/vmapple/uuid.sh "path/to/macosvm.json"
Now we also need to trim the aux partition. It contains metadata that we can just discard:
.. code-block:: bash
:caption: Command to trim the aux file
$ dd if="aux.img" of="aux.img.trimmed" bs=$(( 0x4000 )) skip=1
How to run
----------
Then, we can launch QEMU with the Virtualization.Framework pre-boot environment and the readily
installed target disk images. I recommend to port forward the VM's ssh and vnc ports to the host
to get better interactive access into the target system:
.. code-block:: bash
:caption: Example execution command line
$ UUID="$(contrib/vmapple/uuid.sh 'macosvm.json')"
$ AVPBOOTER="/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin"
$ AUX="aux.img.trimmed"
$ DISK="disk.img"
$ qemu-system-aarch64 \
-serial mon:stdio \
-m 4G \
-accel hvf \
-M vmapple,uuid="$UUID" \
-bios "$AVPBOOTER" \
-drive file="$AUX",if=pflash,format=raw \
-drive file="$DISK",if=pflash,format=raw \
-drive file="$AUX",if=none,id=aux,format=raw \
-drive file="$DISK",if=none,id=root,format=raw \
-device vmapple-virtio-blk-pci,variant=aux,drive=aux \
-device vmapple-virtio-blk-pci,variant=root,drive=root \
-netdev user,id=net0,ipv6=off,hostfwd=tcp::2222-:22,hostfwd=tcp::5901-:5900 \
-device virtio-net-pci,netdev=net0
+1
View File
@@ -103,6 +103,7 @@ Board-specific documentation
arm/stellaris
arm/stm32
arm/virt
arm/vmapple
arm/xenpvh
arm/xlnx-versal-virt
arm/xlnx-zynq
+1
View File
@@ -42,6 +42,7 @@ source ufs/Kconfig
source usb/Kconfig
source virtio/Kconfig
source vfio/Kconfig
source vmapple/Kconfig
source xen/Kconfig
source watchdog/Kconfig
+2 -4
View File
@@ -390,8 +390,8 @@ static void get_hw_error_offsets(uint64_t ghes_addr,
*read_ack_register_addr = ghes_addr + sizeof(uint64_t);
}
void ghes_record_cper_errors(const void *cper, size_t len,
uint16_t source_id, Error **errp)
static void ghes_record_cper_errors(const void *cper, size_t len,
uint16_t source_id, Error **errp)
{
uint64_t cper_addr = 0, read_ack_register_addr = 0, read_ack_register;
AcpiGedState *acpi_ged_state;
@@ -440,8 +440,6 @@ void ghes_record_cper_errors(const void *cper, size_t len,
/* Write the generic error data entry into guest memory */
cpu_physical_memory_write(cper_addr, cper, len);
return;
}
int acpi_ghes_memory_errors(uint16_t source_id, uint64_t physical_address)
+1
View File
@@ -2,6 +2,7 @@ config ARM_VIRT
bool
default y
depends on ARM
depends on TCG || KVM || HVF
imply PCI_DEVICES
imply TEST_DEVICES
imply VFIO_AMD_XGBE
+45 -80
View File
@@ -42,6 +42,7 @@
#include "qemu/cutils.h"
#include "qemu/bcd.h"
#include "target/arm/cpu-qom.h"
#include "trace.h"
static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
{
@@ -1731,7 +1732,7 @@ static void omap_clkm_write(void *opaque, hwaddr addr,
case 0x18: /* ARM_SYSST */
if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
s->clkm.clocking_scheme = (value >> 11) & 7;
printf("%s: clocking scheme set to %s\n", __func__,
trace_omap1_pwl_clocking_scheme(
clkschemename[s->clkm.clocking_scheme]);
}
s->clkm.cold_start &= value & 0x3f;
@@ -2335,7 +2336,7 @@ static void omap_pwl_update(struct omap_pwl_s *s)
if (output != s->output) {
s->output = output;
printf("%s: Backlight now at %i/256\n", __func__, output);
trace_omap1_pwl_backlight(output);
}
}
@@ -2470,8 +2471,8 @@ static void omap_pwt_write(void *opaque, hwaddr addr,
break;
case 0x04: /* VRC */
if ((value ^ s->vrc) & 1) {
if (value & 1)
printf("%s: %iHz buzz on\n", __func__, (int)
if (value & 1) {
trace_omap1_pwt_buzz(
/* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
((omap_clk_getrate(s->clk) >> 3) /
/* Pre-multiplexer divider */
@@ -2487,8 +2488,9 @@ static void omap_pwt_write(void *opaque, hwaddr addr,
/* 80/127 divider */
((value & (1 << 5)) ? 80 : 127) /
(107 * 55 * 63 * 127)));
else
printf("%s: silence!\n", __func__);
} else {
trace_omap1_pwt_silence();
}
}
s->vrc = value & 0x7f;
break;
@@ -2559,8 +2561,9 @@ static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
{
s->alarm_ti = mktimegm(&s->alarm_tm);
if (s->alarm_ti == -1)
printf("%s: conversion failed\n", __func__);
if (s->alarm_ti == -1) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: conversion failed\n", __func__);
}
}
static uint64_t omap_rtc_read(void *opaque, hwaddr addr, unsigned size)
@@ -2659,25 +2662,16 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
switch (offset) {
case 0x00: /* SECONDS_REG */
#ifdef ALMDEBUG
printf("RTC SEC_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_sec;
s->ti += from_bcd(value);
return;
case 0x04: /* MINUTES_REG */
#ifdef ALMDEBUG
printf("RTC MIN_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_min * 60;
s->ti += from_bcd(value) * 60;
return;
case 0x08: /* HOURS_REG */
#ifdef ALMDEBUG
printf("RTC HRS_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_hour * 3600;
if (s->pm_am) {
s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
@@ -2687,17 +2681,11 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x0c: /* DAYS_REG */
#ifdef ALMDEBUG
printf("RTC DAY_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_mday * 86400;
s->ti += from_bcd(value) * 86400;
return;
case 0x10: /* MONTHS_REG */
#ifdef ALMDEBUG
printf("RTC MTH_REG <-- %02x\n", value);
#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
new_tm.tm_mon = from_bcd(value);
ti[0] = mktimegm(&s->current_tm);
@@ -2714,9 +2702,6 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x14: /* YEARS_REG */
#ifdef ALMDEBUG
printf("RTC YRS_REG <-- %02x\n", value);
#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
ti[0] = mktimegm(&s->current_tm);
@@ -2736,25 +2721,16 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return; /* Ignored */
case 0x20: /* ALARM_SECONDS_REG */
#ifdef ALMDEBUG
printf("ALM SEC_REG <-- %02x\n", value);
#endif
s->alarm_tm.tm_sec = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x24: /* ALARM_MINUTES_REG */
#ifdef ALMDEBUG
printf("ALM MIN_REG <-- %02x\n", value);
#endif
s->alarm_tm.tm_min = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x28: /* ALARM_HOURS_REG */
#ifdef ALMDEBUG
printf("ALM HRS_REG <-- %02x\n", value);
#endif
if (s->pm_am)
s->alarm_tm.tm_hour =
((from_bcd(value & 0x3f)) % 12) +
@@ -2765,33 +2741,21 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x2c: /* ALARM_DAYS_REG */
#ifdef ALMDEBUG
printf("ALM DAY_REG <-- %02x\n", value);
#endif
s->alarm_tm.tm_mday = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x30: /* ALARM_MONTHS_REG */
#ifdef ALMDEBUG
printf("ALM MON_REG <-- %02x\n", value);
#endif
s->alarm_tm.tm_mon = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x34: /* ALARM_YEARS_REG */
#ifdef ALMDEBUG
printf("ALM YRS_REG <-- %02x\n", value);
#endif
s->alarm_tm.tm_year = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x40: /* RTC_CTRL_REG */
#ifdef ALMDEBUG
printf("RTC CONTROL <-- %02x\n", value);
#endif
s->pm_am = (value >> 3) & 1;
s->auto_comp = (value >> 2) & 1;
s->round = (value >> 1) & 1;
@@ -2801,32 +2765,20 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x44: /* RTC_STATUS_REG */
#ifdef ALMDEBUG
printf("RTC STATUSL <-- %02x\n", value);
#endif
s->status &= ~((value & 0xc0) ^ 0x80);
omap_rtc_interrupts_update(s);
return;
case 0x48: /* RTC_INTERRUPTS_REG */
#ifdef ALMDEBUG
printf("RTC INTRS <-- %02x\n", value);
#endif
s->interrupts = value;
return;
case 0x4c: /* RTC_COMP_LSB_REG */
#ifdef ALMDEBUG
printf("RTC COMPLSB <-- %02x\n", value);
#endif
s->comp_reg &= 0xff00;
s->comp_reg |= 0x00ff & value;
return;
case 0x50: /* RTC_COMP_MSB_REG */
#ifdef ALMDEBUG
printf("RTC COMPMSB <-- %02x\n", value);
#endif
s->comp_reg &= 0x00ff;
s->comp_reg |= 0xff00 & (value << 8);
return;
@@ -3024,8 +2976,9 @@ static void omap_mcbsp_source_tick(void *opaque)
if (!s->rx_rate)
return;
if (s->rx_req)
printf("%s: Rx FIFO overrun\n", __func__);
if (s->rx_req) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Rx FIFO overrun\n", __func__);
}
s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
@@ -3070,8 +3023,9 @@ static void omap_mcbsp_sink_tick(void *opaque)
if (!s->tx_rate)
return;
if (s->tx_req)
printf("%s: Tx FIFO underrun\n", __func__);
if (s->tx_req) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Tx FIFO underrun\n", __func__);
}
s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
@@ -3173,7 +3127,7 @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
/* Fall through. */
case 0x02: /* DRR1 */
if (s->rx_req < 2) {
printf("%s: Rx FIFO underrun\n", __func__);
qemu_log_mask(LOG_GUEST_ERROR, "%s: Rx FIFO underrun\n", __func__);
omap_mcbsp_rx_done(s);
} else {
s->tx_req -= 2;
@@ -3278,8 +3232,9 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
}
if (s->tx_req < 2)
omap_mcbsp_tx_done(s);
} else
printf("%s: Tx FIFO overrun\n", __func__);
} else {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Tx FIFO overrun\n", __func__);
}
return;
case 0x08: /* SPCR2 */
@@ -3293,8 +3248,11 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
case 0x0a: /* SPCR1 */
s->spcr[0] &= 0x0006;
s->spcr[0] |= 0xf8f9 & value;
if (value & (1 << 15)) /* DLB */
printf("%s: Digital Loopback mode enable attempt\n", __func__);
if (value & (1 << 15)) { /* DLB */
qemu_log_mask(LOG_UNIMP,
"%s: Digital Loopback mode enable attempt\n",
__func__);
}
if (~value & 1) { /* RRST */
s->spcr[0] &= ~6;
s->rx_req = 0;
@@ -3325,13 +3283,19 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
return;
case 0x18: /* MCR2 */
s->mcr[1] = value & 0x03e3;
if (value & 3) /* XMCM */
printf("%s: Tx channel selection mode enable attempt\n", __func__);
if (value & 3) { /* XMCM */
qemu_log_mask(LOG_UNIMP,
"%s: Tx channel selection mode enable attempt\n",
__func__);
}
return;
case 0x1a: /* MCR1 */
s->mcr[0] = value & 0x03e1;
if (value & 1) /* RMCM */
printf("%s: Rx channel selection mode enable attempt\n", __func__);
if (value & 1) { /* RMCM */
qemu_log_mask(LOG_UNIMP,
"%s: Rx channel selection mode enable attempt\n",
__func__);
}
return;
case 0x1c: /* RCERA */
s->rcer[0] = value & 0xffff;
@@ -3412,8 +3376,9 @@ static void omap_mcbsp_writew(void *opaque, hwaddr addr,
}
if (s->tx_req < 4)
omap_mcbsp_tx_done(s);
} else
printf("%s: Tx FIFO overrun\n", __func__);
} else {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Tx FIFO overrun\n", __func__);
}
return;
}
@@ -3531,7 +3496,7 @@ static void omap_lpg_tick(void *opaque)
timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
s->cycle = !s->cycle;
printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
trace_omap1_lpg_led(s->cycle ? "on" : "off");
}
static void omap_lpg_update(struct omap_lpg_s *s)
@@ -3551,11 +3516,11 @@ static void omap_lpg_update(struct omap_lpg_s *s)
}
timer_del(s->tm);
if (on == period && s->on < s->period)
printf("%s: LED is on\n", __func__);
else if (on == 0 && s->on)
printf("%s: LED is off\n", __func__);
else if (on && (on != s->on || period != s->period)) {
if (on == period && s->on < s->period) {
trace_omap1_lpg_led("on");
} else if (on == 0 && s->on) {
trace_omap1_lpg_led("off");
} else if (on && (on != s->on || period != s->period)) {
s->cycle = 0;
s->on = on;
s->period = period;
-4
View File
@@ -76,10 +76,6 @@ static uint64_t static_read(void *opaque, hwaddr offset,
static void static_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
#ifdef SPY
printf("%s: value %" PRIx64 " %u bytes written at 0x%x\n",
__func__, value, size, (int)offset);
#endif
}
static const MemoryRegionOps static_ops = {
+7
View File
@@ -1,5 +1,12 @@
# See docs/devel/tracing.rst for syntax documentation.
# omap1.c
omap1_pwl_clocking_scheme(const char *scheme) "omap1 CLKM: clocking scheme set to %s"
omap1_pwl_backlight(int output) "omap1 PWL: backlight now at %d/256"
omap1_pwt_buzz(int freq) "omap1 PWT: %dHz buzz on"
omap1_pwt_silence(void) "omap1 PWT: buzzer silenced"
omap1_lpg_led(const char *onoff) "omap1 LPG: LED is %s"
# virt-acpi-build.c
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
+5 -2
View File
@@ -27,6 +27,7 @@
#include "qom/object.h"
#include "audio/audio.h"
#include "target/arm/cpu-qom.h"
#include "qemu/log.h"
#define VERSATILE_FLASH_ADDR 0x34000000
#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
@@ -110,7 +111,8 @@ static uint64_t vpb_sic_read(void *opaque, hwaddr offset,
case 8: /* PICENABLE */
return s->pic_enable;
default:
printf ("vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
return 0;
}
}
@@ -144,7 +146,8 @@ static void vpb_sic_write(void *opaque, hwaddr offset,
vpb_sic_update_pic(s);
break;
default:
printf ("vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
return;
}
vpb_sic_update(s);
+2 -3
View File
@@ -5,10 +5,9 @@
*/
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/qapi-commands-migration.h"
#include "hw/boards.h"
#include "system/system.h"
#include "system/xen.h"
#include "hw/hw.h"
#include "hw/xen/xen-hvm-common.h"
#include "hw/xen/arch_hvm.h"
+14 -3
View File
@@ -50,7 +50,7 @@ static void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
req->mr_next = NULL;
}
static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
{
VirtIOBlock *s = req->dev;
VirtIODevice *vdev = VIRTIO_DEVICE(s);
@@ -961,8 +961,18 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
break;
}
default:
virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
g_free(req);
{
/*
* Give subclasses a chance to handle unknown requests. This way the
* class lookup is not in the hot path.
*/
VirtIOBlkClass *vbk = VIRTIO_BLK_GET_CLASS(s);
if (!vbk->handle_unknown_request ||
!vbk->handle_unknown_request(req, mrb, type)) {
virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
g_free(req);
}
}
}
return 0;
}
@@ -2029,6 +2039,7 @@ static const TypeInfo virtio_blk_info = {
.instance_size = sizeof(VirtIOBlock),
.instance_init = virtio_blk_instance_init,
.class_init = virtio_blk_class_init,
.class_size = sizeof(VirtIOBlkClass),
};
static void virtio_register_types(void)
+4 -2
View File
@@ -221,7 +221,7 @@ static int bcm2835_aux_can_receive(void *opaque)
{
BCM2835AuxState *s = opaque;
return s->read_count < BCM2835_AUX_RX_FIFO_LEN;
return BCM2835_AUX_RX_FIFO_LEN - s->read_count;
}
static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
@@ -243,7 +243,9 @@ static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size)
{
bcm2835_aux_put_fifo(opaque, *buf);
for (int i = 0; i < size; i++) {
bcm2835_aux_put_fifo(opaque, buf[i]);
}
}
static const MemoryRegionOps bcm2835_aux_ops = {
+6 -2
View File
@@ -386,7 +386,8 @@ static void imx_serial_write(void *opaque, hwaddr offset,
static int imx_can_receive(void *opaque)
{
IMXSerialState *s = (IMXSerialState *)opaque;
return s->ucr2 & UCR2_RXEN && fifo32_num_used(&s->rx_fifo) < FIFO_SIZE;
return s->ucr2 & UCR2_RXEN ? fifo32_num_free(&s->rx_fifo) : 0;
}
static void imx_put_data(void *opaque, uint32_t value)
@@ -417,7 +418,10 @@ static void imx_receive(void *opaque, const uint8_t *buf, int size)
IMXSerialState *s = (IMXSerialState *)opaque;
s->usr2 |= USR2_WAKE;
imx_put_data(opaque, *buf);
for (int i = 0; i < size; i++) {
imx_put_data(opaque, buf[i]);
}
}
static void imx_event(void *opaque, QEMUChrEvent event)
+11 -5
View File
@@ -17,6 +17,8 @@
#include "chardev/char-fe.h"
#include "qom/object.h"
#define FIFO_DEPTH 4
struct mcf_uart_state {
SysBusDevice parent_obj;
@@ -27,7 +29,7 @@ struct mcf_uart_state {
uint8_t imr;
uint8_t bg1;
uint8_t bg2;
uint8_t fifo[4];
uint8_t fifo[FIFO_DEPTH];
uint8_t tb;
int current_mr;
int fifo_len;
@@ -247,14 +249,16 @@ static void mcf_uart_reset(DeviceState *dev)
static void mcf_uart_push_byte(mcf_uart_state *s, uint8_t data)
{
/* Break events overwrite the last byte if the fifo is full. */
if (s->fifo_len == 4)
if (s->fifo_len == FIFO_DEPTH) {
s->fifo_len--;
}
s->fifo[s->fifo_len] = data;
s->fifo_len++;
s->sr |= MCF_UART_RxRDY;
if (s->fifo_len == 4)
if (s->fifo_len == FIFO_DEPTH) {
s->sr |= MCF_UART_FFULL;
}
mcf_uart_update(s);
}
@@ -277,14 +281,16 @@ static int mcf_uart_can_receive(void *opaque)
{
mcf_uart_state *s = (mcf_uart_state *)opaque;
return s->rx_enabled && (s->sr & MCF_UART_FFULL) == 0;
return s->rx_enabled ? FIFO_DEPTH - s->fifo_len : 0;
}
static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
{
mcf_uart_state *s = (mcf_uart_state *)opaque;
mcf_uart_push_byte(s, buf[0]);
for (int i = 0; i < size; i++) {
mcf_uart_push_byte(s, buf[i]);
}
}
static const MemoryRegionOps mcf_uart_ops = {
+22 -8
View File
@@ -85,6 +85,7 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
#define CR_OUT1 (1 << 12)
#define CR_RTS (1 << 11)
#define CR_DTR (1 << 10)
#define CR_RXE (1 << 9)
#define CR_TXE (1 << 8)
#define CR_LBE (1 << 7)
#define CR_UARTEN (1 << 0)
@@ -184,7 +185,7 @@ static void pl011_fifo_rx_put(void *opaque, uint32_t value)
s->read_fifo[slot] = value;
s->read_count++;
s->flags &= ~PL011_FLAG_RXFE;
trace_pl011_fifo_rx_put(value, s->read_count);
trace_pl011_fifo_rx_put(value, s->read_count, pipe_depth);
if (s->read_count == pipe_depth) {
trace_pl011_fifo_rx_full();
s->flags |= PL011_FLAG_RXFF;
@@ -247,12 +248,13 @@ static void pl011_write_txdata(PL011State *s, uint8_t data)
static uint32_t pl011_read_rxdata(PL011State *s)
{
uint32_t c;
unsigned fifo_depth = pl011_get_fifo_depth(s);
s->flags &= ~PL011_FLAG_RXFF;
c = s->read_fifo[s->read_pos];
if (s->read_count > 0) {
s->read_count--;
s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
s->read_pos = (s->read_pos + 1) & (fifo_depth - 1);
}
if (s->read_count == 0) {
s->flags |= PL011_FLAG_RXFE;
@@ -260,7 +262,7 @@ static uint32_t pl011_read_rxdata(PL011State *s)
if (s->read_count == s->read_trigger - 1) {
s->int_level &= ~INT_RX;
}
trace_pl011_read_fifo(s->read_count);
trace_pl011_read_fifo(s->read_count, fifo_depth);
s->rsr = c >> 8;
pl011_update(s);
qemu_chr_fe_accept_input(&s->chr);
@@ -485,15 +487,25 @@ static void pl011_write(void *opaque, hwaddr offset,
static int pl011_can_receive(void *opaque)
{
PL011State *s = (PL011State *)opaque;
int r;
unsigned fifo_depth = pl011_get_fifo_depth(s);
unsigned fifo_available = fifo_depth - s->read_count;
r = s->read_count < pl011_get_fifo_depth(s);
trace_pl011_can_receive(s->lcr, s->read_count, r);
return r;
if (!(s->cr & CR_UARTEN)) {
qemu_log_mask(LOG_GUEST_ERROR,
"PL011 receiving data on disabled UART\n");
}
if (!(s->cr & CR_RXE)) {
qemu_log_mask(LOG_GUEST_ERROR,
"PL011 receiving data on disabled RX UART\n");
}
trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
return fifo_available;
}
static void pl011_receive(void *opaque, const uint8_t *buf, int size)
{
trace_pl011_receive(size);
/*
* In loopback mode, the RX input signal is internally disconnected
* from the entire receiving logics; thus, all inputs are ignored,
@@ -503,7 +515,9 @@ static void pl011_receive(void *opaque, const uint8_t *buf, int size)
return;
}
pl011_fifo_rx_put(opaque, *buf);
for (int i = 0; i < size; i++) {
pl011_fifo_rx_put(opaque, buf[i]);
}
}
static void pl011_event(void *opaque, QEMUChrEvent event)
+14 -16
View File
@@ -320,7 +320,7 @@ static uint64_t sh_serial_read(void *opaque, hwaddr offs,
static int sh_serial_can_receive(SHSerialState *s)
{
return s->scr & (1 << 4);
return s->scr & (1 << 4) ? SH_RX_FIFO_LENGTH - s->rx_head : 0;
}
static void sh_serial_receive_break(SHSerialState *s)
@@ -353,22 +353,20 @@ static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
if (s->feat & SH_SERIAL_FEAT_SCIF) {
int i;
for (i = 0; i < size; i++) {
if (s->rx_cnt < SH_RX_FIFO_LENGTH) {
s->rx_fifo[s->rx_head++] = buf[i];
if (s->rx_head == SH_RX_FIFO_LENGTH) {
s->rx_head = 0;
}
s->rx_cnt++;
if (s->rx_cnt >= s->rtrg) {
s->flags |= SH_SERIAL_FLAG_RDF;
if (s->scr & (1 << 6) && s->rxi) {
timer_del(&s->fifo_timeout_timer);
qemu_set_irq(s->rxi, 1);
}
} else {
timer_mod(&s->fifo_timeout_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu);
s->rx_fifo[s->rx_head++] = buf[i];
if (s->rx_head == SH_RX_FIFO_LENGTH) {
s->rx_head = 0;
}
s->rx_cnt++;
if (s->rx_cnt >= s->rtrg) {
s->flags |= SH_SERIAL_FLAG_RDF;
if (s->scr & (1 << 6) && s->rxi) {
timer_del(&s->fifo_timeout_timer);
qemu_set_irq(s->rxi, 1);
}
} else {
timer_mod(&s->fifo_timeout_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu);
}
}
} else {
+28 -16
View File
@@ -251,6 +251,23 @@ static int sifive_uart_be_change(void *opaque)
return 0;
}
static void sifive_uart_reset_enter(Object *obj, ResetType type)
{
SiFiveUARTState *s = SIFIVE_UART(obj);
s->txfifo = 0;
s->ie = 0;
s->ip = 0;
s->txctrl = 0;
s->rxctrl = 0;
s->div = 0;
s->rx_fifo_len = 0;
memset(s->rx_fifo, 0, SIFIVE_UART_RX_FIFO_SIZE);
fifo8_reset(&s->tx_fifo);
}
static const Property sifive_uart_properties[] = {
DEFINE_PROP_CHR("chardev", SiFiveUARTState, chr),
};
@@ -270,30 +287,24 @@ static void sifive_uart_realize(DeviceState *dev, Error **errp)
{
SiFiveUARTState *s = SIFIVE_UART(dev);
fifo8_create(&s->tx_fifo, SIFIVE_UART_TX_FIFO_SIZE);
s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
fifo_trigger_update, s);
qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
sifive_uart_event, sifive_uart_be_change, s,
NULL, true);
if (qemu_chr_fe_backend_connected(&s->chr)) {
qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
sifive_uart_event, sifive_uart_be_change, s,
NULL, true);
}
}
static void sifive_uart_reset_enter(Object *obj, ResetType type)
static void sifive_uart_unrealize(DeviceState *dev)
{
SiFiveUARTState *s = SIFIVE_UART(obj);
SiFiveUARTState *s = SIFIVE_UART(dev);
s->txfifo = 0;
s->ie = 0;
s->ip = 0;
s->txctrl = 0;
s->rxctrl = 0;
s->div = 0;
s->rx_fifo_len = 0;
memset(s->rx_fifo, 0, SIFIVE_UART_RX_FIFO_SIZE);
fifo8_create(&s->tx_fifo, SIFIVE_UART_TX_FIFO_SIZE);
fifo8_destroy(&s->tx_fifo);
}
static void sifive_uart_reset_hold(Object *obj, ResetType type)
@@ -329,6 +340,7 @@ static void sifive_uart_class_init(ObjectClass *oc, void *data)
ResettableClass *rc = RESETTABLE_CLASS(oc);
dc->realize = sifive_uart_realize;
dc->unrealize = sifive_uart_unrealize;
dc->vmsd = &vmstate_sifive_uart;
rc->phases.enter = sifive_uart_reset_enter;
rc->phases.hold = sifive_uart_reset_hold;

Some files were not shown because too many files have changed in this diff Show More