From c04018e93390e31b40044f3db92c173fb0ccb3d2 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Wed, 26 Feb 2014 17:20:09 +0000 Subject: [PATCH] dma/pl330: implement dmaadnh instruction Implement the missing DMAADNH instruction. This is a minor variant of the DMAADDH instruction, so factor out to a common implementation for both (dmaadxh). Signed-off-by: Peter Crosthwaite Message-id: 73ab13532a7cae53441da89b46c279b5f50785e3.1393372019.git.peter.crosthwaite@xilinx.com Signed-off-by: Peter Maydell --- hw/dma/pl330.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index b5d586b92b..608a58c47d 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -601,10 +601,12 @@ static inline void pl330_fault(PL330Chan *ch, uint32_t flags) * LEN - number of elements in ARGS array */ -static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) +static void pl330_dmaadxh(PL330Chan *ch, uint8_t *args, bool ra, bool neg) { - uint16_t im = (((uint16_t)args[1]) << 8) | ((uint16_t)args[0]); - uint8_t ra = (opcode >> 1) & 1; + uint32_t im = (args[1] << 8) | args[0]; + if (neg) { + im |= 0xffffu << 16; + } if (ch->is_manager) { pl330_fault(ch, PL330_FAULT_UNDEF_INSTR); @@ -617,6 +619,16 @@ static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) } } +static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) +{ + pl330_dmaadxh(ch, args, extract32(opcode, 1, 1), false); +} + +static void pl330_dmaadnh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) +{ + pl330_dmaadxh(ch, args, extract32(opcode, 1, 1), true); +} + static void pl330_dmaend(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) { @@ -1042,6 +1054,7 @@ static void pl330_dmawmb(PL330Chan *ch, uint8_t opcode, /* NULL terminated array of the instruction descriptions. */ static const PL330InsnDesc insn_desc[] = { { .opcode = 0x54, .opmask = 0xFD, .size = 3, .exec = pl330_dmaaddh, }, + { .opcode = 0x5c, .opmask = 0xFD, .size = 3, .exec = pl330_dmaadnh, }, { .opcode = 0x00, .opmask = 0xFF, .size = 1, .exec = pl330_dmaend, }, { .opcode = 0x35, .opmask = 0xFF, .size = 2, .exec = pl330_dmaflushp, }, { .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago, },