Newbie MMU question

Newbie MMU question

I've written some signal processing code in Xscale asm and want to do some cache analysis (how will d/m cache affect speed?). To this end, I've collected all the MMU/cache sample code sequences from the Xscale Developer's manual and created a mem_config.s function that basically (tries to!) enable MMU, enable and flush Icache/BTB and enable D/M cache and drain write/fill buffers. The MMU enable code snippet said something about 'one-to-one virtual to physical address mapping' - my question is reg this comment. What exactly does this mean and how do I accomplish this? I'm calling the mem_config() routine from main() and switching to supervisor mode from user mode. Basically, after the 'MCR' instruction (write to CPSR), the simulator crashes saying 'no memory mapped at address 0x4'. I'm guessing this is related to address translation (changed from physical to virtual in mem_config()) but I've no clue as to how to fix it. Any help is greatly appreciated!

(Development platform: XDB 2.0, GNU tools ver 3.1).

Thanks.

Code Listing:

.text
.align 2
.global mem_config
.type mem_config,function

mem_config:

@ mrc/mcr can only be accessed in privileged modes (supervisor mode
@ for instance). Switch to Supervisor mode here...

mode_change_to_supervisor:

mrs r0,cpsr @ Read CPSR
mov r6,r0 @ store current CPSR state - don't touch r6!
bic r0,r0,#0x1F @ Clear current state
orr r0,r0,#0x13 @ Mode = Supervisor
msr cpsr_c,r0 @ Update status register

@ Wait for the change to take effect...
nop
nop
nop

@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@
@ Sequence of operations for cache enabling: Enable Instruction cache,
@ Enable translation, Drain the write buffer, Enable Data cache - DO
@ NOT COMBINE THESE OPERATIONS! See Table 7-12, Cache Functions for
@ details about the following commands.
@
@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@ Enable instruction cache
@ Icache state at reset: Disabled, Unlocked, Invalidated (or flushed)
@ Icache can be enabled by setting bit 12 in CP15, Reg 1

enable_icache:

mrc p15,0,r0,c1,c0,0 @ Read CP15, Reg 1 into r0
orr r0,r0,#0x1000 @ Set bit 12
mcr p15,0,r0,c1,c0,0 @ Write to CP15, Reg 1
nop
nop
nop

@ Icache is enabled from this point on...

enable_mmu:

@ Enable MMU - MMU is enabled by setting bit 0 in coprocessor 15 Register 1
@ (Control Register). When MMU is disabled, accesses to the instruction
@ cache default to cacheable and all accesses to data memory are made
@ non-cacheable. MMU is guaranteed to be enabled after the CPWAIT instruction.

mrc p15,0,r0,c1,c0,0 @ Read CP15, Reg 1
orr r0,r0,#0x1 @ Enable MMU
mcr p15,0,r0,c1,c0,0 @ Write to CP15, Reg 1

@ Wait loop
mrc p15, 0, r0, c2, c0, 0 @ arbitrary read of CP15
mov r0, r0 @ wait for it
sub pc, pc, #4 @ branch to next instruction
nop
nop
nop

@ MMU is enabled from this point on...virtual addressing (translation on)

@ Invalidate I
cache and Branch Target Buffer - Icache is assumed to be
@ unlocked. Locked cache lines will not be cleared!!!

flush_icache_and_btb:

mcr p15,0,r1,c7,c5,0 @ Invalidate Icache and BTB

nop
nop
nop

@ Icache is now flushed...

@ Enable data cache
@ Dcache state at reset: Disabled, invalid (valid bits set to zero) and
@ round-robin bit points to way 31, data RAM destroyed if configured
@ Dcache and Mini Dcache are enabled by setting bit 2 in CP15, Reg 1

enable_D_and_M_cache:

mcr p15,0,r0,c7,c10,4 @ Drain Write/Fill buffers
mrc p15,0,r0,c1,c0,0 @ Read CP15, Reg 1 into r0
orr r0,r0,#4 @ Set bit 2
mcr p15,0,r0,c1,c0,0 @ Write to CP15, Reg 1

nop
nop
nop

@ Dcache and Mcache are enabled from this point on...

@ NOTE: Reset state of Dcache and Mcache assumed! You may have to
@ physically clean the 2 caches if this routine is called in user mode

@ mrc/mcr can only be accessed in priveleged modes (supervisor mode
@ for instance). Switch to Supervisor mode here...

mode_change_to_previous:

mrs r0,cpsr @ Read CPSR
bic r0,r0,#0x1F @ Clear current state
mov r1,r6 @ Restore previous mode - hopefully user!
orr r0,r0,r1 @ Set Mode at entry to function
msr cpsr_c,r0 @ Update status register

nop
nop
nop

@ End memory configuration

4 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

I received some info from a friend regarding this issue, please take a look below and see if it helps.

An
==========================

I had a look at you assembly code and there are a vital bit missing. Before you can turn on the MMU you must set up the page mapping tables and set up the address to the table base register. It is also important that you have 1-1 mapping in these tables at least for the code where you do the change over from physical to virtual addressing.

Basically the following steps are missing somehow in the code:

1. Set up the mapping tables - XScale? allow you to define the following pages:
- 1KB Tiny page
- 4KB Small or Extended Small page
- 64KB Large page
- 1MB Section
Each of those must be defined in a page table. To make life a bit easier XScale? use a two level page table scheme:
- 1st level table containing 4096 pointers to 2nd level tables or to a 1MB page (section).
- 2nd level table can be either a) a course page with 256 pointers to large, extended small or small pages. B) a fine page with 1024 pointers to large, small or tiny page.

What is a bit tricky is that there can be only 16 large pages in the course page table [and 256 small /extended small pages] - large pages require duplication of sequential entries in the table. The same is true for the fine page table - 16 large pages, 256 small pages and 1024 tiny pages. Both small and large will have duplicated entries.

To start you may want to make life simple and in this case I would suggest to use only sections.

How to get 1-1 mapping? Simple - here the virtual and physical address is the same. From low to high section 0 has physical address [=pointer in 1st level table] 0 and section 1 has physical address 100000 and so on?

You should also look at the page protection as these are set in the page mapping tables.

2. Once the tables are set up you need to load CP15 register 2 [Table Base Register] with the physical address to the 1st level table which must start on a 16KB boundary.

3. Only now can you turn on the MMU.

I hope this give you some idea what is missing.

That helps a lot...thanks very much!

greenhorn,

I'm glad that the info was helpful. Please come back and let us know what you have found.

An

Connectez-vous pour laisser un commentaire.