]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] ppc32: boot and platform fixes
authorAndrew Morton <akpm@osdl.org>
Fri, 13 Feb 2004 07:47:41 +0000 (23:47 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 13 Feb 2004 07:47:41 +0000 (23:47 -0800)
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.

arch/ppc/Kconfig
arch/ppc/boot/common/bootinfo.c [new file with mode: 0644]
arch/ppc/boot/simple/Makefile
arch/ppc/boot/simple/misc-spruce.c
arch/ppc/boot/simple/misc.c
arch/ppc/platforms/spruce.h
arch/ppc/platforms/spruce_setup.c
include/asm-ppc/bootinfo.h

index 3a327de435896f2cb3dc5609bc2e6468a31665a6..74029be4365b22d53fd00cfb64eff881619c600f 100644 (file)
@@ -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 (file)
index 0000000..9c6e528
--- /dev/null
@@ -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);
+}
index 2cdf790230ebd0c9a3bd7b2184e4113a399874e6..9edf21b52fb334aade1d351b6249c4b736178cf8 100644 (file)
@@ -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
index a11c5f70df50ee48ba9607fb6e741e3fd661b4a3..62044ca3575f31dd8430109f26906be0fb01a879 100644 (file)
  */
 
 #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);
 }
index 9ad6e428389a049b46193fd2e18d371c720f3a8d..3f1933066eebf96025590a4f9212e6b40d5ff6b9 100644 (file)
@@ -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
 #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. */
index eaabfdcf1705429a747350a96523b902f3468450..d60d1208bdf8b4b55fe9d3e1d07ee024e32dca75 100644 (file)
 #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__ */
index 54a7bdf059b8850378ab3014aa435fdca682e022..e5c174ef601a61def0fe055915e7b6a3fd42f157 100644 (file)
@@ -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
 }
index 213bab4f1481cd877a491ebb7d0a6ee33a282a49..93d955c70d652b06d6b1da3dfd21ea995be52fc9 100644 (file)
@@ -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 */