aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/sni/sniprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sni/sniprom.c')
-rw-r--r--arch/mips/sni/sniprom.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
new file mode 100644
index 000000000000..d1d0f1f493b4
--- /dev/null
+++ b/arch/mips/sni/sniprom.c
@@ -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, " ");
+ }
+}
+