From 971b0ba2b53b6e2d051a860a43e23b092ae8c16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Fri, 3 Jul 2020 01:00:00 +0000 Subject: [PATCH] arm system register encodings --- README.adoc | 69 ++++++++++++++++++++++++++++++++++++++++ lkmc/aarch64_dump_regs.h | 1 + 2 files changed, 70 insertions(+) diff --git a/README.adoc b/README.adoc index 1506075..d02961b 100644 --- a/README.adoc +++ b/README.adoc @@ -11651,6 +11651,13 @@ Here we don't see the last `m5 exit` instruction on the log, but it must just be ==== gem5 checkpoint internals +A quick way to get a <> or full system checkpoint to observe is: + +.... +./run --arch aarch64 --emulator gem5 --baremetal userland/freestanding/gem5_checkpoint.S --trace-insts-stdout +./run --arch aarch64 --emulator gem5 --userland userland/freestanding/gem5_checkpoint.S --trace-insts-stdout +.... + Checkpoints are stored inside the <> at: .... @@ -11667,6 +11674,18 @@ Therefore, just use our superior `--gem5-restore` flag, which uses directory tim The `-r N` integer value is just pure `fs.py` sugar, the backend at `m5.instantiate` just takes the actual tracepoint directory path as input. +The file `m5out/cpt.1000/m5.cpt` contains almost everything in the checkpoint except memory. + +It is a https://docs.python.org/3/library/configparser.html[Python configparser compatible file] with a section structure that matches the <> tree e.g.: + +.... +[system.cpu.itb.walker.power_state] +currState=0 +prvEvalTick=0 +.... + +When a checkpoint is taken, each `SimObject` calls its overridden `serialize` method to generate the checkpoint, and when loading, `unserialize` is called. + [[gem5-restore-new-script]] ==== gem5 checkpoint restore and run a different script @@ -11859,6 +11878,7 @@ which is the `movz` after the checkpoint. The final `m5exit` does not appear due Bibliography: +* https://stackoverflow.com/questions/60876259/which-system-characteristics-such-as-number-of-cores-of-cache-configurations-can * https://stackoverflow.com/questions/49011096/how-to-switch-cpu-models-in-gem5-after-restoring-a-checkpoint-and-then-observe-t ===== gem5 fast forward @@ -11956,6 +11976,31 @@ Bibliography: * https://cs.stackexchange.com/questions/69511/what-does-fast-forwarding-mean-in-the-context-of-cpu-simulation +==== gem5 checkpoint upgrader + +The in-tree `util/cpt_upgrader.py` is a tool to upgrade checkpoints taken from an older version of gem5 to be compatible with the newest version, so you can update gem5 without having to re-run the simulation that generated the checkpoints. + +For example, whenever a <>, old checkpoints break unless upgraded. + +Unfortunately, since the process is not very automated (automatable?), and requires manually patching the upgrader every time a new breaking change is done, the upgrader tends to break soon if you try to move many versions of gem5 ahead as of 2020. This is evidenced in bug reports such as this one: https://gem5.atlassian.net/browse/GEM5-472 + +The script can be used as: + +.... +util/cpt_upgrader.py m5out/cpt.1000/m5.cpt +.... + +This updates the `m5.cpt` file in-place, and a `m5out/cpt.1000/m5.cpt.bak` is generated as a backup of the old file. + +The upgrader determines which upgrades are needed by checking the `version_tags` entry of the checkpoint: + +.... +[Globals] +version_tags=arm-ccregs arm-contextidr-el2 arm-gem5-gic-ext ... +.... + +Each of those tags corresponds to a Python file under `util/cpt_upgraders/` e.g. `util/cpt_upgraders/arm-ccregs.py`. + === Pass extra options to gem5 Remember that in the gem5 command line, we can either pass options to the script being run as in: @@ -21523,6 +21568,30 @@ 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 system register encodings + +Each aarch64 system register is specified in the encoding of <> by 5 integer numbers: + +* `op0` +* `op1` +* `CRn` +* `CRm` +* `op2` + +The encodings are given on large tables in <> Chapter D12 "AArch64 System Register Encoding". + +As shown in link:baremetal/arch/aarch64/dump_regs.c[] as of LKMC 4e05b00d23c73cc4d3b83be94affdb6f28008d99, you can use the encoding parameters directly in GNU GAS assembly: + +.... +uint32_t id_isar6_el1; +__asm__ ("mrs %0, s3_0_c0_c2_7" : "=r" (id_isar6_el1) : :); +LKMC_DUMP_SYSTEM_REGS_PRINTF("ID_ISAR6_EL1 0x%" PRIX32 "\n", id_isar6_el1); +.... + +This can be useful to refer to new system registers which your older version of GNU GAS version does not yet have a name for. + +The Linux kernel also uses explicit sysreg encoding extensively since it is of course a very early user of many new system registers, this is done at https://github.com/torvalds/linux/blob/v5.4/arch/arm64/include/asm/sysreg.h[`arch/arm64/include/asm/sysreg.h` in Linux v5.4]. + === ARM SIMD Parent section: xref:simd-assembly[xrefstyle=full] diff --git a/lkmc/aarch64_dump_regs.h b/lkmc/aarch64_dump_regs.h index ccf0f86..7f7cb71 100644 --- a/lkmc/aarch64_dump_regs.h +++ b/lkmc/aarch64_dump_regs.h @@ -37,6 +37,7 @@ void lkmc_dump_system_regs() { __asm__ ("mrs %0, id_isar0_el1" : "=r" (id_isar0_el1) : :); LKMC_DUMP_SYSTEM_REGS_PRINTF("ID_ISAR0_EL1 0x%" PRIX32 "\n", id_isar0_el1); + /* https://cirosantilli.com/linux-kernel-module-cheat#arm-system-register-encodings */ uint32_t id_isar6_el1; __asm__ ("mrs %0, s3_0_c0_c2_7" : "=r" (id_isar6_el1) : :); LKMC_DUMP_SYSTEM_REGS_PRINTF("ID_ISAR6_EL1 0x%" PRIX32 "\n", id_isar6_el1);