This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / mips / sni / sniprom.c
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
new file mode 100644 (file)
index 0000000..d1d0f1f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Big Endian PROM code for SNI RM machines
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
+ * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/addrspace.h>
+#include <asm/sni.h>
+#include <asm/mipsprom.h>
+#include <asm/bootinfo.h>
+
+/* special SNI prom calls */
+/*
+ * This does not exist in all proms - SINIX compares
+ * the prom env variable "version" against "2.0008"
+ * or greater. If lesser it tries to probe interesting
+ * registers
+ */
+#define PROM_GET_MEMCONF       58
+
+#define PROM_VEC               (u64 *)CKSEG1ADDR(0x1fc00000)
+#define PROM_ENTRY(x)          (PROM_VEC + (x))
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG_PRINTF(x...)     prom_printf(x)
+#else
+#define DBG_PRINTF(x...)
+#endif
+
+static int *(*__prom_putchar)(int)        = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
+static char *(*__prom_getenv)(char *)     = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
+static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
+
+char *prom_getenv (char *s)
+{
+       return __prom_getenv(s);
+}
+
+void prom_printf(char *fmt, ...)
+{
+       va_list args;
+       char ppbuf[1024];
+       char *bptr;
+
+       va_start(args, fmt);
+       vsprintf(ppbuf, fmt, args);
+
+       bptr = ppbuf;
+
+       while (*bptr != 0) {
+               if (*bptr == '\n')
+                       __prom_putchar('\r');
+
+               __prom_putchar(*bptr++);
+       }
+       va_end(args);
+}
+
+unsigned long prom_free_prom_memory(void)
+{
+       return 0;
+}
+
+/*
+ * /proc/cpuinfo system type
+ *
+ */
+static const char *systype = "Unknown";
+const char *get_system_type(void)
+{
+       return systype;
+}
+
+#define SNI_IDPROM_BASE                0xbff00000
+#define SNI_IDPROM_MEMSIZE             (SNI_IDPROM_BASE+0x28)  /* Memsize in 16MB quantities */
+#define SNI_IDPROM_BRDTYPE             (SNI_IDPROM_BASE+0x29)  /* Board Type */
+#define SNI_IDPROM_CPUTYPE             (SNI_IDPROM_BASE+0x30)  /* CPU Type */
+
+#define SNI_IDPROM_SIZE        0x1000
+
+#ifdef DEBUG
+static void sni_idprom_dump(void)
+{
+       int     i;
+
+       prom_printf("SNI IDProm dump (first 128byte):\n");
+       for(i=0;i<128;i++) {
+               if (i%16 == 0)
+                       prom_printf("%04x ", i);
+
+               prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE+i));
+
+               if (i%16 == 15)
+                       prom_printf("\n");
+       }
+}
+#endif
+
+static void sni_mem_init(void )
+{
+       int i, memsize;
+       struct membank {
+               u32             size;
+               u32             base;
+               u32             size2;
+               u32             pad1;
+               u32             pad2;
+       } memconf[8];
+
+       /* MemSIZE from prom in 16MByte chunks */
+       memsize=*((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
+
+       DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize);
+
+       /* get memory bank layout from prom */
+       __prom_get_memconf(&memconf);
+
+       DBG_PRINTF("prom_get_mem_conf memory configuration:\n");
+       for(i=0;i<8 && memconf[i].size;i++) {
+               prom_printf("Bank%d: %08x @ %08x\n", i,
+                       memconf[i].size, memconf[i].base);
+               add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
+       }
+}
+
+void __init prom_init(void)
+{
+       int argc = fw_arg0;
+       char **argv = (void *)fw_arg1;
+       unsigned int sni_brd_type = *(unsigned char *) SNI_IDPROM_BRDTYPE;
+       int i;
+
+       DBG_PRINTF("Found SNI brdtype %02x\n", sni_brd_type);
+
+#ifdef DEBUG
+       sni_idprom_dump();
+#endif
+       sni_mem_init();
+
+       /* copy prom cmdline parameters to kernel cmdline */
+       for (i = 1; i < argc; i++) {
+               strcat(arcs_cmdline, argv[i]);
+               if (i < (argc - 1))
+                       strcat(arcs_cmdline, " ");
+       }
+}
+