* Re: Ethernet driver for Linux kernel 2.6 running on ML403
From: Andrew @ 2006-09-19 18:06 UTC (permalink / raw)
To: John Bonesio; +Cc: linuxppc-embedded
In-Reply-To: <2FE3DBF1797A1443AAB3FA0EF6BF4EEC021EA645@XSJ-EXCHVS1.xlnx.xilinx.com>
On Thu, 14 Sep 2006 09:40:53 -0700
"John Bonesio" <john.bonesio@xilinx.com> wrote:
> I am in the group that has control over how this is done. What would
> you propose be done different? Keep in mind that we are trying to
> support a process where someone builds a hardware design and the
> later changes it with new peripherals or perhaps makes minor tweaks.
> We want to make the updating of the Linux kernel to reflect these
> hardware changes easy for people.
>
> Having the ability to make rapid hardware changes, I think, is a bit
> different from what most folks are used to.
I am coming into this a bit late and it has been awhile since I worked
Virtex parts. But it doesn't look like things have changed much.
Since Linux is from a PC base, hardware changes are as rapid as
powering off and plugging a new device in the machine. Rebuilding the
kernel for this is not usually something people consider for this.
So to say Linux people aren't use to rapid hardware changes, seems
pretty backwards to me.
The static configuration of the hardware is the thing that is very
unusual for the software. And having that static hardware setup
compiled into the kernel is a real source of problems.
Typically things get probed, discovered/learned at boot time. Either by
the boot loader, pin strapping, dip switches, user config etc.
I worked on a board with 2 Virtex chips. They had some set of common IP
cores with minor differences between the two. There was no way I wanted
to build 2 sets of kernels and drivers to deal with things.
The first small difference of one chip having 2 serial ports and the
other side only having 1 serial port, rippled the entire IRQ mapping in
both xparameters.h file. There were all kinds of little changes between
the mem mapping and everything else as well.
Depending on how things were used from xparemeters.h I could change the
static numbers to function calls to get values, but most of the time I
easist to hack up the drivers to pick one of two values depending on
the chip.
At first I just used a kernel boot param saved in u-boot flash to tell
the SW which chip it was running on. Then I got our HW people to put
in a single bit in another register for SW to tell which chip was
running. That saved us setup step in production of setting up flash
with different items.
There are trade offs on how much it is worth being determined at run
time compared to compiled into the kernel, but with the current
xparemters.h you are stuck with things compiled in. Getting to a point
where anything can be learned at run time, or just pulled from flash
would be a big step forward. But at that point it should still be easy
to compile things into the kernel if someone has major sw space
constraints.
I also keep hearing about doing partial re-configuration bit streams.
Were the FPGA can change at run time as well. (ie switch from an
CAT5 ethernet IP core over to an 802.11 ethernet depending on if the
user plugs in a cable or an antenna)
How would you even plan to do that with the xparemters.h file and the
drivers as it is now?
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Linas Vepstas @ 2006-09-19 18:29 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20060919222351.d27a1a06.sfr@canb.auug.org.au>
On Tue, Sep 19, 2006 at 10:23:51PM +1000, Stephen Rothwell wrote:
Perhaps this:
> +void _insb(volatile u8 __iomem *port, void *buf, int ns)
> +{
> + asm volatile("sync");
> + if (ns <= 0)
> + return;
> + asm volatile(
should be this:
> +void _insb(volatile u8 __iomem *port, void *buf, int ns)
> +{
> + if (ns <= 0)
> + return;
> + asm volatile("sync");
> + asm volatile(
to assuage David Howell's concern. Not that ns should be negative
in the first place ... but what the hey.
Re Davids other comment: "ns" stands for "no byte-swap", and
"s" stands for "string" so "insl_ns" is input string of longs,
no byte swap.
Here's a question:
> + asm volatile(
> + "mtctr %2\n"
> + "subi %1,%1,1\n"
> + "0: lbz %2,0(%0)\n"
> + "eieio\n"
> + "stbu %2,1(%1)\n"
> + "bdnz 0b\n"
> + "twi 0,%2,0\n"
What does this twi do? According to my powerpc docs, this would be a
no-op. Does this have some magic synchronizing powers on certain
implementations? If so, there should be at least a comment card added
about why the twi is there. (This special ability of twi might be
well-known to some, but still, this is not immediately obvious,
and not immedately documented in e.g. the PEM.)
--linas
^ permalink raw reply
* Re: Fw: [PATCH] Remove powerpc specific parts of 3c509 driver
From: Linas Vepstas @ 2006-09-19 18:42 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: akpm, ppc-dev, jgarzik, netdev
In-Reply-To: <20060919145433.8fc7d478.sfr@canb.auug.org.au>
On Tue, Sep 19, 2006 at 02:54:33PM +1000, Stephen Rothwell wrote:
>
> On powerpc and ppc, insl_ns and insl are identical as are outsl_ns and
> outsl, so remove the conditional use of insl_ns and outsl_ns.
The rest of this patch might indeed be correct, but the above comment
bothers me. The "ns" versions of routines are supposed to be
non-byte-swapped versions of the insl/outsl routines (which would
byte-swap on big-endian archs such as powerpc.)
> diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
> index cbdae54..add6381 100644
> --- a/drivers/net/3c509.c
> +++ b/drivers/net/3c509.c
> @@ -879,11 +879,7 @@ #endif
> outw(skb->len, ioaddr + TX_FIFO);
> outw(0x00, ioaddr + TX_FIFO);
> /* ... and the packet rounded to a doubleword. */
> -#ifdef __powerpc__
> - outsl_ns(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
> -#else
> outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
> -#endif
Dohh, a hack like this to work around some possbile byte-swapping
bug should never have been done in the first place :-(
However, I presume someone added the __powerpc__ define here
because they picked up a 3c509 at a garage sale, stuck it in
a powerpc, found out it didn't work due to a byte-swapping bug,
and then patched it as above. I'm disturbed that somehow
outsl_ns() became identical to outsl() at some point, presumably
breaking this patch.
--linas
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Kim Phillips @ 2006-09-19 18:52 UTC (permalink / raw)
To: Linas Vepstas; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <20060919182953.GK29167@austin.ibm.com>
On Tue, 19 Sep 2006 13:29:53 -0500
linas@austin.ibm.com (Linas Vepstas) wrote:
>
> What does this twi do? According to my powerpc docs, this would be a
> no-op. Does this have some magic synchronizing powers on certain
> implementations? If so, there should be at least a comment card added
> about why the twi is there. (This special ability of twi might be
> well-known to some, but still, this is not immediately obvious,
> and not immedately documented in e.g. the PEM.)
include/asm-p[ower]pc/io.h sheds some light on the matter:
* With the sequence below (twi; isync; nop), we have found that
* the machine check occurs on one of the three instructions on
* all PPC implementations tested so far. The twi and isync are
* needed on the 601 (in fact twi; sync works too), the isync and
* nop are needed on 604[e|r], and any of twi, sync or isync will
* work on 603[e], 750, 74xx.
* The twi creates an explicit data dependency on the returned
* value which seems to be needed to make the 601 wait for the
* load to finish.
Kim
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Matt Sealey @ 2006-09-19 18:58 UTC (permalink / raw)
To: Kim Phillips; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <20060919135259.303706d3.kim.phillips@freescale.com>
Shouldn't this stuff be optimized out depending on what processor you're
ACTUALLY running?
For a generic "powerpc" kernel it can be understood, but when you
consider that on 970/POWER4 and above they use lwsync instead of sync
(google for them and see the mailing list posts :), just to breathe back
some performance in spinlocks and so on, surely this can be rejigged so
that processors don't do more work than necessary..? Even a noop takes
time doesn't it?
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
Kim Phillips wrote:
> On Tue, 19 Sep 2006 13:29:53 -0500
> linas@austin.ibm.com (Linas Vepstas) wrote:
>
>> What does this twi do? According to my powerpc docs, this would be a
>> no-op. Does this have some magic synchronizing powers on certain
>> implementations? If so, there should be at least a comment card added
>> about why the twi is there. (This special ability of twi might be
>> well-known to some, but still, this is not immediately obvious,
>> and not immedately documented in e.g. the PEM.)
>
> include/asm-p[ower]pc/io.h sheds some light on the matter:
>
> * With the sequence below (twi; isync; nop), we have found that
> * the machine check occurs on one of the three instructions on
> * all PPC implementations tested so far. The twi and isync are
> * needed on the 601 (in fact twi; sync works too), the isync and
> * nop are needed on 604[e|r], and any of twi, sync or isync will
> * work on 603[e], 750, 74xx.
> * The twi creates an explicit data dependency on the returned
> * value which seems to be needed to make the 601 wait for the
> * load to finish.
>
> Kim
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: Fw: [PATCH] Remove powerpc specific parts of 3c509 driver
From: Matt Sealey @ 2006-09-19 18:52 UTC (permalink / raw)
To: Linas Vepstas; +Cc: akpm, Stephen Rothwell, netdev, jgarzik, ppc-dev
In-Reply-To: <20060919184243.GL29167@austin.ibm.com>
Some northbridges and PCI bridges have "clever" byteswapping in
hardware, maybe this is just an effect of that. In theory depending on
the host bridge, you should pass in big endian data and have it swap or
not swap, not pick that way in the driver, UNLESS your driver expects
bigendian data, in which case on a bigendian platform you can tell it to
write without swapping. Voila, two functions.
However the existance of these PCI bridges these days? I haven't seen
one in years, and when I have nobody has ever enabled the magic swappy
thing as it's unreliable and can't always tell how you present the data.
One wishes that there was a ntoh and hton style macro in standard use
for PCI access.. hang on though that jsut wouldn't work would it.
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
Linas Vepstas wrote:
> On Tue, Sep 19, 2006 at 02:54:33PM +1000, Stephen Rothwell wrote:
>> On powerpc and ppc, insl_ns and insl are identical as are outsl_ns and
>> outsl, so remove the conditional use of insl_ns and outsl_ns.
>
> The rest of this patch might indeed be correct, but the above comment
> bothers me. The "ns" versions of routines are supposed to be
> non-byte-swapped versions of the insl/outsl routines (which would
> byte-swap on big-endian archs such as powerpc.)
>
>> diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
>> index cbdae54..add6381 100644
>> --- a/drivers/net/3c509.c
>> +++ b/drivers/net/3c509.c
>> @@ -879,11 +879,7 @@ #endif
>> outw(skb->len, ioaddr + TX_FIFO);
>> outw(0x00, ioaddr + TX_FIFO);
>> /* ... and the packet rounded to a doubleword. */
>> -#ifdef __powerpc__
>> - outsl_ns(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
>> -#else
>> outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
>> -#endif
>
> Dohh, a hack like this to work around some possbile byte-swapping
> bug should never have been done in the first place :-(
>
> However, I presume someone added the __powerpc__ define here
> because they picked up a 3c509 at a garage sale, stuck it in
> a powerpc, found out it didn't work due to a byte-swapping bug,
> and then patched it as above. I'm disturbed that somehow
> outsl_ns() became identical to outsl() at some point, presumably
> breaking this patch.
>
> --linas
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Linas Vepstas @ 2006-09-19 19:04 UTC (permalink / raw)
To: Kim Phillips; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <20060919135259.303706d3.kim.phillips@freescale.com>
On Tue, Sep 19, 2006 at 01:52:59PM -0500, Kim Phillips wrote:
> On Tue, 19 Sep 2006 13:29:53 -0500
> linas@austin.ibm.com (Linas Vepstas) wrote:
>
> >
> > What does this twi do? According to my powerpc docs, this would be a
> > no-op. Does this have some magic synchronizing powers on certain
> > implementations? If so, there should be at least a comment card added
> > about why the twi is there. (This special ability of twi might be
> > well-known to some, but still, this is not immediately obvious,
> > and not immedately documented in e.g. the PEM.)
>
> include/asm-p[ower]pc/io.h sheds some light on the matter:
>
> * With the sequence below (twi; isync; nop), we have found that
> * the machine check occurs on one of the three instructions on
> * all PPC implementations tested so far. The twi and isync are
> * needed on the 601 (in fact twi; sync works too), the isync and
> * nop are needed on 604[e|r], and any of twi, sync or isync will
> * work on 603[e], 750, 74xx.
> * The twi creates an explicit data dependency on the returned
> * value which seems to be needed to make the 601 wait for the
> * load to finish.
Thanks. I notice that this commentary appears in asm-ppc/io.h
but not in asm-powerpc/io.h -- Perhaps a patch is in order ...
I'm creating such a patch now ...
--linas
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Segher Boessenkool @ 2006-09-19 19:06 UTC (permalink / raw)
To: Linas Vepstas; +Cc: Stephen Rothwell, paulus, ppc-dev
In-Reply-To: <20060919182953.GK29167@austin.ibm.com>
> What does this twi do? According to my powerpc docs, this would be a
> no-op. Does this have some magic synchronizing powers on certain
> implementations?
On all implementations; it's in the PowerPC architecture.
A data-dependent branch followed by an isync ensures that no
instructions after the isync in program order will be
(speculatively) executed, so the load that the twi depends
on has to complete before anything else is executed; in
particular, it's a barrier to keep MMIO reads ordered before
main-storage accesses.
Note that twi alone is not enough; it needs an isync as well.
Any other data-dependent branch instead of twi would do fine
as well.
Segher
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Segher Boessenkool @ 2006-09-19 19:10 UTC (permalink / raw)
To: Matt Sealey; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <45103DF0.9050409@genesi-usa.com>
> For a generic "powerpc" kernel it can be understood, but when you
> consider that on 970/POWER4 and above they use lwsync instead of sync
lwsync (sync 1) doesn't (architecturally) do anything to order MMIO
accesses, so you're misunderstanding something.
> (google for them and see the mailing list posts :), just to breathe
> back
> some performance in spinlocks and so on, surely this can be
> rejigged so
> that processors don't do more work than necessary..? Even a noop takes
> time doesn't it?
No-ops don't matter for performance, compared to the cost of the I/O
itself. It would help to avoid heavier-than-necessary synchronisation
instructions if not needed on some certain CPU (or on non-SMP kernels,
etc.)
Segher
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Matt Sealey @ 2006-09-19 19:20 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <9E674786-9AF3-4322-B642-7BAA58462B74@kernel.crashing.org>
Segher Boessenkool wrote:
>> For a generic "powerpc" kernel it can be understood, but when you
>> consider that on 970/POWER4 and above they use lwsync instead of sync
>
> lwsync (sync 1) doesn't (architecturally) do anything to order MMIO
> accesses, so you're misunderstanding something.
See below :D
>> (google for them and see the mailing list posts :), just to breathe back
>> some performance in spinlocks and so on, surely this can be rejigged so
>> that processors don't do more work than necessary..? Even a noop takes
>> time doesn't it?
>
> No-ops don't matter for performance, compared to the cost of the I/O
> itself. It would help to avoid heavier-than-necessary synchronisation
> instructions if not needed on some certain CPU (or on non-SMP kernels,
> etc.)
But it couldn't hurt, right? There has to be an application note per-CPU
on the correct sequence of operations for such an access (I seem to have
collected a directory full for firmware development), it seems a little
odd to pick and choose one instruction over another for one thing, and
then say you need to do it to support the 601 of all things, and run
this code against the G3/G4/G5 which perhaps doesn't care or is more
intelligent about it (or is guaranteed to have a more intelligent host
bridge at least).
Maybe I'm talking crap, please say so :D
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
^ permalink raw reply
* [PATCH]: powerpc: clarify use of twi/isync in io macros
From: Linas Vepstas @ 2006-09-19 19:30 UTC (permalink / raw)
To: paulus; +Cc: Stephen Rothwell, ppc-dev
Paul, please apply.
Clarify why twi appears in the i/o macros.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Segher Boessenkool <segher@kernel.crashing.org>
----
include/asm-powerpc/io.h | 11 +++++++++++
1 file changed, 11 insertions(+)
Index: linux-2.6.18-rc7-git1/include/asm-powerpc/io.h
===================================================================
--- linux-2.6.18-rc7-git1.orig/include/asm-powerpc/io.h 2006-09-14 13:38:48.000000000 -0500
+++ linux-2.6.18-rc7-git1/include/asm-powerpc/io.h 2006-09-19 14:26:26.000000000 -0500
@@ -278,6 +278,17 @@ static inline void iosync(void)
* These routines do not perform EEH-related I/O address translation,
* and should not be used directly by device drivers. Use inb/readb
* instead.
+ *
+ * Read operations have additional twi & isync to make sure the read
+ * is actually performed (i.e. the data has come back) before we start
+ * executing any following instructions.
+ *
+ * A data-dependent branch followed by an isync ensures that no
+ * instructions after the isync in program order will be
+ * (speculatively) executed, so the load that the twi depends
+ * on has to complete before anything else is executed; in
+ * particular, it's a barrier to keep MMIO reads ordered before
+ * main-storage accesses.
*/
static inline int in_8(const volatile unsigned char __iomem *addr)
{
^ permalink raw reply
* Re: Fw: [PATCH] Remove powerpc specific parts of 3c509 driver
From: Linas Vepstas @ 2006-09-19 19:44 UTC (permalink / raw)
To: Matt Sealey; +Cc: akpm, Stephen Rothwell, netdev, jgarzik, ppc-dev
In-Reply-To: <45103C62.4080003@genesi-usa.com>
On Tue, Sep 19, 2006 at 08:52:18PM +0200, Matt Sealey wrote:
[...]
>
> Linas Vepstas wrote:
> >On Tue, Sep 19, 2006 at 02:54:33PM +1000, Stephen Rothwell wrote:
> >>On powerpc and ppc, insl_ns and insl are identical as are outsl_ns and
> >>outsl, so remove the conditional use of insl_ns and outsl_ns.
> >
> >The rest of this patch might indeed be correct, but the above comment
> >bothers me. The "ns" versions of routines are supposed to be
> >non-byte-swapped versions of the insl/outsl routines (which would
Never mind. Silly me don't know my history.
asm-powerpc/io.h clearly states
* The *_ns versions below don't do byte-swapping.
* Neither do the standard versions now, these are just here
* for older code.
Seems that the byteswapping machanism was changed a while ago,
and no longer handled in this way any more.
--linas
^ permalink raw reply
* Re: common flatdevtree code
From: Mark A. Greer @ 2006-09-19 19:45 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Hollis Blanchard
In-Reply-To: <17665.28367.380866.565218@cargo.ozlabs.ibm.com>
On Fri, Sep 08, 2006 at 11:23:27PM +1000, Paul Mackerras wrote:
Content-Description: message body text
> Mark,
>
> Here's where I'm up to...
>
> Paul.
Paul,
Any update to this or do you want to go with this? (I haven't tested
it, btw).
Mark
^ permalink raw reply
* Re: [POWERPC] convert string i/o operations to C
From: Segher Boessenkool @ 2006-09-19 19:47 UTC (permalink / raw)
To: Matt Sealey; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <45104304.3000205@genesi-usa.com>
> But it couldn't hurt, right? There has to be an application note
> per-CPU on the correct sequence of operations for such an access (I
> seem to have collected a directory full for firmware development),
The architecture describes the rules already, not many CPUs
have "faster"/"better" sequences.
> it seems a little odd to pick and choose one instruction over
> another for one thing, and then say you need to do it to support
> the 601 of all things, and run this code against the G3/G4/G5 which
> perhaps doesn't care or is more intelligent about it (or is
> guaranteed to have a more intelligent host bridge at least).
The comment you're referring to is old; it doesn't talk about
synchronisation requirements, but focuses on having the CPU
trap on exactly these instructions when an access causes a
(asynchronous) machine check. Asynchronous exceptions don't
necessarily return the instruction pointer where the real
failure was, so it's no surprise different CPUs have a different
idea about it. It's pretty safe to assume (but not guaranteed)
that it will always be somewhere between the load and the insn
after the isync, inclusive, though.
Segher
^ permalink raw reply
* Re: [PATCH]: powerpc: clarify use of twi/isync in io macros
From: Segher Boessenkool @ 2006-09-19 19:57 UTC (permalink / raw)
To: Linas Vepstas; +Cc: Stephen Rothwell, paulus, ppc-dev
In-Reply-To: <20060919193020.GN29167@austin.ibm.com>
> + *
> + * Read operations have additional twi & isync to make sure the read
> + * is actually performed (i.e. the data has come back) before we
> start
> + * executing any following instructions.
> + *
> + * A data-dependent branch followed by an isync ensures that no
> + * instructions after the isync in program order will be
> + * (speculatively) executed
..."before the isync has completed, and it won't complete until
the branch is resolved;"...
> so the load that the twi depends
> + * on has to complete before anything else is executed; in
> + * particular, it's a barrier to keep MMIO reads ordered before
> + * main-storage accesses.
> */
You shouldn't post my test and put your signed-off on it, esp.
if I forgot to type half a sentence :-) Here, have one though:
Signed-off-by: Segher Boessenkool <segher@kernel.crashing.org>
Segher
^ permalink raw reply
* Re: Ethernet driver for Linux kernel 2.6 running on ML403
From: Grant Likely @ 2006-09-19 20:10 UTC (permalink / raw)
To: Peter Korsgaard; +Cc: linuxppc-embedded
In-Reply-To: <528646bc0609190717u1c7cd349m7e08e5bafd341c38@mail.gmail.com>
On 9/19/06, Grant Likely <grant.likely@secretlab.ca> wrote:
> On 9/19/06, Peter Korsgaard <jacmet@sunsite.dk> wrote:
> > >>>>> "GL" == Grant Likely <grant.likely@secretlab.ca> writes:
> > GL> If we reject the Xilinx driver code, then we either have to do
> > GL> without Xilinx support in mainline, or we need to write new
> > GL> drivers that address the above issues (support multiple IP
> > GL> versions, etc). The Xilinx support in mainline right now does not
> > GL> use any Xilinx code. (Xilinx PIC and UART).
> >
> > I think the best option is to simply forget about the Xilinx code,
> > see the FPGAs as any other PPC system and write normal device drivers
> > for it. Your platform bus stuff and my (to-be-mainlined) uartlite
> > driver is a first step in this direction..
>
> Too bad platform bus is sooo last year. :p
>
> Time to hack device trees.
Avast! After getting quizzed on IRC about this off-the-cuff comment,
I should probably clarify. Since the Xilinx IP could be wired up to a
ublaze core or an off-chip processor, the drivers still need to use a
platform bus attachment to keep it all cross platform.
So, replace above comment with the following:
Populating the platform device with static code during initialization
is sooo last year.
Time to hack device trees to populate it instead.
:)
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: [PATCH]: powerpc: clarify use of twi/isync in io macros
From: Linas Vepstas @ 2006-09-19 20:10 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Stephen Rothwell, paulus, ppc-dev
In-Reply-To: <72674737-8325-48FA-B04F-C4ADCA2E2BF9@kernel.crashing.org>
On Tue, Sep 19, 2006 at 09:57:11PM +0200, Segher Boessenkool wrote:
> ..."before the isync has completed, and it won't complete until
> the branch is resolved;"...
New improved patch attched.
> You shouldn't post my test and put your signed-off on it, esp.
> if I forgot to type half a sentence :-) Here, have one though:
My moral fiber did twinge before I hit the send button,
but I confused it with a muscle spasm.
> Signed-off-by: Segher Boessenkool <segher@kernel.crashing.org>
--------
Clarify why twi appears in the i/o macros.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Segher Boessenkool <segher@kernel.crashing.org>
----
include/asm-powerpc/io.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
Index: linux-2.6.18-rc7-git1/include/asm-powerpc/io.h
===================================================================
--- linux-2.6.18-rc7-git1.orig/include/asm-powerpc/io.h 2006-09-14 13:38:48.000000000 -0500
+++ linux-2.6.18-rc7-git1/include/asm-powerpc/io.h 2006-09-19 15:04:30.000000000 -0500
@@ -278,6 +278,18 @@ static inline void iosync(void)
* These routines do not perform EEH-related I/O address translation,
* and should not be used directly by device drivers. Use inb/readb
* instead.
+ *
+ * Read operations have additional twi & isync to make sure the read
+ * is actually performed (i.e. the data has come back) before we start
+ * executing any following instructions.
+ *
+ * A data-dependent branch followed by an isync ensures that no
+ * instructions after the isync in program order will be
+ * (speculatively) executed before the isync has completed, and
+ * the isync won't complete until the branch is resolved. The
+ * the load that the twi depends on has to complete before
+ * anything else is executed; in particular, it's a barrier to
+ * keep MMIO reads ordered before main-storage accesses.
*/
static inline int in_8(const volatile unsigned char __iomem *addr)
{
^ permalink raw reply
* Re: [PATCH]: powerpc: clarify use of twi/isync in io macros
From: Segher Boessenkool @ 2006-09-19 20:30 UTC (permalink / raw)
To: Linas Vepstas; +Cc: Stephen Rothwell, paulus, ppc-dev
In-Reply-To: <20060919201053.GP29167@austin.ibm.com>
> My moral fiber did twinge before I hit the send button,
> but I confused it with a muscle spasm.
Heh.
> Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
> Signed-off-by: Segher Boessenkool <segher@kernel.crashing.org>
The other way around, or change mine to a From: -- you took my
stuff, not the other way around. Oh well, doesn't matter as
far as I'm concerned. Some people think that keeping the chain
in the correct order is very important though. Let's just say
it was a cooperative work and fool them all :-)
Segher
^ permalink raw reply
* Re: Ethernet driver for Linux kernel 2.6 running on ML403
From: David H. Lynch Jr. @ 2006-09-19 20:40 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <528646bc0609191310l240d9f94tb18415941f8b5d4f@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2138 bytes --]
Grant Likely wrote:
>
>
> Avast! After getting quizzed on IRC about this off-the-cuff comment,
> I should probably clarify. Since the Xilinx IP could be wired up to a
> ublaze core or an off-chip processor, the drivers still need to use a
> platform bus attachment to keep it all cross platform.
>
> So, replace above comment with the following:
>
> Populating the platform device with static code during initialization
> is sooo last year.
>
> Time to hack device trees to populate it instead.
>
So I got another X V4 board. I hacked in the Platform device stuff
from you ml403 code with changes needed for my hardware.
and my brain is slowly begining to actually grasp what is going on
- I am begining to grasp the platform devices big picture (over a
mountain through a spyglass in the fog)
Where do I begin with Device Trees ?
The vague Picture I have is the have something to do with some
datastructure that Mac's typically create at or prior to boot. And that
for embedded systems we are building them
externally compiling them and then attaching the compiled device
tree to our project.
I got a Xilinv V4 device currently with a Pic, UartLite, TEMAC,
Flash and Keyhole (pseuodo serial host interface). Of those it is only
certain that the flash will always be there.
We have bit images with Keyhole only, Uartlite only TEMAC only,
Sometimes we have a Pic sometimes not. I was trying to get to the point
were I could dynamically add what was there
to Platform devices during initialization.
If Device trees are static, then do they even apply to what I have
to deal with ?
Please pardon my ignorance.
--
Dave Lynch DLA Systems
Software Development: Embedded Linux
717.627.3770 dhlii@dlasys.net http://www.dlasys.net
fax: 1.253.369.9244 Cell: 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
[-- Attachment #2: Type: text/html, Size: 2866 bytes --]
^ permalink raw reply
* Re: Ethernet driver for Linux kernel 2.6 running on ML403
From: Grant Likely @ 2006-09-19 21:27 UTC (permalink / raw)
To: David H. Lynch Jr.; +Cc: linuxppc-embedded
In-Reply-To: <451055D2.5080308@dlasys.net>
On 9/19/06, David H. Lynch Jr. <dhlii@dlasys.net> wrote:
>
> Grant Likely wrote:
>
> Avast! After getting quizzed on IRC about this off-the-cuff comment,
> I should probably clarify. Since the Xilinx IP could be wired up to a
> ublaze core or an off-chip processor, the drivers still need to use a
> platform bus attachment to keep it all cross platform.
>
> So, replace above comment with the following:
>
> Populating the platform device with static code during initialization
> is sooo last year.
>
> Time to hack device trees to populate it instead.
>
> So I got another X V4 board. I hacked in the Platform device stuff from
> you ml403 code with changes needed for my hardware.
> and my brain is slowly begining to actually grasp what is going on - I
> am begining to grasp the platform devices big picture (over a mountain
> through a spyglass in the fog)
>
> Where do I begin with Device Trees ?
Step 1: run away
Step 2: don't look back.
Just kidding. Unless you want to help move Virtex support from
arch/ppc to arch/powerpc, you don't really need to worry about device
trees for a while.
If you are interested, look at
Documentation/powerpc/booting-without-of.txt. Then start poking Matt
Porter about when he's going to get 4xx ported to arch/powerpc.
I've been half heartedly looking at what needs to be done to generate
a device tree based on either system.mhs or xparameters.h. I'm
probably going to write a tiny C program that is compiled against
xparameters.h and spits out a valid dts file. The dts file can then
be run through the device tree compiler to produce the flattened
device tree structure.
>
> The vague Picture I have is the have something to do with some
> datastructure that Mac's typically create at or prior to boot. And that for
> embedded systems we are building them
> externally compiling them and then attaching the compiled device tree
> to our project.
That right. You don't compile device base addresses, irqs, etc into
the kernel. You pass them in at boot time with a data structure.
>
> I got a Xilinv V4 device currently with a Pic, UartLite, TEMAC, Flash
> and Keyhole (pseuodo serial host interface). Of those it is only certain
> that the flash will always be there.
> We have bit images with Keyhole only, Uartlite only TEMAC only,
> Sometimes we have a Pic sometimes not. I was trying to get to the point were
> I could dynamically add what was there
> to Platform devices during initialization.
>
> If Device trees are static, then do they even apply to what I have to
> deal with ?
Device trees don't have to be static. They can be generated/modified
on the fly if the bootloader supports it. Or you can pass a different
tree depending on what IP you have on the board.
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* JTAG debugger for MPC82xx/MPC83xx
From: Steven Hein @ 2006-09-19 21:51 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
My group is starting a new project includes a custom board
with an MPC8258E processor on it. I'm in the process
of evaluating the state of the Linux kernel, toolchains,
etc. for the MPC8258E/MPC8360E, as well as selecting a
JTAG debugger for our project.
I've been researching the available JTAG debuggers that
support the MPC82xx/MPC83xx family, and I've found these
choices so far:
* Abatron BDI-2000
* Green Hills Probe
* Freescale's PowerTAP PRO for PowerPC
* Lauterbach TRACE32-ICD
* WindRiver ICE
* Embedded Toolsmiths Guardian-SE (BUT...this is no longer
being sold, according to an email response I received
from Embedded Toolsmiths)
We will definitely want one with a network connection,
and will will run the debugger software from a Linux host.
Ideally, we would also like one that provides a library
to allow us to write apps to function the debugger.
Can anyone comment on what JTAG debugger they are using,
and how have your experiences been? Are there any other
good options besides the ones mentioned above.
I'd appreciate any input.
Thanks!
Steve
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Steve Hein (ssh@sgi.com) Engineering Diagnostics/Software
Silicon Graphics, Inc.
1168 Industrial Blvd. Phone: (715) 726-8410
Chippewa Falls, WI 54729 Fax: (715) 726-6715
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^ permalink raw reply
* Re: JTAG debugger for MPC82xx/MPC83xx
From: Andy Gospodarek @ 2006-09-19 22:30 UTC (permalink / raw)
To: Steven Hein; +Cc: linuxppc-embedded
In-Reply-To: <4510664B.2020304@sgi.com>
On 9/19/06, Steven Hein <ssh@sgi.com> wrote:
> Hi,
>
> My group is starting a new project includes a custom board
> with an MPC8258E processor on it. I'm in the process
> of evaluating the state of the Linux kernel, toolchains,
> etc. for the MPC8258E/MPC8360E, as well as selecting a
> JTAG debugger for our project.
>
> I've been researching the available JTAG debuggers that
> support the MPC82xx/MPC83xx family, and I've found these
> choices so far:
>
> * Abatron BDI-2000
> * Green Hills Probe
> * Freescale's PowerTAP PRO for PowerPC
> * Lauterbach TRACE32-ICD
> * WindRiver ICE
> * Embedded Toolsmiths Guardian-SE (BUT...this is no longer
> being sold, according to an email response I received
> from Embedded Toolsmiths)
>
> We will definitely want one with a network connection,
> and will will run the debugger software from a Linux host.
> Ideally, we would also like one that provides a library
> to allow us to write apps to function the debugger.
>
> Can anyone comment on what JTAG debugger they are using,
> and how have your experiences been? Are there any other
> good options besides the ones mentioned above.
> I'd appreciate any input.
>
> Thanks!
> Steve
>
> --
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Steve Hein (ssh@sgi.com) Engineering Diagnostics/Software
> Silicon Graphics, Inc.
> 1168 Industrial Blvd. Phone: (715) 726-8410
> Chippewa Falls, WI 54729 Fax: (715) 726-6715
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
I've used the BDI on 82xx, 85xx, 83xx, and othersfor custom board
bringup and I liked it. Some may not like the command line interface,
but I found it quite easy to use. I was able to use remote gdb to
debug u-boot, the Linux kernel, and with some trickery userspace apps.
I can't comment specifically on the others (though I have seen some WR
and Lauterbach debuggers and didn't like the user interface), but I
would still recommend the BDI.
^ permalink raw reply
* linux-2.6 system ACE driver - need help
From: agnel juni @ 2006-09-19 22:43 UTC (permalink / raw)
To: linuxppc-embedded, ammubhai
[-- Attachment #1: Type: text/plain, Size: 2703 bytes --]
Hi Ameet
I have posted a few messages regarding Ssytem ACE driver for Linux-2.6.
We are working on a AMCC 440SPe based custom board.
We applied the patch from
http://www.cs.york.ac.uk/rtslab/demos/amos/xupv2pro/patches/linuxppc-2.6.17.1-sysace-1.2.patch
and applied against 2.6.16-2 kernel.
We are trying to make the driver work in interrupt mode.
First, I would like to know if the driver tested in interrupt mode.
We are able to mount the CF, but it is very inconsistent.
Same is the case with fdisk command. When it fails,we get errors which you could see in the screen-dump below.
Are we missing to apply the right patch? Please let us know your inputs to go forward.
Looking forwards for your reply.
Thanks
Junita
/*************** Screen dump ********************/
# fdisk /dev/xsysace
1. sector = 0 xsa_cur_req->sector=0
System ACE: Error 0 when reading sector 2.
2. sector = 2 xsa_cur_req->sector=16
end_request: I/O error, System ACE: Error 0 when reading sectoru dev xsa, sector 16
Buffer I/O error on device xsa, logical block 2
1. sector = 184 xsa_cur_req->sector=184
Command (m for help): p
Disk /dev/xsysace: 524 MB, 524869632 bytes
17 heads, 59 sectors/track, 1022 cylinders
Units = cylinders of 1003 * 512 = 513536 bytes
Device Boot Start End Blocks Id System
/dev/xsysace1 1 1022 512503+ 6 FAT16
Command (m for help): q
And for 'mount' #
#
# mount -t msdos /dev/xsysace /root/cf
1. sector = 0 xsa_cur_req->sector=0
1. sector = 503 xsa_cur_req->sector=503
1. sector = 504 xsa_cur_req->sector=504
1. sector = 506 xsa_cur_req->sector=506
1. sector = 508 xsa_cur_req->sector=508
1. sector = 510 xsa_cur_req->sector=510
# cd /root/cf
< Here Prints Some Symbols like + - etc, which i am
not able to capture/copy -------------ERROR
b: No such file or directory--------------------------------ERROR
pci.h
#
Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.n0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.0Minicom2.00.d#
# cp pci.h /root/
# cd ../
# ls
app cf hello1 pci.h
#
#/root
/dev/xsysace /root/cf
FAT: bogus number of reserved sectors
VFS: Can't find a valid FAT filesystem on dev xsa.
mount: Mounting /dev/xsysace on /root/cf failed: Invalid argument
#
---------------------------------
Find out what India is talking about on - Yahoo! Answers India
Send FREE SMS to your friend's mobile from Yahoo! Messenger Version 8. Get it NOW
[-- Attachment #2: Type: text/html, Size: 6440 bytes --]
^ permalink raw reply
* [PATCH] Start arch/powerpc/boot code reorganization
From: Paul Mackerras @ 2006-09-19 23:00 UTC (permalink / raw)
To: linuxppc-dev
From: Mark A. Greer <mgreer@mvista.com>
This abstracts the operations used in the bootwrapper, and defines
the operations needed for the bootwrapper to run on an OF platform.
The operations have been divided up into platform ops (platform_ops),
firmware ops (fw_ops), device tree ops (dt_ops), and console ops
(console_ops).
The proper operations will be hooked up at runtime to provide the
functionality that you need.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index afc776f..e737741 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -36,7 +36,8 @@ zliblinuxheader := zlib.h zconf.h zutil.
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
-src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
+src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
+src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
new file mode 100644
index 0000000..761c8dc
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree.h
@@ -0,0 +1,46 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FLATDEVTREE_H
+#define FLATDEVTREE_H
+
+#include "types.h"
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER 0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
+#define OF_DT_END_NODE 0x2 /* End node */
+#define OF_DT_PROP 0x3 /* Property: name off, size, content */
+#define OF_DT_NOP 0x4 /* nop */
+#define OF_DT_END 0x9
+
+#define OF_DT_VERSION 0x10
+
+struct boot_param_header {
+ u32 magic; /* magic word OF_DT_HEADER */
+ u32 totalsize; /* total size of DT block */
+ u32 off_dt_struct; /* offset to structure */
+ u32 off_dt_strings; /* offset to strings */
+ u32 off_mem_rsvmap; /* offset to memory reserve map */
+ u32 version; /* format version */
+ u32 last_comp_version; /* last compatible version */
+ /* version 2 fields below */
+ u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
+ /* version 3 fields below */
+ u32 dt_strings_size; /* size of the DT strings block */
+};
+
+#endif /* FLATDEVTREE_H */
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index b66634c..d719bb9 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -14,17 +14,12 @@ #include "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
-#include "prom.h"
#include "zlib.h"
+#include "ops.h"
+#include "flatdevtree.h"
extern void flush_cache(void *, unsigned long);
-
-/* Value picked to match that used by yaboot */
-#define PROG_START 0x01400000 /* only used on 64-bit systems */
-#define RAM_END (512<<20) /* Fixme: use OF */
-#define ONE_MB 0x100000
-
extern char _start[];
extern char __bss_start[];
extern char _end[];
@@ -33,14 +28,6 @@ extern char _vmlinux_end[];
extern char _initrd_start[];
extern char _initrd_end[];
-/* A buffer that may be edited by tools operating on a zImage binary so as to
- * edit the command line passed to vmlinux (by setting /chosen/bootargs).
- * The buffer is put in it's own section so that tools may locate it easier.
- */
-static char builtin_cmdline[512]
- __attribute__((section("__builtin_cmdline")));
-
-
struct addr_range {
unsigned long addr;
unsigned long size;
@@ -51,21 +38,16 @@ static struct addr_range vmlinuz;
static struct addr_range initrd;
static unsigned long elfoffset;
+static int is_64bit;
-static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
+/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */
+static char scratch[46912];
static char elfheader[256];
-
-typedef void (*kernel_entry_t)( unsigned long,
- unsigned long,
- void *,
- void *);
-
+typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
#undef DEBUG
-static unsigned long claim_base;
-
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
@@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen
zlib_inflateEnd(&s);
}
-static unsigned long try_claim(unsigned long size)
-{
- unsigned long addr = 0;
-
- for(; claim_base < RAM_END; claim_base += ONE_MB) {
-#ifdef DEBUG
- printf(" trying: 0x%08lx\n\r", claim_base);
-#endif
- addr = (unsigned long)claim(claim_base, size, 0);
- if ((void *)addr != (void *)-1)
- break;
- }
- if (addr == 0)
- return 0;
- claim_base = PAGE_ALIGN(claim_base + size);
- return addr;
-}
-
static int is_elf64(void *hdr)
{
Elf64_Ehdr *elf64 = hdr;
@@ -169,16 +133,7 @@ static int is_elf64(void *hdr)
vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
-#if defined(PROG_START)
- /*
- * Maintain a "magic" minimum address. This keeps some older
- * firmware platforms running.
- */
-
- if (claim_base < PROG_START)
- claim_base = PROG_START;
-#endif
-
+ is_64bit = 1;
return 1;
}
@@ -212,47 +167,9 @@ static int is_elf32(void *hdr)
return 1;
}
-void export_cmdline(void* chosen_handle)
-{
- int len;
- char cmdline[2] = { 0, 0 };
-
- if (builtin_cmdline[0] == 0)
- return;
-
- len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
- if (len > 0 && cmdline[0] != 0)
- return;
-
- setprop(chosen_handle, "bootargs", builtin_cmdline,
- strlen(builtin_cmdline) + 1);
-}
-
-
-void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+static void prep_kernel(unsigned long *a1, unsigned long *a2)
{
int len;
- kernel_entry_t kernel_entry;
-
- memset(__bss_start, 0, _end - __bss_start);
-
- prom = (int (*)(void *)) promptr;
- chosen_handle = finddevice("/chosen");
- if (chosen_handle == (void *) -1)
- exit();
- if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
- exit();
-
- printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
-
- /*
- * The first available claim_base must be above the end of the
- * the loaded kernel wrapper file (_start to _end includes the
- * initrd image if it is present) and rounded up to a nice
- * 1 MB boundary for good measure.
- */
-
- claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned lo
gunzip(elfheader, sizeof(elfheader),
(unsigned char *)vmlinuz.addr, &len);
} else
- memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
+ memcpy(elfheader, (const void *)vmlinuz.addr,
+ sizeof(elfheader));
if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
exit();
}
+ if (platform_ops.image_hdr)
+ platform_ops.image_hdr(elfheader);
- /* We need to claim the memsize plus the file offset since gzip
+ /* We need to alloc the memsize plus the file offset since gzip
* will expand the header (file offset), then the kernel, then
* possible rubbish we don't care about. But the kernel bss must
* be claimed (it will be zero'd by the kernel itself)
*/
printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
- vmlinux.addr = try_claim(vmlinux.memsize);
+ vmlinux.addr = (unsigned long)malloc(vmlinux.memsize);
if (vmlinux.addr == 0) {
printf("Can't allocate memory for kernel image !\n\r");
exit();
}
/*
- * Now we try to claim memory for the initrd (and copy it there)
+ * Now we try to alloc memory for the initrd (and copy it there)
*/
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
initrd.memsize = initrd.size;
if ( initrd.size > 0 ) {
- printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
- initrd.addr = try_claim(initrd.size);
+ printf("Allocating 0x%lx bytes for initrd ...\n\r",
+ initrd.size);
+ initrd.addr = (unsigned long)malloc((u32)initrd.size);
if (initrd.addr == 0) {
- printf("Can't allocate memory for initial ramdisk !\n\r");
+ printf("Can't allocate memory for initial "
+ "ramdisk !\n\r");
exit();
}
- a1 = initrd.addr;
- a2 = initrd.size;
- printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
- initrd.addr, (unsigned long)_initrd_start, initrd.size);
- memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
- printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
+ *a1 = initrd.addr;
+ *a2 = initrd.size;
+ printf("initial ramdisk moving 0x%lx <- 0x%lx "
+ "(0x%lx bytes)\n\r", initrd.addr,
+ (unsigned long)_initrd_start, initrd.size);
+ memmove((void *)initrd.addr, (void *)_initrd_start,
+ initrd.size);
+ printf("initrd head: 0x%lx\n\r",
+ *((unsigned long *)initrd.addr));
}
/* Eventually gunzip the kernel */
@@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned lo
(unsigned char *)vmlinuz.addr, &len);
printf("done 0x%lx bytes\n\r", len);
} else {
- memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
+ memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
+ vmlinuz.size);
}
- export_cmdline(chosen_handle);
-
/* Skip over the ELF header */
#ifdef DEBUG
printf("... skipping 0x%lx bytes of ELF header\n\r",
@@ -324,23 +248,107 @@ #endif
vmlinux.addr += elfoffset;
flush_cache((void *)vmlinux.addr, vmlinux.size);
+}
- kernel_entry = (kernel_entry_t)vmlinux.addr;
-#ifdef DEBUG
- printf( "kernel:\n\r"
- " entry addr = 0x%lx\n\r"
- " a1 = 0x%lx,\n\r"
- " a2 = 0x%lx,\n\r"
- " prom = 0x%lx,\n\r"
- " bi_recs = 0x%lx,\n\r",
- (unsigned long)kernel_entry, a1, a2,
- (unsigned long)prom, NULL);
-#endif
+void __attribute__ ((weak)) ft_init(void *dt_blob)
+{
+}
- kernel_entry(a1, a2, prom, NULL);
+/* A buffer that may be edited by tools operating on a zImage binary so as to
+ * edit the command line passed to vmlinux (by setting /chosen/bootargs).
+ * The buffer is put in it's own section so that tools may locate it easier.
+ */
+static char builtin_cmdline[COMMAND_LINE_SIZE]
+ __attribute__((__section__("__builtin_cmdline")));
- printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+static void get_cmdline(char *buf, int size)
+{
+ void *devp;
+ int len = strlen(builtin_cmdline);
- exit();
+ buf[0] = '\0';
+
+ if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */
+ len = min(len, size-1);
+ strncpy(buf, builtin_cmdline, len);
+ buf[len] = '\0';
+ }
+ else if ((devp = finddevice("/chosen")))
+ getprop(devp, "bootargs", buf, size);
+}
+
+static void set_cmdline(char *buf)
+{
+ void *devp;
+
+ if ((devp = finddevice("/chosen")))
+ setprop(devp, "bootargs", buf, strlen(buf) + 1);
}
+/* Section where ft can be tacked on after zImage is built */
+union blobspace {
+ struct boot_param_header hdr;
+ char space[8*1024];
+} dt_blob __attribute__((__section__("__builtin_ft")));
+
+struct platform_ops platform_ops;
+struct dt_ops dt_ops;
+struct console_ops console_ops;
+
+void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+{
+ int have_dt = 0;
+ kernel_entry_t kentry;
+ char cmdline[COMMAND_LINE_SIZE];
+
+ memset(__bss_start, 0, _end - __bss_start);
+ memset(&platform_ops, 0, sizeof(platform_ops));
+ memset(&dt_ops, 0, sizeof(dt_ops));
+ memset(&console_ops, 0, sizeof(console_ops));
+
+ /* Override the dt_ops and device tree if there was an flat dev
+ * tree attached to the zImage.
+ */
+ if (dt_blob.hdr.magic == OF_DT_HEADER) {
+ have_dt = 1;
+ ft_init(&dt_blob);
+ }
+
+ if (platform_init(promptr))
+ exit();
+ if (console_ops.open && (console_ops.open() < 0))
+ exit();
+ if (platform_ops.fixups)
+ platform_ops.fixups();
+
+ printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
+ _start, sp);
+
+ prep_kernel(&a1, &a2);
+
+ /* If cmdline came from zimage wrapper or if we can edit the one
+ * in the dt, print it out and edit it, if possible.
+ */
+ if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
+ get_cmdline(cmdline, COMMAND_LINE_SIZE);
+ printf("\n\rLinux/PowerPC load: %s", cmdline);
+ if (console_ops.edit_cmdline)
+ console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
+ printf("\n\r");
+ set_cmdline(cmdline);
+ }
+
+ if (console_ops.close)
+ console_ops.close();
+
+ kentry = (kernel_entry_t) vmlinux.addr;
+ if (have_dt)
+ kentry(dt_ops.ft_addr(), 0, NULL);
+ else
+ /* XXX initrd addr/size should be passed in properties */
+ kentry(a1, a2, promptr);
+
+ /* console closed so printf below may not work */
+ printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
+ exit();
+}
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c
new file mode 100644
index 0000000..fd99f78
--- /dev/null
+++ b/arch/powerpc/boot/of.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+
+typedef void *ihandle;
+typedef void *phandle;
+
+extern char _end[];
+
+/* Value picked to match that used by yaboot */
+#define PROG_START 0x01400000 /* only used on 64-bit systems */
+#define RAM_END (512<<20) /* Fixme: use OF */
+#define ONE_MB 0x100000
+
+int (*prom) (void *);
+
+
+static unsigned long claim_base;
+
+static int call_prom(const char *service, int nargs, int nret, ...)
+{
+ int i;
+ struct prom_args {
+ const char *service;
+ int nargs;
+ int nret;
+ unsigned int args[12];
+ } args;
+ va_list list;
+
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, nret);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
+
+ if (prom(&args) < 0)
+ return -1;
+
+ return (nret > 0)? args.args[nargs]: 0;
+}
+
+static int call_prom_ret(const char *service, int nargs, int nret,
+ unsigned int *rets, ...)
+{
+ int i;
+ struct prom_args {
+ const char *service;
+ int nargs;
+ int nret;
+ unsigned int args[12];
+ } args;
+ va_list list;
+
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, rets);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
+
+ if (prom(&args) < 0)
+ return -1;
+
+ if (rets != (void *) 0)
+ for (i = 1; i < nret; ++i)
+ rets[i-1] = args.args[nargs+i];
+
+ return (nret > 0)? args.args[nargs]: 0;
+}
+
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
+ */
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
+
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
+{
+ for (; *s2; ++s2)
+ if (*s1++ != *s2)
+ return 0;
+ return 1;
+}
+
+static int check_of_version(void)
+{
+ phandle oprom, chosen;
+ char version[64];
+
+ oprom = finddevice("/openprom");
+ if (oprom == (phandle) -1)
+ return 0;
+ if (getprop(oprom, "model", version, sizeof(version)) <= 0)
+ return 0;
+ version[sizeof(version)-1] = 0;
+ printf("OF version = '%s'\r\n", version);
+ if (!string_match(version, "Open Firmware, 1.")
+ && !string_match(version, "FirmWorks,3."))
+ return 0;
+ chosen = finddevice("/chosen");
+ if (chosen == (phandle) -1) {
+ chosen = finddevice("/chosen@0");
+ if (chosen == (phandle) -1) {
+ printf("no chosen\n");
+ return 0;
+ }
+ }
+ if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
+ printf("no mmu\n");
+ return 0;
+ }
+ memory = (ihandle) call_prom("open", 1, 1, "/memory");
+ if (memory == (ihandle) -1) {
+ memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
+ if (memory == (ihandle) -1) {
+ printf("no memory node\n");
+ return 0;
+ }
+ }
+ printf("old OF detected\r\n");
+ return 1;
+}
+
+static void *claim(unsigned long virt, unsigned long size, unsigned long align)
+{
+ int ret;
+ unsigned int result;
+
+ if (need_map < 0)
+ need_map = check_of_version();
+ if (align || !need_map)
+ return (void *) call_prom("claim", 3, 1, virt, size, align);
+
+ ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
+ align, size, virt);
+ if (ret != 0 || result == -1)
+ return (void *) -1;
+ ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
+ align, size, virt);
+ /* 0x12 == coherent + read/write */
+ ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
+ 0x12, size, virt, virt);
+ return (void *) virt;
+}
+
+static void *of_try_claim(u32 size)
+{
+ unsigned long addr = 0;
+ static u8 first_time = 1;
+
+ if (first_time) {
+ claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+ first_time = 0;
+ }
+
+ for(; claim_base < RAM_END; claim_base += ONE_MB) {
+#ifdef DEBUG
+ printf(" trying: 0x%08lx\n\r", claim_base);
+#endif
+ addr = (unsigned long)claim(claim_base, size, 0);
+ if ((void *)addr != (void *)-1)
+ break;
+ }
+ if (addr == 0)
+ return NULL;
+ claim_base = PAGE_ALIGN(claim_base + size);
+ return (void *)addr;
+}
+
+static void of_image_hdr(const void *hdr)
+{
+ const Elf64_Ehdr *elf64 = hdr;
+
+ if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
+ /*
+ * Maintain a "magic" minimum address. This keeps some older
+ * firmware platforms running.
+ */
+ if (claim_base < PROG_START)
+ claim_base = PROG_START;
+ }
+}
+
+static void of_exit(void)
+{
+ call_prom("exit", 0, 0);
+}
+
+/*
+ * OF device tree routines
+ */
+static void *of_finddevice(const char *name)
+{
+ return (phandle) call_prom("finddevice", 1, 1, name);
+}
+
+static int of_getprop(const void *phandle, const char *name, void *buf,
+ const int buflen)
+{
+ return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
+static int of_setprop(const void *phandle, const char *name, const void *buf,
+ const int buflen)
+{
+ return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
+}
+
+/*
+ * OF console routines
+ */
+static void *of_stdout_handle;
+
+static int of_console_open(void)
+{
+ void *devp;
+
+ if (((devp = finddevice("/chosen")) != NULL)
+ && (getprop(devp, "stdout", &of_stdout_handle,
+ sizeof(of_stdout_handle))
+ == sizeof(of_stdout_handle)))
+ return 0;
+
+ return -1;
+}
+
+static void of_console_write(char *buf, int len)
+{
+ call_prom("write", 3, 1, of_stdout_handle, buf, len);
+}
+
+int platform_init(void *promptr)
+{
+ platform_ops.fixups = NULL;
+ platform_ops.image_hdr = of_image_hdr;
+ platform_ops.malloc = of_try_claim;
+ platform_ops.free = NULL;
+ platform_ops.exit = of_exit;
+
+ dt_ops.finddevice = of_finddevice;
+ dt_ops.getprop = of_getprop;
+ dt_ops.setprop = of_setprop;
+ dt_ops.translate_addr = NULL;
+
+ console_ops.open = of_console_open;
+ console_ops.write = of_console_write;
+ console_ops.edit_cmdline = NULL;
+ console_ops.close = NULL;
+ console_ops.data = NULL;
+
+ prom = (int (*)(void *))promptr;
+ return 0;
+}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
new file mode 100644
index 0000000..135eb4b
--- /dev/null
+++ b/arch/powerpc/boot/ops.h
@@ -0,0 +1,100 @@
+/*
+ * Global definition of all the bootwrapper operations.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef _PPC_BOOT_OPS_H_
+#define _PPC_BOOT_OPS_H_
+
+#include "types.h"
+
+#define COMMAND_LINE_SIZE 512
+#define MAX_PATH_LEN 256
+#define MAX_PROP_LEN 256 /* What should this be? */
+
+/* Platform specific operations */
+struct platform_ops {
+ void (*fixups)(void);
+ void (*image_hdr)(const void *);
+ void * (*malloc)(u32 size);
+ void (*free)(void *ptr, u32 size);
+ void (*exit)(void);
+};
+extern struct platform_ops platform_ops;
+
+/* Device Tree operations */
+struct dt_ops {
+ void * (*finddevice)(const char *name);
+ int (*getprop)(const void *node, const char *name, void *buf,
+ const int buflen);
+ int (*setprop)(const void *node, const char *name,
+ const void *buf, const int buflen);
+ u64 (*translate_addr)(const char *path, const u32 *in_addr,
+ const u32 addr_len);
+ unsigned long (*ft_addr)(void);
+};
+extern struct dt_ops dt_ops;
+
+/* Console operations */
+struct console_ops {
+ int (*open)(void);
+ void (*write)(char *buf, int len);
+ void (*edit_cmdline)(char *buf, int len);
+ void (*close)(void);
+ void *data;
+};
+extern struct console_ops console_ops;
+
+/* Serial console operations */
+struct serial_console_data {
+ int (*open)(void);
+ void (*putc)(unsigned char c);
+ unsigned char (*getc)(void);
+ u8 (*tstc)(void);
+ void (*close)(void);
+};
+
+extern int platform_init(void *promptr);
+extern void simple_alloc_init(void);
+extern void ft_init(void *dt_blob);
+extern int serial_console_init(void);
+
+static inline void *finddevice(const char *name)
+{
+ return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
+}
+
+static inline int getprop(void *devp, const char *name, void *buf, int buflen)
+{
+ return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
+}
+
+static inline int setprop(void *devp, const char *name, void *buf, int buflen)
+{
+ return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
+}
+
+static inline void *malloc(u32 size)
+{
+ return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
+}
+
+static inline void free(void *ptr, u32 size)
+{
+ if (platform_ops.free)
+ platform_ops.free(ptr, size);
+}
+
+static inline void exit(void)
+{
+ if (platform_ops.exit)
+ platform_ops.exit();
+ for(;;);
+}
+
+#endif /* _PPC_BOOT_OPS_H_ */
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/prom.c
deleted file mode 100644
index fa00577..0000000
--- a/arch/powerpc/boot/prom.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <stdarg.h>
-#include <stddef.h>
-#include "string.h"
-#include "stdio.h"
-#include "prom.h"
-
-int (*prom)(void *);
-phandle chosen_handle;
-ihandle stdout;
-
-int call_prom(const char *service, int nargs, int nret, ...)
-{
- int i;
- struct prom_args {
- const char *service;
- int nargs;
- int nret;
- unsigned int args[12];
- } args;
- va_list list;
-
- args.service = service;
- args.nargs = nargs;
- args.nret = nret;
-
- va_start(list, nret);
- for (i = 0; i < nargs; i++)
- args.args[i] = va_arg(list, unsigned int);
- va_end(list);
-
- for (i = 0; i < nret; i++)
- args.args[nargs+i] = 0;
-
- if (prom(&args) < 0)
- return -1;
-
- return (nret > 0)? args.args[nargs]: 0;
-}
-
-int call_prom_ret(const char *service, int nargs, int nret,
- unsigned int *rets, ...)
-{
- int i;
- struct prom_args {
- const char *service;
- int nargs;
- int nret;
- unsigned int args[12];
- } args;
- va_list list;
-
- args.service = service;
- args.nargs = nargs;
- args.nret = nret;
-
- va_start(list, rets);
- for (i = 0; i < nargs; i++)
- args.args[i] = va_arg(list, unsigned int);
- va_end(list);
-
- for (i = 0; i < nret; i++)
- args.args[nargs+i] = 0;
-
- if (prom(&args) < 0)
- return -1;
-
- if (rets != (void *) 0)
- for (i = 1; i < nret; ++i)
- rets[i-1] = args.args[nargs+i];
-
- return (nret > 0)? args.args[nargs]: 0;
-}
-
-int write(void *handle, void *ptr, int nb)
-{
- return call_prom("write", 3, 1, handle, ptr, nb);
-}
-
-/*
- * Older OF's require that when claiming a specific range of addresses,
- * we claim the physical space in the /memory node and the virtual
- * space in the chosen mmu node, and then do a map operation to
- * map virtual to physical.
- */
-static int need_map = -1;
-static ihandle chosen_mmu;
-static phandle memory;
-
-/* returns true if s2 is a prefix of s1 */
-static int string_match(const char *s1, const char *s2)
-{
- for (; *s2; ++s2)
- if (*s1++ != *s2)
- return 0;
- return 1;
-}
-
-static int check_of_version(void)
-{
- phandle oprom, chosen;
- char version[64];
-
- oprom = finddevice("/openprom");
- if (oprom == (phandle) -1)
- return 0;
- if (getprop(oprom, "model", version, sizeof(version)) <= 0)
- return 0;
- version[sizeof(version)-1] = 0;
- printf("OF version = '%s'\r\n", version);
- if (!string_match(version, "Open Firmware, 1.")
- && !string_match(version, "FirmWorks,3."))
- return 0;
- chosen = finddevice("/chosen");
- if (chosen == (phandle) -1) {
- chosen = finddevice("/chosen@0");
- if (chosen == (phandle) -1) {
- printf("no chosen\n");
- return 0;
- }
- }
- if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
- printf("no mmu\n");
- return 0;
- }
- memory = (ihandle) call_prom("open", 1, 1, "/memory");
- if (memory == (ihandle) -1) {
- memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
- if (memory == (ihandle) -1) {
- printf("no memory node\n");
- return 0;
- }
- }
- printf("old OF detected\r\n");
- return 1;
-}
-
-void *claim(unsigned long virt, unsigned long size, unsigned long align)
-{
- int ret;
- unsigned int result;
-
- if (need_map < 0)
- need_map = check_of_version();
- if (align || !need_map)
- return (void *) call_prom("claim", 3, 1, virt, size, align);
-
- ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
- align, size, virt);
- if (ret != 0 || result == -1)
- return (void *) -1;
- ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
- align, size, virt);
- /* 0x12 == coherent + read/write */
- ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
- 0x12, size, virt, virt);
- return (void *) virt;
-}
diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h
deleted file mode 100644
index a57b184..0000000
--- a/arch/powerpc/boot/prom.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _PPC_BOOT_PROM_H_
-#define _PPC_BOOT_PROM_H_
-
-typedef void *phandle;
-typedef void *ihandle;
-
-extern int (*prom) (void *);
-extern phandle chosen_handle;
-extern ihandle stdout;
-
-int call_prom(const char *service, int nargs, int nret, ...);
-int call_prom_ret(const char *service, int nargs, int nret,
- unsigned int *rets, ...);
-
-extern int write(void *handle, void *ptr, int nb);
-extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
-
-static inline void exit(void)
-{
- call_prom("exit", 0, 0);
-}
-
-static inline phandle finddevice(const char *name)
-{
- return (phandle) call_prom("finddevice", 1, 1, name);
-}
-
-static inline int getprop(void *phandle, const char *name,
- void *buf, int buflen)
-{
- return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
-}
-
-
-static inline int setprop(void *phandle, const char *name,
- void *buf, int buflen)
-{
- return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
-}
-
-#endif /* _PPC_BOOT_PROM_H_ */
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index b5aa522..6d5f638 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -10,7 +10,7 @@ #include <stdarg.h>
#include <stddef.h>
#include "string.h"
#include "stdio.h"
-#include "prom.h"
+#include "ops.h"
size_t strnlen(const char * s, size_t count)
{
@@ -320,6 +320,6 @@ printf(const char *fmt, ...)
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
- write(stdout, sprint_buf, n);
+ console_ops.write(sprint_buf, n);
return n;
}
diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h
index eb9e16c..73b8a91 100644
--- a/arch/powerpc/boot/stdio.h
+++ b/arch/powerpc/boot/stdio.h
@@ -1,8 +1,16 @@
#ifndef _PPC_BOOT_STDIO_H_
#define _PPC_BOOT_STDIO_H_
+#include <stdarg.h>
+
+#define ENOMEM 12 /* Out of Memory */
+#define EINVAL 22 /* Invalid argument */
+#define ENOSPC 28 /* No space left on device */
+
extern int printf(const char *fmt, ...);
+#define fprintf(fmt, args...) printf(args)
+
extern int sprintf(char *buf, const char *fmt, ...);
extern int vsprintf(char *buf, const char *fmt, va_list args);
diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
new file mode 100644
index 0000000..79d26e7
--- /dev/null
+++ b/arch/powerpc/boot/types.h
@@ -0,0 +1,23 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+#define min(x,y) ({ \
+ typeof(x) _x = (x); \
+ typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x < _y ? _x : _y; })
+
+#define max(x,y) ({ \
+ typeof(x) _x = (x); \
+ typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x > _y ? _x : _y; })
+
+#endif /* _TYPES_H_ */
^ permalink raw reply related
* Re: [POWERPC] convert string i/o operations to C
From: Stephen Rothwell @ 2006-09-19 23:07 UTC (permalink / raw)
To: David Howells; +Cc: ppc-dev, paulus
In-Reply-To: <28673.1158669778@warthog.cambridge.redhat.com>
On Tue, 19 Sep 2006 13:42:58 +0100 David Howells <dhowells@redhat.com> wrote:
>
> Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> > +void _insb(volatile u8 __iomem *port, void *buf, int ns)
> > +{
> > + asm volatile("sync");
> > + if (ns <= 0)
> > + return;
>
> What is "ns" meant to do? It seems to degrade the _insb() op to just a sync,
> but is that correct?
"ns" is the count (maybe I should rename the parameter, but that is what
was in the prototype in io.h). The "sync" is in the same place as it was
in the assembler code that this replaces.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox