Misc HW patch queue

- Restrict probe_access*() functions to TCG (Phil)
 - Extract do_invalidate_device_tlb from vtd_process_device_iotlb_desc (Clément)
 - Fixes in Loongson IPI model (Bibo & Phil)
 - Make docs/interop/firmware.json compatible with qapi-gen.py script (Thomas)
 - Correct MPC I2C MMIO region size (Zoltan)
 - Remove useless cast in Loongson3 Virt machine (Yao)
 - Various uses of range overlap API (Yao)
 - Use ERRP_GUARD macro in nubus_virtio_mmio_realize (Zhao)
 - Use DMA memory API in Goldfish UART model (Phil)
 - Expose fifo8_pop_buf and introduce fifo8_drop (Phil)
 - MAINTAINERS updates (Zhao, Phil)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmagFF8ACgkQ4+MsLN6t
 wN5bKg//f5TwUhsy2ff0FJpHheDOj/9Gc2nZ1U/Fp0E5N3sz3A7MGp91wye6Xwi3
 XG34YN9LK1AVzuCdrEEs5Uaxs1ZS1R2mV+fZaGHwYYxPDdnXxGyp/2Q0eyRxzbcN
 zxE2hWscYSZbPVEru4HvZJKfp4XnE1cqA78fJKMAdtq0IPq38tmQNRlJ+gWD9dC6
 ZUHXPFf3DnucvVuwqb0JYO/E+uJpcTtgR6pc09Xtv/HFgMiS0vKZ1I/6LChqAUw9
 eLMpD/5V2naemVadJe98/dL7gIUnhB8GTjsb4ioblG59AO/uojutwjBSQvFxBUUw
 U5lX9OSn20ouwcGiqimsz+5ziwhCG0R6r1zeQJFqUxrpZSscq7NQp9ygbvirm+wS
 edLc8yTPf4MtYOihzPP9jLPcXPZjEV64gSnJISDDFYWANCrysX3suaFEOuVYPl+s
 ZgQYRVSSYOYHgNqBSRkPKKVUxskSQiqLY3SfGJG4EA9Ktt5lD1cLCXQxhdsqphFm
 Ws3zkrVVL0EKl4v/4MtCgITIIctN1ZJE9u3oPJjASqSvK6EebFqAJkc2SidzKHz0
 F3iYX2AheWNHCQ3HFu023EvFryjlxYk95fs2f6Uj2a9yVbi813qsvd3gcZ8t0kTT
 +dmQwpu1MxjzZnA6838R6OCMnC+UpMPqQh3dPkU/5AF2fc3NnN8=
 =J/I2
 -----END PGP SIGNATURE-----

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

Misc HW patch queue

- Restrict probe_access*() functions to TCG (Phil)
- Extract do_invalidate_device_tlb from vtd_process_device_iotlb_desc (Clément)
- Fixes in Loongson IPI model (Bibo & Phil)
- Make docs/interop/firmware.json compatible with qapi-gen.py script (Thomas)
- Correct MPC I2C MMIO region size (Zoltan)
- Remove useless cast in Loongson3 Virt machine (Yao)
- Various uses of range overlap API (Yao)
- Use ERRP_GUARD macro in nubus_virtio_mmio_realize (Zhao)
- Use DMA memory API in Goldfish UART model (Phil)
- Expose fifo8_pop_buf and introduce fifo8_drop (Phil)
- MAINTAINERS updates (Zhao, Phil)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmagFF8ACgkQ4+MsLN6t
# wN5bKg//f5TwUhsy2ff0FJpHheDOj/9Gc2nZ1U/Fp0E5N3sz3A7MGp91wye6Xwi3
# XG34YN9LK1AVzuCdrEEs5Uaxs1ZS1R2mV+fZaGHwYYxPDdnXxGyp/2Q0eyRxzbcN
# zxE2hWscYSZbPVEru4HvZJKfp4XnE1cqA78fJKMAdtq0IPq38tmQNRlJ+gWD9dC6
# ZUHXPFf3DnucvVuwqb0JYO/E+uJpcTtgR6pc09Xtv/HFgMiS0vKZ1I/6LChqAUw9
# eLMpD/5V2naemVadJe98/dL7gIUnhB8GTjsb4ioblG59AO/uojutwjBSQvFxBUUw
# U5lX9OSn20ouwcGiqimsz+5ziwhCG0R6r1zeQJFqUxrpZSscq7NQp9ygbvirm+wS
# edLc8yTPf4MtYOihzPP9jLPcXPZjEV64gSnJISDDFYWANCrysX3suaFEOuVYPl+s
# ZgQYRVSSYOYHgNqBSRkPKKVUxskSQiqLY3SfGJG4EA9Ktt5lD1cLCXQxhdsqphFm
# Ws3zkrVVL0EKl4v/4MtCgITIIctN1ZJE9u3oPJjASqSvK6EebFqAJkc2SidzKHz0
# F3iYX2AheWNHCQ3HFu023EvFryjlxYk95fs2f6Uj2a9yVbi813qsvd3gcZ8t0kTT
# +dmQwpu1MxjzZnA6838R6OCMnC+UpMPqQh3dPkU/5AF2fc3NnN8=
# =J/I2
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 24 Jul 2024 06:36:47 AM AEST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]

