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 <peter.crosthwaite@xilinx.com> Message-id: 73ab13532a7cae53441da89b46c279b5f50785e3.1393372019.git.peter.crosthwaite@xilinx.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a5ae7e3984
commit
c04018e933
|
@ -601,10 +601,12 @@ static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
|
||||||
* LEN - number of elements in ARGS array
|
* 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]);
|
uint32_t im = (args[1] << 8) | args[0];
|
||||||
uint8_t ra = (opcode >> 1) & 1;
|
if (neg) {
|
||||||
|
im |= 0xffffu << 16;
|
||||||
|
}
|
||||||
|
|
||||||
if (ch->is_manager) {
|
if (ch->is_manager) {
|
||||||
pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
|
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,
|
static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
|
||||||
uint8_t *args, int len)
|
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. */
|
/* NULL terminated array of the instruction descriptions. */
|
||||||
static const PL330InsnDesc insn_desc[] = {
|
static const PL330InsnDesc insn_desc[] = {
|
||||||
{ .opcode = 0x54, .opmask = 0xFD, .size = 3, .exec = pl330_dmaaddh, },
|
{ .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 = 0x00, .opmask = 0xFF, .size = 1, .exec = pl330_dmaend, },
|
||||||
{ .opcode = 0x35, .opmask = 0xFF, .size = 2, .exec = pl330_dmaflushp, },
|
{ .opcode = 0x35, .opmask = 0xFF, .size = 2, .exec = pl330_dmaflushp, },
|
||||||
{ .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago, },
|
{ .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago, },
|
||||||
|
|
Loading…
Reference in a new issue