Calculating virtual address from physical address

2006-05-10 Thread David H. Lynch Jr.
Chris Dumoulin wrote:
 Thanks for your reply; I found it very useful and interesting. Now, I have a 
 whole bunch
 of questions.

 You said that the temporary TLB entries setup in head_4xx.S will eventually 
 be replaced.
 Where is the code that creates these new TLB entries later on? Are the 'real' 
 TLB entries
 only created once, and persist for as long as the system is running, or do 
 TLB entries
 change often while the system is running?
   
It has been a few months since I was deep in this, so I am weaker on
details at the moment.

But the gist is that the MMU in PowerPC's is primarily software
driven. It functions as a cache - there are alot of details, but unless
you arfe getting really deep into memory management you can think of the
MMU as a 64 entry cache. Software - in this instance the Linux VM system
is responsible for deciding exactly what happens when the cache is full
and a new entry needs added.
Manually stuffing an entry into the MMU is safe up until that event
occurs.

The VM system entries (real entries if you wish) are in Linux
Memory management data structures - page tables etc. When a page fault
occurs Linux looks up the correct entry in its tables and replaces one
in the MMU with the required one. Unlike X86's where much of this is
implimented in hardware, in a PowerPC the replacement algorithm can be
anything you want - it is written in software. Therefore handling page
faults is likely to be slower, but the OS is in total control of all
aspects of Memory management. It has very few constraints imposed on it
by the MMU.

Real entries are created and destroyed inside the kernel by
anything that wants memory. Drivers demand mapping of IO based memory
typically when they initiallize and should release it when they unload.
Programs request memory when they need it and release it when they
are done. There are subtle differences between IO memory mapping - the
virtual address for an IO mapped memory device MUST corresponf to a
specific set of addresses, while ordinary requests for a memory mapping
can be satisfied by most any block of memory.


 Do you know what state the MSR will be in at this point in the code? I know 
 what the
 power-on reset state is, but I'm wondering if it'll be in a different state 
 by the time we
 get to this point in head_4xx.S.
   
I am not sure that Linux sets the MSR at any point prior to
head_4xx.S. Regardless, greping the ppc directories within kernel source
for MSR_KERNEL will expose the bits their definitions and the normal state,
In my instance to avoid machine checks I had to conditionally
redefine MSR_KERNEL in one header file to avoid machine checks.


 When you suggest disabling instruction or data address translation, is that 
 just so I
 could access my hardware directly, or is there some other reason?
   
Atleast for me getting through the rfi to start_here: which should
be where you end up immediately after the rfi proved very difficult.

by enabling bits one at a time I was able to test what was happening
and establish what was working. I.E if you only enable instruction
translation, you can still write to your physical IO port, but the 'rfi'
will take you to the virtual address 'start_here:'

This was solely a debugging and problem isolation approach. It also
enabled me to test things bit by bit and assure my self that everything
worked, while loading the MSR with the default KERNEL MSR value and
executing the rfi presumes that a number of things are all setup
properly - a failure in any of them would create a problem. It is not
often in programming that a single instructions makes so many changes
all at once, and therefore in one instant requires so many of them to be
right.

I actually wrote some code the stuffed a value at specific physical
addresses, turned on data address mapping, read the value from the
correct virtual address turned of mapping and then wrote the value to my
debug port.
I also was able to test the TLB entry I inserted the same way.

The bit by bit approach is just a way to figure out why you can not
get from real mode to virtual mode by dividing the problem into
small testable peices.

 You were enabling the MSR bits, one at a time, and found that the machine 
 check was
 causing the hang (I'm assuming that's what you meant by 'sent me to space'). 
 Was the idea
 there to just isolate what type of exception was causing the hang, or were 
 you looking to
 make some permanent changes to the MSR? Is a machine check interrupt caused 
 by trying to
 access an address that doesn't have a TLB entry?
   
Unless I am completely mistaken, machine checks are not cause by
softwded are or programming errors, they are cause by hardware problems,
or atleast by hardware reporting problems  In my instance I forwarded I
c the problem to the FPGA programmers, and disabled the machine check so
that I could move on.

I was able to get some clues prior to my bit by bit tests. 

Calculating virtual address from physical address

2006-05-10 Thread Eugene Surovegin
On Wed, May 10, 2006 at 07:04:30AM -0400, David H. Lynch Jr. wrote:

[skip]

 Unless I am completely mistaken, machine checks are not cause by
 softwded are or programming errors, they are cause by hardware problems,

