aarch64: add basic Aarch32 support

Add database for common, equivalent opcodes for Aarch32 and
Aarch64 execution states

Revisit all functions that access Aarch64 specific registers
or use Aarch64 opcodes and rewrite them to act depending on
current state of the core.

Add core register access functions for Aarch32 state

Add function to determine the core execution state without
reading DSPSR.

Change-Id: I345e9f6d682fb4ba454e4b1d16bb5e1b27570691
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
This commit is contained in:
Matthias Welwarsky
2016-09-15 09:13:51 +02:00
parent 6b392dea66
commit a9931e6a3c
7 changed files with 406 additions and 83 deletions

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2015 by Matthias Welwarsky <matthias.welwarsky@sysgo.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#include <stdbool.h>
#include "armv8.h"
#include "armv8_opcodes.h"
static const uint32_t a64_opcodes[ARMV8_OPC_NUM] = {
[READ_REG_CLIDR] = ARMV8_MRS(SYSTEM_CLIDR, 0),
[READ_REG_CSSELR] = ARMV8_MRS(SYSTEM_CSSELR, 0),
[READ_REG_CCSIDR] = ARMV8_MRS(SYSTEM_CCSIDR, 0),
[WRITE_REG_CSSELR] = ARMV8_MSR_GP(SYSTEM_CSSELR, 0),
[READ_REG_MPIDR] = ARMV8_MRS(SYSTEM_MPIDR, 0),
[READ_REG_DTRRX] = ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 0),
[WRITE_REG_DTRTX] = ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 0),
[WRITE_REG_DSPSR] = ARMV8_MSR_DSPSR(0),
[READ_REG_DSPSR] = ARMV8_MRS_DSPSR(0),
[ARMV8_OPC_DSB_SY] = ARMV8_DSB_SY,
};
static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {
[READ_REG_CLIDR] = T32_FMTITR(ARMV4_5_MRC(15, 1, 0, 0, 0, 1)),
[READ_REG_CSSELR] = T32_FMTITR(ARMV4_5_MRC(15, 2, 0, 0, 0, 0)),
[READ_REG_CCSIDR] = T32_FMTITR(ARMV4_5_MRC(15, 1, 0, 0, 0, 0)),
[WRITE_REG_CSSELR] = T32_FMTITR(ARMV4_5_MCR(15, 2, 0, 0, 0, 0)),
[READ_REG_MPIDR] = T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 0, 0, 5)),
[READ_REG_DTRRX] = T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)),
[WRITE_REG_DTRTX] = T32_FMTITR(ARMV4_5_MCR(14, 0, 0, 0, 5, 0)),
[WRITE_REG_DSPSR] = T32_FMTITR(ARMV8_MCR_DSPSR(0)),
[READ_REG_DSPSR] = T32_FMTITR(ARMV8_MRC_DSPSR(0)),
[ARMV8_OPC_DSB_SY] = T32_FMTITR(ARMV8_DSB_SY_T1),
};
void armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64)
{
if (state_is_aarch64)
armv8->opcodes = &a64_opcodes[0];
else
armv8->opcodes = &t32_opcodes[0];
}
uint32_t armv8_opcode(struct armv8_common *armv8, enum armv8_opcode code)
{
if ((int)code >= ARMV8_OPC_NUM)
return -1;
return *(armv8->opcodes + code);
}