* Re: [HACK] add sandpoint + flattened dt support to arch/powerpc/boot
From: Guennadi Liakhovetski @ 2006-07-19 22:29 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060719221019.GA32203@mag.az.mvista.com>
On Wed, 19 Jul 2006, Mark A. Greer wrote:
>
> Ben and I have talked a little bit privately and the ball is in my court
> to produce a set of patches. To that end, I have them ready so expect to
> see them shortly.
Great! So, I can really relax and enjoy my holiday next week in beautiful
Eifel:-) And as your patches arrive we'll see how best to integrate
kurobox with them.
One question so far. Looking at your sandpoint.dts pci map:
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 */
I can match hardware addresses against defines in
include/asm-ppc/mpc10x.h, but virtual one - is the map above just an
example and anyway-not-used, or is it a new mapping, or am I missing
something and it has always been like that (1-to-1)? At least this comment
* MAP B (CHRP Map)
* Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
* Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
* PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000
* EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
seems to contradict with the above map in pci io area, as well as this
one:
* Want processor accesses of 0xFDxxxxxx to be mapped
* to PCI memory space at 0x00000000. Do not want
Actually, I cannot even match these 2 together?
Thanks
Guennadi
---
Guennadi Liakhovetski
^ permalink raw reply
* [PATCH 0/6] bootwrapper: arch/powerpc/boot code reorg patches
From: Mark A. Greer @ 2006-07-19 22:53 UTC (permalink / raw)
To: linuxppc-dev
Hi,
The following emails from me in this thread are the latest set of
patches that reorg the bootwrapper code so that OF and non-OF
platforms can live together.
I punted somewhat on "The Tool" that's been talked about that takes a
kernel and attaches a flattened device tree (fdt) to it. I thought
about it for a while but I think we need to clarify the requirements
better before it makes sense to spend a lot of cycles on it.
In the interim, dt_blob_start defined in arch/powerpc/boot/main.c allocates
8KB in a separate ELF section called '__builtin_fdt'. You can then
'dd' a dtb generated by the dtc utility directly into that section and it
the bootwrapper will use it. I tried playing with loader scripts so
that the section could be deleted and a new, larger one added
(and that preserves all the alignments, etc. in the zImage) but couldn't
figure out the magic so I've given up for now.
I hope that after OLS (or during?), "The Tool" will be discussed and we
can get that finished. Unless what I've done is good enough but I doubt it...
Notes:
- These patches will collide with Milton Miller's kexec patches but they
haven't been accepted yet so I didn't put my patches on top of them.
- Below is the script that I use to copy a dtb into the __builtin_fdt
section of a zImage so that non-OF machines can use the zImage.
Its basically a hack of the script that Michal Ostrowski provided
for copying a new cmdline to an ELF section.
Mark
--
#!/bin/bash
#
# Copyright (C) 2006 Michal Ostrowski <mostrows at watson.ibm.com <https://ozlabs.org/mailman/listinfo/linuxppc-dev>>, IBM Corp.
#
# Modified to put a dtb into the "__builtin_fdt" section by Mark A. Greer
# <mgreer@mvista.com>
#
# 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
usage(){
echo 'set_builtin_fdt [--fdt <file>] <input_obj> [<output_obj>]'
echo ' Sets the builtin command line embedded in an object file.'
echo
echo ' If <output_obj> is not specified, <input_obj> is modified'
echo ' in place.'
echo ' If --fdt <file> argument is present contents of embedded'
echo ' command line will be copied from <file>, otherwise from stdin.'
exit 1
}
fdt_file=
while case "$#" in 0) break ;; esac
do
case "$1" in
--fdt)
case "$#" in
1)
usage ;;
*)
fdt_file="$2";
shift;;
esac;;
*)
set x "$@"
shift
break ;;
esac
shift
done
if [ "$#" -lt 1 ]; then
echo "No input object specified." ;
usage;
fi
if [ "$#" -gt 2 ]; then
echo "Unrecognized arguments: $@";
usage;
fi
infile=$1
shift;
if [ ! -r "$infile" ] ; then
echo "Can't read '$infile'.";
usage;
fi
if [ "$#" -eq 0 ] ; then
outfile=$infile;
else
outfile=$1;
if ! cp $infile $outfile ; then
echo "Can't create output: '$outfile' $?"
usage;
fi
shift;
fi
offset=$(objdump -h $infile | \
gawk -- '{if($2=="__builtin_fdt") {print strtonum("0x" $6);}}')
size=$(objdump -h $infile | \
gawk -- '{if($2=="__builtin_fdt") {print strtonum("0x" $3);}}')
if [ "x$offset" != "x" ] ; then
if [ "$offset" -ne 0 ] ; then
set -e
# Zero the destination buffer first
exec 2>/dev/null
dd if=$fdt_file of=$outfile bs=1 seek=$offset conv=notrunc count=$size
exit $?
fi
fi
^ permalink raw reply
* [PATCH 1/6] bootwrapper: arch/powerpc/boot code reorg
From: Mark A. Greer @ 2006-07-19 23:00 UTC (permalink / raw)
To: linuxppc-dev
Abstract the operations used in the bootwrapper. The operations
have been divided up into platform ops (platform_ops), firware ops
(fw_ops), device tree ops (dt_ops), and console ops (console_ops).
The proper operations will be hooked up at runtime to provide the
functionality that you need.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
main.c | 219 +++++++++++++++++++++++++++++-----------------------------------
ops.h | 117 ++++++++++++++++++++++++++++++++++
stdio.c | 4 -
types.h | 29 ++++++++
4 files changed, 248 insertions(+), 121 deletions(-)
--
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index b66634c..0e49f58 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,90 @@ #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
+/* 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")));
- kernel_entry(a1, a2, prom, NULL);
+static void get_cmdline(char *buf, int size)
+{
+ void *devp;
+ int len = strlen(builtin_cmdline);
- printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+ buf[0] = '\0';
- exit();
+ 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 fdt can be tacked on after zImage is built */
+#define EMPTY_SECTION_STR "no fdt"
+
+char dt_blob_start[8*1024]
+ __attribute__((__section__("__builtin_fdt"),__aligned__(8)))
+ = EMPTY_SECTION_STR;
+
+struct ops *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);
+
+ ops = platform_init(promptr);
+
+ /* Override the dt_ops if there was an fdt attached to the zImage */
+ if (strcmp(dt_blob_start, EMPTY_SECTION_STR))
+ ops->dt_ops = fdt_init(dt_blob_start);
+
+ if (!ops || !ops->platform_ops || !ops->fw_ops || !ops->dt_ops
+ || !ops->console_ops)
+ exit();
+
+ if (ops->console_ops->open && (ops->console_ops->open() < 0))
+ exit();
+ if (ops->platform_ops->fixups)
+ ops->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) || ops->console_ops->edit_cmdline) {
+ get_cmdline(cmdline, COMMAND_LINE_SIZE);
+ printf("\n\rLinux/PowerPC load: %s", cmdline);
+ if (ops->console_ops->edit_cmdline)
+ ops->console_ops->edit_cmdline(cmdline,
+ COMMAND_LINE_SIZE);
+ printf("\n\r");
+ set_cmdline(cmdline);
+ }
+
+ if (ops->console_ops->close)
+ ops->console_ops->close();
+
+ ops->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..94d97b0
--- /dev/null
+++ b/arch/powerpc/boot/ops.h
@@ -0,0 +1,117 @@
+/*
+ * 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"
+
+/* Platform specific operations */
+struct platform_ops {
+ void (*fixups)(void);
+ void (*exit)(void);
+};
+
+/* Firmware specific operations */
+struct fw_ops {
+ void * (*malloc)(u32 size);
+ void (*free)(void *ptr, u32 size);
+ void (*exit)(void);
+};
+
+/* Device Tree operations */
+struct dt_ops {
+ void * (*finddevice)(const char *name);
+ int (*getprop)(void *node, const char *name, void *buf, int buflen);
+ int (*setprop)(void *node, const char *name, void *buf, int buflen);
+ u64 (*translate_addr)(char *path, u32 *in_addr, u32 addr_len);
+ void (*call_kernel)(void *entry_addr, unsigned long a1,
+ unsigned long a2, void *promptr, void *sp);
+};
+
+/* 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);
+ unsigned char *base;
+ u8 reg_shift;
+};
+
+/* 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;
+};
+
+struct ops {
+ struct platform_ops *platform_ops;
+ struct fw_ops *fw_ops;
+ struct dt_ops *dt_ops;
+ struct console_ops *console_ops;
+};
+
+extern struct ops *ops;
+
+extern struct ops *platform_init(void *promptr);
+extern struct fw_ops *dink_init(void);
+extern struct dt_ops *fdt_init(void *dt_blob);
+extern struct console_ops *ns16550_init(void);
+
+extern int serial_open(void);
+extern void serial_write(char *buf, int len);
+extern void serial_edit_cmdline(char *buf, int len);
+extern void serial_close(void);
+
+static inline void *finddevice(const char *name)
+{
+ return (ops->dt_ops->finddevice) ? ops->dt_ops->finddevice(name) : NULL;
+}
+
+static inline int getprop(void *devp, const char *name, void *buf, int buflen)
+{
+ return (ops->dt_ops->getprop) ?
+ ops->dt_ops->getprop(devp, name, buf, buflen) : -1;
+}
+
+static inline int setprop(void *devp, const char *name, void *buf, int buflen)
+{
+ return (ops->dt_ops->setprop) ?
+ ops->dt_ops->setprop(devp, name, buf, buflen) : -1;
+}
+
+static inline void *malloc(u32 size)
+{
+ return (ops->fw_ops->malloc) ? ops->fw_ops->malloc(size) : NULL;
+}
+
+static inline void free(void *ptr, u32 size)
+{
+ if (ops->fw_ops->free)
+ ops->fw_ops->free(ptr, size);
+}
+
+static inline void exit(void)
+{
+ if (ops) {
+ if (ops->platform_ops && ops->platform_ops->exit)
+ ops->platform_ops->exit();
+ if (ops->fw_ops && ops->fw_ops->exit)
+ ops->fw_ops->exit();
+ }
+ for(;;);
+}
+
+#endif /* _PPC_BOOT_OPS_H_ */
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index b5aa522..7ccc504 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);
+ ops->console_ops->write(sprint_buf, n);
return n;
}
diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
new file mode 100644
index 0000000..2a2fa2b
--- /dev/null
+++ b/arch/powerpc/boot/types.h
@@ -0,0 +1,29 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#define COMMAND_LINE_SIZE 512
+#define MAX_PATH_LEN 256
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+#ifdef __powerpc64__
+typedef unsigned long u64;
+#else
+typedef unsigned long long u64;
+#endif
+
+#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
* [PATCH 2/6] bootwrapper: Add in OF operations (and rename to of.c)
From: Mark A. Greer @ 2006-07-19 23:03 UTC (permalink / raw)
To: linuxppc-dev
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 | 301 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 305 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..313f125
--- /dev/null
+++ b/arch/powerpc/boot/of.c
@@ -0,0 +1,301 @@
+/*
+ * 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) {
+#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
+ claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+ first_time = 0;
+ }
+
+ for(; claim_base < RAM_END; claim_base += ONE_MB) {
+#ifdef DEBUG
+ printf(" trying: 0x%08lx\n\r", claim_base);
+#endif
+ addr = (unsigned long)claim(claim_base, size, 0);
+ if ((void *)addr != (void *)-1)
+ break;
+ }
+ if (addr == 0)
+ return NULL;
+ claim_base = PAGE_ALIGN(claim_base + size);
+ return (void *)addr;
+}
+
+static void of_fw_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(void *phandle, const char *name,
+ void *buf, int buflen)
+{
+ return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
+static int of_setprop(void *phandle, const char *name,
+ void *buf, 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);
+}
+
+/* Init code that hooks up all of the routines */
+static struct platform_ops of_platform_ops;
+static struct fw_ops of_fw_ops;
+static struct dt_ops of_dt_ops;
+static struct console_ops of_console_ops;
+static struct ops of_ops;
+
+struct ops *platform_init(void *promptr)
+{
+ of_platform_ops.fixups = NULL;
+ of_platform_ops.exit = NULL;
+
+ of_fw_ops.malloc = of_try_claim;
+ of_fw_ops.free = NULL;
+ of_fw_ops.exit = of_fw_exit;
+
+ of_dt_ops.finddevice = of_finddevice;
+ of_dt_ops.getprop = of_getprop;
+ of_dt_ops.setprop = of_setprop;
+ of_dt_ops.call_kernel = of_call_kernel;
+
+ of_console_ops.open = of_console_open;
+ of_console_ops.write = of_console_write;
+ of_console_ops.edit_cmdline = NULL;
+ of_console_ops.close = NULL;
+ of_console_ops.data = NULL;
+
+ of_ops.platform_ops = &of_platform_ops;
+ of_ops.fw_ops = &of_fw_ops;
+ of_ops.dt_ops = &of_dt_ops;
+ of_ops.console_ops = &of_console_ops;
+
+ prom = (int (*)(void *))promptr;
+
+ return &of_ops;
+}
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
* [PATCH 3/6] bootwrapper: Add device tree ops for flattened device tree
From: Mark A. Greer @ 2006-07-19 23:05 UTC (permalink / raw)
To: linuxppc-dev
This patch adds the device tree operations (dt_ops) for a flattened
device tree (fdt).
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
Makefile | 2
fdt.c | 525 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 526 insertions(+), 1 deletion(-)
--
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index c2bb541..3e767e5 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -36,7 +36,7 @@ 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 stdio.c main.c div64.S
+src-boot := crt0.S string.S stdio.c main.c div64.S fdt.c
ifeq ($(CONFIG_PPC_MULTIPLATFORM),y)
src-boot += of.c
endif
diff --git a/arch/powerpc/boot/fdt.c b/arch/powerpc/boot/fdt.c
new file mode 100644
index 0000000..ad7e7d5
--- /dev/null
+++ b/arch/powerpc/boot/fdt.c
@@ -0,0 +1,525 @@
+/*
+ * Simple dtb (binary flattened device tree) search/manipulation routines.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ * - The code for strrchr() was copied from lib/string.c and is
+ * copyrighted by Linus Torvalds.
+ * - The smarts for fdt_finddevice() were copied with the author's
+ * permission from u-boot:common/ft_build.c which was written by
+ * Pantelis Antoniou <pantelis@embeddedalley.com>.
+ * - Many of the routines related to fdt_translate_addr() came
+ * from 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.
+ */
+
+/* Supports dtb version 0x10 only */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "ops.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 */
+};
+
+static void *dtb_start;
+static void *dtb_end;
+
+#define MAX_ADDR_CELLS 4
+#define BAD_ADDR ((u64)-1)
+
+struct fdt_bus {
+ u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
+ int (*translate)(u32 *addr, u64 offset, int na);
+};
+
+static inline struct boot_param_header *
+fdt_get_bph(void *dt_blob)
+{
+ return (struct boot_param_header *)dt_blob;
+}
+
+static char *
+fdt_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 void
+fdt_parentize(char *path, u8 leave_slash)
+{
+ char *s = &path[strlen(path) - 1];
+
+ if (*s == '/')
+ *s = '\0';
+ s = fdt_strrchr(path, '/');
+ if (s != NULL) {
+ if (leave_slash)
+ s[1] = '\0';
+ else if (s[0] == '/')
+ s[0] = '\0';
+ }
+}
+
+static inline u32 *
+fdt_next(u32 *dp, u32 **tagpp, char **namepp, char **datapp, u32 **sizepp)
+{
+ static char *str_region;
+
+ *namepp = NULL;
+ *datapp = NULL;
+ *sizepp = NULL;
+
+ if (dp == NULL) { /* first time */
+ struct boot_param_header *bph = fdt_get_bph(dtb_start);
+
+ if (bph->magic != OF_DT_HEADER) {
+ *tagpp = NULL;
+ return NULL;
+ }
+ dp = (u32 *)((u32)dtb_start + bph->off_dt_struct);
+ str_region = (char *)((u32)dtb_start + bph->off_dt_strings);
+ }
+
+ *tagpp = dp;
+
+ switch (*dp++) { /* Tag */
+ case OF_DT_PROP:
+ *sizepp = dp++;
+ *namepp = str_region + *dp++;
+ *datapp = (char *)dp;
+ dp = (u32 *)_ALIGN_UP((unsigned long)dp + **sizepp, 4);
+ break;
+ case OF_DT_BEGIN_NODE:
+ *namepp = (char *)dp;
+ dp = (u32 *)_ALIGN_UP((u32)dp + strlen((char *)dp) + 1, 4);
+ break;
+ case OF_DT_END_NODE:
+ case OF_DT_NOP:
+ break;
+ case OF_DT_END:
+ default:
+ dp = NULL;
+ break;
+ }
+
+ return dp;
+}
+
+static void *
+fdt_finddevice(const char *name)
+{
+ u32 *dp, *tagp, *sizep;
+ char *namep, *datap;
+ static char path[MAX_PATH_LEN];
+
+ path[0] = '\0';
+ dp = NULL;
+
+ while ((dp = fdt_next(dp, &tagp, &namep, &datap, &sizep)) != NULL)
+ switch (*tagp) {
+ case OF_DT_BEGIN_NODE:
+ strcat(path, namep);
+ if (!strcmp(path, name))
+ return tagp;
+ strcat(path, "/");
+ break;
+ case OF_DT_END_NODE:
+ fdt_parentize(path, 1);
+ break;
+ }
+ return NULL;
+}
+
+static int
+fdt_getprop(void *node, const char *name, void *buf, int buflen)
+{
+ u32 *dp, *tagp, *sizep, size;
+ char *namep, *datap;
+ int level;
+
+ level = 0;
+ dp = node;
+
+ while ((dp = fdt_next(dp, &tagp, &namep, &datap, &sizep)) != NULL)
+ switch (*tagp) {
+ case OF_DT_PROP:
+ if ((level == 1) && !strcmp(namep, name)) {
+ size = min(*sizep, (u32)buflen);
+ memcpy(buf, datap, size);
+ return size;
+ }
+ break;
+ case OF_DT_BEGIN_NODE:
+ level++;
+ break;
+ case OF_DT_END_NODE:
+ if (--level <= 0)
+ return -1;
+ break;
+ }
+ return -1;
+}
+
+static void
+fdt_modify_prop(u32 *dp, char *datap, u32 *old_prop_sizep, char *buf,
+ int buflen)
+{
+ u32 old_prop_data_len, new_prop_data_len;
+
+ old_prop_data_len = _ALIGN_UP(*old_prop_sizep, 4);
+ new_prop_data_len = _ALIGN_UP(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 = buflen;
+ }
+ else { /* Need to alloc new area to put larger or smaller fdt */
+ struct boot_param_header *old_bph, *new_bph;
+ u32 *old_tailp, *new_tailp, *new_datap;
+ u32 old_total_size, new_total_size, head_len, tail_len, diff;
+ void *new_dtb_start, *new_dtb_end;
+
+ old_bph = fdt_get_bph(dtb_start),
+ old_total_size = old_bph->totalsize;
+ head_len = (u32)datap - (u32)dtb_start;
+ tail_len = old_total_size - (head_len + old_prop_data_len);
+ old_tailp = (u32 *)((u32)dtb_end - tail_len);
+ new_total_size = head_len + new_prop_data_len + tail_len;
+
+ if (!(new_dtb_start = malloc(new_total_size))) {
+ printf("Can't alloc space for new fdt\n\r");
+ exit();
+ }
+
+ new_dtb_end = (void *)((u32)new_dtb_start + new_total_size);
+ new_datap = (u32 *)((u32)new_dtb_start + head_len);
+ new_tailp = (u32 *)((u32)new_dtb_end - tail_len);
+
+ memcpy(new_dtb_start, dtb_start, head_len);
+ memcpy(new_datap, buf, buflen);
+ memcpy(new_tailp, old_tailp, tail_len);
+ *(new_datap - 2) = buflen;
+
+ new_bph = fdt_get_bph(new_dtb_start),
+ new_bph->totalsize = new_total_size;
+
+ diff = new_prop_data_len - old_prop_data_len;
+
+ /* Adjust offsets of other sections, if necessary */
+ if (new_bph->off_dt_strings > new_bph->off_dt_struct)
+ new_bph->off_dt_strings += diff;
+
+ if (new_bph->off_mem_rsvmap > new_bph->off_dt_struct)
+ new_bph->off_mem_rsvmap += diff;
+
+ free(dtb_start, old_total_size);
+
+ dtb_start = new_dtb_start;
+ dtb_end = new_dtb_end;
+ }
+}
+
+/* Only modifies existing properties */
+static int
+fdt_setprop(void *node, const char *name, void *buf, int buflen)
+{
+ u32 *dp, *tagp, *sizep;
+ char *namep, *datap;
+ int level;
+
+ level = 0;
+ dp = node;
+
+ while ((dp = fdt_next(dp, &tagp, &namep, &datap, &sizep)) != NULL)
+ switch (*tagp) {
+ case OF_DT_PROP:
+ if ((level == 1) && !strcmp(namep, name)) {
+ fdt_modify_prop(tagp, datap, sizep, buf,buflen);
+ return *sizep;
+ }
+ break;
+ case OF_DT_BEGIN_NODE:
+ level++;
+ break;
+ case OF_DT_END_NODE:
+ if (--level <= 0)
+ return -1;
+ break;
+ }
+ return -1;
+}
+
+static u32
+fdt_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;
+ fdt_parentize(p, 0);
+ } while (strlen(p) > 0);
+ return 1; /* default of 1 */
+}
+
+static u64
+fdt_read_addr(u32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | *(cell++);
+ return r;
+}
+
+static u64
+fdt_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = fdt_read_addr(range, na);
+ s = fdt_read_addr(range + na + pna, ns);
+ da = fdt_read_addr(addr, na);
+
+ if (da < cp || da >= (cp + s))
+ return BAD_ADDR;
+ return da - cp;
+}
+
+static int
+fdt_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+ u64 a = fdt_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
+fdt_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 = fdt_read_addr(range + 1, na - 1);
+ s = fdt_read_addr(range + na + pna, ns);
+ da = fdt_read_addr(addr + 1, na - 1);
+
+ if (da < cp || da >= (cp + s))
+ return BAD_ADDR;
+ return da - cp;
+}
+
+static int
+fdt_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+ return fdt_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static u64
+fdt_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 = fdt_read_addr(range + 1, na - 1);
+ s = fdt_read_addr(range + na + pna, ns);
+ da = fdt_read_addr(addr + 1, na - 1);
+
+ if (da < cp || da >= (cp + s))
+ return BAD_ADDR;
+ return da - cp;
+}
+
+static int
+fdt_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+ return fdt_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static void
+fdt_match_bus(char *path, struct fdt_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 = fdt_bus_isa_map;
+ bus->translate = fdt_bus_isa_translate;
+ } else if (!strcmp(dtype, "pci")) {
+ bus->map = fdt_bus_pci_map;
+ bus->translate = fdt_bus_pci_translate;
+ } else {
+ bus->map = fdt_bus_default_map;
+ bus->translate = fdt_bus_default_translate;
+ }
+ }
+}
+
+static int
+fdt_translate_one(char *path, struct fdt_bus *bus, struct fdt_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 = fdt_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
+fdt_translate_addr(char *p, u32 *in_addr, u32 addr_len)
+{
+ struct fdt_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);
+ fdt_parentize(ppath, 0);
+ fdt_match_bus(ppath, &bus);
+ na = fdt_find_cells(ppath, "#address-cells");
+ ns = fdt_find_cells(ppath, "#size-cells");
+ memcpy(addr, in_addr, na * 4);
+
+ for (;;) {
+ strcpy(path, ppath);
+ fdt_parentize(ppath, 0);
+
+ if (strlen(ppath) == 0)
+ return fdt_read_addr(addr, na);
+
+ fdt_match_bus(ppath, &pbus);
+ pna = fdt_find_cells(ppath, "#address-cells");
+ pns = fdt_find_cells(ppath, "#size-cells");
+
+ if (fdt_translate_one(path, &bus, &pbus, addr, na, ns, pna))
+ exit();
+
+ na = pna;
+ ns = pns;
+ memcpy(&bus, &pbus, sizeof(struct fdt_bus));
+ }
+}
+
+static void
+fdt_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_start);
+#endif
+
+ kernel_entry = entry_addr;
+ kernel_entry(dtb_start, entry_addr, NULL);
+}
+
+static struct dt_ops fdt_dt_ops;
+
+struct dt_ops *
+fdt_init(void *dt_blob)
+{
+ struct boot_param_header *bph;
+
+ fdt_dt_ops.finddevice = fdt_finddevice;
+ fdt_dt_ops.getprop = fdt_getprop;
+ fdt_dt_ops.setprop = fdt_setprop;
+ fdt_dt_ops.translate_addr = fdt_translate_addr;
+ fdt_dt_ops.call_kernel = fdt_call_kernel;
+
+ dtb_start = dt_blob;
+ bph = fdt_get_bph(dtb_start);
+ dtb_end = (void *)((u32)dtb_start + bph->totalsize);
+
+ return &fdt_dt_ops;
+}
^ permalink raw reply related
* [PATCH 4/6] bootwrapper: Add non-OF serial console support
From: Mark A. Greer @ 2006-07-19 23:12 UTC (permalink / raw)
To: linuxppc-dev
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 | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
serial.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
util.S | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 360 insertions(+)
--
diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h
new file mode 100644
index 0000000..05c5348
--- /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>
+ */
+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..661cfff
--- /dev/null
+++ b/arch/powerpc/boot/ns16550.c
@@ -0,0 +1,117 @@
+/*
+ * 16550 serial console support.
+ *
+ * Copied from <file:arch/ppc/boot/common/ns16550.c>
+ * Fdt code, etc. added 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 */
+
+int
+ns16550_get_dt_info(struct serial_console_data *scdp)
+{
+ u64 addr;
+ u32 reg[2], reg_shift;
+ void *devp;
+ char path[MAX_PATH_LEN+1], compat[MAX_PATH_LEN+1];
+
+ scdp->base = NULL;
+ scdp->reg_shift = 0;
+
+ if ((devp = finddevice("/chosen"))
+ && (getprop(devp, "linux,stdout-path", path,
+ sizeof(path)) > 0)
+ && (devp = finddevice(path))
+ && (getprop(devp, "compatible", compat, sizeof(compat))
+ > 0)
+ && !strcmp(compat, "ns16550")
+ && (getprop(devp, "reg", reg, sizeof(reg))
+ == sizeof(reg))) {
+
+ addr = ops->dt_ops->translate_addr(path, reg, sizeof(reg));
+ scdp->base = (unsigned char *)((u32)addr & 0xffffffffu);
+
+ if (getprop(devp, "reg_shift", ®_shift, sizeof(reg_shift))
+ == sizeof(reg_shift))
+ scdp->reg_shift = reg_shift;
+ return 0;
+ }
+ return -1;
+}
+
+static int
+ns16550_open(void)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+
+ if (ns16550_get_dt_info(scdp) < 0)
+ return -1;
+
+ out_8(scdp->base + (UART_FCR << scdp->reg_shift), 0x06);
+ return 0;
+}
+
+static void
+ns16550_putc(unsigned char c)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+ while ((in_8(scdp->base + (UART_LSR << scdp->reg_shift))
+ & UART_LSR_THRE) == 0);
+ out_8(scdp->base, c);
+}
+
+static unsigned char
+ns16550_getc(void)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+ while ((in_8(scdp->base + (UART_LSR << scdp->reg_shift))
+ & UART_LSR_DR) == 0);
+ return in_8(scdp->base);
+}
+
+static u8
+ns16550_tstc(void)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+ return ((in_8(scdp->base + (UART_LSR << scdp->reg_shift)) & UART_LSR_DR)
+ != 0);
+}
+
+static struct serial_console_data ns16550_scd;
+static struct console_ops ns16550_console_ops;
+
+struct console_ops *
+ns16550_init(void)
+{
+ ns16550_scd.open = ns16550_open;
+ ns16550_scd.putc = ns16550_putc;
+ ns16550_scd.getc = ns16550_getc;
+ ns16550_scd.tstc = ns16550_tstc;
+ ns16550_scd.close = NULL;
+ ns16550_scd.base = NULL;
+ ns16550_scd.reg_shift = 0;
+
+ ns16550_console_ops.open = serial_open;
+ ns16550_console_ops.write = serial_write;
+ ns16550_console_ops.edit_cmdline = serial_edit_cmdline;
+ ns16550_console_ops.close = serial_close;
+ ns16550_console_ops.data = &ns16550_scd;
+
+ return &ns16550_console_ops;
+}
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
new file mode 100644
index 0000000..6d064cb
--- /dev/null
+++ b/arch/powerpc/boot/serial.c
@@ -0,0 +1,89 @@
+/*
+ * 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);
+
+int
+serial_open(void)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+ return scdp->open();
+}
+
+void
+serial_write(char *buf, int len)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+
+ while (*buf != '\0')
+ scdp->putc(*buf++);
+}
+
+void
+serial_edit_cmdline(char *buf, int len)
+{
+ int timer = 0, count;
+ char ch, *cp;
+ struct serial_console_data *scdp = ops->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;
+}
+
+void
+serial_close(void)
+{
+ struct serial_console_data *scdp = ops->console_ops->data;
+
+ if (scdp->close)
+ scdp->close();
+}
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
* [PATCH 5/6] bootwrapper: Add support for the DINK firmware
From: Mark A. Greer @ 2006-07-19 23:14 UTC (permalink / raw)
To: linuxppc-dev
This patch adds the firmware operations that support the DINK firmware
from Freescale.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
dink.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 56 insertions(+)
--
diff --git a/arch/powerpc/boot/dink.c b/arch/powerpc/boot/dink.c
new file mode 100644
index 0000000..aa446e2
--- /dev/null
+++ b/arch/powerpc/boot/dink.c
@@ -0,0 +1,56 @@
+/*
+ * 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 "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 *
+dink_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;
+}
+
+static struct fw_ops dink_fw_ops;
+
+struct fw_ops *
+dink_init(void)
+{
+ dink_fw_ops.malloc = dink_malloc;
+ dink_fw_ops.free = NULL;
+ dink_fw_ops.exit = NULL;
+
+ return &dink_fw_ops;
+}
^ permalink raw reply related
* [PATCH 6/6] bootwrapper: Add support for the sandpoint platform
From: Mark A. Greer @ 2006-07-19 23:17 UTC (permalink / raw)
To: linuxppc-dev
This patch adds support for the Freescale Sandpoint platform
to the bootwrapper.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
--
Makefile | 3 +
mpc10x.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
sandpoint.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 259 insertions(+)
--
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 3e767e5..daad857 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -40,6 +40,9 @@ src-boot := crt0.S string.S stdio.c main
ifeq ($(CONFIG_PPC_MULTIPLATFORM),y)
src-boot += of.c
endif
+ifeq ($(CONFIG_SANDPOINT),y)
+src-boot += sandpoint.c mpc10x.c dink.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/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..b5a5462
--- /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, 0x08000000 },
+ /* 745/755 */
+ { 0x00083000, 0xfffff000, 100000000, 28, 0xf, CPU_7XX, 0x08000000 },
+ /* 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)))
+ && (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]));
+ }
+
+ /* 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 */
+}
+
+static struct ops sandpoint_ops;
+static struct platform_ops sandpoint_platform_ops;
+
+struct ops *
+platform_init(void *promptr)
+{
+ sandpoint_platform_ops.fixups = sandpoint_fixups;
+ sandpoint_platform_ops.exit = sandpoint_reset;
+
+ sandpoint_ops.platform_ops = &sandpoint_platform_ops;
+ sandpoint_ops.fw_ops = dink_init();
+ sandpoint_ops.console_ops = ns16550_init();
+
+ return &sandpoint_ops;
+}
^ permalink raw reply related
* Re: [PATCH 5/6] bootwrapper: Add support for the DINK firmware
From: Mark A. Greer @ 2006-07-19 23:33 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060719231421.GF3887@mag.az.mvista.com>
On Wed, Jul 19, 2006 at 04:14:21PM -0700, Mark A. Greer wrote:
> This patch adds the firmware operations that support the DINK firmware
> from Freescale.
>
> Signed-off-by: Mark A. Greer <mgreer@mvista.com>
> --
>
> dink.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 56 insertions(+)
> --
>
> diff --git a/arch/powerpc/boot/dink.c b/arch/powerpc/boot/dink.c
> new file mode 100644
> index 0000000..aa446e2
> --- /dev/null
> +++ b/arch/powerpc/boot/dink.c
> @@ -0,0 +1,56 @@
> +/*
> + * Sandpoint specific fixups.
Obviously an incorrect comment. Will fix.
Mark
--
^ permalink raw reply
* Re: [HACK] add sandpoint + flattened dt support to arch/powerpc/boot
From: Mark A. Greer @ 2006-07-20 0:39 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linuxppc-dev
In-Reply-To: <Pine.LNX.4.60.0607200008560.9110@poirot.grange>
On Thu, Jul 20, 2006 at 12:29:04AM +0200, Guennadi Liakhovetski wrote:
> On Wed, 19 Jul 2006, Mark A. Greer wrote:
> >
> > Ben and I have talked a little bit privately and the ball is in my court
> > to produce a set of patches. To that end, I have them ready so expect to
> > see them shortly.
>
> Great! So, I can really relax and enjoy my holiday next week in beautiful
> Eifel:-) And as your patches arrive we'll see how best to integrate
> kurobox with them.
Okay, but don't be in too much of a rush. I'm sure there will be
comments that will induce changes to those patches.
> One question so far. Looking at your sandpoint.dts pci map:
>
> 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 */
>
> I can match hardware addresses against defines in
> include/asm-ppc/mpc10x.h,
Don't spend a lot of time in ppc, powerpc is where you need to live now.
> but virtual one - is the map above just an
> example and anyway-not-used, or is it a new mapping, or am I missing
> something and it has always been like that (1-to-1)? At least this comment
The above mapping are physical addresses and are a part of the hardware
description passed into the kernel (i.e., the fdt). It knows nothing
about virtual addresses.
> * MAP B (CHRP Map)
> * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
> * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
> * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000
This table is telling you how the hardware maps processor physical
memory space to/from PCI I/O and MEM space. For example, if the
processor reads physical location 0xfe000000 that will go across the
hostbridge and read PCI I/O location/register 0 (assuming there is a
PCI device set to respond to that PCI I/O address). If a PCI device
reads PCI MEM address 0 it will go across the hostbridge and read
address 0 of the processor's physical address space (i.e., system
memory address 0).
> * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
>
> seems to contradict with the above map in pci io area, as well as this
> one:
>
> * Want processor accesses of 0xFDxxxxxx to be mapped
> * to PCI memory space at 0x00000000. Do not want
>
> Actually, I cannot even match these 2 together?
You need to read the "Address Map B Options Register" section of the
824x or 10x manuals. This is talking about an alias capability of the
hardware that I enabled...but as I think about it, I probably shouldn't
have. 8-P Anyway, if you get confused by a comment, read the code--code
doesn't lie...it may be wrong, but it doesn't lie. ;)
Mark
--
^ permalink raw reply
* Re: reboot on PQ2FADS board.
From: Lei Sun @ 2006-07-20 2:45 UTC (permalink / raw)
To: Mathieu Deschamps; +Cc: linuxppc-embedded
In-Reply-To: <200607191833.32693.mathieu.deschamps@com2gether.net>
On 7/19/06, Mathieu Deschamps <mathieu.deschamps@com2gether.net> wrote:
> Hi,
>
> On Wednesday 19 July 2006 16:12, Lei Sun wrote:
> > Hi :
> > I tried your approach last ight, (in fact I copied part of the
> > do_reboot() code from u-boot and put it in m8260_restart() function in
> > the kernel). The only difference is the first line,
> > volatile immap_t *immap = (immap_t *) IMAP_ADDR;
> > in my case it is
> > volatile immap_t * immap = cpm2_immr;
> > I am using different source tree.
> > it simply hangs, rather then reset.
> >
> [...]
>
> Give a try to :
> startaddr = 0xff000104;
That address was in the code before for warm-reset. It didn't work, I
tried the CheckStop approach, it didn't work either.
thanks
lei
^ permalink raw reply
* Re: reboot on PQ2FADS board.
From: Lei Sun @ 2006-07-20 3:46 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <20060719063317.86A66352681@atlas.denx.de>
Hi :
The following is the version I am using, it's pretty much same as
do_reset() code in u-boot -1.1.4 for m8260 target. However the machine
just hangs.
I wonder if there are any difference between Power on Reset and Hard
reset? in my case maybe the machine did get reset, but the u-boot
didn't get executed correctly in the case of hard reset ? It doesn't
explain the fact that i can run "reset" in u-boot console though.
Any comments are highly appreciated! I am stucked in here now.
m8260_restart(char * cmd)
uint startaddr;
unsigned long msr;
char badval;
volatile cpm2_map_t *immap = cpm2_immr;
/* Enable CheckStop reset. */
immap->im_clkrst.car_rmr |= 0x00000001;
/* Interrupts and MMU off */
__asm__ __volatile__("mfmsr %0":"=r" (msr):);
msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
__asm__ __volatile__("mtmsr %0":: "r" (msr));
startaddr = 0x04400000; /* this is taken from u-boot-1.1.4 */
/* Access bad address.*/
((void (*)(void)) startaddr) ();
return 1;
}
On 7/19/06, Wolfgang Denk <wd@denx.de> wrote:
> In message <4879B0C6C249214CBE7AB04453F84E4D050B0F@zch01exm20.fsl.freescale.net> you wrote:
> >
> > > command cause machine check and kernel ooops. The problem seems in
> > > the "m8260_gorom" in head.S. The restart() function in m8260_setup.c
> > > passed 2 parameters to that assembly code, r3 is the bd_info , r4 is
> > > the warm start address, I changed it to 0xFF800100, that's where the
> > > u-boot's _start_warm lives, I have verified that address by typing "g
> > > ff800100" in u-boot console, which cause the board reset.
> >
> > Are you sure ff800100 is _start_warm lives? In latest u-boot
>
> Trying to jump to some boot rom address is IMHO always a bad approach
> to reboot a system. You should always try to cause a reset condition
> for the CPU, and thus for all the associated hardware. On 8xx / 8260
> systems this is usually done by going through a machine check. We
> have the following code in our linuxppc_2_4_devel tree, which works
> on ALL 8260 systems, no matter whioch boot loder they use:
>
> static void
> m8260_restart(char *cmd)
> {
> __volatile__ unsigned char dummy;
> ulong msr;
>
> cli();
> volatile immap_t *immap = (immap_t *) IMAP_ADDR;
>
> immap->im_clkrst.car_rmr = 1; /* Checkstop Reset enable */
>
> /* Interrupts and MMU off */
> __asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
>
> msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
> __asm__ __volatile__ ("mtmsr %0"::"r" (msr));
>
> dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
>
> printk("Restart failed\n");
> for (;;);
> }
>
>
> Best regards,
>
> Wolfgang Denk
>
> --
> Software Engineering: Embedded and Realtime Systems, Embedded Linux
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> If a group of N persons implements a COBOL compiler, there will be
> N-1 passes. Someone in the group has to be the manager. - T. Cheatham
>
^ permalink raw reply
* export-objs in spi Makefile broke in latest linuxppc_2_4_deve l [r eposted]?
From: Heiko Schocher @ 2006-07-20 4:55 UTC (permalink / raw)
To: linuxppc-embedded; +Cc: Chad.Rowan
Hello Chad
> linuxppc_2_4_devel is alive and well.
>
> http://www.denx.de/cgi-bin/gitweb.cgi?p=linuxppc_2_4_devel.git;a=shortlog
You speak from the DENX linuxppc_2_4_devel Kernel? If so, I think you are right.
I had the same problem, some days ago. I made a SPI bitbanging algorithm, but
I dont know, if this goes in the git repository from DENX ... Wolfgang?
> -----Original Message-----
> From: Kumar Gala [mailto:galak at kernel.crashing.org]
> Sent: Wednesday, July 19, 2006 4:17 PM
> To: Rowan, Chad
> Cc: linuxppc-embedded at ozlabs.org
> Subject: Re: export-objs in spi Makefile broke in latest linuxppc_2_4_devel
> [r eposted]?
>
>
> > On Jul 19, 2006, at 2:13 PM, Rowan, Chad wrote:
> >
> > Shouldn't export-objs in drivers/spi be:
> >
> > export-objs := spi-core.o spi-algo-mpc5xxx.o spi-algo-mpc5xxx-psc.o \
> > spi-iti5200.o spi-eval.o
> >
> > instead of:
> >
> > export-objs := spi-core.o spi-algo-mpc5xxx.o spi-algo-mpc5200psc.o \
> > spi-iti5200.o spi-eval.o
> >
> > I believe the spi-algo-mpc5200psc.o should be spi-algo-mpc5xxx-psc.o,
> > correct?
>
> Are you really serious about linuxppc_2_4_devel? I can't believe
> linuxppc_2_4_devel has changed in months (if not over a year).
Commit: 98b663155ab7ab07dd85a8d03f437ab4fc29476b
Author: Wolfgang Denk <wd@pollux.denx.de> Thu, 13 Jul 2006 20:17:25 +0200
MCC200: fix QuadUART I/O addressing and interrupt init on new H/W
Patch by Johann Glaser, 13 Jul 2006
It progresses ;-)
Best regards
Heiko
^ permalink raw reply
* RE: [PATCH] Add USB to MPC8349 PB platform support
From: Li Yang-r58472 @ 2006-07-20 6:32 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, linux-usb-devel
In-Reply-To: <C3A460A5-612C-4B0D-9DDA-EB1AE3FEF6EB@kernel.crashing.org>
> -----Original Message-----
> From: linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org
> [mailto:linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org] On =
Behalf
Of Kumar
> Gala
> Sent: Thursday, July 20, 2006 4:09 AM
> To: Li Yang-r58472
> Cc: linuxppc-dev@ozlabs.org; linux-usb-devel@lists.sourceforge.net
> Subject: Re: [PATCH] Add USB to MPC8349 PB platform support
>=20
>=20
> On Jul 14, 2006, at 6:52 AM, Li Yang wrote:
>=20
> > This adds USB platform support to MPC8349 PB. It works with the
> > fsl_usb2_udc driver.
> >
> > Signed-off-by: Li Yang <leoli@freescale.com>
> > ---
> >
> > arch/powerpc/platforms/83xx/Kconfig | 4 ++
> > arch/powerpc/platforms/83xx/mpc834x_sys.c | 72 +++++++++++++++++++
> > ++++++++++
> > arch/powerpc/platforms/83xx/mpc834x_sys.h | 24 ++++++++++
> > 3 files changed, 113 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/
> > platforms/83xx/Kconfig
> > index 7675e67..8404cdf 100644
> > --- a/arch/powerpc/platforms/83xx/Kconfig
> > +++ b/arch/powerpc/platforms/83xx/Kconfig
> > @@ -24,4 +31,14 @@ config MPC834x
> > select PPC_INDIRECT_PCI
> > default y if MPC834x_SYS
> >
> > +config 834x_USB_SUPPORT
> > + bool
> > + default y if MPC834x_SYS && (USB || USB_GADGET)
> > +
> > endmenu
>=20
> I dont think we need this, we should be able to use the USB, and 834x
> CONFIG options in the code.
>=20
> > diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/
> > powerpc/platforms/83xx/mpc834x_sys.c
> > index 7e789d2..f10d4ae 100644
> > --- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
> > +++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
> > @@ -36,6 +36,7 @@ #include <asm/irq.h>
> > #include <asm/prom.h>
> > #include <asm/udbg.h>
> > #include <sysdev/fsl_soc.h>
> > +#include <linux/fsl_devices.h>
> > #include "mpc83xx.h"
> > @@ -71,6 +72,72 @@ mpc83xx_map_irq(struct pci_dev *dev, uns
> > }
> > #endif /* CONFIG_PCI */
> > +#ifdef CONFIG_834x_USB_SUPPORT
>=20
> Just make it dependent on CONFIG_USB_EHCI_HCD or something like that.
Will need to check EHCI_HCD/GADGET and their _MODULE variations though.
Not very neat I think. Anyway, it's your call.
>=20
> > +void mpc834x_usb_board_cfg(void)
> > +{
> > + unsigned char __iomem *bcsr;
> > + volatile unsigned char *bcsr5_p;
> > +
> > + /*
> > + * if SYS board is plug into PIB board,
> > + * force to use the PHY on SYS board
> > + * */
> > + bcsr =3D ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
> > + bcsr5_p =3D bcsr + BCSR5_OFF;
> > + if ( (*bcsr5_p & BCSR5_INT_USB) =3D=3D 0 )
> > + *bcsr5_p =3D (*bcsr5_p | BCSR5_INT_USB);
> > + iounmap(bcsr);
> > +}
> > +
> > +/* Note: This is only for PB, not for PB+PIB
> > + * On PB only port0 is connected using ULPI */
> > +static int mpc834x_usb_cfg(void)
> > +{
> > + unsigned long sccr, sicrl;
> > + volatile unsigned long *p;
> > + unsigned long __iomem *immap;
> > + struct device_node *np =3D NULL;
> > + int port0_is_dr =3D 0;
> > +
> > + if ((np =3D of_find_compatible_node(np, "usb", "fsl-usb2-dr")) =
!=3D
> > NULL)
> > + port0_is_dr =3D 1;
> > + if ((np =3D of_find_compatible_node(np, "usb", "fsl-usb2-mph")) =
!=3D
> > NULL){
> > + if (port0_is_dr) {
> > + printk(KERN_WARNING
> > + "There is only one USB port on PB board!
\n");
> > + return -1;
> > + } else if (!port0_is_dr)
> > + /* No usb port enabled */
> > + return -1;
> > + }
> > +
> > + immap =3D ioremap(get_immrbase(), 0x100000);
> > +
> > + /* Configure clock */
> > + p =3D (volatile unsigned long *)((u32)immap + MPC83XX_SCCR_OFFS);
> > + sccr =3D *p;
> > + if (port0_is_dr)
> > + sccr |=3D MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
> > + else
> > + sccr |=3D MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
> > + *p =3D sccr;
>=20
> This really needs to take into account the platform frequency. I
> guess technically, at 1:3 we will always be below the max 133Mhz.
Generally, I assume the user is using a core frequency around the
recommended frequency in spec. In some special cases, they do need to
use a lower core frequency. But, I think it's too special to be
addressed here. Anyway it's easy to change for users.
>=20
> > +
> > + /* Configure Pin */
> > + p =3D (volatile unsigned long *)((u32)immap + MPC83XX_SICRL_OFFS);
> > + sicrl =3D *p;
> > + /* set port0 only */
> > + if (port0_is_dr) + sicrl |=3D MPC83XX_SICRL_USB0;
> > + else + sicrl &=3D ~(MPC83XX_SICRL_USB0);
> > + *p =3D sicrl;
> > +
>=20
> Why dont we just do all this in fsl_usb_of_init
It's easier to do in fsl_usb_of_init. But do you think it's ok to put
834x specific code there?
>=20
> > + iounmap(immap);
> > + return 0;
> > +}
> > +
> > +#endif /* CONFIG_834x_USB_SUPPORT */
> > +
> > /*
> >
**********************************************************************
> > **
> > *
> > * Setup the architecture
> > @@ -102,6 +169,11 @@ #ifdef CONFIG_PCI
> > ppc_md.pci_exclude_device =3D mpc83xx_exclude_device;
> > #endif
> > +#ifdef CONFIG_834x_USB_SUPPORT
> > + mpc834x_usb_cfg();
> > + mpc834x_usb_board_cfg();
> > +#endif
> > +
> > #ifdef CONFIG_ROOT_NFS
> > ROOT_DEV =3D Root_NFS;
> > #else
> > diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.h b/arch/
> > powerpc/platforms/83xx/mpc834x_sys.h
> > index fedecb7..30e45e8 100644
> > --- a/arch/powerpc/platforms/83xx/mpc834x_sys.h
> > +++ b/arch/powerpc/platforms/83xx/mpc834x_sys.h
> > @@ -20,4 +20,28 @@ #define PIRQB MPC83xx_IRQ_EXT5
> > #define PIRQC MPC83xx_IRQ_EXT6
> > #define PIRQD MPC83xx_IRQ_EXT7
> > +#define BCSR_PHYS_ADDR ((uint)0xf8000000)
> > +#define BCSR_SIZE ((uint)(32 * 1024))
> > + +#define BCSR5_OFF 0x05
> > +#define BCSR5_INT_USB 0x02
> > +
> > +#define MPC83XX_SCCR_OFFS 0xA08
> > +#define MPC83XX_SCCR_USB_MPHCM_11 0x00c00000
> > +#define MPC83XX_SCCR_USB_MPHCM_01 0x00400000
> > +#define MPC83XX_SCCR_USB_MPHCM_10 0x00800000
> > +#define MPC83XX_SCCR_USB_DRCM_11 0x00300000
> > +#define MPC83XX_SCCR_USB_DRCM_01 0x00100000
> > +#define MPC83XX_SCCR_USB_DRCM_10 0x00200000
> > +
> > +/* system i/o configuration register low */
> > +#define MPC83XX_SICRL_OFFS 0x114
> > +#define MPC83XX_SICRL_USB0 0x40000000
> > +#define MPC83XX_SICRL_USB1 0x20000000
> > +
> > +/* system i/o configuration register high */
> > +#define MPC83XX_SICRH_OFFS 0x118
> > +#define MPC83XX_SICRH_USB_UTMI 0x00020000
>=20
> Are these really generic to all MPC83XX? We should move these to
> include something like asm-ppc/mpc83xx.h
No, probably need to change the naming to MPC834x_*. The offsets are
generic, but the USB bits are not. If there is an asm/mpc834x.h, it
will be better there.
>=20
> > +
> > +
> > #endif /* __MACH_MPC83XX_SYS_H__ */
>=20
> - kumar
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* RE: [linux-usb-devel] [PATCH] Add USB to MPC8349 PB platform support
From: Li Yang-r58472 @ 2006-07-20 6:45 UTC (permalink / raw)
To: Pete Zaitcev; +Cc: linuxppc-dev, linux-usb-devel
In-Reply-To: <20060719121922.ef989b1d.zaitcev@redhat.com>
> -----Original Message-----
> From: Pete Zaitcev [mailto:zaitcev@redhat.com]
> Sent: Thursday, July 20, 2006 3:19 AM
> To: Li Yang-r58472
> Cc: dan@embeddedalley.com; linuxppc-dev@ozlabs.org;
galak@kernel.crashing.org;
> linux-usb-devel@lists.sourceforge.net; zaitcev@redhat.com
> Subject: Re: [linux-usb-devel] [PATCH] Add USB to MPC8349 PB platform
support
>=20
> On Thu, 20 Jul 2006 02:59:44 +0800, "Li Yang" <LeoLi@freescale.com>
wrote:
>=20
> > But why? Most embedded products facing end-user wouldn't like users
> > to modify the system by themselves.
>=20
> Certainly vendors won't like to give consumers extra freedoms.
> However, consumers like those freedoms, even if they would not
> use them in any specific instance.
>=20
> > Sometimes they even put effort in preventing user to do so.
>=20
> Jerks and criminals, that's what they are. Why would Linux developers
> care about needs of these people?
>=20
> Free software is about protecting the rights of users against
> vendors who "wouldn't like" users doing what they want with the
> product they bought.
>=20
> > The only kind of products I can think of, which
> > want the users to modify the code is reference boards, IMHO.
>=20
> Ever heard of WRT54? But in fact, every product out there may provide
> its owner an additional value when customized. I'd love to fix some
> bugs in my microwave, for instance. The silly thing will not start
> the timer if the door is open. It probably uses the same function
> which prevents cooking from starting (it also has a hardware interlock
> that cuts the magnetron, but this is different).
You are right. We really need to stick up for the freedom of software
as Richard Stallman advocated. :) However, I was talking about code
that goes into public kernel source tree. It's ok to distribute the
code with CD or web link. But if the code is not generic enough or
can't be reused, it won't qualify to be included in mainstream kernel
tree, I think.
-- Leo
^ permalink raw reply
* Re: reboot on PQ2FADS board.
From: Wolfgang Denk @ 2006-07-20 6:46 UTC (permalink / raw)
To: Lei Sun; +Cc: linuxppc-embedded
In-Reply-To: <f9a7e7a80607192046s3f17e8a5s4cfba43f1747e9ec@mail.gmail.com>
In message <f9a7e7a80607192046s3f17e8a5s4cfba43f1747e9ec@mail.gmail.com> you wrote:
>
> m8260_restart(char * cmd)
...
> startaddr = 0x04400000; /* this is taken from u-boot-1.1.4 */
This is a random address which happens to be not mapped in the
specific board (MPC8260ADS.h). The approach taken here is strongly
deprecated - it is juat an examp[le of a badly maintained board. In-
stead, I recommend to use an addrress which causes a checkstop on all
boards, idependently of the cspecific memory map. This is what we do
here:
> > dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
In the end, the effect is the same.
And I have no idea why it would not work on your board. Attach a
debugger and find out where exactly the code is hanging.
Ummm... and if you run under a debugger, *detach* it and check if
reset starts to work...
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
It's certainly convenient the way the crime (or condition) of
stupidity carries with it its own punishment, automatically
admisistered without remorse, pity, or prejudice. :-)
-- Tom Christiansen in <559seq$ag1$1@csnews.cs.colorado.edu>
^ permalink raw reply
* Re: [PATCH] Add USB to MPC8349 PB platform support
From: Marc Leeman @ 2006-07-20 7:21 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <4AC92920-4642-4899-B8CA-8EE5A1CDE0B3@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 2302 bytes --]
> >Though I do agree that there is a gap: it would be nice to have some
> >place to submit the kernel patches;
>
> This should be the kernel. The general rule of thumb I've used is if
> its useful to more than one other person its worth trying to get into
> the kernel. However, I can see if you are doing a one off kernel for
That is about the same rule that I use; luckily (a credit to the Linux
kernel and other developers); I don't have to change much stuff like
that.
> your embedded product that getting your changes into the kernel
> wouldn't be worth while. You have to have a desire to interact with
> the community if you want to get your code in.
There is a grey zone, but let's talk about a specific case:
In my current queue, I have to write a Host Port Interface (HPI) protocol
(serial) to a TI DSP. I would imagine that this is a useful
contribution. However, using HPI is almost by nature limited to specific
embedded designs (most of which differ slightly from one another).
Furthermore; I will need to use a number of GPIO pins on a 834x
processor. Using this needs to be backed by configuration settings in
U-Boot. If someone else makes a similar design; it would most likely be
with another processor family; and even then; they'll have other pins
connected/used.
Though the protocol would be a real nice addition; the physical
connection/configuration make including it in the main kernel tree
difficult.
> Personally, I see it useful if for no other reason that someone will
> fixup my board port if/when they change something which will make my
> moving to a newer kernel release that much easier.
Even though I would welcome this; our boards are included in larger
expensive systems that would just be shipped back in case of problems;
but we've never had functional (linux) problems (yet).
Come to think of it, I have a number of minor patches for 8349SYS based
configurations; where can I find the last devel code (next to 2.6.17)
for patch creation (and to whom to send them back)?
--
greetz, marc
If you must address me, do so as Your Supreme Eminence. Which you
should be doing anyway.
Rygel - Throne for a Loss
scorpius.homelinux.org 2.6.17 #2 PREEMPT Thu Jun 22 07:18:33 CEST 2006 GNU/Linux
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* RE: reboot on PQ2FADS board.
From: Liu Dave-r63238 @ 2006-07-20 7:22 UTC (permalink / raw)
To: Wolfgang Denk, Li Yang-r58472; +Cc: linuxppc-embedded
In-Reply-To: <20060719063317.86A66352681@atlas.denx.de>
This way maybe can not work. when the MMU turn off,=20
the next instructions maybe can not be fetched if these instructions
didn't exist cache.=20
so it is possible these instruction can not executed. =20
>=20
> Trying to jump to some boot rom address is IMHO always a bad=20
> approach to reboot a system. You should always try to cause a=20
> reset condition for the CPU, and thus for all the=20
> associated hardware. On 8xx / 8260 systems this is usually=20
> done by going through a machine check. We have the =20
> following code in our linuxppc_2_4_devel tree, which works on=20
> ALL 8260 systems, no matter whioch boot loder they use:
>=20
> static void
> m8260_restart(char *cmd)
> { =20
> __volatile__ unsigned char dummy;
> ulong msr;
> =20
> cli();
> volatile immap_t *immap =3D (immap_t *) IMAP_ADDR;
> =20
> immap->im_clkrst.car_rmr =3D 1; /* Checkstop Reset enable =
*/
> =20
> /* Interrupts and MMU off */
> __asm__ __volatile__ ("mfmsr %0":"=3Dr" (msr):);
> =20
> msr &=3D ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
> __asm__ __volatile__ ("mtmsr %0"::"r" (msr));=20
> =20
Now the MMU trun off, is real address mode. But the PC still is
0xC00xxxx.. It is old effective address.
> dummy =3D ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
These instructions will locate on the real address space...... It is
0xC00xxxx- KERNELBASE
> =20
> printk("Restart failed\n");
> for (;;);
> } =20
>=20
^ permalink raw reply
* regarding MAL
From: Sangameshwar Pujari @ 2006-07-20 8:03 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 214 bytes --]
Hi,
i am porting a EMAC driver from NetBSD to my Xilinix ML403 embeddded board . NETBSD code is Having a Media Access Layer (MAL) , which i want to know bit , is it the same MAC layer .
regards
sangamesh
[-- Attachment #2: Type: text/html, Size: 703 bytes --]
^ permalink raw reply
* Re: MPC8260 SCC UART hardware flow control
From: Mathieu Deschamps @ 2006-07-20 8:18 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linuxppc-embedded
In-Reply-To: <200607191718.00328.laurent.pinchart@tbox.biz>
Hi Laurent,
On Wednesday 19 July 2006 17:18, Laurent Pinchart wrote:
> Hi everybody,
>
> I was wondering if anyone had implemented hardware flow control support in
> the cpm_uart driver. If not, I would appreciate pointers regarding how to
> do so.
>
> Best regards,
>
> Laurent Pinchart
>
I had. PQ2 CPM is a dedicated part which handles this aspect for you via
its microcode. This also means you can't play with it the old way and making
your own HHS with a CD/DSR :). Back to seriousness, rather this means you
needn't adding modem signal handling in cpm_uart driver. So don't define
modem_something that's an ancient reliq from the times, I guess, no CPM was
put auxillary.
So how to tell CPM to cope with HHS ? Simple, you "just" have to put SCC's
Dedicated pins the right way which depends on your board type. Remember you
can't do any HHS with SMC. Refer to Dedicated Pins chapter in the litterature
[41.4.2]. Also take a look at SCC GSMR register [20.8] and to SCC UART mode
PSMR register [21-14] to maybe use protocol specificities.
When you'll have your kernel ready, you would do probably something like :
stty -F $port crtscts $SPEED
As Wolfgang said HHS works for DTE-DCE only (roughly but visually you must
have plugs opposite gender on both ends), trying DTE-DTE HHS dialog is bound
to failure despite time spend on it.
Cdy,
Mathieu Deschamps
Com2gether Design Center
Electronic and Embedded Engineering Services
www.com2gether.net
^ permalink raw reply
* RE: Linux bin Commands download
From: Li Yang-r58472 @ 2006-07-20 8:54 UTC (permalink / raw)
To: andreas Sotirakopoulos; +Cc: linuxppc-embedded
In-Reply-To: <200607201134.02445.menwn@yahoo.co.uk>
So you are using embedded powerpc platform? There are several embedded
Linux distributions, e.g. from montavista, denx, and Freescale. You can
google them yourself.
If you are using Freescale powerpc, I would recommend the LTIB BSP
packages which can be downloaded at www.freescale.com
Best Regards,
Leo
> -----Original Message-----
> From: andreas Sotirakopoulos [mailto:menwn@yahoo.co.uk]
> Sent: Thursday, July 20, 2006 4:34 PM
> To: Li Yang-r58472
> Subject: Re: Linux bin Commands download
>=20
> On Wednesday 19 July 2006 08:31, you wrote:
> Thanks, I would like though to know... is rpm suitable for the purpose
i want
> them?
> I want to store the commands (lets say the command ls) in a directory
> on a FreeBSD 6 box (i386) and export this directory for NFS so as to
mount it
> bfrom the powerpc and run the commands from that directory.
> thanks in advance
> andreas
> > > -----Original Message-----
> > > From: linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org
> > > [mailto:linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org] On
Behalf
> >
> > Of none
> >
> > > none
> > > Sent: Tuesday, July 18, 2006 8:35 PM
> > > To: linuxppc-dev@ozlabs.org
> > > Subject: Linux bin Commands download
> > >
> > > Hi
> > > I would like to download precompiled linux commands
> > > and programs for powerPC but i cannot find any
> > > binaries anyware. Are there any links?
> >
> > You can find rpm at http://rpmfind.net. And there are also a couple
of
> > powerpc distributions out there.
> >
> > > thanks in advance
> > > sotirakopoulos andreas
>=20
>=20
>=20
>=20
> ___________________________________________________________
> All new Yahoo! Mail "The new Interface is stunning in its simplicity
and ease of
> use." - PC Magazine
> http://uk.docs.yahoo.com/nowyoucan.html
^ permalink raw reply
* loading large lkm is so slow on ppc linux
From: Miao Qingjun @ 2006-07-20 9:17 UTC (permalink / raw)
To: linuxppc-embedded, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 222 bytes --]
Hi,
It seems module_frob_arch_sections()/count_relocs() spent so much time when loading large lkm.
Can just "return 0" in ppc version of module_frob_arch_sections()?
or just "return num" in count_relocs()?
thanks
[-- Attachment #2: Type: text/html, Size: 759 bytes --]
^ permalink raw reply
* mpc8360sar
From: Alex Zeffertt @ 2006-07-20 10:39 UTC (permalink / raw)
To: linuxppc-embedded, linux-atm-general
Hi lists,
I'm writing to announce a new project http://mpc8360sar.sourceforge.net .
This is an ATM driver for the QUICC Engine (QE) of the PowerQUICC II Pro
range of processors. It is based on Tony Li's fsl-atm driver and my
mpc8260sar driver. I've basically used Tony's driver for the most low level
stuff and ported a lot of extra functionality from my PQII driver.
You will need the Linux BSP from Freescale to build this driver.
I have only tested this driver on mpc832xe-mds, but it should also work on
the mpc8360e-pb board.
If you use mpc8360sar, please let me know how you get on. In particular
let me know if you work out how to stop the QE occaisionally corrupting the
TCT when using external channels.
Regards,
Alex
^ permalink raw reply
* RE: [linux-usb-devel] [PATCH] Fix Freescale high-speed USB hostdependency
From: Li Yang-r58472 @ 2006-07-20 11:42 UTC (permalink / raw)
To: Kumar Gala, gregkh; +Cc: linuxppc-dev, linux-usb-devel
In-Reply-To: <6DFEB2BB-05AB-441E-854E-297987B97A0E@kernel.crashing.org>
Another one in header file.
---
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 679c1cd..8da2774 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -642,7 +642,7 @@ #endif
=20
/*----------------------------------------------------------------------
---*/
-#ifdef CONFIG_PPC_83xx
+#ifdef CONFIG_MPC834x
/* Some Freescale processors have an erratum in which the TT
* port number in the queue head was 0..N-1 instead of 1..N.
*/
> -----Original Message-----
> From: linux-usb-devel-bounces@lists.sourceforge.net
> [mailto:linux-usb-devel-bounces@lists.sourceforge.net] On Behalf Of
Kumar Gala
> Sent: Friday, July 14, 2006 9:52 PM
> To: Li Yang-r58472
> Cc: linuxppc-dev@ozlabs.org; gregkh@suse.de;
> linux-usb-devel@lists.sourceforge.net
> Subject: Re: [linux-usb-devel] [PATCH] Fix Freescale high-speed USB
hostdependency
>=20
> Acked-by: Kumar Gala <galak@kernel.crashing.org>
>=20
> On Jul 14, 2006, at 6:58 AM, Li Yang wrote:
>=20
> > The high-speed USB SOC only exists on MPC834x family not MPC83xx
> > family.
> >
> > Signed-off-by: Li Yang <leoli@freescale.com>
> >
> > ---
> >
> > drivers/usb/host/ehci-hcd.c | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-
> > hcd.c index 79f2d8b..3af1844 100644
> > --- a/drivers/usb/host/ehci-hcd.c
> > +++ b/drivers/usb/host/ehci-hcd.c
> > @@ -892,7 +892,7 @@ #include "ehci-pci.c"
> > #define EHCI_BUS_GLUED
> > #endif
> >
> > -#ifdef CONFIG_PPC_83xx
> > +#ifdef CONFIG_MPC834x
> > #include "ehci-fsl.c"
> > #define EHCI_BUS_GLUED
> > #endif
^ permalink raw reply related
* RE: [Linux-ATM-General] mpc8360sar
From: Li Tony-r64360 @ 2006-07-20 12:07 UTC (permalink / raw)
To: Alex Zeffertt, linuxppc-embedded, linux-atm-general
In-Reply-To: <44BF5D6D.1070400@cambridgebroadband.com>
Hi, alex
I am tony li. I am glad to know that you add many features support.
Do you have test the UBR and AAL0 ? I am lack of enviroment test them
now.
I have not read your code detailly.:)
And which ltib release version is your base ? I have updated my code a
little which contain a workaround for a bug.
Tony.li =20
-----Original Message-----
From: linux-atm-general-bounces@lists.sourceforge.net
[mailto:linux-atm-general-bounces@lists.sourceforge.net] On Behalf Of
Alex Zeffertt
Sent: Thursday, July 20, 2006 6:40 PM
To: linuxppc-embedded@ozlabs.org;
linux-atm-general@lists.sourceforge.net
Subject: [Linux-ATM-General] mpc8360sar
Hi lists,
I'm writing to announce a new project http://mpc8360sar.sourceforge.net
.
This is an ATM driver for the QUICC Engine (QE) of the PowerQUICC II Pro
range of processors. It is based on Tony Li's fsl-atm driver and my
mpc8260sar driver. I've basically used Tony's driver for the most low
level stuff and ported a lot of extra functionality from my PQII driver.
You will need the Linux BSP from Freescale to build this driver.
I have only tested this driver on mpc832xe-mds, but it should also work
on the mpc8360e-pb board.
If you use mpc8360sar, please let me know how you get on. In particular
let me know if you work out how to stop the QE occaisionally corrupting
the TCT when using external channels.
Regards,
Alex
------------------------------------------------------------------------
-
Take Surveys. Earn Cash. Influence the Future of IT Join
SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=3Djoin.php&p=3Dsourceforge&CID=3D=
DEVDE
V
_______________________________________________
Linux-atm-general mailing list
Linux-atm-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-atm-general
^ 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