You can trivially trigger MachineChecks without any hardware problems 
- just map some non-existent physical address and try to access it.

-- 
Eugene




Calculating virtual address from physical address

2006-05-06 Thread Alexander Szekely
 How is a virtual address 
 calculated for a high address like 0x4F60?

Add this to the MMU initialzation code (initial_mmu):

/* map leds - 1:1 phys=virt */
lis r3,0x4F60 at h
ori r3,r3,0x4F60 at l
mr  r4,r3
clrrwi  r4,r4,12
ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)

clrrwi  r3,r3,12
ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))

li  r0,0/* TLB slot 0 */
tlbwe   r4,r0,TLB_DATA
tlbwe   r3,r0,TLB_TAG

Then you have a one to one mapping between physical and virtual memory, 
and you can access the LEDs at the same address after turning one the
MMU.

BTW, we had a similar problem, but the reason was not turning on the
MMU. The MMU is enabled by writing MSR_KERNEL the status register. This
also enables the machine state exception interrupt. 

Our hardware design produced PLB bus exceptions, which was unnoticed on
standalone applications. But this bus exceptions also trigger machine
state exceptions. So instead of jumping to start_here the processor
branched to 0x200 - unfortunatly the trap table is not set up at this
point in the boot process...

Alex 




Calculating virtual address from physical address

2006-05-06 Thread Chris Dumoulin
Thanks for your reply; I found it very useful and interesting. Now, I have a 
whole bunch
of questions.

You said that the temporary TLB entries setup in head_4xx.S will eventually be 
replaced.
Where is the code that creates these new TLB entries later on? Are the 'real' 
TLB entries
only created once, and persist for as long as the system is running, or do TLB 
entries
change often while the system is running?

Do you know what state the MSR will be in at this point in the code? I know 
what the
power-on reset state is, but I'm wondering if it'll be in a different state by 
the time we
get to this point in head_4xx.S.

When you suggest disabling instruction or data address translation, is that 
just so I
could access my hardware directly, or is there some other reason?

You were enabling the MSR bits, one at a time, and found that the machine check 
was
causing the hang (I'm assuming that's what you meant by 'sent me to space'). 
Was the idea
there to just isolate what type of exception was causing the hang, or were you 
looking to
make some permanent changes to the MSR? Is a machine check interrupt caused by 
trying to
access an address that doesn't have a TLB entry?

Can you point me to some information about Grant's platform bus changes that 
you were
talking about? I am using a custom V2Pro board, and I'd be interested to see if 
this code
is something I should be looking at.

Thanks alot,
Chris


On May 05, David H. Lynch Jr. dhlii at dlasys.net wrote:
 
 Chris Dumoulin wrote:
  My LEDs are at address 0x4F60 and my CONFIG_KERNEL_START is 
  0xC000. If this address were low enough, I would just add 0xC000 
  to the address to get the virtual address, but since my LED address is 
  so high, the sum will be well past the 32-bit maximum address value. How 
  is a virtual address calculated for a high address like 0x4F60?

 There are macros tophys and tovirt  that convert addresses between
 physical and virtual. There are use example in the head_4xx.S file you
 are already in.
 
 If you are going to use a port for debugging you need to create a
 tlb entry for it.
 Same file in initial_mmu the code inside the if
 defined(CONFIG_SERIAL_TEXT_DEBUG) should provide an example how to do that.
 
 Be forwarned that any entries you create now will eventually
 disappear (took 2 weeks to figure that out once), but that may not
 happen intil after /init starts.
 
 Also with a little of jiggering arround the bits in MSR_KERNEL you
 can enable Data address translation independently of instruction address
 translation as well as disable or enable a variety of
 checks. It took me three weeks to get a new Xilinx V4 board through
 the rfi and to start_here in the same turn_on_mmu code you are working on.
 
 Eventually I ended up enabling the MSR bits one at a time until I
 discovered that enabling the Machine Check sent me to space.
 
 Regardless, once I relialized I could test the code with the MSR
 bits enabled one at a time isolating the problem became easier.
 

 The two issues I addressed above which relate specifically to your
 efforts with the ml300, constituted more than 80% of my effort to get a
 Xilinx Virtex 4 running.
 
 Finally, I started prior to grants platform bus changes. I have been
 adapting my V4 code to fit with Grants changes (the client has what they
 want so they do not care)
 I have not put alot of effort into this, but I currently get
 waylayed much later in new platform bus specific initialization code.
 I had no problem with the older board specific initialization code.
 
 If you are running on a real ml300 I am surprised you are having any
 problems though I do not have an ml300 to check that.
 But if you are running on a custom V2Pro board you have to get the
 board specific initalization right and therefore could trip over the
 issue I am currently having migrating from old to new.
 
 
 

 
 
 
  BTW, he is the assembly code that I'm working with (from 
  arch/ppc/kernel/head_4xx.S):
 
  .text
  _GLOBAL(_stext)
  _GLOBAL(_start)
 
  /* Save parameters we are passed.
  */
  mrr31,r3
  mrr30,r4
  mrr29,r5
  mrr28,r6
  mrr27,r7
 
  /* CRD: set LED state here */
  lisr26,0x4F60 at h
  orir26,r26,0x4F60 at l
  li  r25,LED_STATE_0
  stw r25,0(r26)
 
  /* We have to turn on the MMU right away so we get cache modes
   * set correctly.
   */
  blinitial_mmu
 
  /* CRD: set LED state here */
  lisr26,0x4F60 at h
  orir26,r26,0x4F60 at l
  li  r25,LED_STATE_1
  stw r25,0(r26)
 
  /* We now have the lower 16 Meg mapped into TLB entries, and the caches
   * ready to work.
   */
  turn_on_mmu:
  lisr0,MSR_KERNEL at h
  orir0,r0,MSR_KERNEL at l
  mtsprSPRN_SRR1,r0
  lisr0,start_here at h
  orir0,r0,start_here at l
  mtspr

