learn more formally arm 32 bit CP registers, fix QEMU baremetal run with cli args

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2020-06-16 02:00:01 +00:00
parent 7d32b26fde
commit da40e84075
4 changed files with 66 additions and 1 deletions

View File

@@ -21486,6 +21486,35 @@ Guaranteed undefined! Therefore raise illegal instruction signal. Used by GCC `_
Why GNU GAS 2.29 does not have a mnemonic for it in A64 because it is very recent: shows in <<armarm8-db>> but not `ca`.
==== ARM system register instructions
Examples of using them can be found at: <<dump-regs>>
aarch64 only uses exactly 2 instructions:
* MRS: reads a system register to a regular register
* MSR: writes to the system register
aarch32 is a bit more messy due to older setups, we have both:
* MRS and MSR which are much like in aarch64
* coprocessor accesses:
** MRC: reads a system register, C means coprocessor, which is how system registers were previously known as
** MCR: write to the system register
** MRRC: like MRC, but used for the system registers that are marked as 64-bit, and reads to two general purpose regis
** MCRR: write version of MCRR
<<armarm8-fa>> G1.19.4 "Background to the System register interface" says that only CP14 and CP15 are specified by the ISA:
____
The interface to the System registers was originally defined as part of a generic coprocessor interface, that gave access to 15 coprocessors, CP0 - CP15. Of these, CP8 - CP15 were reserved for use by Arm, while CP0 - CP7 were available for IMPLEMENTATION DEFINED coprocessors.
____
and the actual coprocessor registers are specified at:
* CP14: Table G7-1 "Mapping of (coproc ==0b1110) MCR, MRC, and MRRC instruction arguments to System registers"
* CP15: Table G7-3 "VMSAv8-32 (coproc==0b1111) register summary, in MCR/MRC parameter order."
=== ARM SIMD
Parent section: xref:simd-assembly[xrefstyle=full]
@@ -21909,6 +21938,11 @@ ISA quick references can be found in some places:
https://static.docs.arm.com/ddi0487/db/DDI0487D_b_armv8_arm.pdf
[[armarm8-fa]]
===== ARMv8 architecture reference manual db
https://static.docs.arm.com/ddi0487/fa/DDI0487F_a_armv8_arm.pdf
[[armv8-programmers-guide]]
===== Programmer's Guide for ARMv8-A

View File

@@ -10,6 +10,35 @@ int main(void) {
/* https://cirosantilli.com/linux-kernel-module-cheat#arm-exception-levels */
printf("SPSR.M 0x%" PRIX32 "\n", spsr & 0xF);
/* CP14 https://cirosantilli.com/linux-kernel-module-cheat#arm-system-register-instructions */
uint32_t dbgdidr;
__asm__ ("mrc p14, 0, %0, c0, c0, 0" : "=r" (dbgdidr) : :);
printf("DBGDIDR 0x%" PRIX32 "\n", dbgdidr);
#if !LKMC_GEM5
uint32_t dbgdrar_0;
uint32_t dbgdrar_1;
__asm__ ("mrrc p14, 0, %0, %1, c1" : "=r" (dbgdrar_0), "=r" (dbgdrar_1) : :);
printf("DBGDRAR 0x%" PRIX64 "\n", dbgdrar_0 | ((uint64_t)dbgdrar_1 << 32));
#endif
/* CP15 https://cirosantilli.com/linux-kernel-module-cheat#arm-system-register-instructions */
uint32_t midr;
__asm__ ("mrc p15, 0, %0, c0, c0, 0" : "=r" (midr) : :);
printf("MIDR 0x%" PRIX32 "\n", midr);
printf("MIDR.Architecture 0x%" PRIX32 "\n", (midr >> 16) & 0xF);
uint32_t ctr;
__asm__ ("mrc p15, 0, %0, c0, c0, 0" : "=r" (ctr) : :);
printf("CTR 0x%" PRIX32 "\n", ctr);
uint32_t ttbr0_0;
uint32_t ttbr0_1;
__asm__ ("mrrc p15, 0, %0, %1, c2" : "=r" (ttbr0_0), "=r" (ttbr0_1) : :);
printf("TTBR0 0x%" PRIX64 "\n", ttbr0_0 | ((uint64_t)ttbr0_1 << 32));
#if 0
/* TODO blows up exception in EL, but works with -machine secure=on. */
uint32_t nsacr;

View File

@@ -5,6 +5,7 @@
/* https://cirosantilli.com/linux-kernel-module-cheat#dump-regs */
/* So that a sigle source will work with baremetal and printk from kernel module. */
#ifndef LKMC_DUMP_SYSTEM_REGS_PRINTF
#define LKMC_DUMP_SYSTEM_REGS_PRINTF printf
#endif

3
run
View File

@@ -502,6 +502,8 @@ Extra options to append at the end of the emulator command line.
))
argv_addr_cur += len(arg) + 1
baremetal_cli_path = os.path.join(self.env['run_dir'], 'baremetal_cli.raw')
if self.env['emulator'] == 'qemu':
self.make_run_dirs()
with open(baremetal_cli_path, 'wb') as f:
f.write(struct.pack('<{}'.format(self.python_struct_int_format(self.env['int_size'])), len(cli_args)))
f.write(b''.join(argv_addr_data))
@@ -702,7 +704,6 @@ Extra options to append at the end of the emulator command line.
cpu = 'max'
else:
extra_emulator_args.extend(extra_qemu_args)
self.make_run_dirs()
if debug_vm:
serial_monitor = []
else: