linux - ARM: Disabling MMU and updating PC -


in short, shut down mmu (and cache) operations in linux context (from inside kernel), debug purposes, run tests. clear, don't intend system still functional after that.

about setup: i'm fiddling freescale vybrid (vf610) - integrates cortex a5 - , low power modes. since i'm experimenting suspiciously local memory corruption while chip in "low power stop" mode , ddr3 in self refresh, i'm trying shift operations bit bit, , right performing suspend/resume steps without executing wfi. since before instruction run address translation, , after without (it's reset), "simulate" "manually" shutting down mmu.

(i currently have no jtag nor other debug access chip. load via mmc/tftp/nfs, , debug leds.)

what i've tried far:

    /* disable icache, dcache , branch prediction */     mrc     p15, 0, r6, c1, c0, 0     ldr r7, =0x1804     bic r6, r6, r7     mcr     p15, 0, r6, c1, c0, 0     isb      /* disable mmu , tex */     bic r7, r6, r7     isb     mcr p15, 0, r6, c1, c0, 0   @ turn on mmu, i-cache, etc     mrc p15, 0, r6, c0, c0, 0   @ read id reg     isb     dsb     dmb 

and other variations same effect.

what observe:

before mmu block, can light led (3 assembly instructions, no branch, nothing fancy, nor access ddr, in self refresh - virtual address gpio port stored in register before that).

after mmu block, can no more, whether try physical or virtual addresses.

i think problem may related pc, retains outdated virtual address. seeing how things done elsewhere in kernel, other way round (that is, while enabling translation) :

    ldr r3, =cpu_resume_after_mmu      instr_sync     mcr p15, 0, r0, c1, c0, 0   @ turn on mmu, i-cache, etc     mrc p15, 0, r0, c0, c0, 0   @ read id reg     instr_sync      mov r0, r0     mov r0, r0     ret r3          @ jump virtual address endproc(cpu_resume_mmu)     .popsection cpu_resume_after_mmu: 

(from arch/arm/kernel/sleep.s, cpu_resume_mmu)

i wonder 2 instructions delay related to, , documented. i've found nothing on subject. i've tried equivalent, without success:

    adr lr, bsym(phys_block)      /* disable icache, dcache , branch prediction */     mrc     p15, 0, r6, c1, c0, 0     ldr r7, =0x1804     bic r6, r6, r7     mcr     p15, 0, r6, c1, c0, 0     isb      /* disable mmu , tex */     bic r7, r6, r7     isb     mcr p15, 0, r6, c1, c0, 0   @ turn on mmu, i-cache, etc     mrc p15, 0, r6, c0, c0, 0   @ read id reg     isb     dsb     msb      mov r0, r0     mov r0, r0     ret lr  phys_block:     blue_light     loop 

thanks has clue or pointers!

since both jacen , dwelch kindly brought answer needed through comment (each), answer own question here sake of clarity:

the trick add identity mapping from/to page doing transition, allowing jump "physical" (though virtual) pc, disable mmu.

here final code (a bit specific, commented):

    /* duplicate mapping here */      mrc p15, 0, r4, c2, c0, 0 // ttrb0     ldr r10, =0x00003fff     bic r4, r10 // extract page table physical base address     orr r4, #0xc0000000 // nastily "translate" virtual 1      /*      * here r8 holds vf_suspend's physical address. had no way of      * doing more "locally", since both physical , virtual      * space code runtime-allocated.      */      add lr, r8, #(phys_block-vf_suspend) // -> phys_block physical address       lsr r9, lr, #20 // section_shift     -> page index     add r7, r4, r9, lsl #2 // pmd_order  -> entry address     ldr r10, =0x00000c0e // flags     orr r9, r10, r9, lsl #20 // section_shift   -> entry value     str r9, [r7] // write entry      ret lr  // jump / transition virtual addressing  phys_block:     /* disable mmu , tex */     isb     mrc     p15, 0, r6, c1, c0, 0     ldr r7, =0x10000001     bic r6, r6, r7     mcr p15, 0, r6, c1, c0, 0   @ turn on mmu, i-cache, etc     mrc p15, 0, r6, c0, c0, 0   @ read id reg     isb     dsb     dmb      /* disable icache, dcache , branch prediction */     mrc     p15, 0, r6, c1, c0, 0     ldr r7, =0x1804     bic r6, r6, r7     mcr     p15, 0, r6, c1, c0, 0     isb      // done ! 

Comments

Popular posts from this blog

javascript - Google App Script ContentService downloadAsFile not working -

javascript - Function overwritting -

php - Find a regex to take part of Email -