* tag 'hw-misc-20240723' of https://github.com/philmd/qemu: (28 commits)
  MAINTAINERS: Add myself as a reviewer of machine core
  MAINTAINERS: Cover guest-agent in QAPI schema
  util/fifo8: Introduce fifo8_drop()
  util/fifo8: Expose fifo8_pop_buf()
  util/fifo8: Rename fifo8_pop_buf() -> fifo8_pop_bufptr()
  util/fifo8: Rename fifo8_peek_buf() -> fifo8_peek_bufptr()
  util/fifo8: Use fifo8_reset() in fifo8_create()
  util/fifo8: Fix style
  chardev/char-fe: Document returned value on error
  hw/char/goldfish: Use DMA memory API
  hw/nubus/virtio-mmio: Fix missing ERRP_GUARD() in realize handler
  dump: make range overlap check more readable
  crypto/block-luks: make range overlap check more readable
  system/memory_mapping: make range overlap check more readable
  sparc/ldst_helper: make range overlap check more readable
  cxl/mailbox: make range overlap check more readable
  util/range: Make ranges_overlap() return bool
  hw/mips/loongson3_virt: remove useless type cast
  hw/i2c/mpc_i2c: Fix mmio region size
  docs/interop/firmware.json: convert "Example" section
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-07-24 15:39:43 +10:00
commit 6410f877f5
26 changed files with 226 additions and 161 deletions

View File

