mirror of https://github.com/xemu-project/xemu.git
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:
commit
6410f877f5
|
@ -1879,6 +1879,7 @@ M: Eduardo Habkost <eduardo@habkost.net>
|
||||||
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
|
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
|
||||||
R: Philippe Mathieu-Daudé <philmd@linaro.org>
|
R: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||||
R: Yanan Wang <wangyanan55@huawei.com>
|
R: Yanan Wang <wangyanan55@huawei.com>
|
||||||
|
R: Zhao Liu <zhao1.liu@intel.com>
|
||||||
S: Supported
|
S: Supported
|
||||||
F: hw/core/cpu-common.c
|
F: hw/core/cpu-common.c
|
||||||
F: hw/core/cpu-sysemu.c
|
F: hw/core/cpu-sysemu.c
|
||||||
|
@ -3221,6 +3222,7 @@ M: Eric Blake <eblake@redhat.com>
|
||||||
M: Markus Armbruster <armbru@redhat.com>
|
M: Markus Armbruster <armbru@redhat.com>
|
||||||
S: Supported
|
S: Supported
|
||||||
F: qapi/*.json
|
F: qapi/*.json
|
||||||
|
F: qga/qapi-schema.json
|
||||||
T: git https://repo.or.cz/qemu/armbru.git qapi-next
|
T: git https://repo.or.cz/qemu/armbru.git qapi-next
|
||||||
|
|
||||||
QObject
|
QObject
|
||||||
|
|
|
@ -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_NORETURN void cpu_loop_exit(CPUState *cpu)
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
|
@ -81,7 +81,7 @@ static void msmouse_chr_accept_input(Chardev *chr)
|
||||||
const uint8_t *buf;
|
const uint8_t *buf;
|
||||||
uint32_t size;
|
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);
|
qemu_chr_be_write(chr, buf, size);
|
||||||
len = qemu_chr_be_can_write(chr);
|
len = qemu_chr_be_can_write(chr);
|
||||||
avail -= size;
|
avail -= size;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "qemu/uuid.h"
|
#include "qemu/uuid.h"
|
||||||
|
|
||||||
#include "qemu/bitmap.h"
|
#include "qemu/bitmap.h"
|
||||||
|
#include "qemu/range.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reference for the LUKS format implemented here is
|
* Reference for the LUKS format implemented here is
|
||||||
|
@ -572,7 +573,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks,
|
||||||
header_sectors,
|
header_sectors,
|
||||||
slot2->stripes);
|
slot2->stripes);
|
||||||
|
|
||||||
if (start1 + len1 > start2 && start2 + len2 > start1) {
|
if (ranges_overlap(start1, len1, start2, len2)) {
|
||||||
error_setg(errp,
|
error_setg(errp,
|
||||||
"Keyslots %zu and %zu are overlapping in the header",
|
"Keyslots %zu and %zu are overlapping in the header",
|
||||||
i, j);
|
i, j);
|
||||||
|
|
|
@ -42,7 +42,7 @@ depending on the guest architecture.
|
||||||
- :ref:`Yes<QEMU-PC-System-emulator>`
|
- :ref:`Yes<QEMU-PC-System-emulator>`
|
||||||
- Yes
|
- Yes
|
||||||
- The ubiquitous desktop PC CPU architecture, 32 and 64 bit.
|
- The ubiquitous desktop PC CPU architecture, 32 and 64 bit.
|
||||||
* - Loongarch
|
* - LoongArch
|
||||||
- Yes
|
- Yes
|
||||||
- Yes
|
- Yes
|
||||||
- A MIPS-like 64bit RISC architecture developed in China
|
- A MIPS-like 64bit RISC architecture developed in China
|
||||||
|
|
|
@ -14,8 +14,10 @@
|
||||||
# = Firmware
|
# = Firmware
|
||||||
##
|
##
|
||||||
|
|
||||||
{ 'include' : 'machine.json' }
|
{ 'pragma': {
|
||||||
{ 'include' : 'block-core.json' }
|
'member-name-exceptions': [
|
||||||
|
'FirmwareArchitecture' # x86_64
|
||||||
|
] } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @FirmwareOSInterface:
|
# @FirmwareOSInterface:
|
||||||
|
@ -60,6 +62,27 @@
|
||||||
{ 'enum' : 'FirmwareDevice',
|
{ 'enum' : 'FirmwareDevice',
|
||||||
'data' : [ 'flash', 'kernel', 'memory' ] }
|
'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:
|
# @FirmwareTarget:
|
||||||
#
|
#
|
||||||
|
@ -81,7 +104,7 @@
|
||||||
# Since: 3.0
|
# Since: 3.0
|
||||||
##
|
##
|
||||||
{ 'struct' : 'FirmwareTarget',
|
{ 'struct' : 'FirmwareTarget',
|
||||||
'data' : { 'architecture' : 'SysEmuTarget',
|
'data' : { 'architecture' : 'FirmwareArchitecture',
|
||||||
'machines' : [ 'str' ] } }
|
'machines' : [ 'str' ] } }
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -200,6 +223,20 @@
|
||||||
'enrolled-keys', 'requires-smm', 'secure-boot',
|
'enrolled-keys', 'requires-smm', 'secure-boot',
|
||||||
'verbose-dynamic', 'verbose-static' ] }
|
'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:
|
# @FirmwareFlashFile:
|
||||||
#
|
#
|
||||||
|
@ -219,7 +256,7 @@
|
||||||
##
|
##
|
||||||
{ 'struct' : 'FirmwareFlashFile',
|
{ 'struct' : 'FirmwareFlashFile',
|
||||||
'data' : { 'filename' : 'str',
|
'data' : { 'filename' : 'str',
|
||||||
'format' : 'BlockdevDriver' } }
|
'format' : 'FirmwareFormat' } }
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -433,7 +470,7 @@
|
||||||
#
|
#
|
||||||
# Since: 3.0
|
# Since: 3.0
|
||||||
#
|
#
|
||||||
# Examples:
|
# .. qmp-example::
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# "description": "SeaBIOS",
|
# "description": "SeaBIOS",
|
||||||
|
|
12
dump/dump.c
12
dump/dump.c
|
@ -30,6 +30,7 @@
|
||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "win_dump.h"
|
#include "win_dump.h"
|
||||||
|
#include "qemu/range.h"
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#ifdef CONFIG_LZO
|
#ifdef CONFIG_LZO
|
||||||
|
@ -574,8 +575,10 @@ static void get_offset_range(hwaddr phys_addr,
|
||||||
|
|
||||||
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
||||||
if (dump_has_filter(s)) {
|
if (dump_has_filter(s)) {
|
||||||
if (block->target_start >= s->filter_area_begin + s->filter_area_length ||
|
if (!ranges_overlap(block->target_start,
|
||||||
block->target_end <= s->filter_area_begin) {
|
block->target_end - block->target_start,
|
||||||
|
s->filter_area_begin,
|
||||||
|
s->filter_area_length)) {
|
||||||
/* This block is out of the range */
|
/* This block is out of the range */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -734,8 +737,9 @@ int64_t dump_filtered_memblock_start(GuestPhysBlock *block,
|
||||||
{
|
{
|
||||||
if (filter_area_length) {
|
if (filter_area_length) {
|
||||||
/* return -1 if the block is not within filter area */
|
/* return -1 if the block is not within filter area */
|
||||||
if (block->target_start >= filter_area_start + filter_area_length ||
|
if (!ranges_overlap(block->target_start,
|
||||||
block->target_end <= filter_area_start) {
|
block->target_end - block->target_start,
|
||||||
|
filter_area_start, filter_area_length)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "sysemu/dma.h"
|
||||||
#include "hw/char/goldfish_tty.h"
|
#include "hw/char/goldfish_tty.h"
|
||||||
|
|
||||||
#define GOLDFISH_TTY_VERSION 1
|
#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)
|
static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
|
||||||
{
|
{
|
||||||
uint32_t to_copy;
|
uint32_t to_copy;
|
||||||
uint8_t *buf;
|
|
||||||
uint8_t data_out[GOLFISH_TTY_BUFFER_SIZE];
|
uint8_t data_out[GOLFISH_TTY_BUFFER_SIZE];
|
||||||
int len;
|
int len;
|
||||||
uint64_t ptr;
|
uint64_t ptr;
|
||||||
|
@ -97,8 +97,8 @@ static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
|
||||||
while (len) {
|
while (len) {
|
||||||
to_copy = MIN(GOLFISH_TTY_BUFFER_SIZE, len);
|
to_copy = MIN(GOLFISH_TTY_BUFFER_SIZE, len);
|
||||||
|
|
||||||
address_space_rw(&address_space_memory, ptr,
|
dma_memory_read_relaxed(&address_space_memory, ptr,
|
||||||
MEMTXATTRS_UNSPECIFIED, data_out, to_copy, 0);
|
data_out, to_copy);
|
||||||
qemu_chr_fe_write_all(&s->chr, data_out, to_copy);
|
qemu_chr_fe_write_all(&s->chr, data_out, to_copy);
|
||||||
|
|
||||||
len -= to_copy;
|
len -= to_copy;
|
||||||
|
@ -109,9 +109,9 @@ static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
|
||||||
len = s->data_len;
|
len = s->data_len;
|
||||||
ptr = s->data_ptr;
|
ptr = s->data_ptr;
|
||||||
while (len && !fifo8_is_empty(&s->rx_fifo)) {
|
while (len && !fifo8_is_empty(&s->rx_fifo)) {
|
||||||
buf = (uint8_t *)fifo8_pop_buf(&s->rx_fifo, len, &to_copy);
|
const uint8_t *buf = fifo8_pop_bufptr(&s->rx_fifo, len, &to_copy);
|
||||||
address_space_rw(&address_space_memory, ptr,
|
|
||||||
MEMTXATTRS_UNSPECIFIED, buf, to_copy, 1);
|
dma_memory_write_relaxed(&address_space_memory, ptr, buf, to_copy);
|
||||||
|
|
||||||
len -= to_copy;
|
len -= to_copy;
|
||||||
ptr += to_copy;
|
ptr += to_copy;
|
||||||
|
|
|
@ -1653,8 +1653,8 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
|
||||||
|
|
||||||
QLIST_FOREACH(ent, poison_list, node) {
|
QLIST_FOREACH(ent, poison_list, node) {
|
||||||
/* Check for no overlap */
|
/* Check for no overlap */
|
||||||
if (ent->start >= query_start + query_length ||
|
if (!ranges_overlap(ent->start, ent->length,
|
||||||
ent->start + ent->length <= query_start) {
|
query_start, query_length)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
record_count++;
|
record_count++;
|
||||||
|
@ -1666,8 +1666,8 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
|
||||||
uint64_t start, stop;
|
uint64_t start, stop;
|
||||||
|
|
||||||
/* Check for no overlap */
|
/* Check for no overlap */
|
||||||
if (ent->start >= query_start + query_length ||
|
if (!ranges_overlap(ent->start, ent->length,
|
||||||
ent->start + ent->length <= query_start) {
|
query_start, query_length)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct MPCI2CState {
|
||||||
uint8_t cr;
|
uint8_t cr;
|
||||||
uint8_t sr;
|
uint8_t sr;
|
||||||
uint8_t dr;
|
uint8_t dr;
|
||||||
uint8_t dfssr;
|
uint8_t dfsrr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool mpc_i2c_is_enabled(MPCI2CState *s)
|
static bool mpc_i2c_is_enabled(MPCI2CState *s)
|
||||||
|
@ -293,7 +293,7 @@ static void mpc_i2c_write(void *opaque, hwaddr addr,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MPC_I2C_DFSRR:
|
case MPC_I2C_DFSRR:
|
||||||
s->dfssr = value;
|
s->dfsrr = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF("ERROR: Bad write addr 0x%x\n", (unsigned int)addr);
|
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(cr, MPCI2CState),
|
||||||
VMSTATE_UINT8(sr, MPCI2CState),
|
VMSTATE_UINT8(sr, MPCI2CState),
|
||||||
VMSTATE_UINT8(dr, MPCI2CState),
|
VMSTATE_UINT8(dr, MPCI2CState),
|
||||||
VMSTATE_UINT8(dfssr, MPCI2CState),
|
VMSTATE_UINT8(dfsrr, MPCI2CState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -329,7 +329,7 @@ static void mpc_i2c_realize(DeviceState *dev, Error **errp)
|
||||||
MPCI2CState *i2c = MPC_I2C(dev);
|
MPCI2CState *i2c = MPC_I2C(dev);
|
||||||
sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
|
sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
|
||||||
memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
|
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);
|
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
|
||||||
i2c->bus = i2c_init_bus(dev, "i2c");
|
i2c->bus = i2c_init_bus(dev, "i2c");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2666,13 +2666,43 @@ static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
|
||||||
return true;
|
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,
|
static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
|
||||||
VTDInvDesc *inv_desc)
|
VTDInvDesc *inv_desc)
|
||||||
{
|
{
|
||||||
VTDAddressSpace *vtd_dev_as;
|
VTDAddressSpace *vtd_dev_as;
|
||||||
IOMMUTLBEvent event;
|
|
||||||
hwaddr addr;
|
hwaddr addr;
|
||||||
uint64_t sz;
|
|
||||||
uint16_t sid;
|
uint16_t sid;
|
||||||
bool size;
|
bool size;
|
||||||
|
|
||||||
|
@ -2697,28 +2727,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* According to ATS spec table 2.4:
|
do_invalidate_device_tlb(vtd_dev_as, size, addr);
|
||||||
* 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);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "exec/memory.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#ifdef TARGET_LOONGARCH64
|
#ifdef TARGET_LOONGARCH64
|
||||||
#include "target/loongarch/cpu.h"
|
#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 the mask is 0, we need not to do anything.
|
||||||
*/
|
*/
|
||||||
if ((val >> 27) & 0xf) {
|
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++) {
|
for (i = 0; i < 4; i++) {
|
||||||
/* get mask for byte writing */
|
/* get mask for byte writing */
|
||||||
if (val & (0x1 << (27 + i))) {
|
if (val & (0x1 << (27 + i))) {
|
||||||
|
@ -113,7 +114,7 @@ static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
|
||||||
|
|
||||||
data &= mask;
|
data &= mask;
|
||||||
data |= (val >> 32) & ~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;
|
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 = {
|
static const VMStateDescription vmstate_ipi_core = {
|
||||||
.name = "ipi-single",
|
.name = "ipi-single",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
|
@ -352,28 +360,18 @@ static void loongson_ipi_class_init(ObjectClass *klass, void *data)
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
dc->realize = loongson_ipi_realize;
|
dc->realize = loongson_ipi_realize;
|
||||||
|
dc->unrealize = loongson_ipi_unrealize;
|
||||||
device_class_set_props(dc, ipi_properties);
|
device_class_set_props(dc, ipi_properties);
|
||||||
dc->vmsd = &vmstate_loongson_ipi;
|
dc->vmsd = &vmstate_loongson_ipi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loongson_ipi_finalize(Object *obj)
|
static const TypeInfo loongson_ipi_types[] = {
|
||||||
{
|
{
|
||||||
LoongsonIPI *s = LOONGSON_IPI(obj);
|
.name = TYPE_LOONGSON_IPI,
|
||||||
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
g_free(s->cpu);
|
.instance_size = sizeof(LoongsonIPI),
|
||||||
}
|
.class_init = loongson_ipi_class_init,
|
||||||
|
}
|
||||||
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 void loongson_ipi_register_types(void)
|
DEFINE_TYPES(loongson_ipi_types)
|
||||||
{
|
|
||||||
type_register_static(&loongson_ipi_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
type_init(loongson_ipi_register_types)
|
|
||||||
|
|
|
@ -355,8 +355,8 @@ static uint64_t load_kernel(CPUMIPSState *env)
|
||||||
|
|
||||||
kernel_size = load_elf(loaderparams.kernel_filename, NULL,
|
kernel_size = load_elf(loaderparams.kernel_filename, NULL,
|
||||||
cpu_mips_kseg0_to_phys, NULL,
|
cpu_mips_kseg0_to_phys, NULL,
|
||||||
(uint64_t *)&kernel_entry,
|
&kernel_entry,
|
||||||
(uint64_t *)&kernel_low, (uint64_t *)&kernel_high,
|
&kernel_low, &kernel_high,
|
||||||
NULL, 0, EM_MIPS, 1, 0);
|
NULL, 0, EM_MIPS, 1, 0);
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
error_report("could not load kernel '%s': %s",
|
error_report("could not load kernel '%s': %s",
|
||||||
|
|
|
@ -349,7 +349,7 @@ static void aw_emac_write(void *opaque, hwaddr offset, uint64_t value,
|
||||||
"allwinner_emac: TX length > fifo data length\n");
|
"allwinner_emac: TX length > fifo data length\n");
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
data = fifo8_pop_buf(fifo, len, &ret);
|
data = fifo8_pop_bufptr(fifo, len, &ret);
|
||||||
qemu_send_packet(nc, data, ret);
|
qemu_send_packet(nc, data, ret);
|
||||||
aw_emac_tx_reset(s, chan);
|
aw_emac_tx_reset(s, chan);
|
||||||
/* Raise TX interrupt */
|
/* Raise TX interrupt */
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "hw/nubus/nubus-virtio-mmio.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)
|
static void nubus_virtio_mmio_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
NubusVirtioMMIODeviceClass *nvmdc = NUBUS_VIRTIO_MMIO_GET_CLASS(dev);
|
NubusVirtioMMIODeviceClass *nvmdc = NUBUS_VIRTIO_MMIO_GET_CLASS(dev);
|
||||||
NubusVirtioMMIO *s = NUBUS_VIRTIO_MMIO(dev);
|
NubusVirtioMMIO *s = NUBUS_VIRTIO_MMIO(dev);
|
||||||
NubusDevice *nd = NUBUS_DEVICE(dev);
|
NubusDevice *nd = NUBUS_DEVICE(dev);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* 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
|
* Copyright (C) 2021 Loongson Technology Corporation Limited
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -197,39 +197,9 @@ static uint8_t esp_fifo_pop(ESPState *s)
|
||||||
return val;
|
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)
|
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);
|
esp_update_drq(s);
|
||||||
return len;
|
return len;
|
||||||
|
@ -335,7 +305,7 @@ static void do_command_phase(ESPState *s)
|
||||||
if (!cmdlen || !s->current_dev) {
|
if (!cmdlen || !s->current_dev) {
|
||||||
return;
|
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);
|
current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, s->lun);
|
||||||
if (!current_lun) {
|
if (!current_lun) {
|
||||||
|
@ -381,7 +351,7 @@ static void do_message_phase(ESPState *s)
|
||||||
/* Ignore extended messages for now */
|
/* Ignore extended messages for now */
|
||||||
if (s->cmdfifo_cdb_offset) {
|
if (s->cmdfifo_cdb_offset) {
|
||||||
int len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(&s->cmdfifo));
|
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;
|
s->cmdfifo_cdb_offset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -486,7 +456,7 @@ static bool esp_cdb_ready(ESPState *s)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pbuf = fifo8_peek_buf(&s->cmdfifo, len, &n);
|
pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
|
||||||
if (n < len) {
|
if (n < len) {
|
||||||
/*
|
/*
|
||||||
* In normal use the cmdfifo should never wrap, but include this check
|
* In normal use the cmdfifo should never wrap, but include this check
|
||||||
|
|
|
@ -228,6 +228,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
|
||||||
* is thread-safe.
|
* is thread-safe.
|
||||||
*
|
*
|
||||||
* Returns: the number of bytes consumed (0 if no associated Chardev)
|
* 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);
|
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.
|
* attempted to be written. This function is thread-safe.
|
||||||
*
|
*
|
||||||
* Returns: the number of bytes consumed (0 if no associated Chardev)
|
* 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);
|
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.
|
* Read data to a buffer from the back end.
|
||||||
*
|
*
|
||||||
* Returns: the number of bytes read (0 if no associated Chardev)
|
* 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);
|
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,9 @@ static inline void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_TCG)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* probe_access:
|
* probe_access:
|
||||||
* @env: CPUArchState
|
* @env: CPUArchState
|
||||||
|
@ -357,6 +360,7 @@ int probe_access_flags(CPUArchState *env, vaddr addr, int size,
|
||||||
bool nonfault, void **phost, uintptr_t retaddr);
|
bool nonfault, void **phost, uintptr_t retaddr);
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* probe_access_full:
|
* probe_access_full:
|
||||||
* Like probe_access_flags, except also return into @pfull.
|
* 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,
|
MMUAccessType access_type, int mmu_idx,
|
||||||
void **phost, CPUTLBEntryFull **pfull);
|
void **phost, CPUTLBEntryFull **pfull);
|
||||||
|
|
||||||
#endif
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
#endif /* CONFIG_TCG */
|
||||||
|
|
||||||
static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
|
static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,10 +15,9 @@ typedef struct {
|
||||||
* @fifo: struct Fifo8 to initialise with new FIFO
|
* @fifo: struct Fifo8 to initialise with new FIFO
|
||||||
* @capacity: capacity of the newly created 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.
|
* when finished using the fifo. The FIFO is initially empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void fifo8_create(Fifo8 *fifo, uint32_t capacity);
|
void fifo8_create(Fifo8 *fifo, uint32_t capacity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,9 +25,8 @@ void fifo8_create(Fifo8 *fifo, uint32_t capacity);
|
||||||
* @fifo: FIFO to cleanup
|
* @fifo: FIFO to cleanup
|
||||||
*
|
*
|
||||||
* Cleanup a FIFO created with fifo8_create(). Frees memory created for FIFO
|
* 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);
|
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.
|
* 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().
|
* Clients are responsible for checking for fullness using fifo8_is_full().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void fifo8_push(Fifo8 *fifo, uint8_t data);
|
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
|
* Clients are responsible for checking the space left in the FIFO using
|
||||||
* fifo8_num_free().
|
* fifo8_num_free().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num);
|
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.
|
* Returns: The popped data byte.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t fifo8_pop(Fifo8 *fifo);
|
uint8_t fifo8_pop(Fifo8 *fifo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo8_pop_buf:
|
* fifo8_pop_buf:
|
||||||
* @fifo: FIFO to pop from
|
* @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
|
* @max: maximum number of bytes to pop
|
||||||
* @numptr: pointer filled with number of bytes returned (can be NULL)
|
* @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
|
* 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
|
* the internal FIFO backing store and data (without checking for overflow!)
|
||||||
* are called on the FIFO.
|
* 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
|
* 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
|
* around in the ring buffer; in this case only a contiguous part of the data
|
||||||
* is returned.
|
* 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
|
* return at least 1 byte. max must not be 0 or greater than the number of
|
||||||
* bytes in the FIFO.
|
* bytes in the FIFO.
|
||||||
*
|
*
|
||||||
|
@ -91,15 +102,15 @@ uint8_t fifo8_pop(Fifo8 *fifo);
|
||||||
*
|
*
|
||||||
* Returns: A pointer to popped data.
|
* 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
|
* @fifo: FIFO to read from
|
||||||
* @max: maximum number of bytes to peek
|
* @max: maximum number of bytes to peek
|
||||||
* @numptr: pointer filled with number of bytes returned (can be NULL)
|
* @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
|
* The buffer containing the data peeked into is returned. This buffer points
|
||||||
* directly into the FIFO backing store. Since data is invalidated once any
|
* 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
|
* 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
|
* around in the ring buffer; in this case only a contiguous part of the data
|
||||||
* is returned.
|
* 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
|
* return at least 1 byte. max must not be 0 or greater than the number of
|
||||||
* bytes in the FIFO.
|
* 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.
|
* 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:
|
* 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.
|
* Reset a FIFO. All data is discarded and the FIFO is emptied.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void fifo8_reset(Fifo8 *fifo);
|
void fifo8_reset(Fifo8 *fifo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,7 +156,6 @@ void fifo8_reset(Fifo8 *fifo);
|
||||||
*
|
*
|
||||||
* Returns: True if the fifo is empty, false otherwise.
|
* Returns: True if the fifo is empty, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool fifo8_is_empty(Fifo8 *fifo);
|
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.
|
* Returns: True if the fifo is full, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool fifo8_is_full(Fifo8 *fifo);
|
bool fifo8_is_full(Fifo8 *fifo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,7 +176,6 @@ bool fifo8_is_full(Fifo8 *fifo);
|
||||||
*
|
*
|
||||||
* Returns: Number of free bytes.
|
* Returns: Number of free bytes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32_t fifo8_num_free(Fifo8 *fifo);
|
uint32_t fifo8_num_free(Fifo8 *fifo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,7 +186,6 @@ uint32_t fifo8_num_free(Fifo8 *fifo);
|
||||||
*
|
*
|
||||||
* Returns: Number of used bytes.
|
* Returns: Number of used bytes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32_t fifo8_num_used(Fifo8 *fifo);
|
uint32_t fifo8_num_used(Fifo8 *fifo);
|
||||||
|
|
||||||
extern const VMStateDescription vmstate_fifo8;
|
extern const VMStateDescription vmstate_fifo8;
|
||||||
|
|
|
@ -210,8 +210,8 @@ static inline int range_covers_byte(uint64_t offset, uint64_t len,
|
||||||
|
|
||||||
/* Check whether 2 given ranges overlap.
|
/* Check whether 2 given ranges overlap.
|
||||||
* Undefined if ranges that wrap around 0. */
|
* Undefined if ranges that wrap around 0. */
|
||||||
static inline int ranges_overlap(uint64_t first1, uint64_t len1,
|
static inline bool ranges_overlap(uint64_t first1, uint64_t len1,
|
||||||
uint64_t first2, uint64_t len2)
|
uint64_t first2, uint64_t len2)
|
||||||
{
|
{
|
||||||
uint64_t last1 = range_get_last(first1, len1);
|
uint64_t last1 = range_get_last(first1, len1);
|
||||||
uint64_t last2 = range_get_last(first2, len2);
|
uint64_t last2 = range_get_last(first2, len2);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/range.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#include "sysemu/memory_mapping.h"
|
#include "sysemu/memory_mapping.h"
|
||||||
|
@ -353,8 +354,7 @@ void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
|
||||||
MemoryMapping *cur, *next;
|
MemoryMapping *cur, *next;
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(cur, &list->head, next, next) {
|
QTAILQ_FOREACH_SAFE(cur, &list->head, next, next) {
|
||||||
if (cur->phys_addr >= begin + length ||
|
if (!ranges_overlap(cur->phys_addr, cur->length, begin, length)) {
|
||||||
cur->phys_addr + cur->length <= begin) {
|
|
||||||
QTAILQ_REMOVE(&list->head, cur, next);
|
QTAILQ_REMOVE(&list->head, cur, next);
|
||||||
g_free(cur);
|
g_free(cur);
|
||||||
list->num--;
|
list->num--;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "qemu/range.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
|
@ -240,9 +241,7 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
|
||||||
if (new_ctx == ctx) {
|
if (new_ctx == ctx) {
|
||||||
uint64_t vaddr = tlb[i].tag & ~0x1fffULL;
|
uint64_t vaddr = tlb[i].tag & ~0x1fffULL;
|
||||||
uint64_t size = 8192ULL << 3 * TTE_PGSIZE(tlb[i].tte);
|
uint64_t size = 8192ULL << 3 * TTE_PGSIZE(tlb[i].tte);
|
||||||
if (new_vaddr == vaddr
|
if (ranges_overlap(new_vaddr, new_size, vaddr, size)) {
|
||||||
|| (new_vaddr < vaddr + size
|
|
||||||
&& vaddr < new_vaddr + new_size)) {
|
|
||||||
DPRINTF_MMU("auto demap entry [%d] %lx->%lx\n", i, vaddr,
|
DPRINTF_MMU("auto demap entry [%d] %lx->%lx\n", i, vaddr,
|
||||||
new_vaddr);
|
new_vaddr);
|
||||||
replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
|
replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
|
||||||
|
|
|
@ -287,7 +287,7 @@ static void kbd_send_chars(QemuTextConsole *s)
|
||||||
const uint8_t *buf;
|
const uint8_t *buf;
|
||||||
uint32_t size;
|
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);
|
qemu_chr_be_write(s->chr, buf, size);
|
||||||
len = qemu_chr_be_can_write(s->chr);
|
len = qemu_chr_be_can_write(s->chr);
|
||||||
avail -= size;
|
avail -= size;
|
||||||
|
|
2
ui/gtk.c
2
ui/gtk.c
|
@ -1820,7 +1820,7 @@ static void gd_vc_send_chars(VirtualConsole *vc)
|
||||||
const uint8_t *buf;
|
const uint8_t *buf;
|
||||||
uint32_t size;
|
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);
|
qemu_chr_be_write(vc->vte.chr, buf, size);
|
||||||
len = qemu_chr_be_can_write(vc->vte.chr);
|
len = qemu_chr_be_can_write(vc->vte.chr);
|
||||||
avail -= size;
|
avail -= size;
|
||||||
|
|
48
util/fifo8.c
48
util/fifo8.c
|
@ -16,12 +16,17 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "qemu/fifo8.h"
|
#include "qemu/fifo8.h"
|
||||||
|
|
||||||
|
void fifo8_reset(Fifo8 *fifo)
|
||||||
|
{
|
||||||
|
fifo->num = 0;
|
||||||
|
fifo->head = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void fifo8_create(Fifo8 *fifo, uint32_t capacity)
|
void fifo8_create(Fifo8 *fifo, uint32_t capacity)
|
||||||
{
|
{
|
||||||
fifo->data = g_new(uint8_t, capacity);
|
fifo->data = g_new(uint8_t, capacity);
|
||||||
fifo->capacity = capacity;
|
fifo->capacity = capacity;
|
||||||
fifo->head = 0;
|
fifo8_reset(fifo);
|
||||||
fifo->num = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fifo8_destroy(Fifo8 *fifo)
|
void fifo8_destroy(Fifo8 *fifo)
|
||||||
|
@ -87,20 +92,49 @@ static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max,
|
||||||
return ret;
|
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);
|
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);
|
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;
|
const uint8_t *buf;
|
||||||
fifo->head = 0;
|
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)
|
bool fifo8_is_empty(Fifo8 *fifo)
|
||||||
|
|
Loading…
Reference in New Issue