Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-02-12 23:47:41 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2004-02-12 23:47:41 -0800
commit0ee5a7d5d8313851d74d2e5c7655b0feda4c1891 (patch)
tree41d0a1f39bf0c15da52975cb92827d04f2c58d55
parent39ef4295a6bfb444c731d513cb041f1e770bf178 (diff)
[PATCH] ppc32: boot and platform fixes
From: Tom Rini <trini@kernel.crashing.org> From: Randy Vinson <rvinson@mvista.com> - Fixup IBM Spruce support (GEN550, general fixes and cleanups). - Forward-port the INTERACTIVE_CONSOLE bits from 2.4. - Forward-port the bootinfo code. - Add a weak get_mem_size() function.
-rw-r--r--arch/ppc/Kconfig2
-rw-r--r--arch/ppc/boot/common/bootinfo.c70
-rw-r--r--arch/ppc/boot/simple/Makefile4
-rw-r--r--arch/ppc/boot/simple/misc-spruce.c235
-rw-r--r--arch/ppc/boot/simple/misc.c83
-rw-r--r--arch/ppc/platforms/spruce.h32
-rw-r--r--arch/ppc/platforms/spruce_setup.c83
-rw-r--r--include/asm-ppc/bootinfo.h11
8 files changed, 265 insertions, 255 deletions
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 3a327de43589..74029be4365b 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -609,7 +609,7 @@ config PPC_OF
config PPC_GEN550
bool
- depends on SANDPOINT || MCPN765
+ depends on SANDPOINT || MCPN765 || SPRUCE
default y
config FORCE
diff --git a/arch/ppc/boot/common/bootinfo.c b/arch/ppc/boot/common/bootinfo.c
new file mode 100644
index 000000000000..9c6e528940e9
--- /dev/null
+++ b/arch/ppc/boot/common/bootinfo.c
@@ -0,0 +1,70 @@
+/*
+ * arch/ppc/common/bootinfo.c
+ *
+ * General bootinfo record utilities
+ * Author: Randy Vinson <rvinson@mvista.com>
+ *
+ * 2002 (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 <linux/types.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+
+#include "nonstdio.h"
+
+static struct bi_record * birec = NULL;
+
+static struct bi_record *
+__bootinfo_build(struct bi_record *rec, unsigned long tag, unsigned long size,
+ void *data)
+{
+ /* set the tag */
+ rec->tag = tag;
+
+ /* if the caller has any data, copy it */
+ if (size)
+ memcpy(rec->data, (char *)data, size);
+
+ /* set the record size */
+ rec->size = sizeof(struct bi_record) + size;
+
+ /* advance to the next available space */
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ return rec;
+}
+
+void
+bootinfo_init(struct bi_record *rec)
+{
+
+ /* save start of birec area */
+ birec = rec;
+
+ /* create an empty list */
+ rec = __bootinfo_build(rec, BI_FIRST, 0, NULL);
+ (void) __bootinfo_build(rec, BI_LAST, 0, NULL);
+
+}
+
+void
+bootinfo_append(unsigned long tag, unsigned long size, void * data)
+{
+
+ struct bi_record *rec = birec;
+
+ /* paranoia */
+ if ((rec == NULL) || (rec->tag != BI_FIRST))
+ return;
+
+ /* find the last entry in the list */
+ while (rec->tag != BI_LAST)
+ rec = (struct bi_record *)((ulong)rec + rec->size);
+
+ /* overlay BI_LAST record with new one and tag on a new BI_LAST */
+ rec = __bootinfo_build(rec, tag, size, data);
+ (void) __bootinfo_build(rec, BI_LAST, 0, NULL);
+}
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index 2cdf790230eb..9edf21b52fb3 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -30,7 +30,7 @@ tftpboot := /tftpboot
# Normally, we use the 'misc.c' file for decompress_kernel and
# whatnot. Sometimes we need to override this however.
-misc-y := misc.o
+misc-y := misc.o ../common/bootinfo.o
# Normally, we have our images end in .elf, but something we want to
# change this.
@@ -103,7 +103,7 @@ zimageinitrd-$(pcore) := zImage.initrd-STRIPELF
zimageinitrd-$(CONFIG_SPRUCE) := zImage.initrd-TREE
end-$(CONFIG_SPRUCE) := spruce
entrypoint-$(CONFIG_SPRUCE) := 0x00800000
- misc-$(CONFIG_SPRUCE) := misc-spruce.o
+ misc-$(CONFIG_SPRUCE) += misc-spruce.o
# SMP images should have a '.smp' suffix.
end-$(CONFIG_SMP) += .smp
diff --git a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c
index a11c5f70df50..62044ca3575f 100644
--- a/arch/ppc/boot/simple/misc-spruce.c
+++ b/arch/ppc/boot/simple/misc-spruce.c
@@ -15,55 +15,19 @@
*/
#include <linux/types.h>
-#include <linux/elf.h>
#include <linux/config.h>
#include <linux/pci.h>
-#include <asm/page.h>
-#include <asm/mmu.h>
#include <asm/bootinfo.h>
-#include "zlib.h"
+extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
+ unsigned long cksum);
/* Define some important locations of the Spruce. */
#define SPRUCE_PCI_CONFIG_ADDR 0xfec00000
#define SPRUCE_PCI_CONFIG_DATA 0xfec00004
#define SPRUCE_ISA_IO_BASE 0xf8000000
-unsigned long com_port;
-
-char *avail_ram;
-char *end_avail;
-
-/* The linker tells us where the image is. */
-extern char __image_begin, __image_end;
-extern char __ramdisk_begin, __ramdisk_end;
-extern char _end[];
-
-#ifdef CONFIG_CMDLINE
-#define CMDLINE CONFIG_CMDLINE
-#else
-#define CMDLINE ""
-#endif
-char cmd_preset[] = CMDLINE;
-char cmd_buf[256];
-char *cmd_line = cmd_buf;
-
-unsigned long initrd_size = 0;
-
-char *zimage_start;
-int zimage_size;
-
-extern void udelay(long);
-extern void puts(const char *);
-extern void putc(const char c);
-extern void puthex(unsigned long val);
-extern int getc(void);
-extern int tstc(void);
-extern void gunzip(void *, int, unsigned char *, int *);
-
-extern unsigned long serial_init(int chan, void *ignored);
-
/* PCI configuration space access routines. */
unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR;
unsigned char *pci_config_data = (unsigned char *)SPRUCE_PCI_CONFIG_DATA;
@@ -146,45 +110,16 @@ unsigned long isa_io_base = SPRUCE_ISA_IO_BASE;
#define MEM_B2EA 0x60
unsigned long
-load_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
+get_mem_size(void)
{
- int timer = 0;
- char *cp, ch;
-
int loop;
- int csr0;
- int csr_id;
- int *mem_addr = (int *)0xff500008;
- int *mem_data = (int *)0xff50000c;
- int mem_size = 0;
+ unsigned long mem_size = 0;
unsigned long mem_mben;
unsigned long mem_type;
unsigned long mem_start;
unsigned long mem_end;
- int *pif_addr = (int *)0xff500000;
- int *pif_data = (int *)0xff500004;
- int pci_devfn;
- int found_multi = 0;
- unsigned short vendor;
- unsigned short device;
- unsigned short command;
- unsigned char header_type;
- unsigned int bar0;
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- /* Initialize the serial console port */
- com_port = serial_init(0, NULL);
-#endif
-
- /*
- * Gah, these firmware guys need to learn that hardware
- * byte swapping is evil! Disable all hardware byte
- * swapping so it doesn't hurt anyone.
- */
- *pif_addr = PLBMIFOPT;
- asm("sync");
- *pif_data = 0x00000000;
- asm("sync");
+ volatile int *mem_addr = (int *)0xff500008;
+ volatile int *mem_data = (int *)0xff50000c;
/* Get the size of memory from the memory controller. */
*mem_addr = MEM_MBEN;
@@ -235,6 +170,33 @@ load_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
mem_size += mem_end - mem_start + 0x100000;
}
+ return mem_size;
+}
+
+unsigned long
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
+{
+ int csr0;
+ int csr_id;
+ int pci_devfn;
+ int found_multi = 0;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned short command;
+ unsigned char header_type;
+ unsigned int bar0;
+ volatile int *pif_addr = (int *)0xff500000;
+ volatile int *pif_data = (int *)0xff500004;
+
+ /*
+ * Gah, these firmware guys need to learn that hardware
+ * byte swapping is evil! Disable all hardware byte
+ * swapping so it doesn't hurt anyone.
+ */
+ *pif_addr = PLBMIFOPT;
+ asm("sync");
+ *pif_data = 0x00000000;
+ asm("sync");
/* Search out and turn off the PcNet ethernet boot device. */
for (pci_devfn = 1; pci_devfn < 0xff; pci_devfn++) {
@@ -310,134 +272,5 @@ load_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
}
}
- /* assume the chunk below 8M is free */
- end_avail = (char *)0x00800000;
-
- /*
- * We link ourself to 0x00800000. When we run, we relocate
- * ourselves there. So we just need __image_begin for the
- * start. -- Tom
- */
- zimage_start = (char *)(unsigned long)(&__image_begin);
- zimage_size = (unsigned long)(&__image_end) -
- (unsigned long)(&__image_begin);
-
- initrd_size = (unsigned long)(&__ramdisk_end) -
- (unsigned long)(&__ramdisk_begin);
-
- /*
- * The zImage and initrd will be between start and _end, so they've
- * already been moved once. We're good to go now. -- Tom
- */
- avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
- puts("zimage at: "); puthex((unsigned long)zimage_start);
- puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
- puts("\n");
-
- if ( initrd_size ) {
- puts("initrd at: ");
- puthex((unsigned long)(&__ramdisk_begin));
- puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
- }
-
- avail_ram = (char *)0x00400000;
- end_avail = (char *)0x00800000;
- puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
- puthex((unsigned long)end_avail); puts("\n");
-
- /* Display standard Linux/PPC boot prompt for kernel args */
- puts("\nLinux/PPC load: ");
- cp = cmd_line;
- memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
- while ( *cp ) putc(*cp++);
- while (timer++ < 5*1000) {
- if (tstc()) {
- while ((ch = getc()) != '\n' && ch != '\r') {
- if (ch == '\b') {
- if (cp != cmd_line) {
- cp--;
- puts("\b \b");
- }
- } else {
- *cp++ = ch;
- putc(ch);
- }
- }
- break; /* Exit 'timer' loop */
- }
- udelay(1000); /* 1 msec */
- }
- *cp = 0;
- puts("\n");
-
- puts("Uncompressing Linux...");
-
- gunzip(0, 0x400000, zimage_start, &zimage_size);
-
- puts("done.\n");
-
- {
- struct bi_record *rec;
- unsigned long initrd_loc;
- unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
- (1 << 20) - 1, (1 << 20));
- rec = (struct bi_record *)rec_loc;
-
- /* We need to make sure that the initrd and bi_recs do not
- * overlap. */
- if ( initrd_size ) {
- initrd_loc = (unsigned long)(&__ramdisk_begin);
- /* If the bi_recs are in the middle of the current
- * initrd, move the initrd to the next MB
- * boundary. */
- if ((rec_loc > initrd_loc) &&
- ((initrd_loc + initrd_size)
- > rec_loc)) {
- initrd_loc = _ALIGN((unsigned long)(zimage_size)
- + (2 << 20) - 1, (2 << 20));
- memmove((void *)initrd_loc, &__ramdisk_begin,
- initrd_size);
- puts("initrd moved: "); puthex(initrd_loc);
- puts(" "); puthex(initrd_loc + initrd_size);
- puts("\n");
- }
- }
-
- rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_BOOTLOADER_ID;
- memcpy( (void *)rec->data, "spruceboot", 11);
- rec->size = sizeof(struct bi_record) + 10 + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_MEMSIZE;
- rec->data[0] = mem_size;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_CMD_LINE;
- memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
- rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
- rec = (struct bi_record *)((ulong)rec + rec->size);
-
- if ( initrd_size ) {
- rec->tag = BI_INITRD;
- rec->data[0] = initrd_loc;
- rec->data[1] = initrd_size;
- rec->size = sizeof(struct bi_record) + 2 *
- sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec +
- rec->size);
- }
-
- rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- }
-
- puts("Now booting the kernel\n");
-
- return 0;
+ return decompress_kernel(load_addr, num_words, cksum);
}
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index 9ad6e428389a..3f1933066eeb 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc/common/misc-simple.c
+ * arch/ppc/simple/misc.c
*
* Misc. bootloader code for many machines. This assumes you have are using
* a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory
@@ -46,6 +46,15 @@
#define HAS_KEYB 0
#endif
+/* Will / Can the user give input?
+ * Val Henson has requested that Gemini doesn't wait for the
+ * user to edit the cmdline or not.
+ */
+#if (defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_VGA_CONSOLE)) \
+ && !defined(CONFIG_GEMINI)
+#define INTERACTIVE_CONSOLE 1
+#endif
+
char *avail_ram;
char *end_avail;
char *zimage_start;
@@ -66,19 +75,28 @@ extern char _end[];
extern unsigned long start;
extern int CRT_tstc(void);
-extern unsigned long get_mem_size(void);
extern unsigned long serial_init(int chan, void *ignored);
extern void serial_close(unsigned long com_port);
extern void gunzip(void *, int, unsigned char *, int *);
extern void serial_fixups(void);
+/* Allow get_mem_size to be hooked into. This is the default. */
+unsigned long __attribute__ ((weak))
+get_mem_size(void)
+{
+ return 0;
+}
+
struct bi_record *
decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
{
+#ifdef INTERACTIVE_CONSOLE
int timer = 0;
- char *cp, ch;
+ char ch;
+#endif
+ char *cp;
struct bi_record *rec;
- unsigned long TotalMemory = 0, rec_loc, initrd_loc;
+ unsigned long initrd_loc, TotalMemory = 0;
serial_fixups();
com_port = serial_init(0, NULL);
@@ -93,13 +111,11 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
__asm__ __volatile__("eieio");
#endif
-#if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4)
/*
* Call get_mem_size(), which is memory controller dependent,
* and we must have the correct file linked in here.
*/
TotalMemory = get_mem_size();
-#endif
/* assume the chunk below 8M is free */
end_avail = (char *)0x00800000;
@@ -170,9 +186,11 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
while ( *cp ) putc(*cp++);
-#ifndef CONFIG_GEMINI
- /* Val Henson has requested that Gemini doesn't wait for the
- * user to edit the cmdline or not. */
+#ifdef INTERACTIVE_CONSOLE
+ /*
+ * If they have a console, allow them to edit the command line.
+ * Otherwise, don't bother wasting the five seconds.
+ */
while (timer++ < 5*1000) {
if (tstc()) {
while ((ch = getc()) != '\n' && ch != '\r') {
@@ -205,16 +223,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
gunzip(0, 0x400000, zimage_start, &zimage_size);
puts("done.\n");
- /*
- * Create bi_recs for cmd_line and initrds
- */
- rec_loc = _ALIGN((unsigned long)(zimage_size) +
- (1 << 20) - 1, (1 << 20));
- rec = (struct bi_record *)rec_loc;
+ /* get the bi_rec address */
+ rec = bootinfo_addr(zimage_size);
/* We need to make sure that the initrd and bi_recs do not
* overlap. */
if ( initrd_size ) {
+ unsigned long rec_loc = (unsigned long) rec;
initrd_loc = (unsigned long)(&__ramdisk_begin);
/* If the bi_recs are in the middle of the current
* initrd, move the initrd to the next MB
@@ -231,39 +246,25 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
}
}
- rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ bootinfo_init(rec);
+ if ( TotalMemory )
+ bootinfo_append(BI_MEMSIZE, sizeof(int), (void*)&TotalMemory);
- if ( TotalMemory ) {
- rec->tag = BI_MEMSIZE;
- rec->data[0] = TotalMemory;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- }
+ bootinfo_append(BI_CMD_LINE, strlen(cmd_line)+1, (void*)cmd_line);
- rec->tag = BI_CMD_LINE;
- memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
- rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ /* add a bi_rec for the initrd if it exists */
+ if (initrd_size) {
+ unsigned long initrd[2];
- if ( initrd_size ) {
- rec->tag = BI_INITRD;
- rec->data[0] = initrd_loc;
- rec->data[1] = initrd_size;
- rec->size = sizeof(struct bi_record) + 2 *
- sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec +
- rec->size);
- }
+ initrd[0] = initrd_loc;
+ initrd[1] = initrd_size;
- rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ bootinfo_append(BI_INITRD, sizeof(initrd), &initrd);
+ }
puts("Now booting the kernel\n");
serial_close(com_port);
- return (struct bi_record *)rec_loc;
+ return rec;
}
/* Allow decompress_kernel to be hooked into. This is the default. */
diff --git a/arch/ppc/platforms/spruce.h b/arch/ppc/platforms/spruce.h
index eaabfdcf1705..d60d1208bdf8 100644
--- a/arch/ppc/platforms/spruce.h
+++ b/arch/ppc/platforms/spruce.h
@@ -35,11 +35,37 @@
#define SPRUCE_MEM_SIZE 0x04000000
#define SPRUCE_BUS_SPEED 66666667
-#define SPRUCE_SERIAL_1_ADDR 0xff600300
-#define SPRUCE_SERIAL_2_ADDR 0xff600400
-
#define SPRUCE_NVRAM_BASE_ADDR 0xff800000
#define SPRUCE_RTC_BASE_ADDR SPRUCE_NVRAM_BASE_ADDR
+/*
+ * Serial port defines
+ */
+#define SPRUCE_FPGA_REG_A 0xff820000
+#define SPRUCE_UARTCLK_33M 0x02
+#define SPRUCE_UARTCLK_IS_33M(reg) (reg & SPRUCE_UARTCLK_33M)
+
+#define UART0_IO_BASE 0xff600300
+#define UART1_IO_BASE 0xff600400
+
+#define RS_TABLE_SIZE 2
+
+#define SPRUCE_BAUD_33M (33000000/64)
+#define SPRUCE_BAUD_30M (30000000/64)
+#define BASE_BAUD SPRUCE_BAUD_33M
+
+#define UART0_INT 3
+#define UART1_INT 4
+
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_INT, \
+ ASYNC_BOOT_AUTOCONF, \
+ iomem_base: UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0) \
+ STD_UART_OP(1)
+
#endif /* __ASM_SPRUCE_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/spruce_setup.c b/arch/ppc/platforms/spruce_setup.c
index 54a7bdf059b8..e5c174ef601a 100644
--- a/arch/ppc/platforms/spruce_setup.c
+++ b/arch/ppc/platforms/spruce_setup.c
@@ -28,6 +28,9 @@
#include <linux/seq_file.h>
#include <linux/ide.h>
#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -39,6 +42,7 @@
#include <platforms/spruce.h>
#include <asm/todc.h>
#include <asm/bootinfo.h>
+#include <asm/kgdb.h>
#include <syslib/cpc700.h>
@@ -103,6 +107,46 @@ spruce_show_cpuinfo(struct seq_file *m)
return 0;
}
+static void __init
+spruce_early_serial_map(void)
+{
+ u32 uart_clk;
+ struct uart_port serial_req;
+
+ if (SPRUCE_UARTCLK_IS_33M(readb(SPRUCE_FPGA_REG_A)))
+ uart_clk = SPRUCE_BAUD_33M * 16;
+ else
+ uart_clk = SPRUCE_BAUD_30M * 16;
+
+ /* Setup serial port access */
+ memset(&serial_req, 0, sizeof(serial_req));
+ serial_req.uartclk = uart_clk;
+ serial_req.irq = UART0_INT;
+ serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ serial_req.iotype = SERIAL_IO_MEM;
+ serial_req.membase = (u_char *)UART0_IO_BASE;
+ serial_req.regshift = 0;
+
+ gen550_init(0, &serial_req);
+
+#ifdef CONFIG_SERIAL_8250
+ if (early_serial_setup(&serial_req) != 0)
+ printk("Early serial init of port 0 failed\n");
+#endif
+
+ /* Assume early_serial_setup() doesn't modify serial_req */
+ serial_req.line = 1;
+ serial_req.irq = UART1_INT;
+ serial_req.membase = (u_char *)UART1_IO_BASE;
+
+ gen550_init(1, &serial_req);
+
+#ifdef CONFIG_SERIAL_8250
+ if (early_serial_setup(&serial_req) != 0)
+ printk("Early serial init of port 1 failed\n");
+#endif
+}
+
TODC_ALLOC();
static void __init
@@ -128,10 +172,11 @@ spruce_setup_arch(void)
ROOT_DEV = Root_SDA1;
#endif
-#ifdef CONFIG_DUMMY_CONSOLE
+#ifdef CONFIG_VT
conswitchp = &dummy_con;
#endif
+
/* Identify the system */
printk(KERN_INFO "System Identification: IBM Spruce\n");
printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
@@ -146,12 +191,12 @@ spruce_restart(char *cmd)
/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
__asm__ __volatile__
("\n\
- lis 3,0xfff0
- ori 3,3,0x0100
- mtspr 26,3
- li 3,0
- mtspr 27,3
- rfi
+ lis 3,0xfff0 \n\
+ ori 3,3,0x0100 \n\
+ mtspr 26,3 \n\
+ li 3,0 \n\
+ mtspr 27,3 \n\
+ rfi \n\
");
for(;;);
}
@@ -175,12 +220,27 @@ spruce_map_io(void)
0x08000000, _PAGE_IO);
}
+/*
+ * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
+ */
+static __inline__ void
+spruce_set_bat(void)
+{
+ mb();
+ mtspr(DBAT1U, 0xf8000ffe);
+ mtspr(DBAT1L, 0xf800002a);
+ mb();
+}
+
void __init
platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
parse_bootinfo(find_bootinfo());
+ /* Map in board regs, etc. */
+ spruce_set_bat();
+
isa_io_base = SPRUCE_ISA_IO_BASE;
pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE;
@@ -202,4 +262,13 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.nvram_read_val = todc_direct_read_val;
ppc_md.nvram_write_val = todc_direct_write_val;
+
+ spruce_early_serial_map();
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ ppc_md.progress = gen550_progress;
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#ifdef CONFIG_KGDB
+ ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
+#endif
}
diff --git a/include/asm-ppc/bootinfo.h b/include/asm-ppc/bootinfo.h
index 213bab4f1481..93d955c70d65 100644
--- a/include/asm-ppc/bootinfo.h
+++ b/include/asm-ppc/bootinfo.h
@@ -10,6 +10,7 @@
#define _PPC_BOOTINFO_H
#include <linux/config.h>
+#include <asm/page.h>
#if defined(CONFIG_APUS) && !defined(__BOOTER__)
#include <asm-m68k/bootinfo.h>
@@ -29,11 +30,21 @@ struct bi_record {
#define BI_SYSMAP 0x1015
#define BI_MACHTYPE 0x1016
#define BI_MEMSIZE 0x1017
+#define BI_BOARD_INFO 0x1018
extern struct bi_record *find_bootinfo(void);
+extern void bootinfo_init(struct bi_record *rec);
+extern void bootinfo_append(unsigned long tag, unsigned long size, void * data);
extern void parse_bootinfo(struct bi_record *rec);
extern unsigned long boot_mem_size;
+static inline struct bi_record *
+bootinfo_addr(unsigned long offset)
+{
+
+ return (struct bi_record *)_ALIGN((offset) + (1 << 20) - 1,
+ (1 << 20));
+}
#endif /* CONFIG_APUS */