mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-22 17:55:57 +01:00
learn more formally arm 32 bit CP registers, fix QEMU baremetal run with cli args
This commit is contained in:
34
README.adoc
34
README.adoc
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
3
run
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user