@ -1879,6 +1879,7 @@ M: Eduardo Habkost <eduardo@habkost.net>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
R: Philippe Mathieu-Daudé <philmd@linaro.org>
R: Yanan Wang <wangyanan55@huawei.com>
R: Zhao Liu <zhao1.liu@intel.com>
S: Supported
F: hw/core/cpu-common.c
F: hw/core/cpu-sysemu.c
@ -3221,6 +3222,7 @@ M: Eric Blake <eblake@redhat.com>
M: Markus Armbruster <armbru@redhat.com>
S: Supported
F: qapi/*.json
F: qga/qapi-schema.json
T: git https://repo.or.cz/qemu/armbru.git qapi-next
QObject

View File

@ -18,20 +18,6 @@ void tb_flush(CPUState *cpu)
{
}
int probe_access_flags(CPUArchState *env, vaddr addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t retaddr)
{
g_assert_not_reached();
}
void *probe_access(CPUArchState *env, vaddr addr, int size,
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
/* Handled by hardware accelerator. */
g_assert_not_reached();
}
G_NORETURN void cpu_loop_exit(CPUState *cpu)
{
g_assert_not_reached();

View File

@ -81,7 +81,7 @@ static void msmouse_chr_accept_input(Chardev *chr)
const uint8_t *buf;
uint32_t size;
buf = fifo8_pop_buf(&mouse->outbuf, MIN(len, avail), &size);
buf = fifo8_pop_bufptr(&mouse->outbuf, MIN(len, avail), &size);
qemu_chr_be_write(chr, buf, size);
len = qemu_chr_be_can_write(chr);
avail -= size;

View File

@ -33,6 +33,7 @@
#include "qemu/uuid.h"
#include "qemu/bitmap.h"
#include "qemu/range.h"
/*
* Reference for the LUKS format implemented here is
@ -572,7 +573,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks,
header_sectors,
slot2->stripes);
if (start1 + len1 > start2 && start2 + len2 > start1) {
if (ranges_overlap(start1, len1, start2, len2)) {
error_setg(errp,
"Keyslots %zu and %zu are overlapping in the header",
i, j);

View File

@ -42,7 +42,7 @@ depending on the guest architecture.
- :ref:`Yes<QEMU-PC-System-emulator>`
- Yes
- The ubiquitous desktop PC CPU architecture, 32 and 64 bit.
* - Loongarch
* - LoongArch
- Yes
- Yes
- A MIPS-like 64bit RISC architecture developed in China

View File

@ -14,8 +14,10 @@
# = Firmware
##
{ 'include' : 'machine.json' }
{ 'include' : 'block-core.json' }
{ 'pragma': {
'member-name-exceptions': [
'FirmwareArchitecture' # x86_64
] } }
##
# @FirmwareOSInterface:
@ -60,6 +62,27 @@
{ 'enum' : 'FirmwareDevice',
'data' : [ 'flash', 'kernel', 'memory' ] }
##
# @FirmwareArchitecture:
#
# Enumeration of architectures for which Qemu uses additional
# firmware files.
#
# @aarch64: 64-bit Arm.
#
# @arm: 32-bit Arm.
#
# @i386: 32-bit x86.
#
# @loongarch64: 64-bit LoongArch. (since: 7.1)
#
# @x86_64: 64-bit x86.
#
# Since: 3.0
##
{ 'enum' : 'FirmwareArchitecture',
'data' : [ 'aarch64', 'arm', 'i386', 'loongarch64', 'x86_64' ] }
##
# @FirmwareTarget:
#
@ -81,7 +104,7 @@
# Since: 3.0
##
{ 'struct' : 'FirmwareTarget',
'data' : { 'architecture' : 'SysEmuTarget',
'data' : { 'architecture' : 'FirmwareArchitecture',
'machines' : [ 'str' ] } }
##
@ -200,6 +223,20 @@
'enrolled-keys', 'requires-smm', 'secure-boot',
'verbose-dynamic', 'verbose-static' ] }
##
# @FirmwareFormat:
#
# Formats that are supported for firmware images.
#
# @raw: Raw disk image format.
#
# @qcow2: The QCOW2 image format.
#
# Since: 3.0
##
{ 'enum': 'FirmwareFormat',
'data': [ 'raw', 'qcow2' ] }
##
# @FirmwareFlashFile:
#
@ -219,7 +256,7 @@
##
{ 'struct' : 'FirmwareFlashFile',
'data' : { 'filename' : 'str',
'format' : 'BlockdevDriver' } }
'format' : 'FirmwareFormat' } }
##
@ -433,7 +470,7 @@
#
# Since: 3.0
#
# Examples:
# .. qmp-example::
#
# {
# "description": "SeaBIOS",

View File

@ -30,6 +30,7 @@
#include "migration/blocker.h"
#include "hw/core/cpu.h"
#include "win_dump.h"
#include "qemu/range.h"
#include <zlib.h>
#ifdef CONFIG_LZO
@ -574,8 +575,10 @@ static void get_offset_range(hwaddr phys_addr,
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
if (dump_has_filter(s)) {
if (block->target_start >= s->filter_area_begin + s->filter_area_length ||
block->target_end <= s->filter_area_begin) {
if (!ranges_overlap(block->target_start,
block->target_end - block->target_start,
s->filter_area_begin,
s->filter_area_length)) {
/* This block is out of the range */
continue;
}
@ -734,8 +737,9 @@ int64_t dump_filtered_memblock_start(GuestPhysBlock *block,
{
if (filter_area_length) {
/* return -1 if the block is not within filter area */
if (block->target_start >= filter_area_start + filter_area_length ||
block->target_end <= filter_area_start) {
if (!ranges_overlap(block->target_start,
block->target_end - block->target_start,
filter_area_start, filter_area_length)) {
return -1;
}

View File

@ -16,6 +16,7 @@
#include "qemu/log.h"
#include "trace.h"
#include "exec/address-spaces.h"
#include "sysemu/dma.h"
#include "hw/char/goldfish_tty.h"
#define GOLDFISH_TTY_VERSION 1
@ -69,7 +70,6 @@ static uint64_t goldfish_tty_read(void *opaque, hwaddr addr,
static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
{
uint32_t to_copy;
uint8_t *buf;
uint8_t data_out[GOLFISH_TTY_BUFFER_SIZE];
int len;
uint64_t ptr;
@ -97,8 +97,8 @@ static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
while (len) {
to_copy = MIN(GOLFISH_TTY_BUFFER_SIZE, len);
address_space_rw(&address_space_memory, ptr,
MEMTXATTRS_UNSPECIFIED, data_out, to_copy, 0);
dma_memory_read_relaxed(&address_space_memory, ptr,
data_out, to_copy);
qemu_chr_fe_write_all(&s->chr, data_out, to_copy);
len -= to_copy;
@ -109,9 +109,9 @@ static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
len = s->data_len;
ptr = s->data_ptr;
while (len && !fifo8_is_empty(&s->rx_fifo)) {
buf = (uint8_t *)fifo8_pop_buf(&s->rx_fifo, len, &to_copy);
address_space_rw(&address_space_memory, ptr,
MEMTXATTRS_UNSPECIFIED, buf, to_copy, 1);
const uint8_t *buf = fifo8_pop_bufptr(&s->rx_fifo, len, &to_copy);
dma_memory_write_relaxed(&address_space_memory, ptr, buf, to_copy);
len -= to_copy;
ptr += to_copy;

View File

@ -1653,8 +1653,8 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
QLIST_FOREACH(ent, poison_list, node) {
/* Check for no overlap */
if (ent->start >= query_start + query_length ||
ent->start + ent->length <= query_start) {
if (!ranges_overlap(ent->start, ent->length,
query_start, query_length)) {
continue;
}
record_count++;
@ -1666,8 +1666,8 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
uint64_t start, stop;
/* Check for no overlap */
if (ent->start >= query_start + query_length ||
ent->start + ent->length <= query_start) {
if (!ranges_overlap(ent->start, ent->length,
query_start, query_length)) {
continue;
}

View File

@ -82,7 +82,7 @@ struct MPCI2CState {
uint8_t cr;
uint8_t sr;
uint8_t dr;
uint8_t dfssr;
uint8_t dfsrr;
};
static bool mpc_i2c_is_enabled(MPCI2CState *s)
@ -293,7 +293,7 @@ static void mpc_i2c_write(void *opaque, hwaddr addr,
}
break;
case MPC_I2C_DFSRR:
s->dfssr = value;
s->dfsrr = value;
break;
default:
DPRINTF("ERROR: Bad write addr 0x%x\n", (unsigned int)addr);
@ -319,7 +319,7 @@ static const VMStateDescription mpc_i2c_vmstate = {
VMSTATE_UINT8(cr, MPCI2CState),
VMSTATE_UINT8(sr, MPCI2CState),
VMSTATE_UINT8(dr, MPCI2CState),
VMSTATE_UINT8(dfssr, MPCI2CState),
VMSTATE_UINT8(dfsrr, MPCI2CState),
VMSTATE_END_OF_LIST()
}
};
@ -329,7 +329,7 @@ static void mpc_i2c_realize(DeviceState *dev, Error **errp)
MPCI2CState *i2c = MPC_I2C(dev);
sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
"mpc-i2c", 0x14);
"mpc-i2c", 0x15);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
i2c->bus = i2c_init_bus(dev, "i2c");
}

View File

@ -2666,13 +2666,43 @@ static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
return true;
}
static void do_invalidate_device_tlb(VTDAddressSpace *vtd_dev_as,
bool size, hwaddr addr)
{
/*
* According to ATS spec table 2.4:
* S = 0, bits 15:12 = xxxx range size: 4K
* S = 1, bits 15:12 = xxx0 range size: 8K
* S = 1, bits 15:12 = xx01 range size: 16K
* S = 1, bits 15:12 = x011 range size: 32K
* S = 1, bits 15:12 = 0111 range size: 64K
* ...
*/
IOMMUTLBEvent event;
uint64_t sz;
if (size) {
sz = (VTD_PAGE_SIZE * 2) << cto64(addr >> VTD_PAGE_SHIFT);
addr &= ~(sz - 1);
} else {
sz = VTD_PAGE_SIZE;
}
event.type = IOMMU_NOTIFIER_DEVIOTLB_UNMAP;
event.entry.target_as = &vtd_dev_as->as;
event.entry.addr_mask = sz - 1;
event.entry.iova = addr;
event.entry.perm = IOMMU_NONE;
event.entry.translated_addr = 0;
memory_region_notify_iommu(&vtd_dev_as->iommu, 0, event);
}
static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
VTDInvDesc *inv_desc)
{
VTDAddressSpace *vtd_dev_as;
IOMMUTLBEvent event;
hwaddr addr;
uint64_t sz;
uint16_t sid;
bool size;
@ -2697,28 +2727,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
goto done;
}
/* According to ATS spec table 2.4:
* S = 0, bits 15:12 = xxxx range size: 4K
* S = 1, bits 15:12 = xxx0 range size: 8K
* S = 1, bits 15:12 = xx01 range size: 16K
* S = 1, bits 15:12 = x011 range size: 32K
* S = 1, bits 15:12 = 0111 range size: 64K
* ...
*/
if (size) {
sz = (VTD_PAGE_SIZE * 2) << cto64(addr >> VTD_PAGE_SHIFT);
addr &= ~(sz - 1);
} else {
sz = VTD_PAGE_SIZE;
}
event.type = IOMMU_NOTIFIER_DEVIOTLB_UNMAP;
event.entry.target_as = &vtd_dev_as->as;
event.entry.addr_mask = sz - 1;
event.entry.iova = addr;
event.entry.perm = IOMMU_NONE;
event.entry.translated_addr = 0;
memory_region_notify_iommu(&vtd_dev_as->iommu, 0, event);
do_invalidate_device_tlb(vtd_dev_as, size, addr);
done:
return true;

View File

@ -14,6 +14,7 @@
#include "qapi/error.h"
#include "qemu/log.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"
#include "migration/vmstate.h"
#ifdef TARGET_LOONGARCH64
#include "target/loongarch/cpu.h"
@ -102,7 +103,7 @@ static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
* if the mask is 0, we need not to do anything.
*/
if ((val >> 27) & 0xf) {
data = address_space_ldl(iocsr_as, addr, attrs, NULL);
data = address_space_ldl_le(iocsr_as, addr, attrs, NULL);
for (i = 0; i < 4; i++) {
/* get mask for byte writing */
if (val & (0x1 << (27 + i))) {
@ -113,7 +114,7 @@ static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
data &= mask;
data |= (val >> 32) & ~mask;
address_space_stl(iocsr_as, addr, data, attrs, NULL);
address_space_stl_le(iocsr_as, addr, data, attrs, NULL);
return MEMTX_OK;
}
@ -317,6 +318,13 @@ static void loongson_ipi_realize(DeviceState *dev, Error **errp)
}
}
static void loongson_ipi_unrealize(DeviceState *dev)
{
LoongsonIPI *s = LOONGSON_IPI(dev);
g_free(s->cpu);
}
static const VMStateDescription vmstate_ipi_core = {
.name = "ipi-single",
.version_id = 2,
@ -352,28 +360,18 @@ static void loongson_ipi_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = loongson_ipi_realize;
dc->unrealize = loongson_ipi_unrealize;
device_class_set_props(dc, ipi_properties);
dc->vmsd = &vmstate_loongson_ipi;
}
static void loongson_ipi_finalize(Object *obj)
{
LoongsonIPI *s = LOONGSON_IPI(obj);
g_free(s->cpu);
}
static const TypeInfo loongson_ipi_info = {
.name = TYPE_LOONGSON_IPI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LoongsonIPI),
.class_init = loongson_ipi_class_init,
.instance_finalize = loongson_ipi_finalize,
static const TypeInfo loongson_ipi_types[] = {
{
.name = TYPE_LOONGSON_IPI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LoongsonIPI),
.class_init = loongson_ipi_class_init,
}
};
static void loongson_ipi_register_types(void)
{
type_register_static(&loongson_ipi_info);
}
type_init(loongson_ipi_register_types)
DEFINE_TYPES(loongson_ipi_types)

View File

@ -355,8 +355,8 @@ static uint64_t load_kernel(CPUMIPSState *env)
kernel_size = load_elf(loaderparams.kernel_filename, NULL,
cpu_mips_kseg0_to_phys, NULL,
(uint64_t *)&kernel_entry,
(uint64_t *)&kernel_low, (uint64_t *)&kernel_high,
&kernel_entry,
&kernel_low, &kernel_high,
NULL, 0, EM_MIPS, 1, 0);
if (kernel_size < 0) {
error_report("could not load kernel '%s': %s",

View File

@ -349,7 +349,7 @@ static void aw_emac_write(void *opaque, hwaddr offset, uint64_t value,
"allwinner_emac: TX length > fifo data length\n");
}
if (len > 0) {
data = fifo8_pop_buf(fifo, len, &ret);
data = fifo8_pop_bufptr(fifo, len, &ret);
qemu_send_packet(nc, data, ret);
aw_emac_tx_reset(s, chan);
/* Raise TX interrupt */

View File

@ -7,6 +7,7 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/nubus/nubus-virtio-mmio.h"
@ -23,6 +24,7 @@ static void nubus_virtio_mmio_set_input_irq(void *opaque, int n, int level)
static void nubus_virtio_mmio_realize(DeviceState *dev, Error **errp)
{
ERRP_GUARD();
NubusVirtioMMIODeviceClass *nvmdc = NUBUS_VIRTIO_MMIO_GET_CLASS(dev);
NubusVirtioMMIO *s = NUBUS_VIRTIO_MMIO(dev);
NubusDevice *nd = NUBUS_DEVICE(dev);

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Loongarch LS7A Real Time Clock emulation
* LoongArch LS7A Real Time Clock emulation
*
* Copyright (C) 2021 Loongson Technology Corporation Limited
*/

View File

@ -197,39 +197,9 @@ static uint8_t esp_fifo_pop(ESPState *s)
return val;
}
static uint32_t esp_fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
{
const uint8_t *buf;
uint32_t n, n2;
int len;
if (maxlen == 0) {
return 0;
}
len = maxlen;
buf = fifo8_pop_buf(fifo, len, &n);
if (dest) {
memcpy(dest, buf, n);
}
/* Add FIFO wraparound if needed */
len -= n;
len = MIN(len, fifo8_num_used(fifo));
if (len) {
buf = fifo8_pop_buf(fifo, len, &n2);
if (dest) {
memcpy(&dest[n], buf, n2);
}
n += n2;
}
return n;
}
static uint32_t esp_fifo_pop_buf(ESPState *s, uint8_t *dest, int maxlen)
{
uint32_t len = esp_fifo8_pop_buf(&s->fifo, dest, maxlen);
uint32_t len = fifo8_pop_buf(&s->fifo, dest, maxlen);
esp_update_drq(s);
return len;
@ -335,7 +305,7 @@ static void do_command_phase(ESPState *s)
if (!cmdlen || !s->current_dev) {
return;
}
esp_fifo8_pop_buf(&s->cmdfifo, buf, cmdlen);
fifo8_pop_buf(&s->cmdfifo, buf, cmdlen);
current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, s->lun);
if (!current_lun) {
@ -381,7 +351,7 @@ static void do_message_phase(ESPState *s)
/* Ignore extended messages for now */
if (s->cmdfifo_cdb_offset) {
int len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(&s->cmdfifo));
esp_fifo8_pop_buf(&s->cmdfifo, NULL, len);
fifo8_drop(&s->cmdfifo, len);
s->cmdfifo_cdb_offset = 0;
}
}
@ -486,7 +456,7 @@ static bool esp_cdb_ready(ESPState *s)
return false;
}
pbuf = fifo8_peek_buf(&s->cmdfifo, len, &n);
pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
if (n < len) {
/*
* In normal use the cmdfifo should never wrap, but include this check

View File

@ -228,6 +228,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
* is thread-safe.
*
* Returns: the number of bytes consumed (0 if no associated Chardev)
* or -1 on error.
*/
int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
@ -242,6 +243,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
* attempted to be written. This function is thread-safe.
*
* Returns: the number of bytes consumed (0 if no associated Chardev)
* or -1 on error.
*/
int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
@ -253,6 +255,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
* Read data to a buffer from the back end.
*
* Returns: the number of bytes read (0 if no associated Chardev)
* or -1 on error.
*/
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);

View File

@ -301,6 +301,9 @@ static inline void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
{
}
#endif
#if defined(CONFIG_TCG)
/**
* probe_access:
* @env: CPUArchState
@ -357,6 +360,7 @@ int probe_access_flags(CPUArchState *env, vaddr addr, int size,
bool nonfault, void **phost, uintptr_t retaddr);
#ifndef CONFIG_USER_ONLY
/**
* probe_access_full:
* Like probe_access_flags, except also return into @pfull.
@ -392,7 +396,8 @@ int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size,
MMUAccessType access_type, int mmu_idx,
void **phost, CPUTLBEntryFull **pfull);
#endif
#endif /* !CONFIG_USER_ONLY */
#endif /* CONFIG_TCG */
static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
{

View File

@ -15,10 +15,9 @@ typedef struct {
* @fifo: struct Fifo8 to initialise with new FIFO
* @capacity: capacity of the newly created FIFO
*
* Create a FIFO of the specified size. Clients should call fifo8_destroy()
* Create a FIFO of the specified capacity. Clients should call fifo8_destroy()
* when finished using the fifo. The FIFO is initially empty.
*/
void fifo8_create(Fifo8 *fifo, uint32_t capacity);
/**
@ -26,9 +25,8 @@ void fifo8_create(Fifo8 *fifo, uint32_t capacity);
* @fifo: FIFO to cleanup
*
* Cleanup a FIFO created with fifo8_create(). Frees memory created for FIFO
*storage. The FIFO is no longer usable after this has been called.
* storage. The FIFO is no longer usable after this has been called.
*/
void fifo8_destroy(Fifo8 *fifo);
/**
@ -39,7 +37,6 @@ void fifo8_destroy(Fifo8 *fifo);
* Push a data byte to the FIFO. Behaviour is undefined if the FIFO is full.
* Clients are responsible for checking for fullness using fifo8_is_full().
*/
void fifo8_push(Fifo8 *fifo, uint8_t data);
/**
@ -52,7 +49,6 @@ void fifo8_push(Fifo8 *fifo, uint8_t data);
* Clients are responsible for checking the space left in the FIFO using
* fifo8_num_free().
*/
void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num);
/**
@ -64,25 +60,40 @@ void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num);
*
* Returns: The popped data byte.
*/
uint8_t fifo8_pop(Fifo8 *fifo);
/**
* fifo8_pop_buf:
* @fifo: FIFO to pop from
* @dest: the buffer to write the data into (can be NULL)
* @destlen: size of @dest and maximum number of bytes to pop
*
* Pop a number of elements from the FIFO up to a maximum of @destlen.
* The popped data is copied into the @dest buffer.
* Care is taken when the data wraps around in the ring buffer.
*
* Returns: number of bytes popped.
*/
uint32_t fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen);
/**
* fifo8_pop_bufptr:
* @fifo: FIFO to pop from
* @max: maximum number of bytes to pop
* @numptr: pointer filled with number of bytes returned (can be NULL)
*
* Pop a number of elements from the FIFO up to a maximum of max. The buffer
* New code should prefer to use fifo8_pop_buf() instead of fifo8_pop_bufptr().
*
* Pop a number of elements from the FIFO up to a maximum of @max. The buffer
* containing the popped data is returned. This buffer points directly into
* the FIFO backing store and data is invalidated once any of the fifo8_* APIs
* are called on the FIFO.
* the internal FIFO backing store and data (without checking for overflow!)
* and is invalidated once any of the fifo8_* APIs are called on the FIFO.
*
* The function may return fewer bytes than requested when the data wraps
* around in the ring buffer; in this case only a contiguous part of the data
* is returned.
*
* The number of valid bytes returned is populated in *numptr; will always
* The number of valid bytes returned is populated in *@numptr; will always
* return at least 1 byte. max must not be 0 or greater than the number of
* bytes in the FIFO.
*
@ -91,15 +102,15 @@ uint8_t fifo8_pop(Fifo8 *fifo);
*
* Returns: A pointer to popped data.
*/
const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
const uint8_t *fifo8_pop_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
/**
* fifo8_peek_buf: read upto max bytes from the fifo
* fifo8_peek_bufptr: read upto max bytes from the fifo
* @fifo: FIFO to read from
* @max: maximum number of bytes to peek
* @numptr: pointer filled with number of bytes returned (can be NULL)
*
* Peek into a number of elements from the FIFO up to a maximum of max.
* Peek into a number of elements from the FIFO up to a maximum of @max.
* The buffer containing the data peeked into is returned. This buffer points
* directly into the FIFO backing store. Since data is invalidated once any
* of the fifo8_* APIs are called on the FIFO, it is the caller responsibility
@ -109,7 +120,7 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
* around in the ring buffer; in this case only a contiguous part of the data
* is returned.
*
* The number of valid bytes returned is populated in *numptr; will always
* The number of valid bytes returned is populated in *@numptr; will always
* return at least 1 byte. max must not be 0 or greater than the number of
* bytes in the FIFO.
*
@ -118,7 +129,16 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
*
* Returns: A pointer to peekable data.
*/
const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
const uint8_t *fifo8_peek_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
/**
* fifo8_drop:
* @fifo: FIFO to drop bytes
* @len: number of bytes to drop
*
* Drop (consume) bytes from a FIFO.
*/
void fifo8_drop(Fifo8 *fifo, uint32_t len);
/**
* fifo8_reset:
@ -126,7 +146,6 @@ const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
*
* Reset a FIFO. All data is discarded and the FIFO is emptied.
*/
void fifo8_reset(Fifo8 *fifo);
/**
@ -137,7 +156,6 @@ void fifo8_reset(Fifo8 *fifo);
*
* Returns: True if the fifo is empty, false otherwise.
*/
bool fifo8_is_empty(Fifo8 *fifo);
/**
@ -148,7 +166,6 @@ bool fifo8_is_empty(Fifo8 *fifo);
*
* Returns: True if the fifo is full, false otherwise.
*/
bool fifo8_is_full(Fifo8 *fifo);
/**
@ -159,7 +176,6 @@ bool fifo8_is_full(Fifo8 *fifo);
*
* Returns: Number of free bytes.
*/
uint32_t fifo8_num_free(Fifo8 *fifo);
/**
@ -170,7 +186,6 @@ uint32_t fifo8_num_free(Fifo8 *fifo);
*
* Returns: Number of used bytes.
*/
uint32_t fifo8_num_used(Fifo8 *fifo);
extern const VMStateDescription vmstate_fifo8;

View File

@ -210,8 +210,8 @@ static inline int range_covers_byte(uint64_t offset, uint64_t len,
/* Check whether 2 given ranges overlap.
* Undefined if ranges that wrap around 0. */
static inline int ranges_overlap(uint64_t first1, uint64_t len1,
uint64_t first2, uint64_t len2)
static inline bool ranges_overlap(uint64_t first1, uint64_t len1,
uint64_t first2, uint64_t len2)
{
uint64_t last1 = range_get_last(first1, len1);
uint64_t last2 = range_get_last(first2, len2);

View File

@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/range.h"
#include "qapi/error.h"
#include "sysemu/memory_mapping.h"
@ -353,8 +354,7 @@ void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
MemoryMapping *cur, *next;
QTAILQ_FOREACH_SAFE(cur, &list->head, next, next) {
if (cur->phys_addr >= begin + length ||
cur->phys_addr + cur->length <= begin) {
if (!ranges_overlap(cur->phys_addr, cur->length, begin, length)) {
QTAILQ_REMOVE(&list->head, cur, next);
g_free(cur);
list->num--;

View File

@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/range.h"
#include "cpu.h"
#include "tcg/tcg.h"
#include "exec/helper-proto.h"
@ -240,9 +241,7 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
if (new_ctx == ctx) {
uint64_t vaddr = tlb[i].tag & ~0x1fffULL;
uint64_t size = 8192ULL << 3 * TTE_PGSIZE(tlb[i].tte);
if (new_vaddr == vaddr
|| (new_vaddr < vaddr + size
&& vaddr < new_vaddr + new_size)) {
if (ranges_overlap(new_vaddr, new_size, vaddr, size)) {
DPRINTF_MMU("auto demap entry [%d] %lx->%lx\n", i, vaddr,
new_vaddr);
replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);

View File

@ -287,7 +287,7 @@ static void kbd_send_chars(QemuTextConsole *s)
const uint8_t *buf;
uint32_t size;
buf = fifo8_pop_buf(&s->out_fifo, MIN(len, avail), &size);
buf = fifo8_pop_bufptr(&s->out_fifo, MIN(len, avail), &size);
qemu_chr_be_write(s->chr, buf, size);
len = qemu_chr_be_can_write(s->chr);
avail -= size;

View File

@ -1820,7 +1820,7 @@ static void gd_vc_send_chars(VirtualConsole *vc)
const uint8_t *buf;
uint32_t size;
buf = fifo8_pop_buf(&vc->vte.out_fifo, MIN(len, avail), &size);
buf = fifo8_pop_bufptr(&vc->vte.out_fifo, MIN(len, avail), &size);
qemu_chr_be_write(vc->vte.chr, buf, size);
len = qemu_chr_be_can_write(vc->vte.chr);
avail -= size;

View File

@ -16,12 +16,17 @@
#include "migration/vmstate.h"
#include "qemu/fifo8.h"
void fifo8_reset(Fifo8 *fifo)
{
fifo->num = 0;
fifo->head = 0;
}
void fifo8_create(Fifo8 *fifo, uint32_t capacity)
{
fifo->data = g_new(uint8_t, capacity);
fifo->capacity = capacity;
fifo->head = 0;
fifo->num = 0;
fifo8_reset(fifo);
}
void fifo8_destroy(Fifo8 *fifo)
@ -87,20 +92,49 @@ static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max,
return ret;
}
const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
const uint8_t *fifo8_peek_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
{
return fifo8_peekpop_buf(fifo, max, numptr, false);
}
const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
const uint8_t *fifo8_pop_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
{
return fifo8_peekpop_buf(fifo, max, numptr, true);
}
void fifo8_reset(Fifo8 *fifo)
uint32_t fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen)
{
fifo->num = 0;
fifo->head = 0;
const uint8_t *buf;
uint32_t n1, n2 = 0;
uint32_t len;
if (destlen == 0) {
return 0;
}
len = destlen;
buf = fifo8_pop_bufptr(fifo, len, &n1);
if (dest) {
memcpy(dest, buf, n1);
}
/* Add FIFO wraparound if needed */
len -= n1;
len = MIN(len, fifo8_num_used(fifo));
if (len) {
buf = fifo8_pop_bufptr(fifo, len, &n2);
if (dest) {
memcpy(&dest[n1], buf, n2);
}
}
return n1 + n2;
}
void fifo8_drop(Fifo8 *fifo, uint32_t len)
{
len -= fifo8_pop_buf(fifo, NULL, len);
assert(len == 0);
}
bool fifo8_is_empty(Fifo8 *fifo)