cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

coresight-cpu-debug.rst (8596B)


      1==========================
      2Coresight CPU Debug Module
      3==========================
      4
      5   :Author:   Leo Yan <leo.yan@linaro.org>
      6   :Date:     April 5th, 2017
      7
      8Introduction
      9------------
     10
     11Coresight CPU debug module is defined in ARMv8-a architecture reference manual
     12(ARM DDI 0487A.k) Chapter 'Part H: External debug', the CPU can integrate
     13debug module and it is mainly used for two modes: self-hosted debug and
     14external debug. Usually the external debug mode is well known as the external
     15debugger connects with SoC from JTAG port; on the other hand the program can
     16explore debugging method which rely on self-hosted debug mode, this document
     17is to focus on this part.
     18
     19The debug module provides sample-based profiling extension, which can be used
     20to sample CPU program counter, secure state and exception level, etc; usually
     21every CPU has one dedicated debug module to be connected. Based on self-hosted
     22debug mechanism, Linux kernel can access these related registers from mmio
     23region when the kernel panic happens. The callback notifier for kernel panic
     24will dump related registers for every CPU; finally this is good for assistant
     25analysis for panic.
     26
     27
     28Implementation
     29--------------
     30
     31- During driver registration, it uses EDDEVID and EDDEVID1 - two device ID
     32  registers to decide if sample-based profiling is implemented or not. On some
     33  platforms this hardware feature is fully or partially implemented; and if
     34  this feature is not supported then registration will fail.
     35
     36- At the time this documentation was written, the debug driver mainly relies on
     37  information gathered by the kernel panic callback notifier from three
     38  sampling registers: EDPCSR, EDVIDSR and EDCIDSR: from EDPCSR we can get
     39  program counter; EDVIDSR has information for secure state, exception level,
     40  bit width, etc; EDCIDSR is context ID value which contains the sampled value
     41  of CONTEXTIDR_EL1.
     42
     43- The driver supports a CPU running in either AArch64 or AArch32 mode. The
     44  registers naming convention is a bit different between them, AArch64 uses
     45  'ED' for register prefix (ARM DDI 0487A.k, chapter H9.1) and AArch32 uses
     46  'DBG' as prefix (ARM DDI 0487A.k, chapter G5.1). The driver is unified to
     47  use AArch64 naming convention.
     48
     49- ARMv8-a (ARM DDI 0487A.k) and ARMv7-a (ARM DDI 0406C.b) have different
     50  register bits definition. So the driver consolidates two difference:
     51
     52  If PCSROffset=0b0000, on ARMv8-a the feature of EDPCSR is not implemented;
     53  but ARMv7-a defines "PCSR samples are offset by a value that depends on the
     54  instruction set state". For ARMv7-a, the driver checks furthermore if CPU
     55  runs with ARM or thumb instruction set and calibrate PCSR value, the
     56  detailed description for offset is in ARMv7-a ARM (ARM DDI 0406C.b) chapter
     57  C11.11.34 "DBGPCSR, Program Counter Sampling Register".
     58
     59  If PCSROffset=0b0010, ARMv8-a defines "EDPCSR implemented, and samples have
     60  no offset applied and do not sample the instruction set state in AArch32
     61  state". So on ARMv8 if EDDEVID1.PCSROffset is 0b0010 and the CPU operates
     62  in AArch32 state, EDPCSR is not sampled; when the CPU operates in AArch64
     63  state EDPCSR is sampled and no offset are applied.
     64
     65
     66Clock and power domain
     67----------------------
     68
     69Before accessing debug registers, we should ensure the clock and power domain
     70have been enabled properly. In ARMv8-a ARM (ARM DDI 0487A.k) chapter 'H9.1
     71Debug registers', the debug registers are spread into two domains: the debug
     72domain and the CPU domain.
     73::
     74
     75                                +---------------+
     76                                |               |
     77                                |               |
     78                     +----------+--+            |
     79        dbg_clock -->|          |**|            |<-- cpu_clock
     80                     |    Debug |**|   CPU      |
     81 dbg_power_domain -->|          |**|            |<-- cpu_power_domain
     82                     +----------+--+            |
     83                                |               |
     84                                |               |
     85                                +---------------+
     86
     87For debug domain, the user uses DT binding "clocks" and "power-domains" to
     88specify the corresponding clock source and power supply for the debug logic.
     89The driver calls the pm_runtime_{put|get} operations as needed to handle the
     90debug power domain.
     91
     92For CPU domain, the different SoC designs have different power management
     93schemes and finally this heavily impacts external debug module. So we can
     94divide into below cases:
     95
     96- On systems with a sane power controller which can behave correctly with
     97  respect to CPU power domain, the CPU power domain can be controlled by
     98  register EDPRCR in driver. The driver firstly writes bit EDPRCR.COREPURQ
     99  to power up the CPU, and then writes bit EDPRCR.CORENPDRQ for emulation
    100  of CPU power down. As result, this can ensure the CPU power domain is
    101  powered on properly during the period when access debug related registers;
    102
    103- Some designs will power down an entire cluster if all CPUs on the cluster
    104  are powered down - including the parts of the debug registers that should
    105  remain powered in the debug power domain. The bits in EDPRCR are not
    106  respected in these cases, so these designs do not support debug over
    107  power down in the way that the CoreSight / Debug designers anticipated.
    108  This means that even checking EDPRSR has the potential to cause a bus hang
    109  if the target register is unpowered.
    110
    111  In this case, accessing to the debug registers while they are not powered
    112  is a recipe for disaster; so we need preventing CPU low power states at boot
    113  time or when user enable module at the run time. Please see chapter
    114  "How to use the module" for detailed usage info for this.
    115
    116
    117Device Tree Bindings
    118--------------------
    119
    120See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
    121
    122
    123How to use the module
    124---------------------
    125
    126If you want to enable debugging functionality at boot time, you can add
    127"coresight_cpu_debug.enable=1" to the kernel command line parameter.
    128
    129The driver also can work as module, so can enable the debugging when insmod
    130module::
    131
    132  # insmod coresight_cpu_debug.ko debug=1
    133
    134When boot time or insmod module you have not enabled the debugging, the driver
    135uses the debugfs file system to provide a knob to dynamically enable or disable
    136debugging:
    137
    138To enable it, write a '1' into /sys/kernel/debug/coresight_cpu_debug/enable::
    139
    140  # echo 1 > /sys/kernel/debug/coresight_cpu_debug/enable
    141
    142To disable it, write a '0' into /sys/kernel/debug/coresight_cpu_debug/enable::
    143
    144  # echo 0 > /sys/kernel/debug/coresight_cpu_debug/enable
    145
    146As explained in chapter "Clock and power domain", if you are working on one
    147platform which has idle states to power off debug logic and the power
    148controller cannot work well for the request from EDPRCR, then you should
    149firstly constraint CPU idle states before enable CPU debugging feature; so can
    150ensure the accessing to debug logic.
    151
    152If you want to limit idle states at boot time, you can use "nohlt" or
    153"cpuidle.off=1" in the kernel command line.
    154
    155At the runtime you can disable idle states with below methods:
    156
    157It is possible to disable CPU idle states by way of the PM QoS
    158subsystem, more specifically by using the "/dev/cpu_dma_latency"
    159interface (see Documentation/power/pm_qos_interface.rst for more
    160details).  As specified in the PM QoS documentation the requested
    161parameter will stay in effect until the file descriptor is released.
    162For example::
    163
    164  # exec 3<> /dev/cpu_dma_latency; echo 0 >&3
    165  ...
    166  Do some work...
    167  ...
    168  # exec 3<>-
    169
    170The same can also be done from an application program.
    171
    172Disable specific CPU's specific idle state from cpuidle sysfs (see
    173Documentation/admin-guide/pm/cpuidle.rst)::
    174
    175  # echo 1 > /sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
    176
    177Output format
    178-------------
    179
    180Here is an example of the debugging output format::
    181
    182  ARM external debug module:
    183  coresight-cpu-debug 850000.debug: CPU[0]:
    184  coresight-cpu-debug 850000.debug:  EDPRSR:  00000001 (Power:On DLK:Unlock)
    185  coresight-cpu-debug 850000.debug:  EDPCSR:  handle_IPI+0x174/0x1d8
    186  coresight-cpu-debug 850000.debug:  EDCIDSR: 00000000
    187  coresight-cpu-debug 850000.debug:  EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
    188  coresight-cpu-debug 852000.debug: CPU[1]:
    189  coresight-cpu-debug 852000.debug:  EDPRSR:  00000001 (Power:On DLK:Unlock)
    190  coresight-cpu-debug 852000.debug:  EDPCSR:  debug_notifier_call+0x23c/0x358
    191  coresight-cpu-debug 852000.debug:  EDCIDSR: 00000000
    192  coresight-cpu-debug 852000.debug:  EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)