* Re: SystemAce Driver.
From: Ameet Patil @ 2006-09-08 15:46 UTC (permalink / raw)
To: sudheer; +Cc: linuxppc-embedded
In-Reply-To: <44FFE0EC.6010603@gmail.com>
Hi Sudheer,
Ah! I never did the test for polled mode. There might be issue with
that. Will have a look....
-Ameet
sudheer wrote:
> Hi Ameet Patil
>
> Ameet Patil wrote:
>> Hi Sudheer,
>> Frank has already answered your questions. If you have any problems
>> with the SysAce patch... do let me know. I have written a small
>> tutorial here if it helps...
> I have used your SystemAce patch with linux-2.6.16-2. The kernel gets
> loaded with the ace module and is fine.
> I want the driver in polling mode. So i have commented few lines related
> to interrupt in the adapter.c file- xsysace_init function.
>
> When i give the fdisk command, it gives few errors and then enters to
> the fdisk commad promt. It prints the partitions, etc.
>
> But when i try to quit from the fdisk, it hangs. I am not able to
> complete the request properly (i guess in xsa_thread function in
> adapter.c file)
>
> The dump is as follows:
> SystemACE: Error 1 when reading sector 60.
> end_request: I/O error, dev xsa, sector 56
> SystemACE: Error 1351 when reading sector 62.
> end_request: I/O error, dev xsa, sector 56
>
> Command (m for help): p
>
> Disk /dev/xsysace: 512 MB, 512483328 bytes
> 16 heads, 62 sectors/track, 1009 cylinders
> Units = cylinders of 992 * 512 = 507904 bytes
> Device Boot Start End Blocks Id System
> /dev/xsysace1 1 1009 500433 6 FAT16
>
> Command (m for help): q
> -------
> The fdisk enters into xsysace_ioctl function but no commands are
> implemented in the ioctl function and returns an error.
>
> Please help me in this issue and let me know if any other details required.
>
> Thanks
> Sudheer
>
>>
>> http://linux.get2knowmore.com
>>
>>
>> -Ameet
>>
>> sudheer wrote:
>>> Hello Ameet Patil
>>>
>>> I am looking for linux kernel source 2.6.16 with system ace
>>> controller support. I downloaded the linux-2.6.16 and linux-2.6.17-1
>>> source from kernel.org but could not find any files related to system
>>> ace controller ( No xilinx_sysace directory in drivers/block/) . I
>>> have checked penguinppc.org also but could not get it.
>>>
>>> Can you please send to me the link where i could download the
>>> linuxppc-2.6.16 source with system ace support.
>>>
>>> Thanks & Regards
>>> Sudheer
>>>
>>> Ameet Patil wrote:
>>>> Hi Raja,
>>>> I have ported the Xilinx System ACE driver to 2.6 kernel. Find
>>>> the latest one here:
>>>> http://www.cs.york.ac.uk/rtslab/demos/amos/xupv2pro/patches/linuxppc-2.6.17.1-sysace-1.2.patch
>>>>
>>>>
>>>> NOTE: this patch wouldn't work if you are using the TEMAC driver. In
>>>> which case use the -after-TEMAC patch found in the patches folder
>>>> above.
>>>>
>>>> Check the following discussions (threads) for more details:
>>>> 1. "Xilinx SystemACE driver for 2.6"
>>>> 2. "Xilinx BSP for linux 2.6"
>>>> 3. "Kernel hangs after "Now booting the kernel"."
>>>>
>>>> cheers,
>>>> -Ameet
>>>>
>>>> Raja Chidambaram wrote:
>>>>
>>>>> Hi all,
>>>>> We are working on customized board with amcc 440SPe
>>>>> processor & xilinx System Ace controller. The System
>>>>> Ace controller is connected to compact flash driver.
>>>>>
>>>>> We use u-boot 1.2 as bootloader & linux kernel
>>>>> 2.6.16-2.
>>>>>
>>>>> On the process the u-boot is able to detect compact
>>>>> flash through Xilinx SystemAce controller & able to
>>>>> load the kernel image into compact flash.But when the
>>>>> linux boot's up it not able to detect the System Ace
>>>>> controller or compact flash.
>>>>>
>>>>> Note:we need to have the root file system in compact
>>>>> flash.
>>>>>
>>>>> Is their any drivers available for SystemAce
>>>>> controller on linux 2.6,if their how to get it.please
>>>>> help me in this
>>>>> with regards
>>>>> raja
>>>>>
>>>>>
>>>>>
>>>>> __________________________________________________
>>>>> Do You Yahoo!?
>>>>> Tired of spam? Yahoo! Mail has the best spam protection around
>>>>> http://mail.yahoo.com _______________________________________________
>>>>> Linuxppc-embedded mailing list
>>>>> Linuxppc-embedded@ozlabs.org
>>>>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>>>>
>>>>>
>>>> _______________________________________________
>>>> Linuxppc-embedded mailing list
>>>> Linuxppc-embedded@ozlabs.org
>>>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>>>
>>>>
>>>
>>
>
^ permalink raw reply
* kprobe support for ppc 32 bit
From: Bizhan Gholikhamseh (bgholikh) @ 2006-09-08 15:21 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 333 bytes --]
My understanding is that the kprobe is part of the standard linux 2.6
source tree.
I am not able to find any files related to the kprobe in ppc 32 bit
architecture source tree
, however, there are some related files for ppc 64 bit architecture
source tree.
directory.
What am I missing?
Many thanks in advance,
Bizhan
[-- Attachment #2: Type: text/html, Size: 1313 bytes --]
^ permalink raw reply
* Cell - linux compatibility question
From: Donald Chiarulli @ 2006-09-08 15:27 UTC (permalink / raw)
To: cell_support; +Cc: linuxppc64-dev, Steve Levitan
Hello folks..
We are about to order a 1U dual cell server from Mercury Computer, see:
http://www.mc.com/products/view/index.cfm?id=96&type=boards
They are offering a linux (yellow dog) from terra-soft on this
platform based on the 2.6.14-1 kernel. I understand that your kernel
(I assume that it is fedora core 5) is built for the blade board that
you show on your website.
Do you know anyone who has experience with porting the Cell GNU
toolchain to this platform?
Any predictions on the relative difficulty?
Thanks in advance for any input you may be able to provide.
Don Chiarulli
Computer Science
University of Pittsburgh
^ permalink raw reply
* Compile Error Report
From: wei.li4 @ 2006-09-08 15:16 UTC (permalink / raw)
To: linuxppc-embedded
Hi All,
I am working on linux-2.6.18-rc2-g73a589b5.tar.bz2 for MPC875, the
cross-tools are from ELDK 4.0. After configuration and do 'make
zImage', I got these error:
CC arch/ppc/boot/simple/m8xx_tty.o
arch/ppc/boot/simple/m8xx_tty.c:32: error: static declaration of 'cpmp'
follows non-static declaration
include/asm/commproc.h:74: error: previous declaration of 'cpmp' was here
make[2]: *** [arch/ppc/boot/simple/m8xx_tty.o] Error 1
I also got these errors if I used these tools on Linux 2.6.13, but
there is no error if I use tools from ELDK 3.1.1, can anyone help me
figure it out? Thanks.
Wei
^ permalink raw reply
* Re: [PATCH 1/1] bootwrapper: add flat device tree support code
From: Hollis Blanchard @ 2006-09-08 14:46 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060908034623.GG5203@mag.az.mvista.com>
On Thu, 2006-09-07 at 20:46 -0700, Mark A. Greer wrote:
> --- /dev/null
> +++ b/arch/powerpc/boot/flatdevtree.c
> @@ -0,0 +1,628 @@
> +/*
> + * DO NOT EDIT THIS FILE!!
> + *
> + * The master copy is kept in a mercurial repository that you can clone:
> + * "hg clone http://unsanctioned.org/flatdevtree/hgweb.py flatdevtree"
> + * Please send patches to Hollis Blanchard <hollisb@us.ibm.com> and
> + * CC: <Linuxppc-dev@ozlabs.org>
> + *
Actually I'm not intending for that to be a long-term URL. If we need
something permanent for this file, I can set something up on
penguinppc.org...
(NAK)
-Hollis
^ permalink raw reply
* [PATCH] print backtrace when entering xmon
From: Olaf Hering @ 2006-09-08 14:29 UTC (permalink / raw)
To: Paul Mackeras, linuxppc-dev
xmon does not print a backtrace per default. This is bad on systems with
USB keyboard, the most needed info about the crash is lost.
print a backtrace during the very first xmon entry.
Booting with xmon=nobt disables the autobacktrace functionality.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
arch/powerpc/Kconfig.debug | 2 ++
arch/powerpc/kernel/setup-common.c | 4 ++++
arch/powerpc/xmon/xmon.c | 10 ++++++++++
3 files changed, 16 insertions(+)
Index: linux-2.6.18-rc6/arch/powerpc/Kconfig.debug
===================================================================
--- linux-2.6.18-rc6.orig/arch/powerpc/Kconfig.debug
+++ linux-2.6.18-rc6/arch/powerpc/Kconfig.debug
@@ -74,6 +74,8 @@ config XMON
very early during boot. 'xmon=on' will just enable the xmon
debugger hooks. 'xmon=off' will disable the debugger hooks
if CONFIG_XMON_DEFAULT is set.
+ xmon will print a backtrace on the very first invocation.
+ 'xmon=nobt' will disable this autobacktrace.
config XMON_DEFAULT
bool "Enable xmon by default"
Index: linux-2.6.18-rc6/arch/powerpc/kernel/setup-common.c
===================================================================
--- linux-2.6.18-rc6.orig/arch/powerpc/kernel/setup-common.c
+++ linux-2.6.18-rc6/arch/powerpc/kernel/setup-common.c
@@ -444,6 +444,8 @@ void __init smp_setup_cpu_maps(void)
int __initdata do_early_xmon;
#ifdef CONFIG_XMON
+extern int xmon_no_auto_backtrace;
+
static int __init early_xmon(char *p)
{
/* ensure xmon is enabled */
@@ -452,6 +454,8 @@ static int __init early_xmon(char *p)
xmon_init(1);
if (strncmp(p, "off", 3) == 0)
xmon_init(0);
+ if (strncmp(p, "nobt", 4) == 0)
+ xmon_no_auto_backtrace = 1;
if (strncmp(p, "early", 5) != 0)
return 0;
}
Index: linux-2.6.18-rc6/arch/powerpc/xmon/xmon.c
===================================================================
--- linux-2.6.18-rc6.orig/arch/powerpc/xmon/xmon.c
+++ linux-2.6.18-rc6/arch/powerpc/xmon/xmon.c
@@ -137,10 +137,14 @@ static void bootcmds(void);
static void proccall(void);
void dump_segments(void);
static void symbol_lookup(void);
+static void xmon_show_stack(unsigned long sp, unsigned long lr,
+ unsigned long pc);
static void xmon_print_symbol(unsigned long address, const char *mid,
const char *after);
static const char *getvecname(unsigned long vec);
+int xmon_no_auto_backtrace;
+
extern int print_insn_powerpc(unsigned long, unsigned long, int);
extern void xmon_enter(void);
@@ -736,6 +740,12 @@ cmds(struct pt_regs *excp)
last_cmd = NULL;
xmon_regs = excp;
+
+ if (!xmon_no_auto_backtrace) {
+ xmon_no_auto_backtrace = 1;
+ xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
+ }
+
for(;;) {
#ifdef CONFIG_SMP
printf("%x:", smp_processor_id());
^ permalink raw reply
* Re: powerpc power management
From: John Rigby @ 2006-09-08 14:18 UTC (permalink / raw)
To: Vaidyanathan S; +Cc: linuxppc
In-Reply-To: <450121E2.5050207@in.ibm.com>
MPC5200 which has a 603 core.
On 9/8/06, Vaidyanathan S <svaidy@in.ibm.com> wrote:
> Hi John,
>
> John Rigby wrote:
> > I need to implement suspend to ram (sleep mode) on an embedded powerpc
> > processor. I have googled generally and searched the lkml, this list
> > and the linux power management mailing list. It seems after all this
> > searching that the only existing code is for the powermac in
> > drivers/macintosh/(variousfiles) and
> > arch/powerpc/platforms/powermac/(variousfiles). Is this true or am I
> > missing something?
> >
>
> Powermac code related to apple platforms seems to be the only
> supported platform for pwr mgt under Linux.
>
> What ppc platforms are you looking at?
>
> > Thanks
> > John
>
> -- Vaidy
>
>
^ permalink raw reply
* Re: common flatdevtree code
From: Paul Mackerras @ 2006-09-08 13:23 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Hollis Blanchard
In-Reply-To: <20060908005630.GA9823@mag.az.mvista.com>
[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 41 bytes --]
Mark,
Here's where I'm up to...
Paul.
[-- Attachment #2: flatdevtree.c --]
[-- Type: application/x-csrc, Size: 17045 bytes --]
[-- Attachment #3: flatdevtree.h --]
[-- Type: application/x-chdr, Size: 4042 bytes --]
[-- Attachment #4: flatdevtree_env.h --]
[-- Type: application/x-chdr, Size: 1008 bytes --]
^ permalink raw reply
* Re: MPC8360E USB Host Controller Driver
From: Alex Zeffertt @ 2006-09-08 8:27 UTC (permalink / raw)
To: Li Yang; +Cc: n.balaji, linuxppc-embedded
In-Reply-To: <a0bc9bf80609071137o254edcc1s7bfd905c489cb604@mail.gmail.com>
Li Yang wrote:
> On 9/7/06, Alex Zeffertt <ajz@cambridgebroadband.com> wrote:
>> Li Yang-r58472 wrote:
>> >> i have a MPC8347E running with the Freescale E(F)HCI driver
>> >> and Kernel 2.6.17 (Freescale LTIB).
>> >>
>> >> Because of this mail, i checked, if there are any periodical
>> >> interrupts, without real USB payload.
>> >>
>> >> The result is: NO
>> >>
>> >> If i attach a USB-mouse, i get 5 interrupts.
>> >> If i remove it again, 1 additional.
>> >>
>> >> Nothing else, silence !
>> >>
>> >> USB works well with USB 1.1 and 2.0 devices (This was not the
>> >> case with earlier Kernels, e.g. 2.6.13, because for the
>> >> switching between 1.1 and 2.0 you need a transaction
>> >> translator driver).
>> >
>> > MPC834x USB is very different from the USB of CPM/QE. It is an
>> > integrated EHCI controller.
>> >
>>
>>
>> So, the question is still open, does the QuiccEngine HCI (a.k.a. FHCI)
>> generate loading on the PPC core when there is no traffic on the USB?
>
> Yes, but no. If the bus is idle for some time, you can put the bus
> into suspend state. Then there will be no extra load to the core.
>
Is that what Freescale's linux driver does then?
Can it detect new USB devices in suspend state?
Regards,
Alex
^ permalink raw reply
* Re: powerpc power management
From: Vaidyanathan S @ 2006-09-08 7:55 UTC (permalink / raw)
To: John Rigby; +Cc: linuxppc
In-Reply-To: <4b73d43f0609071905j26ab0317k144d78963e041cba@mail.gmail.com>
Hi John,
John Rigby wrote:
> I need to implement suspend to ram (sleep mode) on an embedded powerpc
> processor. I have googled generally and searched the lkml, this list
> and the linux power management mailing list. It seems after all this
> searching that the only existing code is for the powermac in
> drivers/macintosh/(variousfiles) and
> arch/powerpc/platforms/powermac/(variousfiles). Is this true or am I
> missing something?
>
Powermac code related to apple platforms seems to be the only
supported platform for pwr mgt under Linux.
What ppc platforms are you looking at?
> Thanks
> John
-- Vaidy
^ permalink raw reply
* [PATCH 1/1] bootwrapper: add flat device tree support code
From: Mark A. Greer @ 2006-09-08 3:46 UTC (permalink / raw)
To: linuxppc-dev
This patch adds a copy of the flat device tree code to the bootwrapper.
This code is only a copy of what exists in a mercurial repository that
can be cloned:
"hg clone http://unsanctioned.org/flatdevtree/hgweb.py flatdevtree"
Do not edit this file in the bootwrapper, send patches to
Hollis Blanchard <hollisb@us.ibm.com> and CC: Linuxppc-dev@ozlabs.org.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
Makefile | 2
flatdevtree.c | 628 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
flatdevtree.h | 106 +++++++++
3 files changed, 735 insertions(+), 1 deletion(-)
--
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 44a3055..1c4f11b 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -40,7 +40,7 @@ src-boot := crt0.S string.S stdio.c main
ifeq ($(CONFIG_PPC_MULTIPLATFORM),y)
src-boot += of.c
else
-src-boot += flatdevtree_misc.c
+src-boot += flatdevtree.c flatdevtree_misc.c
endif
ifeq ($(CONFIG_SANDPOINT),y)
src-boot += sandpoint.c mpc10x.c simple_alloc.c serial.c ns16550.c util.S
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c
new file mode 100644
index 0000000..a8d9722
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree.c
@@ -0,0 +1,628 @@
+/*
+ * DO NOT EDIT THIS FILE!!
+ *
+ * The master copy is kept in a mercurial repository that you can clone:
+ * "hg clone http://unsanctioned.org/flatdevtree/hgweb.py flatdevtree"
+ * Please send patches to Hollis Blanchard <hollisb@us.ibm.com> and
+ * CC: <Linuxppc-dev@ozlabs.org>
+ *
+ * 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.
+ *
+ * Copyright Pantelis Antoniou 2006
+ * Copyright (C) IBM Corporation 2006
+ * 2006 (c) MontaVista Software, Inc.
+ *
+ * Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ * Mark A. Greer <mgreer@mvista.com>
+ */
+
+#include "flatdevtree.h"
+
+struct ft_entity {
+ u32 *tagp; /* Ptr to tag field */
+ char *name; /* Name of node or property; else NULL */
+ char *datap; /* Ptr to data, if property; else NULL */
+ u32 *sizep; /* Ptr to propery size; else NULL */
+};
+
+/* Set ptrs to current one's info; return addr of next one */
+static u32 *ft_next(u32 *p, const void *bphp, struct ft_entity *ftep)
+{
+ const struct boot_param_header *bph = bphp;
+ const u32 *p_strings = (const u32 *)
+ ((const char *)bph + be32_to_cpu(bph->off_dt_strings));
+ const u32 version = be32_to_cpu(bph->version);
+ u32 sz;
+
+ if (p == NULL) /* Start at top of tree */
+ p = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct));
+
+ ftep->name = NULL;
+ ftep->datap = NULL;
+ ftep->sizep = NULL;
+ ftep->tagp = p;
+
+ switch (be32_to_cpu(*p++)) { /* Tag */
+ case OF_DT_BEGIN_NODE:
+ ftep->name = (char *)p;
+ p = (u32 *)_ALIGN((unsigned long)p + strlen((char *)p) + 1, 4);
+ break;
+ case OF_DT_PROP:
+ sz = be32_to_cpu(*p);
+ ftep->sizep = p++;
+ ftep->name = (char *)p_strings + be32_to_cpu(*p++);
+ if ((version < 0x10) && (sz >= 8))
+ p = (u32 *)_ALIGN((unsigned long)p, 8);
+ ftep->datap = (char *)p;
+ p = (u32 *)_ALIGN((unsigned long)p + sz, 4);
+ break;
+ case OF_DT_END_NODE:
+ case OF_DT_NOP:
+ break;
+ case OF_DT_END:
+ default:
+ p = NULL;
+ break;
+ }
+
+ return p;
+}
+
+static void ft_put_word(struct ft_cxt *cxt, u32 v)
+{
+ if (cxt->overflow) /* do nothing */
+ return;
+
+ /* check for overflow */
+ if (cxt->p + 4 > cxt->pstr) {
+ cxt->overflow = 1;
+ return;
+ }
+
+ *(u32 *) cxt->p = cpu_to_be32(v);
+ cxt->p += 4;
+}
+
+static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz)
+{
+ char *p;
+
+ if (cxt->overflow) /* do nothing */
+ return;
+
+ /* next pointer pos */
+ p = (char *) _ALIGN((unsigned long)cxt->p + sz, 4);
+
+ /* check for overflow */
+ if (p > cxt->pstr) {
+ cxt->overflow = 1;
+ return;
+ }
+
+ memcpy(cxt->p, data, sz);
+ if ((sz & 3) != 0)
+ memset(cxt->p + sz, 0, 4 - (sz & 3));
+ cxt->p = p;
+}
+
+void ft_begin_node(struct ft_cxt *cxt, const char *name)
+{
+ ft_put_word(cxt, OF_DT_BEGIN_NODE);
+ ft_put_bin(cxt, name, strlen(name) + 1);
+}
+
+void ft_end_node(struct ft_cxt *cxt)
+{
+ ft_put_word(cxt, OF_DT_END_NODE);
+}
+
+void ft_nop(struct ft_cxt *cxt)
+{
+ ft_put_word(cxt, OF_DT_NOP);
+}
+
+static int lookup_string(struct ft_cxt *cxt, const char *name)
+{
+ char *p;
+
+ p = cxt->pstr;
+ while (p < cxt->pstr_begin) {
+ if (strcmp(p, (char *)name) == 0)
+ return p - cxt->p_begin;
+ p += strlen(p) + 1;
+ }
+
+ return -1;
+}
+
+void ft_prop(struct ft_cxt *cxt, const char *name,
+ const void *data, unsigned int sz)
+{
+ int len, off;
+
+ if (cxt->overflow)
+ return;
+
+ len = strlen(name) + 1;
+
+ off = lookup_string(cxt, name);
+ if (off == -1) {
+ /* check if we have space */
+ if (cxt->p + 12 + sz + len > cxt->pstr) {
+ cxt->overflow = 1;
+ return;
+ }
+
+ cxt->pstr -= len;
+ memcpy(cxt->pstr, name, len);
+ off = cxt->pstr - cxt->p_begin;
+ }
+
+ /* now put offset from beginning of *STRUCTURE* */
+ /* will be fixed up at the end */
+ ft_put_word(cxt, OF_DT_PROP);
+ ft_put_word(cxt, sz);
+ ft_put_word(cxt, off);
+ ft_put_bin(cxt, data, sz);
+}
+
+void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
+{
+ ft_prop(cxt, name, str, strlen(str) + 1);
+}
+
+void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
+{
+ u32 v = cpu_to_be32((u32) val);
+
+ ft_prop(cxt, name, &v, 4);
+}
+
+/* start construction of the flat OF tree */
+void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size)
+{
+ struct boot_param_header *bph = blob;
+ u32 off;
+
+ /* clear the cxt */
+ memset(cxt, 0, sizeof(*cxt));
+
+ cxt->bph = bph;
+ cxt->max_size = max_size;
+
+ /* zero everything in the header area */
+ memset(bph, 0, sizeof(*bph));
+
+ bph->magic = cpu_to_be32(OF_DT_HEADER);
+ bph->version = cpu_to_be32(0x10);
+ bph->last_comp_version = cpu_to_be32(0x10);
+
+ /* start pointers */
+ cxt->pres_begin = (char *) _ALIGN((unsigned long)(bph + 1), 8);
+ cxt->pres = cxt->pres_begin;
+
+ off = (unsigned long)cxt->pres_begin - (unsigned long)bph;
+ bph->off_mem_rsvmap = cpu_to_be32(off);
+
+ ((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
+ ((u64 *) cxt->pres)[1] = 0;
+
+ cxt->p_anchor = cxt->pres + 16; /* over the terminator */
+}
+
+/* add a reserver physical area to the rsvmap */
+void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
+{
+ ((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */
+ ((u64 *) cxt->pres)[1] = cpu_to_be64(size);
+
+ cxt->pres += 18; /* advance */
+
+ ((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
+ ((u64 *) cxt->pres)[1] = 0;
+
+ /* keep track of size */
+ cxt->res_size = cxt->pres + 16 - cxt->pres_begin;
+
+ cxt->p_anchor = cxt->pres + 16; /* over the terminator */
+}
+
+void ft_begin_tree(struct ft_cxt *cxt)
+{
+ cxt->p_begin = cxt->p_anchor;
+ cxt->pstr_begin = (char *)cxt->bph + cxt->max_size; /* point at the end */
+
+ cxt->p = cxt->p_begin;
+ cxt->pstr = cxt->pstr_begin;
+}
+
+int ft_end_tree(struct ft_cxt *cxt)
+{
+ struct boot_param_header *bph = cxt->bph;
+ int off, sz, sz1;
+ u32 tag, v;
+ char *p;
+
+ ft_put_word(cxt, OF_DT_END);
+
+ if (cxt->overflow)
+ return -ENOMEM;
+
+ /* size of the areas */
+ cxt->struct_size = cxt->p - cxt->p_begin;
+ cxt->strings_size = cxt->pstr_begin - cxt->pstr;
+
+ /* the offset we must move */
+ off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size;
+
+ /* the new strings start */
+ cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
+
+ /* move the whole string area */
+ memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size);
+
+ /* now perform the fixup of the strings */
+ p = cxt->p_begin;
+ while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) {
+ p += 4;
+
+ if (tag == OF_DT_BEGIN_NODE) {
+ p = (char *) _ALIGN((unsigned long)p + strlen(p) + 1, 4);
+ continue;
+ }
+
+ if (tag == OF_DT_END_NODE || tag == OF_DT_NOP)
+ continue;
+
+ if (tag != OF_DT_PROP)
+ return -EINVAL;
+
+ sz = be32_to_cpu(*(u32 *) p);
+ p += 4;
+
+ v = be32_to_cpu(*(u32 *) p);
+ v -= off;
+ *(u32 *) p = cpu_to_be32(v); /* move down */
+ p += 4;
+
+ p = (char *) _ALIGN((unsigned long)p + sz, 4);
+ }
+
+ /* fix sizes */
+ p = (char *)cxt->bph;
+ sz = (cxt->pstr_begin + cxt->strings_size) - p;
+ sz1 = _ALIGN(sz, 16); /* align at 16 bytes */
+ if (sz != sz1)
+ memset(p + sz, 0, sz1 - sz);
+ bph->totalsize = cpu_to_be32(sz1);
+ bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p);
+ bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p);
+
+ /* the new strings start */
+ cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
+ cxt->pstr = cxt->pstr_begin + cxt->strings_size;
+
+ return 0;
+}
+
+/**********************************************************************/
+
+static inline int isprint(int c)
+{
+ return c >= 0x20 && c <= 0x7e;
+}
+
+static int is_printable_string(const void *data, int len)
+{
+ const char *s = data;
+ const char *ss;
+
+ /* zero length is not */
+ if (len == 0)
+ return 0;
+
+ /* must terminate with zero */
+ if (s[len - 1] != '\0')
+ return 0;
+
+ ss = s;
+ while (*s && isprint(*s))
+ s++;
+
+ /* not zero, or not done yet */
+ if (*s != '\0' || (s + 1 - ss) < len)
+ return 0;
+
+ return 1;
+}
+
+static void print_data(const void *data, int len)
+{
+ int i;
+ const char *s;
+
+ /* no data, don't print */
+ if (len == 0)
+ return;
+
+ if (is_printable_string(data, len)) {
+ printf(" = \"%s\"", (char *)data);
+ return;
+ }
+
+ switch (len) {
+ case 1: /* byte */
+ printf(" = <0x%02x>", (*(char *) data) & 0xff);
+ break;
+ case 2: /* half-word */
+ printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
+ break;
+ case 4: /* word */
+ printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+ break;
+ case 8: /* double-word */
+ printf(" = <0x%16llx>", be64_to_cpu(*(u64 *) data));
+ break;
+ default: /* anything else... hexdump */
+ printf(" = [");
+ for (i = 0, s = data; i < len; i++)
+ printf("%02x%s", s[i], i < len - 1 ? " " : "");
+ printf("]");
+
+ break;
+ }
+}
+
+void ft_dump_blob(const void *bphp)
+{
+ const struct boot_param_header *bph = bphp;
+ const u64 *p_rsvmap = (const u64 *)
+ ((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
+ struct ft_entity fte;
+ u32 i, *p;
+ int depth, shift;
+ u64 addr, size;
+
+
+ if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
+ /* not valid tree */
+ return;
+ }
+
+ depth = 0;
+ shift = 4;
+
+ for (i = 0;; i++) {
+ addr = be64_to_cpu(p_rsvmap[i * 2]);
+ size = be64_to_cpu(p_rsvmap[i * 2 + 1]);
+ if (addr == 0 && size == 0)
+ break;
+
+ printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size);
+ }
+
+ p = NULL;
+ while ((p = ft_next(p, bphp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
+ case OF_DT_BEGIN_NODE:
+ printf("%*s%s {\n", depth * shift, "", fte.name);
+ depth++;
+ break;
+ case OF_DT_END_NODE:
+ depth--;
+ printf("%*s};\n", depth * shift, "");
+ break;
+ case OF_DT_NOP:
+ printf("%*s[NOP]\n", depth * shift, "");
+ break;
+ case OF_DT_END:
+ break;
+ case OF_DT_PROP:
+ printf("%*s%s", depth * shift, "", fte.name);
+ print_data(fte.datap, *fte.sizep);
+ printf(";\n");
+ break;
+ default:
+ fprintf(stderr, "%*s ** Unknown tag 0x%08x\n",
+ depth * shift, "", *fte.tagp);
+ return;
+ }
+}
+
+void ft_backtrack_node(struct ft_cxt *cxt)
+{
+ if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
+ return; /* XXX only for node */
+
+ cxt->p -= 4;
+}
+
+/* note that the root node of the blob is "peeled" off */
+void ft_merge_blob(struct ft_cxt *cxt, void *blob)
+{
+ struct ft_entity fte;
+ u32 *p;
+ int depth;
+
+ if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
+ return; /* XXX only for node */
+
+ cxt->p -= 4;
+
+ depth = 0;
+ p = NULL;
+ while ((p = ft_next(p, blob, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
+ case OF_DT_BEGIN_NODE:
+ if (depth++ > 0)
+ ft_begin_node(cxt, fte.name);
+ break;
+ case OF_DT_END_NODE:
+ ft_end_node(cxt);
+ if (--depth == 0)
+ return;
+ break;
+ case OF_DT_PROP:
+ ft_prop(cxt, fte.name, fte.datap, *fte.sizep);
+ break;
+ }
+}
+
+/**********************************************************************/
+
+void *ft_find_node(const void *bphp, const char *srch_path)
+{
+ struct ft_entity fte;
+ u32 *p;
+ static char path[MAX_PATH_LEN];
+
+ path[0] = '\0';
+ p = NULL;
+ while ((p = ft_next(p, bphp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
+ case OF_DT_BEGIN_NODE:
+ strcat(path, fte.name);
+ if (!strcmp(path, srch_path))
+ return fte.tagp;
+ strcat(path, "/");
+ break;
+ case OF_DT_END_NODE:
+ ft_parentize(path, 1);
+ break;
+ }
+ return NULL;
+}
+
+int ft_get_prop(const void *bphp, const void *node, const char *propname,
+ void *buf, const unsigned int buflen)
+{
+ struct ft_entity fte;
+ u32 *p, size;
+ int depth;
+
+ depth = 0;
+ p = (u32 *)node;
+ while ((p = ft_next(p, bphp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
+ case OF_DT_BEGIN_NODE:
+ depth++;
+ break;
+ case OF_DT_PROP:
+ if ((depth == 1) && !strcmp(fte.name, propname)) {
+ size = min(be32_to_cpu(*fte.sizep),(u32)buflen);
+ memcpy(buf, fte.datap, size);
+ return size;
+ }
+ break;
+ case OF_DT_END_NODE:
+ if (--depth <= 0)
+ return -1;
+ break;
+ }
+ return -1;
+}
+
+static void ft_modify_prop(void **bphpp, char *datap, u32 *old_prop_sizep,
+ const char *buf, const unsigned int buflen)
+{
+ u32 old_prop_data_len, new_prop_data_len;
+
+ old_prop_data_len = _ALIGN(be32_to_cpu(*old_prop_sizep), 4);
+ new_prop_data_len = _ALIGN(buflen, 4);
+
+ /* Check if new prop data fits in old prop data area */
+ if (new_prop_data_len == old_prop_data_len) {
+ memcpy(datap, buf, buflen);
+ *old_prop_sizep = cpu_to_be32(buflen);
+ } else {
+ /* Need to alloc new area to put larger or smaller ft */
+ struct boot_param_header *old_bph = *bphpp, *new_bph;
+ u32 *old_tailp, *new_tailp, *new_datap;
+ u32 old_total_size, new_total_size, head_len, tail_len, diff, v;
+
+ old_total_size = be32_to_cpu(old_bph->totalsize);
+ head_len = (u32)(datap - (char *)old_bph);
+ tail_len = old_total_size - (head_len + old_prop_data_len);
+ old_tailp = (u32 *)(datap + old_prop_data_len);
+ new_total_size = head_len + new_prop_data_len + tail_len;
+
+ if (!(new_bph = ft_malloc(new_total_size))) {
+ printf("Can't alloc space for new ft\n");
+ ft_exit(-ENOSPC);
+ }
+
+ new_datap = (u32 *)((char *)new_bph + head_len);
+ new_tailp = (u32 *)((char *)new_datap + new_prop_data_len);
+
+ memcpy(new_bph, *bphpp, head_len);
+ memcpy(new_datap, buf, buflen);
+ memcpy(new_tailp, old_tailp, tail_len);
+
+ *(new_datap - 2) = cpu_to_be32(buflen); /* Set prop size */
+
+ new_bph->totalsize = cpu_to_be32(new_total_size);
+ diff = new_prop_data_len - old_prop_data_len;
+
+ if (be32_to_cpu(old_bph->off_dt_strings)
+ > be32_to_cpu(old_bph->off_dt_struct)) {
+ v = be32_to_cpu(new_bph->off_dt_strings);
+ new_bph->off_dt_strings = cpu_to_be32(v + diff);
+ }
+
+ if (be32_to_cpu(old_bph->off_mem_rsvmap)
+ > be32_to_cpu(old_bph->off_dt_struct)) {
+ v = be32_to_cpu(new_bph->off_mem_rsvmap);
+ new_bph->off_mem_rsvmap = cpu_to_be32(v + diff);
+ }
+
+ ft_free(*bphpp, old_total_size);
+ *bphpp = new_bph;
+ }
+}
+
+/*
+ * - Only modifies existing properties.
+ * - The dev tree passed in may be freed and a new one allocated
+ * (and *bphpp set to location of new dev tree).
+ */
+int ft_set_prop(void **bphpp, const void *node, const char *propname,
+ const void *buf, const unsigned int buflen)
+{
+ struct ft_entity fte;
+ u32 *p;
+ int depth;
+
+ depth = 0;
+ p = (u32 *)node;
+ while ((p = ft_next(p, *bphpp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
+ case OF_DT_BEGIN_NODE:
+ depth++;
+ break;
+ case OF_DT_PROP:
+ if ((depth == 1) && !strcmp(fte.name, propname)) {
+ ft_modify_prop(bphpp, fte.datap, fte.sizep, buf,
+ buflen);
+ return be32_to_cpu(*fte.sizep);
+ }
+ break;
+ case OF_DT_END_NODE:
+ if (--depth <= 0)
+ return -1;
+ break;
+ }
+ return -1;
+}
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
new file mode 100644
index 0000000..0690dd5
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree.h
@@ -0,0 +1,106 @@
+/*
+ * 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 "flatdevtree_env.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 */
+};
+
+struct ft_cxt {
+ struct boot_param_header *bph;
+ int max_size; /* maximum size of tree */
+ int overflow; /* set when this happens */
+ char *p, *pstr, *pres; /* running pointers */
+ char *p_begin, *pstr_begin, *pres_begin; /* starting pointers */
+ char *p_anchor; /* start of constructed area */
+ int struct_size, strings_size, res_size;
+};
+
+void ft_begin_node(struct ft_cxt *cxt, const char *name);
+void ft_end_node(struct ft_cxt *cxt);
+
+void ft_begin_tree(struct ft_cxt *cxt);
+int ft_end_tree(struct ft_cxt *cxt);
+
+void ft_nop(struct ft_cxt *cxt);
+void ft_prop(struct ft_cxt *cxt, const char *name,
+ const void *data, unsigned int sz);
+void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
+void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
+void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
+void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
+
+void ft_dump_blob(const void *bphp);
+void ft_merge_blob(struct ft_cxt *cxt, void *blob);
+
+void *ft_find_node(const void *bphp, const char *srch_path);
+int ft_get_prop(const void *bphp, const void *node, const char *propname,
+ void *buf, const unsigned int buflen);
+int ft_set_prop(void **bphp, const void *node, const char *propname,
+ const void *buf, const unsigned int buflen);
+
+static inline char *ft_strrchr(const char *s, int c)
+{
+ const char *p = s + strlen(s);
+
+ do {
+ if (*p == (char)c)
+ return (char *)p;
+ } while (--p >= s);
+ return NULL;
+}
+
+/* 'path' is modified */
+static inline void ft_parentize(char *path, int leave_slash)
+{
+ char *s = &path[strlen(path) - 1];
+
+ if (*s == '/')
+ *s = '\0';
+ s = ft_strrchr(path, '/');
+ if (s != NULL) {
+ if (leave_slash)
+ s[1] = '\0';
+ else if (s[0] == '/')
+ s[0] = '\0';
+ }
+}
+
+#endif /* FLATDEVTREE_H */
^ permalink raw reply related
* Re: [PATCH 6/6] Add support for the sandpoint platform
From: Mark A. Greer @ 2006-09-08 3:41 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060719231725.GG3887@mag.az.mvista.com>
This patch adds support for the Freescale Sandpoint platform
to the bootwrapper.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
boot/Makefile | 3
boot/dts/sandpoint.dts | 218 +++++++
boot/mpc10x.c | 109 +++
boot/sandpoint.c | 147 +++++
configs/sandpoint_defconfig | 1111 ++++++++++++++++++++++++++++++++++++++
platforms/embedded6xx/Kconfig | 2
platforms/embedded6xx/Makefile | 1
platforms/embedded6xx/sandpoint.c | 385 +++++++++++++
8 files changed, 1976 insertions(+)
--
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index f1877ac..44a3055 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -42,6 +42,9 @@ src-boot += of.c
else
src-boot += flatdevtree_misc.c
endif
+ifeq ($(CONFIG_SANDPOINT),y)
+src-boot += sandpoint.c mpc10x.c simple_alloc.c serial.c ns16550.c util.S
+endif
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
diff --git a/arch/powerpc/boot/dts/sandpoint.dts b/arch/powerpc/boot/dts/sandpoint.dts
new file mode 100644
index 0000000..016d57a
--- /dev/null
+++ b/arch/powerpc/boot/dts/sandpoint.dts
@@ -0,0 +1,218 @@
+/*
+ * Device Tree Souce for Freescale Sandpoint
+ *
+ * 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.
+ *
+ * add flash parts, rtc, ??
+ *
+ * To build:
+ * dtc -I dts -O asm -o sandpoint.S -V 16 sandpoint.dts
+ * dtc -I dts -O dtb -o sandpoint.dtb -V 16 sandpoint.dts
+ */
+
+/ {
+ linux,phandle = <1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "Sandpoint X3";
+ compatible = "Sandpoint";
+
+ cpus {
+ linux,phandle = <2000>;
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,603e { /* Really 75x, 74xx, 824x */
+ linux,phandle = <2100>;
+ linux,boot-cpu;
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; /* Set by bootwrapper */
+ timebase-frequency = <0>; /* Set by bootwrapper */
+ /* Following required by dtc but not used */
+ i-cache-line-size = <0>;
+ d-cache-line-size = <0>;
+ i-cache-size = <0>;
+ d-cache-size = <0>;
+ };
+ };
+
+ memory {
+ linux,phandle = <3000>;
+ device_type = "memory";
+ reg = <00000000 00000000>; /* Set by bootwrapper */
+ };
+
+ soc10x@fc000000 { /* Freescale/Tundra MPC10x */
+ linux,phandle = <4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ compatible = "mpc10x";
+ store-gathering = <0>; /* 0 == off, !0 == on */
+ bug-frequency = <0>; /* Set by bootwrapper */
+ reg = <fc000000 00100000>;
+ ranges = <80000000 80000000 70000000 /* pci mem space */
+ fc000000 fc000000 00100000 /* EUMB */
+ fe000000 fe000000 00c00000 /* pci i/o space */
+ fec00000 fec00000 00300000 /* pci cfg regs */
+ fef00000 fef00000 00100000 >; /* pci iack */
+
+ dma@fc001100 {
+ linux,phandle = <4100>;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "dma";
+ compatible = "fsl-dma";
+ clock-frequency = <0>;
+ reg = <fc001100 24>;
+ interrupts = <33 0>;
+ interrupt-parent = <4400>;
+ };
+
+ dma@fc001200 {
+ linux,phandle = <4200>;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "dma";
+ compatible = "fsl-dma";
+ clock-frequency = <0>;
+ reg = <fc001200 24>;
+ interrupts = <34 0>;
+ interrupt-parent = <4400>;
+ };
+
+ i2c@fc003000 {
+ linux,phandle = <4300>;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "i2c";
+ compatible = "fsl-i2c";
+ clock-frequency = <0>;
+ reg = <fc003000 1000>;
+ interrupts = <32 0>;
+ interrupt-parent = <4400>;
+ };
+
+ pic@fc040000 { /* EPIC */
+ linux,phandle = <4400>;
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ device_type = "open-pic";
+ compatible = "chrp,open-pic";
+ interrupt-controller;
+ reg = <fc040000 40000>;
+ clock-frequency = <0>;
+ clock-ratio = <7>;
+ serial-mode = <1>;
+ built-in;
+ };
+
+ pci@fec00000 {
+ linux,phandle = <4500>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "mpc10x-pci";
+ reg = <fec00000 00400000>;
+ ranges = <01000000 0 0 fe000000 0 00c00000
+ 02000000 0 80000000 80000000 0 70000000>;
+ bus-range = <0 ff>;
+ clock-frequency = <7f28155>;
+ interrupt-pci-iack = <fef00000>; /* New - PCI IACK */
+ interrupt-parent = <4400>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0b - i8259 on Windbond */
+ 5800 0 0 1 4400 0 0
+ 5800 0 0 2 4400 0 0
+ 5800 0 0 3 4400 0 0
+ 5800 0 0 4 4400 0 0
+ /* IDSEL 0x0d - PCI slot 1 */
+ 6800 0 0 1 4400 2 0
+ 6800 0 0 2 4400 5 0
+ 6800 0 0 3 4400 4 0
+ 6800 0 0 4 4400 3 0
+ /* IDSEL 0x0e - PCI slot 2 */
+ 7000 0 0 1 4400 3 0
+ 7000 0 0 2 4400 2 0
+ 7000 0 0 3 4400 5 0
+ 7000 0 0 4 4400 4 0
+ /* IDSEL 0x0f - PCI slot 3 */
+ 7800 0 0 1 4400 4 0
+ 7800 0 0 2 4400 3 0
+ 7800 0 0 3 4400 2 0
+ 7800 0 0 4 4400 5 0
+ /* IDSEL 0x10 - PCI slot 4 */
+ 8000 0 0 1 4400 5 0
+ 8000 0 0 2 4400 4 0
+ 8000 0 0 3 4400 3 0
+ 8000 0 0 4 4400 2 0
+ >;
+
+ isa {
+ linux,phandle = <4510>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "isa";
+ compatible = "isa";
+ ranges = <1 0 01000000 0 0 00800000>;
+ interrupt-parent = <4511>;
+
+ i8259@4d0 {
+ linux,phandle = <4511>;
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ device_type = "interrupt-controller";
+ compatible = "chrp,iic";
+ interrupt-controller;
+ clock-frequency = <0>;
+ built-in;
+ interrupt-parent = <4400>;
+ interrupts = < 0 0 >;
+ };
+
+ serial@3f8 {
+ linux,phandle = <4512>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <1 3f8 8>;
+ clock-frequency = <1c2000>;
+ current-speed = <2580>;
+ interrupts = <4 0>;
+ };
+
+ serial@2f8 {
+ linux,phandle = <4513>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <1 2f8 8>;
+ clock-frequency = <1c2000>;
+ current-speed = <2580>;
+ interrupts = <3 0>;
+ };
+ };
+ };
+ };
+
+ chosen {
+ linux,phandle = <5000>;
+ linux,platform = <1>;
+ bootargs = "ip=on";
+ /* bootargs = "ip=on"; */
+ linux,stdout-path = "/soc10x@fc000000/pci@fec00000/isa/serial@3f8";
+ interrupt-controller = <4400>;
+ };
+};
diff --git a/arch/powerpc/boot/mpc10x.c b/arch/powerpc/boot/mpc10x.c
new file mode 100644
index 0000000..3e4de93
--- /dev/null
+++ b/arch/powerpc/boot/mpc10x.c
@@ -0,0 +1,109 @@
+/*
+ * Freescale mpc10[67] & mpc824[015] specific code.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001 (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.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+
+/* Map B (CHRP Map) Defines */
+#define MPC10X_MAPB_CNFG_ADDR 0xfec00000
+#define MPC10X_MAPB_CNFG_DATA 0xfee00000
+
+/* Define offsets for the memory controller registers in the config space */
+#define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */
+#define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */
+#define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */
+#define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */
+
+#define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */
+#define MPC10X_MCTLR_MEM_END_2 0x94 /* Banks 4-7 */
+#define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */
+#define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */
+
+#define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0
+
+#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+
+/* Indirect PCI config space access routines */
+static inline void
+pci_indirect_read_config_byte(u32 *cfg_addr, u32 *cfg_data, int devfn,
+ int offset, u8 *val)
+{
+ out_be32(cfg_addr,
+ ((offset & 0xfc) << 24) | (devfn << 16) | (0 << 8) | 0x80);
+ *val = in_8((u8 *)(cfg_data + (offset & 3)));
+ return;
+}
+
+static inline void
+pci_indirect_read_config_dword(u32 *cfg_addr, u32 *cfg_data, int devfn,
+ int offset, u32 *val)
+{
+ out_be32(cfg_addr,
+ ((offset & 0xfc) << 24) | (devfn << 16) | (0 << 8) | 0x80);
+ *val = in_le32(cfg_data + (offset & 3));
+ return;
+}
+
+/*
+ * Read the memory controller registers to determine the amount of memory in
+ * the system. This assumes that the firmware has correctly set up the memory
+ * controller registers.
+ * Assume memory map B (CHRP).
+ */
+u32
+mpc10x_get_mem_size(void)
+{
+ u32 *config_addr, *config_data, val;
+ u32 start, end, total, offset, i;
+ u8 bank_enables;
+
+ config_addr = (u32 *)MPC10X_MAPB_CNFG_ADDR;
+ config_data = (u32 *)MPC10X_MAPB_CNFG_DATA;
+
+ pci_indirect_read_config_byte(config_addr, config_data, PCI_DEVFN(0,0),
+ MPC10X_MCTLR_MEM_BANK_ENABLES, &bank_enables);
+
+ total = 0;
+
+ for (i=0; i<8; i++) {
+ if (bank_enables & (1 << i)) {
+ offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
+ pci_indirect_read_config_dword(config_addr, config_data,
+ PCI_DEVFN(0,0), offset, &val);
+ start = (val >> ((i & 3) << 3)) & 0xff;
+
+ offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
+ pci_indirect_read_config_dword(config_addr, config_data,
+ PCI_DEVFN(0,0), offset, &val);
+ val = (val >> ((i & 3) << 3)) & 0x03;
+ start = (val << 28) | (start << 20);
+
+ offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
+ pci_indirect_read_config_dword(config_addr, config_data,
+ PCI_DEVFN(0,0), offset, &val);
+ end = (val >> ((i & 3) << 3)) & 0xff;
+
+ offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
+ pci_indirect_read_config_dword(config_addr, config_data,
+ PCI_DEVFN(0,0), offset, &val);
+ val = (val >> ((i & 3) << 3)) & 0x03;
+ end = (val << 28) | (end << 20) | 0xfffff;
+
+ total += (end - start + 1);
+ }
+ }
+
+ return total;
+}
diff --git a/arch/powerpc/boot/sandpoint.c b/arch/powerpc/boot/sandpoint.c
new file mode 100644
index 0000000..7062c16
--- /dev/null
+++ b/arch/powerpc/boot/sandpoint.c
@@ -0,0 +1,147 @@
+/*
+ * Sandpoint specific fixups.
+ *
+ * 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.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+
+#define CPU_824X 0
+#define CPU_7XX 1
+#define CPU_7457 2
+#define CPU_NUM 3
+
+static u32 cpu_pll[CPU_NUM][32] = {
+ [CPU_824X] = { /* 824x */
+ 5, 6, 9, 4, 4, 5, 2, 6, 6, 4, 9, 6, 5, 7, 6, 7,
+ 4, 5, 4, 6, 7, 8, 8, 4, 6, 5, 8, 6, 6, 5, 7, 0
+ },
+ [CPU_7XX] = { /* 750/755 */
+ 0, 15, 14, 2, 4, 13, 20, 9, 6, 11, 8, 10, 16, 12, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+ },
+ [CPU_7457] = { /* 7457 */
+ 23, 34, 15, 30, 14, 36, 2, 40, 4, 42, 13, 26, 17, 48, 19, 18,
+ 6, 21, 11, 22, 8, 20, 10, 24, 16, 28, 12, 32, 27, 56, 0, 25
+ }
+};
+
+static struct processor_info {
+ u32 pvr;
+ u32 mask;
+ u32 bus_freq;
+ u32 hid1_shift;
+ u32 hid1_mask;
+ u32 pll_tbl_idx;
+ u32 max_mem; /* DINK still sets up mem ctlr wrong */
+} processor_info_tbl[] = { /* From cputable -- MHz are only guesses */
+ /* 824x */
+ { 0x00810000, 0x7fff0000, 100000000, 27, 0x1f, CPU_824X, 0x08000000 },
+ /* 750 */
+ { 0x00084202, 0xffffffff, 100000000, 28, 0xf, CPU_7XX, 0x02000000 },
+ /* 745/755 */
+ { 0x00083000, 0xfffff000, 100000000, 28, 0xf, CPU_7XX, 0x02000000 },
+ /* 7447/7457 Rev 1.0 */
+ { 0x80020100, 0xffffffff, 100000000, 12, 0x1f, CPU_7457, 0x04000000 },
+ /* 7447/7457 Rev 1.1 */
+ { 0x80020101, 0xffffffff, 100000000, 12, 0x1f, CPU_7457, 0x04000000 },
+ /* 7447/7457 Rev 1.2 & up*/
+ { 0x80020000, 0xffff0000, 100000000, 12, 0x1f, CPU_7457, 0x04000000 },
+ /* 7447A */
+ { 0x80030000, 0xffff0000, 100000000, 12, 0x1f, CPU_7457, 0x80000000 },
+};
+
+static struct processor_info *get_processor_info(u32 pvr)
+{
+ struct processor_info *pit = processor_info_tbl;
+ u32 i;
+
+ for (i=0; i<ARRAY_SIZE(processor_info_tbl); i++, pit++)
+ if (pit->pvr == (pvr & pit->mask))
+ return pit;
+ return NULL;
+}
+
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
+
+#define SPRN_PVR 0x11F /* Processor Version Register */
+#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
+#define mfspr(rn) ({unsigned long rval; \
+ asm volatile("mfspr %0," __stringify(rn) \
+ : "=r" (rval)); rval;})
+
+static void sandpoint_fixups(void)
+{
+ u32 i, v[2], hid1, max_mem = 0xffffffff;
+ void *devp;
+ struct processor_info *pit;
+ extern u32 mpc10x_get_mem_size(void);
+
+ /* Update cpu's clock-frequency & timebase-frequency in fdt */
+ if ((pit = get_processor_info(mfspr(SPRN_PVR)))) {
+ if ((devp = finddevice("/cpus/PowerPC,603e"))) {
+ max_mem = pit->max_mem;
+
+ hid1 = (mfspr(SPRN_HID1) >> pit->hid1_shift)
+ & pit->hid1_mask;
+ v[0] = pit->bus_freq
+ * cpu_pll[pit->pll_tbl_idx][hid1]/2;
+ setprop(devp, "clock-frequency", v, sizeof(v[0]));
+
+ v[0] = pit->bus_freq / 4;
+ setprop(devp, "timebase-frequency", v, sizeof(v[0]));
+ }
+ if ((devp = finddevice("/soc10x@fc000000")))
+ setprop(devp, "clock-frequency", &pit->bus_freq,
+ sizeof(u32));
+ }
+
+ /* Get the RAM size from the memory controller & update fdt */
+ if ((devp = finddevice("/memory"))) {
+ i = mpc10x_get_mem_size();
+ v[0] = 0;
+ v[1] = min(i, max_mem);
+ setprop(devp, "reg", v, sizeof(v));
+ }
+
+ /* XXXX stuff from platforms/.../sandpoint.c should be here */
+}
+
+static void sandpoint_reset(void)
+{
+ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+ _nmask_and_or_msr(0, (1<<6)); /* Set exception prefix high - firmware */
+
+ /* Reset system via Port 92 */
+ out_8((volatile unsigned char *)0xfe000092, 0x00);
+ out_8((volatile unsigned char *)0xfe000092, 0x01);
+
+ for(;;); /* Spin until reset happens */
+}
+
+int platform_init(void *promptr)
+{
+ /* dt_ops should already be set up in start() */
+ if (!dt_ops.finddevice || !dt_ops.getprop || !dt_ops.setprop
+ || !dt_ops.translate_addr || !dt_ops.call_kernel)
+ return -1;
+
+ platform_ops.fixups = sandpoint_fixups;
+ platform_ops.exit = sandpoint_reset;
+ simple_alloc_init();
+
+ return serial_console_init();
+}
diff --git a/arch/powerpc/configs/sandpoint_defconfig b/arch/powerpc/configs/sandpoint_defconfig
new file mode 100644
index 0000000..bfbb9b8
--- /dev/null
+++ b/arch/powerpc/configs/sandpoint_defconfig
@@ -0,0 +1,1111 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc5
+# Thu Sep 7 16:24:12 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_PPC_ISERIES is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_APUS is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+CONFIG_PPC_TODC=y
+# CONFIG_KATANA is not set
+# CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
+# CONFIG_LOPEC is not set
+# CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
+# CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
+CONFIG_SANDPOINT=y
+# CONFIG_MPC7448HPC2 is not set
+# CONFIG_RADSTONE_PPC7D is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+# CONFIG_EV64360 is not set
+CONFIG_PPC_GEN550=y
+CONFIG_EPIC_SERIAL_MODE=y
+CONFIG_MPC10X_BRIDGE=y
+CONFIG_MPC10X_OPENPIC=y
+# CONFIG_MPC10X_STORE_GATHERING is not set
+# CONFIG_SANDPOINT_ENABLE_UART1 is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
+# CONFIG_PCMCIA_XIRCOM is not set
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+CONFIG_BDI_SWITCH=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 234a861..e5ac829 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -69,7 +69,9 @@ config PRPMC800
config SANDPOINT
bool "Motorola-Sandpoint"
+ select MPIC
select PPC_I8259
+ select PPC_UDBG_16550
help
Select SANDPOINT if configuring for a Motorola Sandpoint X3
(any flavor).
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index fa499fe..042b6ca 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -2,3 +2,4 @@ #
# Makefile for the 6xx/7xx/7xxxx linux kernel.
#
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
+obj-$(CONFIG_SANDPOINT) += sandpoint.o
diff --git a/arch/powerpc/platforms/embedded6xx/sandpoint.c b/arch/powerpc/platforms/embedded6xx/sandpoint.c
new file mode 100644
index 0000000..56b7746
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/sandpoint.c
@@ -0,0 +1,385 @@
+/*
+ * Board setup routines for the Freescale Sandpoint Test Platform.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2000-2003 (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.
+ */
+
+/*
+ * This file adds support for the Freescale Sandpoint Test Platform.
+ * These boards have a PPMC slot for the processor so any combination
+ * of cpu and host bridge can be attached. This port is for an 8240 PPMC
+ * module from Freescale and other closely related cpu/host bridge
+ * combinations (e.g., 750/755/7400 with MPC107 host bridge).
+ * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2
+ * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a
+ * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr),
+ * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V
+ * but are really 5V).
+ *
+ * The firmware on the sandpoint is called DINK (not my acronym :). This port
+ * depends on DINK to do some basic initialization (e.g., initialize the memory
+ * ctlr) and to ensure that the processor is using MAP B (CHRP map).
+ *
+ * Since Freescale listened to our suggestions for improvement, we now have
+ * the Sandpoint X3 board. All of the PCI slots are available, it uses
+ * the serial interrupt interface (just a hardware thing we need to
+ * configure properly).
+ *
+ * Use the default X3 switch settings. The interrupts are then:
+ * EPIC Source
+ * 0 SIOINT (8259, active low)
+ * 1 PCI #1
+ * 2 PCI #2
+ * 3 PCI #3
+ * 4 PCI #4
+ * 7 Winbond INTC (IDE interrupt)
+ * 8 Winbond INTD (IDE interrupt)
+ *
+ *
+ * Freescale has finally released a version of DINK32 that correctly
+ * (seemingly) initalizes the memory controller correctly, regardless
+ * of the amount of memory in the system. Once a method of determining
+ * what version of DINK initializes the system for us, if applicable, is
+ * found, we can hopefully stop hardcoding 32MB of RAM.
+ */
+
+#include <linux/initrd.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/root_dev.h>
+
+#include <asm/time.h>
+#include <asm/i8259.h>
+#include <asm/udbg.h>
+#include <asm/todc.h>
+#include <asm/mpic.h>
+#include <asm/todc.h>
+
+/*
+ * Interrupt setup and service. Interrrupts on the Sandpoint come
+ * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
+ * The 8259 is cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4,
+ * IDE is on EPIC 7 and 8.
+ */
+static void sandpoint_8259_cascade(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int cascade_irq = i8259_irq(regs);
+
+ if (cascade_irq != NO_IRQ)
+ generic_handle_irq(cascade_irq, regs);
+ desc->chip->eoi(irq);
+}
+
+static void __init
+sandpoint_init_irq(void)
+{
+ struct mpic *mpic;
+ struct device_node *dnp, *cascade_node = NULL;
+ void *prop;
+ int size;
+ unsigned int cascade_irq;
+ phys_addr_t paddr;
+
+ dnp = of_find_node_by_type(NULL, "open-pic");
+ if (dnp == NULL)
+ return;
+
+ prop = (struct device_node *)get_property(dnp, "reg", &size);
+ paddr = (phys_addr_t)of_translate_address(dnp, prop);
+
+ mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY, 0, 0, " EPIC ");
+
+ prop = (struct device_node *)get_property(dnp, "clock-ratio", &size);
+ if (prop != NULL)
+ mpic_set_clk_ratio(mpic, *(u32 *)prop);
+
+ prop = (struct device_node *)get_property(dnp, "serial-mode", &size);
+ if (prop != NULL)
+ mpic_set_serial_int(mpic, *(u32 *)prop);
+
+ mpic_assign_isu(mpic, 0, paddr + 0x10200);
+ mpic_init(mpic);
+
+ for_each_node_by_type(dnp, "interrupt-controller")
+ if (device_is_compatible(dnp, "chrp,iic")) {
+ cascade_node = dnp;
+ break;
+ }
+
+ if (cascade_node == NULL)
+ return;
+
+ cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+
+ if (cascade_irq == NO_IRQ)
+ return;
+
+ i8259_init(cascade_node, 0);
+ set_irq_chained_handler(cascade_irq, sandpoint_8259_cascade);
+}
+
+static int __init
+add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+ int *bus_range;
+
+ printk("Adding PCI host bridge %s\n", dev->full_name);
+
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int))
+ printk(KERN_WARNING "Can't get bus-range for %s, assume"
+ " bus 0\n", dev->full_name);
+
+ hose = pcibios_alloc_controller();
+ if (hose == NULL)
+ return -ENOMEM;
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+ setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, 1);
+ return 0;
+}
+
+/*
+ * Freescale Sandpoint interrupt routing.
+ */
+static inline int
+x3_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 0, 0, 0, 0 }, /* IDSEL 11 - i8259 on Winbond */
+ { 0, 0, 0, 0 }, /* IDSEL 12 - unused */
+ { 2, 5, 4, 3 }, /* IDSEL 13 - PCI slot 1 */
+ { 3, 2, 5, 4 }, /* IDSEL 14 - PCI slot 2 */
+ { 4, 3, 2, 5 }, /* IDSEL 15 - PCI slot 3 */
+ { 5, 4, 3, 2 }, /* IDSEL 16 - PCI slot 4 */
+ };
+
+ const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#ifdef CONFIG_PPC_TODC
+TODC_ALLOC()
+#endif
+
+static void __init
+sandpoint_setup_arch(void)
+{
+ struct device_node *dnp;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+#ifdef CONFIG_ROOT_NFS
+ ROOT_DEV = Root_NFS;
+#else
+ ROOT_DEV = Root_HDA1;
+#endif
+
+ for (dnp = NULL; (dnp=of_find_node_by_type(dnp,"pci")) != NULL;)
+ add_bridge(dnp);
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = x3_map_irq;
+
+ printk(KERN_INFO "Port by MontaVista Software, Inc. <source@mvista.com>\n");
+
+#ifdef CONFIG_PPC_TODC
+ TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8);
+
+ ppc_md.nvram_read_val = todc_mc146818_read_val;
+ ppc_md.nvram_write_val = todc_mc146818_write_val;
+
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+#endif
+
+ /* DINK32 12.3 and below do not correctly enable any caches.
+ * We will do this now with good known values. Future versions
+ * of DINK32 are supposed to get this correct.
+ */
+ if (cpu_has_feature(CPU_FTR_SPEC7450))
+ /* 745x is different. We only want to pass along enable. */
+ _set_L2CR(L2CR_L2E);
+ else if (cpu_has_feature(CPU_FTR_L2CR))
+ /* All modules have 1MB of L2. We also assume that an
+ * L2 divisor of 3 will work.
+ */
+ _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
+ | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
+#if 0
+ /* Untested right now. */
+ if (cpu_has_feature(CPU_FTR_L3CR)) {
+ /* Magic value. */
+ _set_L3CR(0x8f032000);
+ }
+#endif
+}
+
+static void
+sandpoint_restart(char *cmd)
+{
+ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+
+ local_irq_disable();
+ _nmask_and_or_msr(0, MSR_IP); /* Set exception prefix high - firmware */
+
+ /* Reset system via Port 92 */
+ outb(0x00, 0x92);
+ outb(0x01, 0x92);
+
+ for(;;); /* Spin until reset happens */
+}
+
+static void
+sandpoint_power_off(void)
+{
+ local_irq_disable();
+ for(;;); /* No way to shut power off with software */
+ /* NOTREACHED */
+}
+
+static void
+sandpoint_halt(void)
+{
+ sandpoint_power_off();
+ /* NOTREACHED */
+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE support.
+ */
+static int sandpoint_ide_ports_known = 0;
+static unsigned long sandpoint_ide_regbase[MAX_HWIFS];
+static unsigned long sandpoint_ide_ctl_regbase[MAX_HWIFS];
+static unsigned long sandpoint_idedma_regbase;
+
+static void
+sandpoint_ide_probe(void)
+{
+ struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_WINBOND,
+ PCI_DEVICE_ID_WINBOND_82C105, NULL);
+
+ if (pdev) {
+ sandpoint_ide_regbase[0]=pdev->resource[0].start;
+ sandpoint_ide_regbase[1]=pdev->resource[2].start;
+ sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start;
+ sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start;
+ sandpoint_idedma_regbase=pdev->resource[4].start;
+ pci_dev_put(pdev);
+ }
+
+ sandpoint_ide_ports_known = 1;
+}
+
+static unsigned long
+sandpoint_ide_default_io_base(int index)
+{
+ if (sandpoint_ide_ports_known == 0)
+ sandpoint_ide_probe();
+
+ return sandpoint_ide_regbase[index];
+}
+
+static void __init
+sandpoint_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
+ unsigned long ctrl_port, int *irq)
+{
+ unsigned long reg = data_port;
+ uint alt_status_base;
+ int i;
+
+ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+ hw->io_ports[i] = reg++;
+ }
+
+ if (data_port == sandpoint_ide_regbase[0]) {
+ alt_status_base = sandpoint_ide_ctl_regbase[0] + 2;
+ hw->irq = 14;
+ }
+ else if (data_port == sandpoint_ide_regbase[1]) {
+ alt_status_base = sandpoint_ide_ctl_regbase[1] + 2;
+ hw->irq = 15;
+ }
+ else {
+ alt_status_base = 0;
+ hw->irq = 0;
+ }
+
+ if (ctrl_port) {
+ hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+ } else {
+ hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base;
+ }
+
+ if (irq != NULL) {
+ *irq = hw->irq;
+ }
+}
+
+static int __init
+sandpoint_ide_init(void)
+{
+ /* doesn't find hda without this */
+ ppc_ide_md.default_io_base = sandpoint_ide_default_io_base;
+ /* get error msgs without this */
+ ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports;
+ return 0;
+}
+arch_initcall(sandpoint_ide_init);
+#endif
+
+void __init
+sandpoint_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev)
+ pci_read_irq_line(dev);
+}
+
+#define PLATFORM_NAME "Freescale Sandpoint"
+
+static int __init
+sandpoint_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "Sandpoint"))
+ return 1;
+ return 0;
+}
+
+define_machine(sandpoint) {
+ .name = PLATFORM_NAME,
+ .probe = sandpoint_probe,
+ .setup_arch = sandpoint_setup_arch,
+ .init_IRQ = sandpoint_init_irq,
+ .pcibios_fixup = sandpoint_pcibios_fixup,
+ .get_irq = mpic_get_irq,
+ .restart = sandpoint_restart,
+ .power_off = sandpoint_power_off,
+ .halt = sandpoint_halt,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
^ permalink raw reply related
* Re: [PATCH 5/6] bootwrapper: Add simple memory allocator
From: Mark A. Greer @ 2006-09-08 3:40 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060719231421.GF3887@mag.az.mvista.com>
This patch adds a simple memory allocator to the bootwrapper.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
simple_alloc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+)
--
diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c
new file mode 100644
index 0000000..ccf61b2
--- /dev/null
+++ b/arch/powerpc/boot/simple_alloc.c
@@ -0,0 +1,48 @@
+/*
+ * Simple memory allocator.
+ *
+ * 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.
+ */
+
+/* Some day, put in a real memory allocator */
+
+#include <stddef.h>
+#include "types.h"
+#include "page.h"
+#include "ops.h"
+
+#define MB (1024*1024)
+
+extern char _end[];
+
+static u32 cur_base;
+static u32 end_of_ram = 32 * MB;
+
+static void *simple_malloc(u32 size)
+{
+ void *area = NULL;
+ static u8 first_time = 1;
+
+ if (first_time) {
+ cur_base = _ALIGN_UP((unsigned long)_end, MB);
+ first_time = 0;
+ }
+
+ if ((cur_base + size) < end_of_ram) {
+ area = (void *)cur_base;
+ cur_base += _ALIGN_UP(size, MB);
+ }
+
+ return area;
+}
+
+void simple_alloc_init(void)
+{
+ platform_ops.malloc = simple_malloc;
+ platform_ops.free = NULL;
+}
^ permalink raw reply related
* Re: [PATCH 4/6] bootwrapper: Add non-OF serial console support
From: Mark A. Greer @ 2006-09-08 3:39 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060719231244.GE3887@mag.az.mvista.com>
This patch adds support for serial I/O to the bootwrapper.
It is broken into 2 layers. The first layer is generic serial
operations that calls uart-specific routines to do the actual I/O.
The second layer contains support for a 16550 compatible uart.
The division allows support for other serial devices to be easily
added in the future (e.g., the Marvell MPSC and the Freescale CPM).
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
io.h | 53 ++++++++++++++++++++
ns16550.c | 81 +++++++++++++++++++++++++++++++
serial.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.S | 101 +++++++++++++++++++++++++++++++++++++++
4 files changed, 394 insertions(+)
--
diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h
new file mode 100644
index 0000000..32974ed
--- /dev/null
+++ b/arch/powerpc/boot/io.h
@@ -0,0 +1,53 @@
+#ifndef _IO_H
+#define __IO_H
+/*
+ * Low-level I/O routines.
+ *
+ * Copied from <file:include/asm-powerpc/io.h> (which has no copyright)
+ */
+static inline int in_8(const volatile unsigned char *addr)
+{
+ int ret;
+
+ __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "m" (*addr));
+ return ret;
+}
+
+static inline void out_8(volatile unsigned char *addr, int val)
+{
+ __asm__ __volatile__("stb%U0%X0 %1,%0; sync"
+ : "=m" (*addr) : "r" (val));
+}
+
+static inline unsigned in_le32(const volatile unsigned *addr)
+{
+ unsigned ret;
+
+ __asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "r" (addr), "m" (*addr));
+ return ret;
+}
+
+static inline unsigned in_be32(const volatile unsigned *addr)
+{
+ unsigned ret;
+
+ __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "m" (*addr));
+ return ret;
+}
+
+static inline void out_le32(volatile unsigned *addr, int val)
+{
+ __asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr)
+ : "r" (val), "r" (addr));
+}
+
+static inline void out_be32(volatile unsigned *addr, int val)
+{
+ __asm__ __volatile__("stw%U0%X0 %1,%0; sync"
+ : "=m" (*addr) : "r" (val));
+}
+
+#endif /* _IO_H */
diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c
new file mode 100644
index 0000000..06a6d32
--- /dev/null
+++ b/arch/powerpc/boot/ns16550.c
@@ -0,0 +1,81 @@
+/*
+ * 16550 serial console support.
+ *
+ * Original copied from <file:arch/ppc/boot/common/ns16550.c>
+ * (which had no copyright)
+ * Modifications: 2006 (c) MontaVista Software, Inc.
+ *
+ * Modified by: Mark A. Greer <mgreer@mvista.com>
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+
+#define UART_DLL 0 /* Out: Divisor Latch Low */
+#define UART_DLM 1 /* Out: Divisor Latch High */
+#define UART_FCR 2 /* Out: FIFO Control Register */
+#define UART_LCR 3 /* Out: Line Control Register */
+#define UART_MCR 4 /* Out: Modem Control Register */
+#define UART_LSR 5 /* In: Line Status Register */
+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+#define UART_LSR_DR 0x01 /* Receiver data ready */
+#define UART_MSR 6 /* In: Modem Status Register */
+#define UART_SCR 7 /* I/O: Scratch Register */
+
+static unsigned char *reg_base;
+static u8 reg_shift;
+
+static int ns16550_open(void)
+{
+ out_8(reg_base + (UART_FCR << reg_shift), 0x06);
+ return 0;
+}
+
+static void ns16550_putc(unsigned char c)
+{
+ while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_THRE) == 0);
+ out_8(reg_base, c);
+}
+
+static unsigned char ns16550_getc(void)
+{
+ while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) == 0);
+ return in_8(reg_base);
+}
+
+static u8 ns16550_tstc(void)
+{
+ return ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) != 0);
+}
+
+int ns16550_console_probe_init(char *compat, void *devp, char *path,
+ struct serial_console_data *scdp)
+{
+ u64 addr;
+ u32 reg[2];
+
+ if (strcmp("ns16550", compat))
+ return 0; /* Not my device */
+
+ if (getprop(devp, "reg", reg, sizeof(reg)) != sizeof(reg))
+ return -1; /* dt must be horked so fail */
+
+ addr = dt_ops.translate_addr(path, reg, sizeof(reg));
+ reg_base = (unsigned char *)((u32)addr & 0xffffffffu);
+
+ if (getprop(devp, "reg_shift", ®_shift, sizeof(reg_shift))
+ != sizeof(reg_shift))
+ reg_shift = 0;
+
+ scdp->open = ns16550_open;
+ scdp->putc = ns16550_putc;
+ scdp->getc = ns16550_getc;
+ scdp->tstc = ns16550_tstc;
+ scdp->close = NULL;
+
+ return 1; /* My device and I initialized okay */
+}
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
new file mode 100644
index 0000000..368cce8
--- /dev/null
+++ b/arch/powerpc/boot/serial.c
@@ -0,0 +1,159 @@
+/*
+ * Generic serial console support
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * Code in serial_edit_cmdline() copied from <file:arch/ppc/boot/simple/misc.c>
+ * and was written by Matt Porter <mporter@kernel.crashing.org>.
+ *
+ * 2001,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.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+
+extern void udelay(long delay);
+
+static int serial_open(void)
+{
+ struct serial_console_data *scdp = console_ops.data;
+ return scdp->open();
+}
+
+static void serial_write(char *buf, int len)
+{
+ struct serial_console_data *scdp = console_ops.data;
+
+ while (*buf != '\0')
+ scdp->putc(*buf++);
+}
+
+static void serial_edit_cmdline(char *buf, int len)
+{
+ int timer = 0, count;
+ char ch, *cp;
+ struct serial_console_data *scdp = console_ops.data;
+
+ cp = buf;
+ count = strlen(buf);
+ cp = &buf[count];
+ count++;
+
+ while (timer++ < 5*1000) {
+ if (scdp->tstc()) {
+ while (((ch = scdp->getc()) != '\n') && (ch != '\r')) {
+ /* Test for backspace/delete */
+ if ((ch == '\b') || (ch == '\177')) {
+ if (cp != buf) {
+ cp--;
+ count--;
+ printf("\b \b");
+ }
+ /* Test for ^x/^u (and wipe the line) */
+ } else if ((ch == '\030') || (ch == '\025')) {
+ while (cp != buf) {
+ cp--;
+ count--;
+ printf("\b \b");
+ }
+ } else if (count < len) {
+ *cp++ = ch;
+ count++;
+ scdp->putc(ch);
+ }
+ }
+ break; /* Exit 'timer' loop */
+ }
+ udelay(1000); /* 1 msec */
+ }
+ *cp = 0;
+}
+
+static void serial_close(void)
+{
+ struct serial_console_data *scdp = console_ops.data;
+
+ if (scdp->close)
+ scdp->close();
+}
+
+static int serial_get_stdout_info(void **devpp, char *path)
+{
+ void *devp;
+ char devtype[MAX_PROP_LEN];
+
+ devp = finddevice("/chosen");
+ if ((devp != NULL) && (getprop(devp, "linux,stdout-path", path,
+ MAX_PATH_LEN) > 0)) {
+ /* Check that device_type of stdout device is serial */
+ devp = finddevice(path);
+ if ((devp != NULL) && (getprop(devp, "device_type", devtype,
+ sizeof(devtype)) > 0)
+ && !strcmp(devtype, "serial")) {
+ *devpp = devp;
+ /* *path param is set as well */
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/* Add "weak" definition for each serial driver */
+int __attribute__ ((weak)) ns16550_console_probe_init(char *compat, void *devp,
+ char *path, struct serial_console_data *scdp)
+{
+ return 0; /* "not mine" */
+}
+
+static struct serial_console_data serial_cd;
+
+/* Node's "compatible" property determines which serial driver to use */
+int serial_console_init(void)
+{
+ void *devp;
+ int rc;
+ char path[MAX_PATH_LEN], compat[MAX_PROP_LEN];
+
+ if (serial_get_stdout_info(&devp, path))
+ goto fail;
+
+ if (getprop(devp, "compatible", compat, sizeof(compat)) < 0)
+ goto fail;
+
+ /* Call various serial driver probe routines.
+ * DO NOT put the routine addresses into a table because they
+ * will not be relocated.
+ *
+ * Probe routine return values:
+ * -1: driver owns the device but init failed
+ * 0: driver does not own the device
+ * 1: driver owns the device and initialized it okay
+ */
+ rc = ns16550_console_probe_init(compat, devp, path, &serial_cd);
+ /* Do something like:
+ * if (rc == 0)
+ * rc = next_console_probe_init(compat, devp, path, &serial_cd);
+ * if (rc == 0)
+ * ...
+ */
+
+ if (rc == 1) {
+ console_ops.open = serial_open;
+ console_ops.write = serial_write;
+ console_ops.edit_cmdline = serial_edit_cmdline;
+ console_ops.close = serial_close;
+ console_ops.data = &serial_cd;
+
+ return 0;
+ }
+fail:
+ return -1;
+}
diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S
new file mode 100644
index 0000000..b8e1c23
--- /dev/null
+++ b/arch/powerpc/boot/util.S
@@ -0,0 +1,101 @@
+/*
+ * Copied from <file:arch/powerpc/kernel/misc_32.S>
+ *
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * kexec bits:
+ * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ *
+ * 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 "ppc_asm.h"
+
+#define SPRN_PVR 0x11F /* Processor Version Register */
+
+ .text
+/*
+ * complement mask on the msr then "or" some values on.
+ * _nmask_and_or_msr(nmask, value_to_or)
+ */
+ .globl _nmask_and_or_msr
+_nmask_and_or_msr:
+ mfmsr r0 /* Get current msr */
+ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
+ or r0,r0,r4 /* Or on the bits in r4 (second parm) */
+ SYNC /* Some chip revs have problems here... */
+ mtmsr r0 /* Update machine state */
+ isync
+ blr /* Done */
+
+/* udelay (on non-601 processors) needs to know the period of the
+ * timebase in nanoseconds. This used to be hardcoded to be 60ns
+ * (period of 66MHz/4). Now a variable is used that is initialized to
+ * 60 for backward compatibility, but it can be overridden as necessary
+ * with code something like this:
+ * extern unsigned long timebase_period_ns;
+ * timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+ */
+ .data
+ .globl timebase_period_ns
+timebase_period_ns:
+ .long 60
+
+ .text
+/*
+ * Delay for a number of microseconds
+ */
+ .globl udelay
+udelay:
+ mfspr r4,SPRN_PVR
+ srwi r4,r4,16
+ cmpwi 0,r4,1 /* 601 ? */
+ bne .udelay_not_601
+00: li r0,86 /* Instructions / microsecond? */
+ mtctr r0
+10: addi r0,r0,0 /* NOP */
+ bdnz 10b
+ subic. r3,r3,1
+ bne 00b
+ blr
+
+.udelay_not_601:
+ mulli r4,r3,1000 /* nanoseconds */
+ /* Change r4 to be the number of ticks using:
+ * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns
+ * timebase_period_ns defaults to 60 (16.6MHz) */
+ mflr r5
+ bl 0f
+0: mflr r6
+ mtlr r5
+ lis r5,0b@ha
+ addi r5,r5,0b@l
+ subf r5,r5,r6 /* In case we're relocated */
+ addis r5,r5,timebase_period_ns@ha
+ lwz r5,timebase_period_ns@l(r5)
+ add r4,r4,r5
+ addi r4,r4,-1
+ divw r4,r4,r5 /* BUS ticks */
+1: mftbu r5
+ mftb r6
+ mftbu r7
+ cmpw 0,r5,r7
+ bne 1b /* Get [synced] base time */
+ addc r9,r6,r4 /* Compute end time */
+ addze r8,r5
+2: mftbu r5
+ cmpw 0,r5,r8
+ blt 2b
+ bgt 3f
+ mftb r6
+ cmpw 0,r6,r9
+ blt 2b
+3: blr
^ permalink raw reply related
* Re: [PATCH 3/6] bootwrapper: Add flat device tree ops glue code
From: Mark A. Greer @ 2006-09-08 3:38 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060719230544.GD3887@mag.az.mvista.com>
This patch adds the "glue" files that interface between the bootwrapper
code and the shared code that is in flatdevtree.[ch].
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
Makefile | 2
flatdevtree_env.h | 34 ++++++
flatdevtree_misc.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 295 insertions(+)
--
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index c2bb541..f1877ac 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -39,6 +39,8 @@ #$(addprefix $(obj)/,main.o): $(addprefi
src-boot := crt0.S string.S stdio.c main.c div64.S
ifeq ($(CONFIG_PPC_MULTIPLATFORM),y)
src-boot += of.c
+else
+src-boot += flatdevtree_misc.c
endif
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
diff --git a/arch/powerpc/boot/flatdevtree_env.h b/arch/powerpc/boot/flatdevtree_env.h
new file mode 100644
index 0000000..90e723b
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree_env.h
@@ -0,0 +1,34 @@
+/*
+ * This file adds the header file glue so that the shared files
+ * flatdevicetree.[ch] can compile and work in the powerpc bootwrapper.
+ *
+ * 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_FLATDEVTREE_ENV_H_
+#define _PPC_BOOT_FLATDEVTREE_ENV_H_
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "ops.h"
+
+#define be16_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be32(x) (x)
+#define be64_to_cpu(x) (x)
+#define cpu_to_be64(x) (x)
+
+#define ft_malloc(s) malloc(s)
+#define ft_free(p,s) free(p,s)
+#define ft_exit(x) exit()
+
+#endif /* _PPC_BOOT_FLATDEVTREE_ENV_H_ */
diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c
new file mode 100644
index 0000000..603d89d
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree_misc.c
@@ -0,0 +1,259 @@
+/*
+ * This file does the necessary interface mapping between the bootwrapper
+ * device tree operations and the interface provided by shared source
+ * files flatdevicetree.[ch]. It also provides the bootwrapper-required
+ * functionality that is not provided by flatdevicetree.c
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ * ft_translate_addr() and related routines came from
+ * <file:arch/powerpc/kernel/prom_parse.c> which has no author or
+ * copyright notice.
+ *
+ * 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.
+ */
+#include "flatdevtree.h"
+
+#define MAX_ADDR_CELLS 4
+#define BAD_ADDR ((u64)-1)
+
+struct ft_bus {
+ u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
+ int (*translate)(u32 *addr, u64 offset, int na);
+};
+
+static u32 ft_find_cells(char *path, char *prop)
+{
+ void *devp;
+ u32 num;
+ char p[MAX_PATH_LEN];
+
+ strcpy(p, path);
+ do {
+ if ((devp = finddevice(p))
+ && (getprop(devp, prop, &num, sizeof(num)) > 0))
+ return num;
+ ft_parentize(p, 0);
+ } while (strlen(p) > 0);
+ return 1; /* default of 1 */
+}
+
+static u64 ft_read_addr(u32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | *(cell++);
+ return r;
+}
+
+static u64 ft_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = ft_read_addr(range, na);
+ s = ft_read_addr(range + na + pna, ns);
+ da = ft_read_addr(addr, na);
+
+ if (da < cp || da >= (cp + s))
+ return BAD_ADDR;
+ return da - cp;
+}
+
+static int ft_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+ u64 a = ft_read_addr(addr, na);
+ memset(addr, 0, na * 4);
+ a += offset;
+ if (na > 1)
+ addr[na - 2] = a >> 32;
+ addr[na - 1] = a & 0xffffffffu;
+
+ return 0;
+}
+
+static u64 ft_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x03000000)
+ return BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = ft_read_addr(range + 1, na - 1);
+ s = ft_read_addr(range + na + pna, ns);
+ da = ft_read_addr(addr + 1, na - 1);
+
+ if (da < cp || da >= (cp + s))
+ return BAD_ADDR;
+ return da - cp;
+}
+
+static int ft_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+ return ft_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static u64 ft_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x00000001)
+ return BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = ft_read_addr(range + 1, na - 1);
+ s = ft_read_addr(range + na + pna, ns);
+ da = ft_read_addr(addr + 1, na - 1);
+
+ if (da < cp || da >= (cp + s))
+ return BAD_ADDR;
+ return da - cp;
+}
+
+static int ft_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+ return ft_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static void ft_match_bus(char *path, struct ft_bus *bus)
+{
+ void *devp;
+ char dtype[128]; /* XXXX */
+
+ if ((devp = finddevice(path)) && (getprop(devp, "device_type", dtype,
+ sizeof(dtype)) > 0)) {
+ if (!strcmp(dtype, "isa")) {
+ bus->map = ft_bus_isa_map;
+ bus->translate = ft_bus_isa_translate;
+ } else if (!strcmp(dtype, "pci")) {
+ bus->map = ft_bus_pci_map;
+ bus->translate = ft_bus_pci_translate;
+ } else {
+ bus->map = ft_bus_default_map;
+ bus->translate = ft_bus_default_translate;
+ }
+ }
+}
+
+static int ft_translate_one(char *path, struct ft_bus *bus, struct ft_bus *pbus,
+ u32 *addr, u32 na, u32 ns, u32 pna)
+{
+ void *devp;
+ u32 ranges[10 * (na + pna + ns)]; /* XXXX */
+ u32 *rp;
+ unsigned int rlen;
+ int rone;
+ u64 offset = BAD_ADDR;
+
+ if (!(devp = finddevice(path))
+ || ((rlen = getprop(devp, "ranges", ranges,
+ sizeof(ranges))) < 0)
+ || (rlen == 0)) {
+ offset = ft_read_addr(addr, na);
+ memset(addr, 0, pna * 4);
+ goto finish;
+ }
+
+ rlen /= 4;
+ rone = na + pna + ns;
+ rp = ranges;
+ for (; rlen >= rone; rlen -= rone, rp += rone) {
+ offset = bus->map(addr, rp, na, ns, pna);
+ if (offset != BAD_ADDR)
+ break;
+ }
+ if (offset == BAD_ADDR)
+ return 1;
+ memcpy(addr, rp + na, 4 * pna);
+
+finish:
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+/* 'addr' is modified */
+static u64 ft_translate_addr(const char *p, const u32 *in_addr,
+ const u32 addr_len)
+{
+ struct ft_bus bus, pbus;
+ int na, ns, pna, pns;
+ u32 addr[MAX_ADDR_CELLS];
+ char path[MAX_PATH_LEN], ppath[MAX_PATH_LEN];
+
+ strcpy(ppath, p);
+ ft_parentize(ppath, 0);
+ ft_match_bus(ppath, &bus);
+ na = ft_find_cells(ppath, "#address-cells");
+ ns = ft_find_cells(ppath, "#size-cells");
+ memcpy(addr, in_addr, na * 4);
+
+ for (;;) {
+ strcpy(path, ppath);
+ ft_parentize(ppath, 0);
+
+ if (strlen(ppath) == 0)
+ return ft_read_addr(addr, na);
+
+ ft_match_bus(ppath, &pbus);
+ pna = ft_find_cells(ppath, "#address-cells");
+ pns = ft_find_cells(ppath, "#size-cells");
+
+ if (ft_translate_one(path, &bus, &pbus, addr, na, ns, pna))
+ exit();
+
+ na = pna;
+ ns = pns;
+ memcpy(&bus, &pbus, sizeof(struct ft_bus));
+ }
+}
+
+static void *dtb;
+
+static void *ft_finddevice(const char *name)
+{
+ return ft_find_node(dtb, name);
+}
+
+static int ft_getprop(const void *node, const char *propname, void *buf,
+ const int buflen)
+{
+ return ft_get_prop(dtb, node, propname, buf, buflen);
+}
+
+static int ft_setprop(const void *node, const char *propname, const void *buf,
+ const int buflen)
+{
+ return ft_set_prop(&dtb, node, propname, buf, buflen);
+}
+
+static void ft_call_kernel(void *entry_addr, unsigned long a1, unsigned long a2,
+ void *promptr, void *sp)
+{
+ void (*kernel_entry)(void *dt_blob, void *start_addr,
+ void *must_be_null);
+
+#ifdef DEBUG
+ printf("kernel:\n\r"
+ " entry addr = 0x%lx\n\r"
+ " flattened dt = 0x%lx\n\r",
+ (unsigned long)entry_addr, dtb);
+#endif
+
+ kernel_entry = entry_addr;
+ kernel_entry(dtb, entry_addr, NULL);
+}
+
+void ft_init(void *dt_blob)
+{
+ dt_ops.finddevice = ft_finddevice;
+ dt_ops.getprop = ft_getprop;
+ dt_ops.setprop = ft_setprop;
+ dt_ops.translate_addr = ft_translate_addr;
+ dt_ops.call_kernel = ft_call_kernel;
+
+ dtb = dt_blob;
+}
^ permalink raw reply related
* Re: [PATCH 2/6] bootwrapper: Add in OF operations (and rename to of.c)
From: Mark A. Greer @ 2006-09-08 3:36 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060719230318.GC3887@mag.az.mvista.com>
This patch adds the operations necessary for the bootwrapper to run on
an OF platform. This code used to be in prom.[ch] but was moved to of.c
because its a more accurate name (IMHO).
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
arch/powerpc/boot/prom.c | 165 ------------------------
arch/powerpc/boot/prom.h | 41 ------
b/arch/powerpc/boot/Makefile | 5
b/arch/powerpc/boot/of.c | 286 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 290 insertions(+), 207 deletions(-)
--
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index afc776f..c2bb541 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -36,7 +36,10 @@ 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 := crt0.S string.S stdio.c main.c div64.S
+ifeq ($(CONFIG_PPC_MULTIPLATFORM),y)
+src-boot += of.c
+endif
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c
new file mode 100644
index 0000000..10fc108
--- /dev/null
+++ b/arch/powerpc/boot/of.c
@@ -0,0 +1,286 @@
+/*
+ * 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 "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);
+#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
+ 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_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);
+}
+
+static void of_call_kernel(void *entry_addr, unsigned long a1, unsigned long a2,
+ void *promptr, void *sp)
+{
+ void (*kernel_entry)(unsigned long a1, unsigned long a2, void *promptr,
+ void *sp);
+
+ kernel_entry = entry_addr;
+ kernel_entry(a1, a2, promptr, sp);
+}
+
+/*
+ * 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.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;
+ dt_ops.call_kernel = of_call_kernel;
+
+ 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/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_ */
^ permalink raw reply related
* Re: [PATCH 1/6] bootwrapper: arch/powerpc/boot code reorg
From: Mark A. Greer @ 2006-09-08 3:35 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060719230014.GB3887@mag.az.mvista.com>
Abstract the operations used in the bootwrapper. The operations
have been divided up into platform operations (platform_ops),
device tree operations (dt_ops), and console operations (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>
--
main.c | 226 ++++++++++++++++++++++++++++++----------------------------------
ops.h | 100 ++++++++++++++++++++++++++++
stdio.c | 4 -
stdio.h | 8 ++
types.h | 23 ++++++
5 files changed, 240 insertions(+), 121 deletions(-)
--
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index b66634c..d73f487 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -14,17 +14,11 @@ #include "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
-#include "prom.h"
#include "zlib.h"
+#include "ops.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 +27,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;
@@ -55,17 +41,8 @@ static unsigned long elfoffset;
static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
static char elfheader[256];
-
-typedef void (*kernel_entry_t)( unsigned long,
- unsigned long,
- void *,
- void *);
-
-
#undef DEBUG
-static unsigned long claim_base;
-
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
@@ -123,24 +100,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 +128,6 @@ 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
-
return 1;
}
@@ -212,47 +161,11 @@ 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, void *sp)
{
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);
+ printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start,sp);
vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -263,43 +176,46 @@ 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();
}
- /* 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 */
@@ -314,8 +230,6 @@ void start(unsigned long a1, unsigned lo
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 +238,97 @@ #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)
+{
+ return;
+}
- 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 */
+#define EMPTY_SECTION_STR "no ft"
+
+char dt_blob[8*1024]
+ __attribute__((__section__("__builtin_ft"),__aligned__(8)))
+ = EMPTY_SECTION_STR;
+
+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)
+{
+ 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 (strcmp(dt_blob, EMPTY_SECTION_STR))
+ 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();
+
+ prep_kernel(&a1, &a2, sp);
+
+ /* 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();
+
+ dt_ops.call_kernel((void *)vmlinux.addr, a1, a2, promptr, sp);
+
+ /* console closed so printf below may not work */
+ printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+ exit();
+}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
new file mode 100644
index 0000000..9f7d661
--- /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 * (*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);
+ void (*call_kernel)(void *entry_addr, unsigned long a1,
+ unsigned long a2, void *promptr, void *sp);
+};
+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/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: [PATCH 0/6] bootwrapper: arch/powerpc/boot code reorg patches
From: Mark A. Greer @ 2006-09-08 3:32 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060719225356.GA3887@mag.az.mvista.com>
Hi,
I have respun all the patches in this series and will be submitting them
shortly.
Some things have changed from the previous patches. In particular, the
guts of the flat dev tree code are now in
<file:arch/powerpc/boot/flatdevtree.[ch]>. These files are only *copies*
of the files Hollis Blanchard is maintaining so please do not edit them
in the bootwrapper. The code in those files is still being worked on
so I'm will not submit them in this patch series. However, I will
start a separate email thread with the current copies so you can
build and so those changes don't hold up the acceptance of these patches.
Just don't surprised if the master code has changed by the time you read
this.
Also changed:
- The 'ops' struct & ptr are gone, now uses
platform_ops/dt_ops/console_ops directly.
- There are a couple new files. flatdevtree_env.h has header file
glue so that flatdevtree.[ch] will compile/work.
flatdevtree_misc.c contains interface glue between bootwrapper dt
calls and the implementation in flatdevtree.c, and some functionality
not provided by flatdevtree.c
- dink.c is renamed to simple_alloc.c because the code isn't dink specific.
- I'm submitting the kernel sandpoint code along with the dts (which I
didn't do before) because people have asked for it.
- I changed the name of the section that holds the dtb from
__builtin_fdt to __builtin_ft to match the prefixes used in the
flatdevtree*.[ch] files. If you made a script to attach a dtb to a
zImage like what I emailed before, you'll have to edit it to change
the section name.
Mark
^ permalink raw reply
* RE: MPC8360E USB Host Controller Driver
From: Li Yang-r58472 @ 2006-09-08 3:27 UTC (permalink / raw)
To: Laurent Pinchart, linuxppc-embedded; +Cc: n.balaji
In-Reply-To: <200609071324.30930.laurent.pinchart@tbox.biz>
> Could you give a direct link ? I've been browsing around the=20
> Freescale website for an hour, downloaded hundreds of=20
> megabytes of archives but haven't been able to find the=20
> MPC8360E USB Linux driver.
>=20
> Laurent Pinchart
>=20
> PS: Am I the only one to get lost almost every time when I=20
> look for information on www.freescale.com ?
PS: Contacting local FAE is always a good way and recommended way to get
the latest information.
- Leo
^ permalink raw reply
* [PATCH] kdump : Support kernels having 64k page size.
From: Sachin P. Sant @ 2006-09-08 2:29 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <1157677687.22705.364.camel@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 1489 bytes --]
Benjamin Herrenschmidt wrote:
> On Fri, 2006-09-08 at 06:30 +0530, Sachin P. Sant wrote:
>
>>> You should always do 64k regardless of the page size. I think we have
>>> some ABI requirements here for ELF sections to be 64k aligned anyway
>>> no ?
>>>
>>>
>>>
>> Ben are you aware of any doc where i can find more information. I
>> checked the
>> 64Bit PowerPC ELF ABI doc but couldn't find any specific information about
>> this.
>>
>> Also other question is If we create a 64k segment irrespective of page size
>> [ as compared to 32k currently ] we would be writing extra 32k even for
>> page size of 4K. Which means we have 32k less memory for the kdump
>> kernel. Wouldn't that be an issue ?
>>
>
> 32k sounds like a drop of water in the kdump pool ...
>
> Ben.
>
>
The following kernel patch [ along with a patch to kexec tools posted
seperately ]is required to generate proper core files using kdump on ppc64.
* Create a backup region of 64K size irrespective of the PAGE SIZE.
At present 32K was used as backup size. In the case of 64K page size,
second
PT_LOAD segments starts at 32K and the first one is not page aligned.
__ioremap() (crash_dump.c) fails if pfn = 0 which is the case for the
second
PT_LOAD segment. This is not an issue for 4K page size because the the
first
page (32K backup) is copied to second kernel memory and thus referencing
with the second kernel pfn.
Signed-off-by: Sachin Sant <sachinp@in.ibm.com>
Thanks
-Sachin
[-- Attachment #2: 64k-backup-size-for-kdump --]
[-- Type: text/plain, Size: 1073 bytes --]
* Create a backup region of 64K size irrespective of the PAGE SIZE.
At present 32K was used as backup size. In the case of 64K page size, second
PT_LOAD segments starts at 32K and the first one is not page aligned.
__ioremap() (crash_dump.c) fails if pfn = 0 which is the case for the second
PT_LOAD segment. This is not an issue for 4K page size because the the first
page (32K backup) is copied to second kernel memory and thus referencing
with the second kernel pfn.
Signed-off-by: Sachin Sant <sachinp@in.ibm.com>
---
diff -Naurp a/include/asm-powerpc/kdump.h b/include/asm-powerpc/kdump.h
--- a/include/asm-powerpc/kdump.h 2006-09-01 00:40:10.000000000 +0530
+++ b/include/asm-powerpc/kdump.h 2006-09-08 07:12:18.000000000 +0530
@@ -7,7 +7,7 @@
/* How many bytes to reserve at zero for kdump. The reserve limit should
* be greater or equal to the trampoline's end address.
* Reserve to the end of the FWNMI area, see head_64.S */
-#define KDUMP_RESERVE_LIMIT 0x8000
+#define KDUMP_RESERVE_LIMIT 0x10000 /* 64K */
#ifdef CONFIG_CRASH_DUMP
^ permalink raw reply
* powerpc power management
From: John Rigby @ 2006-09-08 2:05 UTC (permalink / raw)
To: linuxppc
I need to implement suspend to ram (sleep mode) on an embedded powerpc
processor. I have googled generally and searched the lkml, this list
and the linux power management mailing list. It seems after all this
searching that the only existing code is for the powermac in
drivers/macintosh/(variousfiles) and
arch/powerpc/platforms/powermac/(variousfiles). Is this true or am I
missing something?
Thanks
John
^ permalink raw reply
* Re: common flatdevtree code
From: Mark A. Greer @ 2006-09-08 1:11 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras, Hollis Blanchard
In-Reply-To: <20060908005630.GA9823@mag.az.mvista.com>
On Thu, Sep 07, 2006 at 05:56:31PM -0700, Mark A. Greer wrote:
> Hollis, Paul,
>
> I made some more changes that I hope you approve of:
> - Added a hdr to the file to try to make it clear that people should
> not hack the local copy of the file.
> - Fixed a booboo (typo) in my last patch
> - Change the interface to ft_next() to pass a struct that contains the
> pointers that it sets up. Also moved the p_strings & version code
> from the caller to ft_next(). Now, just pass in a NULL value to the
> 'p' param to start at the top of the tree.
> - Cleaned up the callers to ft_next(). I think its much cleaner now.
Forgot to add:
- Change malloc() call to ft_malloc() to be consistent with the changes
made to exit() -> ft_exit() and free -> ft_free().
Mark
^ permalink raw reply
* Re: [PATCH] [v3] PPC 4xx: Enable XMON on PPC 4xx boards
From: Josh Boyer @ 2006-09-08 1:10 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, paulus, mporter
In-Reply-To: <1157677403.22705.360.camel@localhost.localdomain>
On Fri, 2006-09-08 at 11:03 +1000, Benjamin Herrenschmidt wrote:
> > Blindly following the existing convention. I agree it's ugly. I'll fix
> > it up shortly and send out another patch. It'll also fix 440SPE, which
> > also has a different UART address.
>
> It should all move to udbg anyway
udbg is arch/powerpc. This is arch/ppc. I have every intention of
porting this to arch/powerpc when 4xx itself moves over and I'll gladly
use udbg then.
Until then, I'd still like to get this patch (v4) into the kernel since
it's quite useful now.
josh
^ permalink raw reply
* Re: [PATCH] kdump : Support kernels having 64k page size.
From: Benjamin Herrenschmidt @ 2006-09-08 1:08 UTC (permalink / raw)
To: Sachin P. Sant; +Cc: linuxppc-dev
In-Reply-To: <4500C0BA.8060408@in.ibm.com>
On Fri, 2006-09-08 at 06:30 +0530, Sachin P. Sant wrote:
> > You should always do 64k regardless of the page size. I think we have
> > some ABI requirements here for ELF sections to be 64k aligned anyway
> > no ?
> >
> >
> Ben are you aware of any doc where i can find more information. I
> checked the
> 64Bit PowerPC ELF ABI doc but couldn't find any specific information about
> this.
>
> Also other question is If we create a 64k segment irrespective of page size
> [ as compared to 32k currently ] we would be writing extra 32k even for
> page size of 4K. Which means we have 32k less memory for the kdump
> kernel. Wouldn't that be an issue ?
32k sounds like a drop of water in the kdump pool ...
Ben.
^ permalink raw reply
* Re: [PATCH] [v3] PPC 4xx: Enable XMON on PPC 4xx boards
From: Benjamin Herrenschmidt @ 2006-09-08 1:03 UTC (permalink / raw)
To: Josh Boyer; +Cc: mporter, paulus, linuxppc-dev
In-Reply-To: <1157652525.6098.61.camel@zod.rchland.ibm.com>
> Blindly following the existing convention. I agree it's ugly. I'll fix
> it up shortly and send out another patch. It'll also fix 440SPE, which
> also has a different UART address.
It should all move to udbg anyway
Ben.
^ 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