Issue in writing a data in PMU register

Hi,

Following are the query regarding the ARM Cortex A7 MP Core.

In ARM Cortex A7 MP Core,facing a issue in memory mapping the registers and accessing the registers by read and write operations.

By means of the reference manual the base configuration address has been read and set to the respective value.

I am not able to write the values by these assembly instruction " asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(0x07));" 0x07 is a data to be written to the PMU register.Even though the user enable register is set before writing the value to the register.

In the manual,the system control register holds a bit "WXN" [Write permission Execute Never] . According to my board,it was 0 (Regions with write permission are not forced to be XN, this is the reset value).Is this bit setting,blocks the write permissions to the other register?

Do i need to enable any register other than "PMUSERENR" before the write operation?

  • Hi,

    to access PMU registers which are memory mapped, the CPU should be in the debug mode.

    We ordinary access them via CP15 registers by using MCR/MRC instructions.

    Could you really set EN bit of PMUSERENR?

    If you could, I think you might access PMCR.

    PMCR.C and PMCR.P are write only bits and you will see they are always 0s.

    Could not you set even PMCR.E?

    If it could not, it would be strange.

    Can you show us the more detailed procedure you had been taken?

    Best regards,

    Yasuhiko Koumoto.

  • Hi yasuhikokoumoto,

    To access the PMU register,i have mapped the configuration base address as 0x183100000 by reading the P14 register [asm volatile("mrc p15, 4, %0, c15, c0, 0")] and the single core ARM 7 MP is been used.Is it the right way to find the base address for the memory mapping?

    Memory mapping doesn't work for ARMCORE_REGS_START(0x19000000) and the PMU_OFFSET(0x15000).

    How to enable the memory-mapped debug mode through the APB interface?In manual,there are four options as CPU0-CPU3 debug and PMU offsets.

    I am able to set the enable bit of PMUSERENR  and also the PMCR.E bit in PMCR bit by,

    asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (0x1));                     // Enabling the user access

    asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(0x41072001));        // Accessing the PMCR.E bit in PMCR register

    asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(0x8000000f)           // Enabling the counters

    and confirmed by reading back the registers,

    asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r" (PMUSERENR));        // reading the user enable bit

    PMUSERENR =0x00000001

    asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (PMNC));                    // reading the PMNC register

    PMNC =0x41072001      

    For memory mapping,these procedures have been taken:

    Trial 1: Tried setting the PMU_OFFSET to these (0x11000,0x13000,0x15000,0x17000) values by keeping the ARMCORE_REGS_START(0x19000000) and the IPROC_REGS_START (0x18000000) as default,but results in crash.

    Trail 2: Varying both the PMU_OFFSET (0x11000,0x13000,0x15000,0x17000) and the IPROC_REGS_START from 0x11000000 to 0x20000000,the same crash occured.

    Trail 3: Keeping the ARMCORE_REGS_START address and the IPROC_REGS_START address as same 0x18000000

    Trail 4: Setting the base address as 0x183010000 to the ioremap,here the code runs fine and the counter values doesnot increments,remains as 0.

  • Hi,

    first of all the  configuration base address is not the debug APB base address.

    As far as my memory would be correct, it would be a part of the CoreSight memory map. Therefore PMU memory mapped address registers could be only accessible via a debugger.

    Of course, if the processor was in the debug mode, those register would be accessible. The debug APB base address would be a product specific (i.e. implementation dependent). In order to know the value, you must refer to the product reference manual.

    Therefore, you'd better use cp15 registers to deal with PMU functions.

    I wonder why you want to do by using both cp15 registers and the memory mapped registers. You can use PMU only by using cp15 registers.

    However, PMU Event Counters would always show 0 in other than the debug mode.

    You can only PMU Cycle Count Registers in other than the debug mode.

    Although I don't know how to make a processor in the debug mode, it seems that it would be related with JTAG pin states at the reset.

    Some evaluation boards might boot up with the debug mode. In such the case, you could freely use all the PMU functions.

    Best regards,

    Yasuhiko Koumoto.

  • The CoreSight debug registers might be mapped into the CPU's address map. This is dependent on the decisions the SoC designer made. The registers DBGDRAR and DBGDSAR should help in locating the debug registers if they are accessible from the CPU address map.

    The PMUSERENR register affects only User access to the MRC and MCR instructions for the PMU. It has no effect on accesses to the memory-mapped view. An OS controls this access using the MMU as it would for any other peripheral.

    I don't understand the comment "PMU Event Counters would always show 0 in other than the debug mode". There is no "debug mode", and there is no masking of the PMU event counters.

  • Hi Michael,

    I don't understand the comment "PMU Event Counters would always show 0 in other than the debug mode". There is no "debug mode", and there is no masking of the PMU event counters.

    I am against you.

    Strictly speaking, my word of the debug mode means that DBGEN or NIDEN is being set.

    I have already verified this fact by own Cortex-A9 board.

    That is, the event counters cannot read without connecting a debugger.

    Also you can find the same report on many web site. Please search.

    Best regards,

    Yasuhiko Koumoto.

  • Oh, I see what you mean. Yes, NIDEN has to be asserted for the counters to count events. This is, again, a matter for the SoC designer to determine.

    From ARMv8-A onwards, this restriction is removed given that it is mostly self-hosted software that uses the PMU. ARM Cortex-A7 is an ARMv7-A processor.

  • Hi Michael.

    thank you for your clarification.

    I would be good news there is no such restriction at ARMv8-A.

    Best regards,

    Yasuhiko Koumoto.

  • Hi,

    1. Could you please provide me the steps to enable the profiling (to measure the performance)

    2. I would like to know how to assign the event to the counters in PMU through P15 assembly instructions.

    In my case,the counters are not getting incremented, I am not sure which is going wrong.

    I would be very thankful, if I can get clear information for the above points.

  • Hi,

    1. Could you please provide me the steps to enable the profiling (to measure the performance)
    2. I would like to know how to assign the event to the counters in PMU through P15 assembly instructions.

    for each core, you should take the following procedures.
    1) Enable Cycle Counter

        MRC    p15, 0, r0, c9, c12, 1 ; PMCNTENSET read
        ORR    r0, r0, #0x80000000    ; set C-bit (to use Cycle Counter)
        MCR    p15, 0, r0, c9, c12, 1 ; PMCNTENSET write
    

    2) Enable Event Counter N

        MRC    p15, 0, r0, c9, c12, 1 ; PMCNTENSET read
        ORR    r0, r0, #(0x1<<N)      ; set PN-bit (can be set more than 1 bit)
        MCR    p15, 0, r0, c9, c12, 1 ; PMCNTENSET write
    

    ;; 1) and 2) can be done at the same time
    3) Set Event to Event Counter N (repeat until the number of Event Counters to be used)

        MOV    r1, #N                ; select Event Counter N
        MCR    p15, 0, r1, c9, c12, 5 ; PMSELR write
        MOV    r1, #M                ; select Event Number (for example M)
        MCR    p15, 0, r0, c9, c13, 1 ; PMXEVTYPER write
    

    4) Enable PMU

      MRC    p15, 0, r0, c9, c12, 0 ; PMCR read
      ORR    r0, r0, #0x1          ; set E-bit 
      MCR    p15, 0, r0, c9, c12, 0 ; PMCR write
    

    5) Reset Cycle Counter

      MRC    p15, 0, r0, c9, c12, 0 ; PMCR read
      ORR    r0, r0, #0x4          ; set C-bit
      MCR    p15, 0, r0, c9, c12, 0 ; PMCR write
    

    6) Reset Event Counters

      MRC    p15, 0, r0, c9, c12, 0 ; PMCR read
      ORR    r0, r0, #0x2          ; set P-bit
      MCR    p15, 0, r0, c9, c12, 0 ; PMCR wire
    

    ;; 4), 5) and 6) can be done at the same time by setting value #0x7
    7) Read Cycle Counter Initial Value

        MRC    p15, 0, rA, c9, c13, 0 ; PMCCNTR read
    

    8) Execute Programs
    9) Read Cycle Counter Last Value

        MRC    p15, 0, rB, c9, c13, 0 ; PMCCNTR read
    

    10) Read Event Counter N  (repeat until the number of Event Counters to be used)

        MOV    r0, #N                ; select Event Counter N 
        MCR    p15, 0, r0, c9, c12, 5 ; PMSELR write
        MRC    p15, 0, rC, c9, c13, 2 ; PMXEVCNTR read
    

    In my case,the counters are not getting incremented, I am not sure which is going wrong.

    It would be because the internal signal DBGEN or NIDEN had not been set.
    To set these signals, you should connect JTAG debugger to the evaluation board.
    Otherwise, I guess that it would be the same effect if TRSTZ pin would be pulled-up during the system reset.

    By the way, as for some evaluation boards, TRSTZ pin had been handled properly, and Event Counters can be used without any debugger.

    Anyway, Cycle Counter is always available and  it  can be used without the JTAG debugger.

    Best regards,

    Yasuhiko Koumoto.