mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-01 22:42:13 -06:00
target-arm queue:
* Set IL bit for pauth, SVE access, BTI trap syndromes * Handle overflow in calculation of next timer tick * hw/net/can/xlnx-zynqmp: Avoid underflow when popping FIFOs * Various devices: Free array property memory on device finalize * hw/ssi/xilinx_spips: fix an out of bound access * hw/misc, hw/ssi: Fix some URLs for AMD / Xilinx models * hw/dma/xlnx_csu_dma: don't throw guest errors when stopping the SRC DMA -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmVkzLAZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3o79D/0Yh7Q7N4+fc4xdBK5hb1GN 31rBWZ3z0XzBzXrN80g6ig5i+CvTq7+120yx4Kl5bdyAMGdXpryTeNSoa4ewmNtC +c6pqV8IUIHA3axepuHtwjs4wRzWoFz13gy+X/1spfhcrtFpWyRt0f3cc1fElhzX 2K/4H9TD2d5yZBvaKLoJ6GzdK2wtWfucvWQDOUigRF7rvSST3awZ6gkumm+/6EM5 vbIVOqi+0JcnWKJj0i4S1vRUPg0+CuaZN8glXcGkq2BaMfOohpjFGTMY0KsAK1Cv Ow1guxxy2mcLixQ8pX7ii5WHVDCuPqTVcwHUQJqN5Ln6CFEre38jM1ZwgHpWhb8G CoVOu2B96QwPoICD7QomaKCJYHkAczC4KETsTz/Mc+zcU6+cQiv0swc2sDhwBlmT weHQAmZg5dPRl3DQ/8F3llhdYyvOGnUpaaBauJiuH2I5n/qhqbvcgu9G7pGwd2gm lk8LuzjbVEtBu2jFlPCMpvuSuJJciR/3/QdHMGlN6L0ooY6dFL9puW51wFKSh+Kx JqetuUJXVWLTiL9ekLnNPQkuQQwP3WQsIvQO8tjEiuojw1utk/50JPmXg/xHEahx rN8aiLstR4olh1i+CrIee3QR6IwhqZmvEVHROIw0ExJ1L04FCCtPlvJ/G2gD1ta2 oLvqWLlc752+nND72lIJZg== =X700 -----END PGP SIGNATURE----- Merge tag 'pull-target-arm-20231127' of https://git.linaro.org/people/pmaydell/qemu-arm into staging target-arm queue: * Set IL bit for pauth, SVE access, BTI trap syndromes * Handle overflow in calculation of next timer tick * hw/net/can/xlnx-zynqmp: Avoid underflow when popping FIFOs * Various devices: Free array property memory on device finalize * hw/ssi/xilinx_spips: fix an out of bound access * hw/misc, hw/ssi: Fix some URLs for AMD / Xilinx models * hw/dma/xlnx_csu_dma: don't throw guest errors when stopping the SRC DMA # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmVkzLAZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3o79D/0Yh7Q7N4+fc4xdBK5hb1GN # 31rBWZ3z0XzBzXrN80g6ig5i+CvTq7+120yx4Kl5bdyAMGdXpryTeNSoa4ewmNtC # +c6pqV8IUIHA3axepuHtwjs4wRzWoFz13gy+X/1spfhcrtFpWyRt0f3cc1fElhzX # 2K/4H9TD2d5yZBvaKLoJ6GzdK2wtWfucvWQDOUigRF7rvSST3awZ6gkumm+/6EM5 # vbIVOqi+0JcnWKJj0i4S1vRUPg0+CuaZN8glXcGkq2BaMfOohpjFGTMY0KsAK1Cv # Ow1guxxy2mcLixQ8pX7ii5WHVDCuPqTVcwHUQJqN5Ln6CFEre38jM1ZwgHpWhb8G # CoVOu2B96QwPoICD7QomaKCJYHkAczC4KETsTz/Mc+zcU6+cQiv0swc2sDhwBlmT # weHQAmZg5dPRl3DQ/8F3llhdYyvOGnUpaaBauJiuH2I5n/qhqbvcgu9G7pGwd2gm # lk8LuzjbVEtBu2jFlPCMpvuSuJJciR/3/QdHMGlN6L0ooY6dFL9puW51wFKSh+Kx # JqetuUJXVWLTiL9ekLnNPQkuQQwP3WQsIvQO8tjEiuojw1utk/50JPmXg/xHEahx # rN8aiLstR4olh1i+CrIee3QR6IwhqZmvEVHROIw0ExJ1L04FCCtPlvJ/G2gD1ta2 # oLvqWLlc752+nND72lIJZg== # =X700 # -----END PGP SIGNATURE----- # gpg: Signature made Mon 27 Nov 2023 12:06:56 EST # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20231127' of https://git.linaro.org/people/pmaydell/qemu-arm: hw/dma/xlnx_csu_dma: don't throw guest errors when stopping the SRC DMA hw/misc, hw/ssi: Fix some URLs for AMD / Xilinx models hw/ssi/xilinx_spips: fix an out of bound access hw/input/stellaris_gamepad: Free StellarisGamepad::keycodes[] array hw/nvram/xlnx-efuse-ctrl: Free XlnxVersalEFuseCtrl[] "pg0-lock" array hw/nvram/xlnx-efuse: Free XlnxEFuse::ro_bits[] array on finalize() hw/misc/mps2-scc: Free MPS2SCC::oscclk[] array on finalize() hw/virtio: Free VirtIOIOMMUPCI::vdev.reserved_regions[] on finalize() hw/virtio: Add VirtioPCIDeviceTypeInfo::instance_finalize field hw/net/can/xlnx-zynqmp: Avoid underflow while popping RX FIFO hw/net/can/xlnx-zynqmp: Avoid underflow while popping TX FIFOs target/arm: Handle overflow in calculation of next timer tick target/arm: Set IL bit for pauth, SVE access, BTI trap syndromes Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
1376d1c13a
19 changed files with 198 additions and 29 deletions
|
@ -33,13 +33,13 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ref: UG1087 (v1.7) February 8, 2019
|
* Ref: UG1087 (v1.7) February 8, 2019
|
||||||
* https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
|
* https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers
|
||||||
* CSUDMA Module section
|
* CSUDMA Module section
|
||||||
*/
|
*/
|
||||||
REG32(ADDR, 0x0)
|
REG32(ADDR, 0x0)
|
||||||
FIELD(ADDR, ADDR, 2, 30) /* wo */
|
FIELD(ADDR, ADDR, 2, 30) /* wo */
|
||||||
REG32(SIZE, 0x4)
|
REG32(SIZE, 0x4)
|
||||||
FIELD(SIZE, SIZE, 2, 27) /* wo */
|
FIELD(SIZE, SIZE, 2, 27)
|
||||||
FIELD(SIZE, LAST_WORD, 0, 1) /* rw, only exists in SRC */
|
FIELD(SIZE, LAST_WORD, 0, 1) /* rw, only exists in SRC */
|
||||||
REG32(STATUS, 0x8)
|
REG32(STATUS, 0x8)
|
||||||
FIELD(STATUS, DONE_CNT, 13, 3) /* wtc */
|
FIELD(STATUS, DONE_CNT, 13, 3) /* wtc */
|
||||||
|
@ -335,10 +335,14 @@ static uint64_t addr_pre_write(RegisterInfo *reg, uint64_t val)
|
||||||
static uint64_t size_pre_write(RegisterInfo *reg, uint64_t val)
|
static uint64_t size_pre_write(RegisterInfo *reg, uint64_t val)
|
||||||
{
|
{
|
||||||
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
|
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
|
||||||
|
uint64_t size = val & R_SIZE_SIZE_MASK;
|
||||||
|
|
||||||
if (s->regs[R_SIZE] != 0) {
|
if (s->regs[R_SIZE] != 0) {
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
if (size || s->is_dst) {
|
||||||
"%s: Starting DMA while already running.\n", __func__);
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"%s: Starting DMA while already running.\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->is_dst) {
|
if (!s->is_dst) {
|
||||||
|
@ -346,7 +350,7 @@ static uint64_t size_pre_write(RegisterInfo *reg, uint64_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Size is word aligned */
|
/* Size is word aligned */
|
||||||
return val & R_SIZE_SIZE_MASK;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t size_post_read(RegisterInfo *reg, uint64_t val)
|
static uint64_t size_post_read(RegisterInfo *reg, uint64_t val)
|
||||||
|
|
|
@ -63,6 +63,13 @@ static void stellaris_gamepad_realize(DeviceState *dev, Error **errp)
|
||||||
qemu_input_handler_register(dev, &stellaris_gamepad_handler);
|
qemu_input_handler_register(dev, &stellaris_gamepad_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stellaris_gamepad_finalize(Object *obj)
|
||||||
|
{
|
||||||
|
StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
|
||||||
|
|
||||||
|
g_free(s->keycodes);
|
||||||
|
}
|
||||||
|
|
||||||
static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
|
static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
|
||||||
{
|
{
|
||||||
StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
|
StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
|
||||||
|
@ -92,6 +99,7 @@ static const TypeInfo stellaris_gamepad_info[] = {
|
||||||
.name = TYPE_STELLARIS_GAMEPAD,
|
.name = TYPE_STELLARIS_GAMEPAD,
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
.instance_size = sizeof(StellarisGamepad),
|
.instance_size = sizeof(StellarisGamepad),
|
||||||
|
.instance_finalize = stellaris_gamepad_finalize,
|
||||||
.class_init = stellaris_gamepad_class_init,
|
.class_init = stellaris_gamepad_class_init,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -329,6 +329,13 @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
|
||||||
s->oscclk = g_new0(uint32_t, s->num_oscclk);
|
s->oscclk = g_new0(uint32_t, s->num_oscclk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mps2_scc_finalize(Object *obj)
|
||||||
|
{
|
||||||
|
MPS2SCC *s = MPS2_SCC(obj);
|
||||||
|
|
||||||
|
g_free(s->oscclk_reset);
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription mps2_scc_vmstate = {
|
static const VMStateDescription mps2_scc_vmstate = {
|
||||||
.name = "mps2-scc",
|
.name = "mps2-scc",
|
||||||
.version_id = 3,
|
.version_id = 3,
|
||||||
|
@ -385,6 +392,7 @@ static const TypeInfo mps2_scc_info = {
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
.instance_size = sizeof(MPS2SCC),
|
.instance_size = sizeof(MPS2SCC),
|
||||||
.instance_init = mps2_scc_init,
|
.instance_init = mps2_scc_init,
|
||||||
|
.instance_finalize = mps2_scc_finalize,
|
||||||
.class_init = mps2_scc_class_init,
|
.class_init = mps2_scc_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -434,6 +434,52 @@ static bool tx_ready_check(XlnxZynqMPCANState *s)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void read_tx_frame(XlnxZynqMPCANState *s, Fifo32 *fifo, uint32_t *data)
|
||||||
|
{
|
||||||
|
unsigned used = fifo32_num_used(fifo);
|
||||||
|
bool is_txhpb = fifo == &s->txhpb_fifo;
|
||||||
|
|
||||||
|
assert(used > 0);
|
||||||
|
used %= CAN_FRAME_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frame Message Format
|
||||||
|
*
|
||||||
|
* Each frame includes four words (16 bytes). Software must read and write
|
||||||
|
* all four words regardless of the actual number of data bytes and valid
|
||||||
|
* fields in the message.
|
||||||
|
* If software misbehave (not writing all four words), we use the previous
|
||||||
|
* registers content to initialize each missing word.
|
||||||
|
*
|
||||||
|
* If used is 1 then ID, DLC and DATA1 are missing.
|
||||||
|
* if used is 2 then ID and DLC are missing.
|
||||||
|
* if used is 3 then only ID is missing.
|
||||||
|
*/
|
||||||
|
if (used > 0) {
|
||||||
|
data[0] = s->regs[is_txhpb ? R_TXHPB_ID : R_TXFIFO_ID];
|
||||||
|
} else {
|
||||||
|
data[0] = fifo32_pop(fifo);
|
||||||
|
}
|
||||||
|
if (used == 1 || used == 2) {
|
||||||
|
data[1] = s->regs[is_txhpb ? R_TXHPB_DLC : R_TXFIFO_DLC];
|
||||||
|
} else {
|
||||||
|
data[1] = fifo32_pop(fifo);
|
||||||
|
}
|
||||||
|
if (used == 1) {
|
||||||
|
data[2] = s->regs[is_txhpb ? R_TXHPB_DATA1 : R_TXFIFO_DATA1];
|
||||||
|
} else {
|
||||||
|
data[2] = fifo32_pop(fifo);
|
||||||
|
}
|
||||||
|
/* DATA2 triggered the transfer thus is always available */
|
||||||
|
data[3] = fifo32_pop(fifo);
|
||||||
|
|
||||||
|
if (used) {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"%s: Incomplete CAN frame (only %u/%u slots used)\n",
|
||||||
|
TYPE_XLNX_ZYNQMP_CAN, used, CAN_FRAME_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
|
static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
|
||||||
{
|
{
|
||||||
qemu_can_frame frame;
|
qemu_can_frame frame;
|
||||||
|
@ -451,9 +497,7 @@ static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!fifo32_is_empty(fifo)) {
|
while (!fifo32_is_empty(fifo)) {
|
||||||
for (i = 0; i < CAN_FRAME_SIZE; i++) {
|
read_tx_frame(s, fifo, data);
|
||||||
data[i] = fifo32_pop(fifo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
|
if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
|
||||||
/*
|
/*
|
||||||
|
@ -734,14 +778,18 @@ static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val)
|
static uint64_t can_rxfifo_post_read_id(RegisterInfo *reg, uint64_t val)
|
||||||
{
|
{
|
||||||
XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
|
XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
|
||||||
|
unsigned used = fifo32_num_used(&s->rx_fifo);
|
||||||
|
|
||||||
if (!fifo32_is_empty(&s->rx_fifo)) {
|
if (used < CAN_FRAME_SIZE) {
|
||||||
val = fifo32_pop(&s->rx_fifo);
|
|
||||||
} else {
|
|
||||||
ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1);
|
ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1);
|
||||||
|
} else {
|
||||||
|
val = s->regs[R_RXFIFO_ID] = fifo32_pop(&s->rx_fifo);
|
||||||
|
s->regs[R_RXFIFO_DLC] = fifo32_pop(&s->rx_fifo);
|
||||||
|
s->regs[R_RXFIFO_DATA1] = fifo32_pop(&s->rx_fifo);
|
||||||
|
s->regs[R_RXFIFO_DATA2] = fifo32_pop(&s->rx_fifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
can_update_irq(s);
|
can_update_irq(s);
|
||||||
|
@ -902,14 +950,11 @@ static const RegisterAccessInfo can_regs_info[] = {
|
||||||
.post_write = can_tx_post_write,
|
.post_write = can_tx_post_write,
|
||||||
},{ .name = "RXFIFO_ID", .addr = A_RXFIFO_ID,
|
},{ .name = "RXFIFO_ID", .addr = A_RXFIFO_ID,
|
||||||
.ro = 0xffffffff,
|
.ro = 0xffffffff,
|
||||||
.post_read = can_rxfifo_pre_read,
|
.post_read = can_rxfifo_post_read_id,
|
||||||
},{ .name = "RXFIFO_DLC", .addr = A_RXFIFO_DLC,
|
},{ .name = "RXFIFO_DLC", .addr = A_RXFIFO_DLC,
|
||||||
.rsvd = 0xfff0000,
|
.rsvd = 0xfff0000,
|
||||||
.post_read = can_rxfifo_pre_read,
|
|
||||||
},{ .name = "RXFIFO_DATA1", .addr = A_RXFIFO_DATA1,
|
},{ .name = "RXFIFO_DATA1", .addr = A_RXFIFO_DATA1,
|
||||||
.post_read = can_rxfifo_pre_read,
|
|
||||||
},{ .name = "RXFIFO_DATA2", .addr = A_RXFIFO_DATA2,
|
},{ .name = "RXFIFO_DATA2", .addr = A_RXFIFO_DATA2,
|
||||||
.post_read = can_rxfifo_pre_read,
|
|
||||||
},{ .name = "AFR", .addr = A_AFR,
|
},{ .name = "AFR", .addr = A_AFR,
|
||||||
.rsvd = 0xfffffff0,
|
.rsvd = 0xfffffff0,
|
||||||
.post_write = can_filter_enable_post_write,
|
.post_write = can_filter_enable_post_write,
|
||||||
|
|
|
@ -224,6 +224,13 @@ static void efuse_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void efuse_finalize(Object *obj)
|
||||||
|
{
|
||||||
|
XlnxEFuse *s = XLNX_EFUSE(obj);
|
||||||
|
|
||||||
|
g_free(s->ro_bits);
|
||||||
|
}
|
||||||
|
|
||||||
static void efuse_prop_set_drive(Object *obj, Visitor *v, const char *name,
|
static void efuse_prop_set_drive(Object *obj, Visitor *v, const char *name,
|
||||||
void *opaque, Error **errp)
|
void *opaque, Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -280,6 +287,7 @@ static const TypeInfo efuse_info = {
|
||||||
.name = TYPE_XLNX_EFUSE,
|
.name = TYPE_XLNX_EFUSE,
|
||||||
.parent = TYPE_DEVICE,
|
.parent = TYPE_DEVICE,
|
||||||
.instance_size = sizeof(XlnxEFuse),
|
.instance_size = sizeof(XlnxEFuse),
|
||||||
|
.instance_finalize = efuse_finalize,
|
||||||
.class_init = efuse_class_init,
|
.class_init = efuse_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -726,6 +726,13 @@ static void efuse_ctrl_init(Object *obj)
|
||||||
sysbus_init_irq(sbd, &s->irq_efuse_imr);
|
sysbus_init_irq(sbd, &s->irq_efuse_imr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void efuse_ctrl_finalize(Object *obj)
|
||||||
|
{
|
||||||
|
XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(obj);
|
||||||
|
|
||||||
|
g_free(s->extra_pg0_lock_spec);
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_efuse_ctrl = {
|
static const VMStateDescription vmstate_efuse_ctrl = {
|
||||||
.name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
|
.name = TYPE_XLNX_VERSAL_EFUSE_CTRL,
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
|
@ -764,6 +771,7 @@ static const TypeInfo efuse_ctrl_info = {
|
||||||
.instance_size = sizeof(XlnxVersalEFuseCtrl),
|
.instance_size = sizeof(XlnxVersalEFuseCtrl),
|
||||||
.class_init = efuse_ctrl_class_init,
|
.class_init = efuse_ctrl_class_init,
|
||||||
.instance_init = efuse_ctrl_init,
|
.instance_init = efuse_ctrl_init,
|
||||||
|
.instance_finalize = efuse_ctrl_finalize,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void efuse_ctrl_register_types(void)
|
static void efuse_ctrl_register_types(void)
|
||||||
|
|
|
@ -973,6 +973,8 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
|
||||||
|
|
||||||
DB_PRINT_L(0, "addr=" HWADDR_FMT_plx " = %x\n", addr, (unsigned)value);
|
DB_PRINT_L(0, "addr=" HWADDR_FMT_plx " = %x\n", addr, (unsigned)value);
|
||||||
addr >>= 2;
|
addr >>= 2;
|
||||||
|
assert(addr < XLNX_SPIPS_R_MAX);
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case R_CONFIG:
|
case R_CONFIG:
|
||||||
mask = ~(R_CONFIG_RSVD | MAN_START_COM);
|
mask = ~(R_CONFIG_RSVD | MAN_START_COM);
|
||||||
|
@ -1299,7 +1301,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s,
|
memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s,
|
||||||
"spi", XLNX_ZYNQMP_SPIPS_R_MAX * 4);
|
"spi", xsc->reg_size);
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
|
|
||||||
s->irqline = -1;
|
s->irqline = -1;
|
||||||
|
@ -1435,6 +1437,7 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
|
||||||
|
|
||||||
dc->realize = xilinx_qspips_realize;
|
dc->realize = xilinx_qspips_realize;
|
||||||
xsc->reg_ops = &qspips_ops;
|
xsc->reg_ops = &qspips_ops;
|
||||||
|
xsc->reg_size = XLNX_SPIPS_R_MAX * 4;
|
||||||
xsc->rx_fifo_size = RXFF_A_Q;
|
xsc->rx_fifo_size = RXFF_A_Q;
|
||||||
xsc->tx_fifo_size = TXFF_A_Q;
|
xsc->tx_fifo_size = TXFF_A_Q;
|
||||||
}
|
}
|
||||||
|
@ -1450,6 +1453,7 @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data)
|
||||||
dc->vmsd = &vmstate_xilinx_spips;
|
dc->vmsd = &vmstate_xilinx_spips;
|
||||||
|
|
||||||
xsc->reg_ops = &spips_ops;
|
xsc->reg_ops = &spips_ops;
|
||||||
|
xsc->reg_size = XLNX_SPIPS_R_MAX * 4;
|
||||||
xsc->rx_fifo_size = RXFF_A;
|
xsc->rx_fifo_size = RXFF_A;
|
||||||
xsc->tx_fifo_size = TXFF_A;
|
xsc->tx_fifo_size = TXFF_A;
|
||||||
}
|
}
|
||||||
|
@ -1464,6 +1468,7 @@ static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data)
|
||||||
dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
|
dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
|
||||||
device_class_set_props(dc, xilinx_zynqmp_qspips_properties);
|
device_class_set_props(dc, xilinx_zynqmp_qspips_properties);
|
||||||
xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
|
xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
|
||||||
|
xsc->reg_size = XLNX_ZYNQMP_SPIPS_R_MAX * 4;
|
||||||
xsc->rx_fifo_size = RXFF_A_Q;
|
xsc->rx_fifo_size = RXFF_A_Q;
|
||||||
xsc->tx_fifo_size = TXFF_A_Q;
|
xsc->tx_fifo_size = TXFF_A_Q;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,10 +95,18 @@ static void virtio_iommu_pci_instance_init(Object *obj)
|
||||||
TYPE_VIRTIO_IOMMU);
|
TYPE_VIRTIO_IOMMU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_iommu_pci_instance_finalize(Object *obj)
|
||||||
|
{
|
||||||
|
VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(obj);
|
||||||
|
|
||||||
|
g_free(dev->vdev.prop_resv_regions);
|
||||||
|
}
|
||||||
|
|
||||||
static const VirtioPCIDeviceTypeInfo virtio_iommu_pci_info = {
|
static const VirtioPCIDeviceTypeInfo virtio_iommu_pci_info = {
|
||||||
.generic_name = TYPE_VIRTIO_IOMMU_PCI,
|
.generic_name = TYPE_VIRTIO_IOMMU_PCI,
|
||||||
.instance_size = sizeof(VirtIOIOMMUPCI),
|
.instance_size = sizeof(VirtIOIOMMUPCI),
|
||||||
.instance_init = virtio_iommu_pci_instance_init,
|
.instance_init = virtio_iommu_pci_instance_init,
|
||||||
|
.instance_finalize = virtio_iommu_pci_instance_finalize,
|
||||||
.class_init = virtio_iommu_pci_class_init,
|
.class_init = virtio_iommu_pci_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2391,6 +2391,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
|
||||||
.parent = t->parent ? t->parent : TYPE_VIRTIO_PCI,
|
.parent = t->parent ? t->parent : TYPE_VIRTIO_PCI,
|
||||||
.instance_size = t->instance_size,
|
.instance_size = t->instance_size,
|
||||||
.instance_init = t->instance_init,
|
.instance_init = t->instance_init,
|
||||||
|
.instance_finalize = t->instance_finalize,
|
||||||
.class_size = t->class_size,
|
.class_size = t->class_size,
|
||||||
.abstract = true,
|
.abstract = true,
|
||||||
.interfaces = t->interfaces,
|
.interfaces = t->interfaces,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
||||||
*
|
*
|
||||||
* [2] Versal ACAP Register Reference,
|
* [2] Versal ACAP Register Reference,
|
||||||
* https://www.xilinx.com/htmldocs/registers/am012/am012-versal-register-reference.html
|
* https://docs.xilinx.com/r/en-US/am012-versal-register-reference/CFRAME_REG-Module
|
||||||
*/
|
*/
|
||||||
#ifndef HW_MISC_XLNX_VERSAL_CFRAME_REG_H
|
#ifndef HW_MISC_XLNX_VERSAL_CFRAME_REG_H
|
||||||
#define HW_MISC_XLNX_VERSAL_CFRAME_REG_H
|
#define HW_MISC_XLNX_VERSAL_CFRAME_REG_H
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
||||||
*
|
*
|
||||||
* [2] Versal ACAP Register Reference,
|
* [2] Versal ACAP Register Reference,
|
||||||
* https://www.xilinx.com/htmldocs/registers/am012/am012-versal-register-reference.html
|
* https://docs.xilinx.com/r/en-US/am012-versal-register-reference/CFU_CSR-Module
|
||||||
*/
|
*/
|
||||||
#ifndef HW_MISC_XLNX_VERSAL_CFU_APB_H
|
#ifndef HW_MISC_XLNX_VERSAL_CFU_APB_H
|
||||||
#define HW_MISC_XLNX_VERSAL_CFU_APB_H
|
#define HW_MISC_XLNX_VERSAL_CFU_APB_H
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
||||||
*
|
*
|
||||||
* [2] Versal ACAP Register Reference,
|
* [2] Versal ACAP Register Reference,
|
||||||
* https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___pmc_iop_slcr.html
|
* https://docs.xilinx.com/r/en-US/am012-versal-register-reference/PMC_IOP_SLCR-Module
|
||||||
*
|
*
|
||||||
* QEMU interface:
|
* QEMU interface:
|
||||||
* + sysbus MMIO region 0: MemoryRegion for the device's registers
|
* + sysbus MMIO region 0: MemoryRegion for the device's registers
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
|
|
||||||
typedef struct XilinxSPIPS XilinxSPIPS;
|
typedef struct XilinxSPIPS XilinxSPIPS;
|
||||||
|
|
||||||
|
/* For SPIPS, QSPIPS. */
|
||||||
#define XLNX_SPIPS_R_MAX (0x100 / 4)
|
#define XLNX_SPIPS_R_MAX (0x100 / 4)
|
||||||
|
/* For ZYNQMP_QSPIPS. */
|
||||||
#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
|
#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
|
||||||
|
|
||||||
/* Bite off 4k chunks at a time */
|
/* Bite off 4k chunks at a time */
|
||||||
|
@ -125,6 +127,7 @@ struct XilinxSPIPSClass {
|
||||||
SysBusDeviceClass parent_class;
|
SysBusDeviceClass parent_class;
|
||||||
|
|
||||||
const MemoryRegionOps *reg_ops;
|
const MemoryRegionOps *reg_ops;
|
||||||
|
uint64_t reg_size;
|
||||||
|
|
||||||
uint32_t rx_fifo_size;
|
uint32_t rx_fifo_size;
|
||||||
uint32_t tx_fifo_size;
|
uint32_t tx_fifo_size;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
||||||
*
|
*
|
||||||
* [2] Versal ACAP Register Reference,
|
* [2] Versal ACAP Register Reference,
|
||||||
* https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___ospi.html
|
* https://docs.xilinx.com/r/en-US/am012-versal-register-reference/OSPI-Module
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* QEMU interface:
|
* QEMU interface:
|
||||||
|
|
|
@ -246,6 +246,7 @@ typedef struct VirtioPCIDeviceTypeInfo {
|
||||||
size_t instance_size;
|
size_t instance_size;
|
||||||
size_t class_size;
|
size_t class_size;
|
||||||
void (*instance_init)(Object *obj);
|
void (*instance_init)(Object *obj);
|
||||||
|
void (*instance_finalize)(Object *obj);
|
||||||
void (*class_init)(ObjectClass *klass, void *data);
|
void (*class_init)(ObjectClass *klass, void *data);
|
||||||
InterfaceInfo *interfaces;
|
InterfaceInfo *interfaces;
|
||||||
} VirtioPCIDeviceTypeInfo;
|
} VirtioPCIDeviceTypeInfo;
|
||||||
|
|
|
@ -2646,11 +2646,28 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
|
||||||
gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
|
gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
|
||||||
|
|
||||||
if (istatus) {
|
if (istatus) {
|
||||||
/* Next transition is when count rolls back over to zero */
|
/*
|
||||||
nexttick = UINT64_MAX;
|
* Next transition is when (count - offset) rolls back over to 0.
|
||||||
|
* If offset > count then this is when count == offset;
|
||||||
|
* if offset <= count then this is when count == offset + 2^64
|
||||||
|
* For the latter case we set nexttick to an "as far in future
|
||||||
|
* as possible" value and let the code below handle it.
|
||||||
|
*/
|
||||||
|
if (offset > count) {
|
||||||
|
nexttick = offset;
|
||||||
|
} else {
|
||||||
|
nexttick = UINT64_MAX;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Next transition is when we hit cval */
|
/*
|
||||||
nexttick = gt->cval + offset;
|
* Next transition is when (count - offset) == cval, i.e.
|
||||||
|
* when count == (cval + offset).
|
||||||
|
* If that would overflow, then again we set up the next interrupt
|
||||||
|
* for "as far in the future as possible" for the code below.
|
||||||
|
*/
|
||||||
|
if (uadd64_overflow(gt->cval, offset, &nexttick)) {
|
||||||
|
nexttick = UINT64_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Note that the desired next expiry time might be beyond the
|
* Note that the desired next expiry time might be beyond the
|
||||||
|
|
|
@ -216,7 +216,7 @@ static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
|
||||||
|
|
||||||
static inline uint32_t syn_sve_access_trap(void)
|
static inline uint32_t syn_sve_access_trap(void)
|
||||||
{
|
{
|
||||||
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
|
return (EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -242,12 +242,12 @@ static inline uint32_t syn_pacfail(bool data, int keynumber)
|
||||||
|
|
||||||
static inline uint32_t syn_pactrap(void)
|
static inline uint32_t syn_pactrap(void)
|
||||||
{
|
{
|
||||||
return EC_PACTRAP << ARM_EL_EC_SHIFT;
|
return (EC_PACTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t syn_btitrap(int btype)
|
static inline uint32_t syn_btitrap(int btype)
|
||||||
{
|
{
|
||||||
return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
|
return (EC_BTITRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL | btype;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
|
static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
|
||||||
|
|
|
@ -45,7 +45,8 @@ TESTS+=memory-sve
|
||||||
|
|
||||||
# Running
|
# Running
|
||||||
QEMU_BASE_MACHINE=-M virt -cpu max -display none
|
QEMU_BASE_MACHINE=-M virt -cpu max -display none
|
||||||
QEMU_OPTS+=$(QEMU_BASE_MACHINE) -semihosting-config enable=on,target=native,chardev=output -kernel
|
QEMU_BASE_ARGS=-semihosting-config enable=on,target=native,chardev=output
|
||||||
|
QEMU_OPTS+=$(QEMU_BASE_MACHINE) $(QEMU_BASE_ARGS) -kernel
|
||||||
|
|
||||||
# console test is manual only
|
# console test is manual only
|
||||||
QEMU_SEMIHOST=-serial none -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -mon chardev=stdio0,mode=readline
|
QEMU_SEMIHOST=-serial none -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -mon chardev=stdio0,mode=readline
|
||||||
|
@ -56,6 +57,10 @@ run-semiconsole: semiconsole
|
||||||
run-plugin-semiconsole-with-%: semiconsole
|
run-plugin-semiconsole-with-%: semiconsole
|
||||||
$(call skip-test, $<, "MANUAL ONLY")
|
$(call skip-test, $<, "MANUAL ONLY")
|
||||||
|
|
||||||
|
# vtimer test needs EL2
|
||||||
|
QEMU_EL2_MACHINE=-machine virt,virtualization=on,gic-version=2 -cpu cortex-a57 -smp 4
|
||||||
|
run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_BASE_ARGS) -kernel
|
||||||
|
|
||||||
# Simple Record/Replay Test
|
# Simple Record/Replay Test
|
||||||
.PHONY: memory-record
|
.PHONY: memory-record
|
||||||
run-memory-record: memory-record memory
|
run-memory-record: memory-record memory
|
||||||
|
|
48
tests/tcg/aarch64/system/vtimer.c
Normal file
48
tests/tcg/aarch64/system/vtimer.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Simple Virtual Timer Test
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Linaro Ltd
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <minilib.h>
|
||||||
|
|
||||||
|
/* grabbed from Linux */
|
||||||
|
#define __stringify_1(x...) #x
|
||||||
|
#define __stringify(x...) __stringify_1(x)
|
||||||
|
|
||||||
|
#define read_sysreg(r) ({ \
|
||||||
|
uint64_t __val; \
|
||||||
|
asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \
|
||||||
|
__val; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define write_sysreg(r, v) do { \
|
||||||
|
uint64_t __val = (uint64_t)(v); \
|
||||||
|
asm volatile("msr " __stringify(r) ", %x0" \
|
||||||
|
: : "rZ" (__val)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ml_printf("VTimer Test\n");
|
||||||
|
|
||||||
|
write_sysreg(cntvoff_el2, 1);
|
||||||
|
write_sysreg(cntv_cval_el0, -1);
|
||||||
|
write_sysreg(cntv_ctl_el0, 1);
|
||||||
|
|
||||||
|
ml_printf("cntvoff_el2=%lx\n", read_sysreg(cntvoff_el2));
|
||||||
|
ml_printf("cntv_cval_el0=%lx\n", read_sysreg(cntv_cval_el0));
|
||||||
|
ml_printf("cntv_ctl_el0=%lx\n", read_sysreg(cntv_ctl_el0));
|
||||||
|
|
||||||
|
/* Now read cval a few times */
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
ml_printf("%d: cntv_cval_el0=%lx\n", i, read_sysreg(cntv_cval_el0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue