Reply by April 30, 20102010-04-30
Am Wed, 28 Apr 2010 12:12:48 +0100
schrieb Brian Drummond <brian_drummond@btconnect.com>:

> On Wed, 28 Apr 2010 00:12:05 +0200, Martin Br=FCckner <bj2spam@alice-dsl.=
net>
> wrote: >=20 > >Am Tue, 27 Apr 2010 11:17:03 +0100 > >schrieb Brian Drummond <brian_drummond@btconnect.com>: > > > >> On Tue, 27 Apr 2010 10:03:34 +0200, Martin Br=FCckner > >> <bj2spam@alice-dsl.net> wrote: >=20 > >> >> > (*linux)(); > >> >>=20 > >> >> With the assumption that data pointers can be properly > >> >> cast to function pointers, that line should jump to=20 > >> >> location 0x4002b4 and start executing the code there. >=20 > >> Xilinx example code typically has boilerplate to do things like > >> invalidate caches and set up interrupt state before handing over to > >> "real" code. >=20 > >> Have you covered these bases in your own code? > > > >When I started with this project I was sure that Linux invalidates > >caches and sets up the interrupt state a >=20 > You are probably correct on interrupts, but on caches... >=20 > >Anyway, all I tried out yet was disabling the cache but that did not > >help.=20 >=20 > That would do it. Lets Linux invalidate, then enable them when safe. > If that's not your problem, then I can't help further. >=20 > The only other gotchas I remember are: >=20 > (1) the interrupt vector table has to be on a 64k boundary. The tools let=
you
> put it anywhere but the bottom 16 address bits are chopped by the PPC!
Good to know but in my linker script the interrupt vector starts at 0x00000000
>=20 > (2) Downloading a bitfile via Impact, there was one (probably V2Pro-speci=
fic)
> tick box that had to be set to reset the PPC correctly. The only reason I > mention this was that starting via XMD worked correctly.
Yes, there was this box for V2P FPGAs.
>=20 > - Brian >=20
Thank you all for your help. I solved the problem with the help of the second PowerPC core integrated in the Virtex 5. Martin
Reply by Brian Drummond April 28, 20102010-04-28
On Wed, 28 Apr 2010 00:12:05 +0200, Martin Br&#4294967295;ckner <bj2spam@alice-dsl.net>
wrote:

>Am Tue, 27 Apr 2010 11:17:03 +0100 >schrieb Brian Drummond <brian_drummond@btconnect.com>: > >> On Tue, 27 Apr 2010 10:03:34 +0200, Martin Br&#4294967295;ckner >> <bj2spam@alice-dsl.net> wrote:
>> >> > (*linux)(); >> >> >> >> With the assumption that data pointers can be properly >> >> cast to function pointers, that line should jump to >> >> location 0x4002b4 and start executing the code there.
>> Xilinx example code typically has boilerplate to do things like >> invalidate caches and set up interrupt state before handing over to >> "real" code.
>> Have you covered these bases in your own code? > >When I started with this project I was sure that Linux invalidates >caches and sets up the interrupt state a
You are probably correct on interrupts, but on caches...
>Anyway, all I tried out yet was disabling the cache but that did not >help.
That would do it. Lets Linux invalidate, then enable them when safe. If that's not your problem, then I can't help further. The only other gotchas I remember are: (1) the interrupt vector table has to be on a 64k boundary. The tools let you put it anywhere but the bottom 16 address bits are chopped by the PPC! (2) Downloading a bitfile via Impact, there was one (probably V2Pro-specific) tick box that had to be set to reset the PPC correctly. The only reason I mention this was that starting via XMD worked correctly. - Brian
Reply by Marc Jet April 28, 20102010-04-28
Martin Br=FCckner wrote:
> When I started with this project I was sure that Linux invalidates > caches
Whatever Linux does, it doesn't matter unless the CPU is able to see and execute it.
Reply by April 28, 20102010-04-28
Am Tue, 27 Apr 2010 04:07:41 -0700 (PDT)
schrieb Marc Jet <jetmarc@hotmail.com>:

> Martin Br=FCckner wrote: > > void (*linux)(); > > ... > > (*linux)(); >=20 > Wouldn't the last line have to be just this? >=20 > linux();
The result of (*linux)() and linux() is the same.
Reply by Martin Brückner April 27, 20102010-04-27
Am Tue, 27 Apr 2010 18:23:11 +0000 (UTC)
schrieb glen herrmannsfeldt <gah@ugcs.caltech.edu>:

> Joe Chisolm <jchisolm6@earthlink.net> wrote: > > On Mon, 26 Apr 2010 22:50:19 +0200, Martin Br?ckner wrote: > > >> I'm writing a boot loader to start Linux on the PowerPC440 > >> (Virtex5FXT). At first the program copies the kernel into the RAM > >> at address 0x00400000 and afterwards it boots Linux with the > >> following lines: > > >> #define LINUX_START_ADDRESS 0x004002b4 > (snip) > >> (*linux)(); > > > Did you setup the stack pointer? The above is going to try and push > > the return address on the stack. Compile with -S and look at the > > resulting asm output. > > Not knowing at all about the linux boot process, I would have > assumed that one of the first thing that the booting kernel does > would be to set up its own stack. > > It might, though, depend on a previous level of boot program > to have set up a stack for it. I wouldn't expect the boot > ROM to have done it, but often there are multiple levels of > boot programs. > > -- glen
As I wrote before (answering Brian), I also assumed that Linux would manage that. What I found out this day is, that the Linux syslog-buffer is empty. Martin
Reply by Martin Brückner April 27, 20102010-04-27
Am Tue, 27 Apr 2010 11:17:03 +0100
schrieb Brian Drummond <brian_drummond@btconnect.com>:

> On Tue, 27 Apr 2010 10:03:34 +0200, Martin Br&uuml;ckner > <bj2spam@alice-dsl.net> wrote: > > >Am Mon, 26 Apr 2010 22:08:02 +0000 (UTC) > >schrieb glen herrmannsfeldt <gah@ugcs.caltech.edu>: > > > >> Martin Br?ckner <bj2spam@alice-dsl.net> wrote: > >> > >> > I'm writing a boot loader to start Linux on the PowerPC440 > >> > (Virtex5FXT). At first the program copies the kernel into the RAM > >> > at address 0x00400000 and afterwards it boots Linux with the > >> > following lines: > >> > >> > #define LINUX_START_ADDRESS 0x004002b4 > >> > >> (snip) > >> > >> > (*linux)(); > >> > >> With the assumption that data pointers can be properly > >> cast to function pointers, that line should jump to > >> location 0x4002b4 and start executing the code there. > > I haven't used the PPC since the V2Pro, but... > > Xilinx example code typically has boilerplate to do things like > invalidate caches and set up interrupt state before handing over to > "real" code. It is possible that using XMD to reset the CPU does that > for you. > > Have you covered these bases in your own code?
When I started with this project I was sure that Linux invalidates caches and sets up the interrupt state and the comments in arch/powerpc/kernel/head_44x.S seems to confirm that (I am not deep enough into PowerPC Assembler to understand all of its code). Probably there might be a bug in this initializing code. Anyway, all I tried out yet was disabling the cache but that did not help. Do you know where to find more Xilinx-Commands to handle Cache and MMU?
> > - Brian
Martin
Reply by glen herrmannsfeldt April 27, 20102010-04-27
Joe Chisolm <jchisolm6@earthlink.net> wrote:
> On Mon, 26 Apr 2010 22:50:19 +0200, Martin Br?ckner wrote:
>> I'm writing a boot loader to start Linux on the PowerPC440 (Virtex5FXT). >> At first the program copies the kernel into the RAM at address >> 0x00400000 and afterwards it boots Linux with the following lines:
>> #define LINUX_START_ADDRESS 0x004002b4
(snip)
>> (*linux)();
> Did you setup the stack pointer? The above is going to try and push > the return address on the stack. Compile with -S and look at the > resulting asm output.
Not knowing at all about the linux boot process, I would have assumed that one of the first thing that the booting kernel does would be to set up its own stack. It might, though, depend on a previous level of boot program to have set up a stack for it. I wouldn't expect the boot ROM to have done it, but often there are multiple levels of boot programs. -- glen
Reply by Joe Chisolm April 27, 20102010-04-27
On Mon, 26 Apr 2010 22:50:19 +0200, Martin Br&uuml;ckner wrote:

> Hello, > > I'm writing a boot loader to start Linux on the PowerPC440 (Virtex5FXT). > At first the program copies the kernel into the RAM at address > 0x00400000 and afterwards it boots Linux with the following lines: > > #define LINUX_START_ADDRESS 0x004002b4 > > int main() > { > void (*linux)(); > linux = (void*) LINUX_START_ADDRESS; > > ... // here is the code which copies the kernel into ram > > (*linux)(); > } >
Did you setup the stack pointer? The above is going to try and push the return address on the stack. Compile with -S and look at the resulting asm output. [snip]
> Best Regards > Martin Br&uuml;ckner
-- Joe Chisolm Marble Falls, Tx.
Reply by Marc Jet April 27, 20102010-04-27
Martin Br=FCckner wrote:
> void (*linux)(); > ... > (*linux)();
Wouldn't the last line have to be just this? linux();
Reply by Brian Drummond April 27, 20102010-04-27
On Tue, 27 Apr 2010 10:03:34 +0200, Martin Br&#4294967295;ckner
<bj2spam@alice-dsl.net> wrote:

>Am Mon, 26 Apr 2010 22:08:02 +0000 (UTC) >schrieb glen herrmannsfeldt <gah@ugcs.caltech.edu>: > >> Martin Br?ckner <bj2spam@alice-dsl.net> wrote: >> >> > I'm writing a boot loader to start Linux on the PowerPC440 >> > (Virtex5FXT). At first the program copies the kernel into the RAM >> > at address 0x00400000 and afterwards it boots Linux with the >> > following lines: >> >> > #define LINUX_START_ADDRESS 0x004002b4 >> >> (snip) >> >> > (*linux)(); >> >> With the assumption that data pointers can be properly >> cast to function pointers, that line should jump to >> location 0x4002b4 and start executing the code there.
I haven't used the PPC since the V2Pro, but... Xilinx example code typically has boilerplate to do things like invalidate caches and set up interrupt state before handing over to "real" code. It is possible that using XMD to reset the CPU does that for you. Have you covered these bases in your own code? - Brian