Calculating virtual address from physical address

2006-05-06 Thread Grant Likely
On 5/6/06, Chris Dumoulin cdumoulin at ics-ltd.com wrote:
 You said that the temporary TLB entries setup in head_4xx.S will eventually 
 be replaced.
 Where is the code that creates these new TLB entries later on? Are the 'real' 
 TLB entries
 only created once, and persist for as long as the system is running, or do 
 TLB entries
 change often while the system is running?

The kernel maintains a list of mappings between virtual and physical
space.  When the processor takes a TLB miss exception, then exception
handler loads the needed mapping into the TLB and returns from
exception.  (Look in head_4xx.S; specifically at finish_tlb_load). 
TLB entries are loaded in a round-robin fashion as needed.  Since your
early TLB mappings aren't in the kernel page tables; they get
overwritten and can't be reloaded by the TLB miss exception handler.

 Can you point me to some information about Grant's platform bus changes that 
 you were
 talking about? I am using a custom V2Pro board, and I'd be interested to see 
 if this code
 is something I should be looking at.

The platform bus changes moves the devices to use the Platform Bus
infrastructure.  It's kind of a move away from multiple
processor-specific bus management schemes for simple busses.  ie. 
If the processor can access it without special setup code; the device
can go on the platform bus.

Check out http://patchwork.ozlabs.org/linuxppc/ and search for my
name.  There's about 9 patches grouped together.

Cheers,
g.

--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
(403) 399-0195



Calculating virtual address from physical address

2006-05-05 Thread Chris Dumoulin
I'm using a Virtex II Pro-based board with a PPC405. The board is 
hanging somewhere very early in the kernel boot process. I believe it 
may be dying at the point where the MMU is enabled. In order to 
determine the exact point at which my board hangs, I'm blinking two LEDs 
in the assembly code found in arch/ppc/kernel/head_4xx.S, . Currently I 
am only able to successfully access the LEDs before the MMU is turned 
on, but I can't be sure that I'm calculating the virtual address 
properly when I try to access the LED after the MMU is turned on.

My LEDs are at address 0x4F60 and my CONFIG_KERNEL_START is 
0xC000. If this address were low enough, I would just add 0xC000 
to the address to get the virtual address, but since my LED address is 
so high, the sum will be well past the 32-bit maximum address value. How 
is a virtual address calculated for a high address like 0x4F60?

BTW, he is the assembly code that I'm working with (from 
arch/ppc/kernel/head_4xx.S):

.text
_GLOBAL(_stext)
_GLOBAL(_start)

/* Save parameters we are passed.
*/
mrr31,r3
mrr30,r4
mrr29,r5
mrr28,r6
mrr27,r7
   
/* CRD: set LED state here */
lisr26,0x4F60 at h
orir26,r26,0x4F60 at l
li  r25,LED_STATE_0
stw r25,0(r26)
   
/* We have to turn on the MMU right away so we get cache modes
 * set correctly.
 */
blinitial_mmu
   
/* CRD: set LED state here */
lisr26,0x4F60 at h
orir26,r26,0x4F60 at l
li  r25,LED_STATE_1
stw r25,0(r26)

/* We now have the lower 16 Meg mapped into TLB entries, and the caches
 * ready to work.
 */
turn_on_mmu:
lisr0,MSR_KERNEL at h
orir0,r0,MSR_KERNEL at l
mtsprSPRN_SRR1,r0
lisr0,start_here at h
orir0,r0,start_here at l
mtsprSPRN_SRR0,r0
SYNC
   
/* CRD: set LED state here */
lisr26,0x4F60 at h
orir26,r26,0x4F60 at l
li  r25,LED_STATE_2
stw r25,0(r26)
   
rfi/* enables MMU */
   
/* CRD: set LED state here */
/* This address should be a virtual address */
lisr26,0x4F60 at h
orir26,r26,0x4F60 at l
li  r25,LED_STATE_3
stw r25,0(r26)
   
b./* prevent prefetch past rfi */

Regards,
Chris Dumoulin
-- 
*--Christopher Dumoulin--*
Software Team Leader

http://ics-ltd.com/
http://ics-ltd.com/

Interactive Circuits and Systems Ltd.
5430 Canotek Road
Ottawa, ON
K1J 9G2
(613)749-9241
1-800-267-9794 (USA only)


This e-mail is private and confidential and is for the addressee only. 
If misdirected, please notify us by telephone and confirm that it has 
been deleted from your system and any hard copies destroyed. You are 
strictly prohibited from using, printing, distributing or disseminating 
it or any information contained in it save to the intended recipient.



Calculating virtual address from physical address

2006-05-05 Thread Sylvain Munaut
Chris Dumoulin wrote:
 I'm using a Virtex II Pro-based board with a PPC405. The board is 
 hanging somewhere very early in the kernel boot process. I believe it 
 may be dying at the point where the MMU is enabled. In order to 
 determine the exact point at which my board hangs, I'm blinking two LEDs 
 in the assembly code found in arch/ppc/kernel/head_4xx.S, . Currently I 
 am only able to successfully access the LEDs before the MMU is turned 
 on, but I can't be sure that I'm calculating the virtual address 
 properly when I try to access the LED after the MMU is turned on.

Typical when trying to bring up board ...

Once the MMU is turned on, you leds register are most likely ... nowhere
... i.e.
if you don't create a mapping your self there is just no virtual address
that will
access your leds physical address.

What I did on some ppc work was tu use a quick BAT mapping to map some leds.
It's pretty easy to setup. Be aware though that this mapping will get
wiped out when
the kernel sets up the BAT for itself.


Sylvain



Calculating virtual address from physical address

2006-05-05 Thread Matt Porter
On Fri, May 05, 2006 at 09:27:50PM +0200, Sylvain Munaut wrote:
 Chris Dumoulin wrote:
  I'm using a Virtex II Pro-based board with a PPC405. The board is 
  hanging somewhere very early in the kernel boot process. I believe it 
  may be dying at the point where the MMU is enabled. In order to 
  determine the exact point at which my board hangs, I'm blinking two LEDs 
  in the assembly code found in arch/ppc/kernel/head_4xx.S, . Currently I 
  am only able to successfully access the LEDs before the MMU is turned 
  on, but I can't be sure that I'm calculating the virtual address 
  properly when I try to access the LED after the MMU is turned on.
 
 Typical when trying to bring up board ...
 
 Once the MMU is turned on, you leds register are most likely ... nowhere
 ... i.e.
 if you don't create a mapping your self there is just no virtual address
 that will
 access your leds physical address.
 
 What I did on some ppc work was tu use a quick BAT mapping to map some leds.
 It's pretty easy to setup. Be aware though that this mapping will get
 wiped out when
 the kernel sets up the BAT for itself.

There are no BATs on 4xx. However, the same conceptual thing can be
done by wiring a fixed TLB entry to cover those LEDs temporarily
during bringup debug.  The temporary TLB entry will be wiped out by
normal tlb misses after things are running whenever the fixed entry
is clobbered by the round robin replacement.

-Matt



Calculating virtual address from physical address

2006-05-05 Thread Josh Boyer
On Fri, 2006-05-05 at 13:24 -0700, Matt Porter wrote:
 
 There are no BATs on 4xx. However, the same conceptual thing can be
 done by wiring a fixed TLB entry to cover those LEDs temporarily
 during bringup debug.  The temporary TLB entry will be wiped out by
 normal tlb misses after things are running whenever the fixed entry
 is clobbered by the round robin replacement.

At which point you should be able to call ioremap to generate a virtual
address inside a device driver or board file.

josh




Calculating virtual address from physical address

2006-05-05 Thread David H. Lynch Jr.
Chris Dumoulin wrote:
 My LEDs are at address 0x4F60 and my CONFIG_KERNEL_START is 
 0xC000. If this address were low enough, I would just add 0xC000 
 to the address to get the virtual address, but since my LED address is 
 so high, the sum will be well past the 32-bit maximum address value. How 
 is a virtual address calculated for a high address like 0x4F60?
   
There are macros tophys and tovirt  that convert addresses between
physical and virtual. There are use example in the head_4xx.S file you
are already in.

If you are going to use a port for debugging you need to create a
tlb entry for it.
Same file in initial_mmu the code inside the if
defined(CONFIG_SERIAL_TEXT_DEBUG) should provide an example how to do that.

Be forwarned that any entries you create now will eventually
disappear (took 2 weeks to figure that out once), but that may not
happen intil after /init starts.

Also with a little of jiggering arround the bits in MSR_KERNEL you
can enable Data address translation independently of instruction address
translation as well as disable or enable a variety of
checks. It took me three weeks to get a new Xilinx V4 board through
the rfi and to start_here in the same turn_on_mmu code you are working on.

Eventually I ended up enabling the MSR bits one at a time until I
discovered that enabling the Machine Check sent me to space.

Regardless, once I relialized I could test the code with the MSR
bits enabled one at a time isolating the problem became easier.

   
The two issues I addressed above which relate specifically to your
efforts with the ml300, constituted more than 80% of my effort to get a
Xilinx Virtex 4 running.

Finally, I started prior to grants platform bus changes. I have been
adapting my V4 code to fit with Grants changes (the client has what they
want so they do not care)
I have not put alot of effort into this, but I currently get
waylayed much later in new platform bus specific initialization code.
I had no problem with the older board specific initialization code.

If you are running on a real ml300 I am surprised you are having any
problems though I do not have an ml300 to check that.
But if you are running on a custom V2Pro board you have to get the
board specific initalization right and therefore could trip over the
issue I am currently having migrating from old to new.



   



 BTW, he is the assembly code that I'm working with (from 
 arch/ppc/kernel/head_4xx.S):

 .text
 _GLOBAL(_stext)
 _GLOBAL(_start)

 /* Save parameters we are passed.
 */
 mrr31,r3
 mrr30,r4
 mrr29,r5
 mrr28,r6
 mrr27,r7

 /* CRD: set LED state here */
 lisr26,0x4F60 at h
 orir26,r26,0x4F60 at l
 li  r25,LED_STATE_0
 stw r25,0(r26)

 /* We have to turn on the MMU right away so we get cache modes
  * set correctly.
  */
 blinitial_mmu

 /* CRD: set LED state here */
 lisr26,0x4F60 at h
 orir26,r26,0x4F60 at l
 li  r25,LED_STATE_1
 stw r25,0(r26)

 /* We now have the lower 16 Meg mapped into TLB entries, and the caches
  * ready to work.
  */
 turn_on_mmu:
 lisr0,MSR_KERNEL at h
 orir0,r0,MSR_KERNEL at l
 mtsprSPRN_SRR1,r0
 lisr0,start_here at h
 orir0,r0,start_here at l
 mtsprSPRN_SRR0,r0
 SYNC

 /* CRD: set LED state here */
 lisr26,0x4F60 at h
 orir26,r26,0x4F60 at l
 li  r25,LED_STATE_2
 stw r25,0(r26)

 rfi/* enables MMU */

 /* CRD: set LED state here */
 /* This address should be a virtual address */
 lisr26,0x4F60 at h
 orir26,r26,0x4F60 at l
 li  r25,LED_STATE_3
 stw r25,0(r26)

 b./* prevent prefetch past rfi */

 Regards,
 Chris Dumoulin
   


-- 
Dave Lynch  DLA Systems
Software Development:Embedded Linux
717.627.3770   dhlii at dlasys.nethttp://www.dlasys.net
fax: 1.253.369.9244Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too 
numerous to list.

Any intelligent fool can make things bigger and more complex... It takes a 
touch of genius - and a lot of courage to move in the opposite direction.
Albert Einstein