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>
|
||||
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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
12
dump/dump.c
12
dump/dump.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
2
ui/gtk.c
2
ui/gtk.c
|
@ -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;
|
||||
|
|
48
util/fifo8.c
48
util/fifo8.c
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue