aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm47xx/prom.c
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2007-09-25 09:41:24 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-10-11 18:46:06 -0400
commit25e5fb97419f73d39b37e9f73f9492c394de07b2 (patch)
tree42d3ced7426d396fef5a52bc69c20eb4092babf6 /arch/mips/bcm47xx/prom.c
parent2f56cfdd812a17623483d3dfa3370a2e6282b245 (diff)
[MIPS] Add CFE support to BCM47XX
Add CFE support to the BCM47XX code. That includes querying CFE environment variables as well as using CFE to print messages before the serial port is initialized (early printk). Signed-off-by: Aurelien Jarno <aurel32@farad.aurel32.net> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/bcm47xx/prom.c')
-rw-r--r--arch/mips/bcm47xx/prom.c113
1 files changed, 111 insertions, 2 deletions
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index 41ac9dd88bde..079e33d52783 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 2 * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
3 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the 6 * under the terms of the GNU General Public License as published by the
@@ -23,18 +24,117 @@
23 */ 24 */
24 25
25#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/types.h>
28#include <linux/kernel.h>
29#include <linux/spinlock.h>
26#include <asm/bootinfo.h> 30#include <asm/bootinfo.h>
31#include <asm/fw/cfe/cfe_api.h>
32#include <asm/fw/cfe/cfe_error.h>
33
34static int cfe_cons_handle;
27 35
28const char *get_system_type(void) 36const char *get_system_type(void)
29{ 37{
30 return "Broadcom BCM47XX"; 38 return "Broadcom BCM47XX";
31} 39}
32 40
33void __init prom_init(void) 41void prom_putchar(char c)
42{
43 while (cfe_write(cfe_cons_handle, &c, 1) == 0)
44 ;
45}
46
47static __init void prom_init_cfe(void)
48{
49 uint32_t cfe_ept;
50 uint32_t cfe_handle;
51 uint32_t cfe_eptseal;
52 int argc = fw_arg0;
53 char **envp = (char **) fw_arg2;
54 int *prom_vec = (int *) fw_arg3;
55
56 /*
57 * Check if a loader was used; if NOT, the 4 arguments are
58 * what CFE gives us (handle, 0, EPT and EPTSEAL)
59 */
60 if (argc < 0) {
61 cfe_handle = (uint32_t)argc;
62 cfe_ept = (uint32_t)envp;
63 cfe_eptseal = (uint32_t)prom_vec;
64 } else {
65 if ((int)prom_vec < 0) {
66 /*
67 * Old loader; all it gives us is the handle,
68 * so use the "known" entrypoint and assume
69 * the seal.
70 */
71 cfe_handle = (uint32_t)prom_vec;
72 cfe_ept = 0xBFC00500;
73 cfe_eptseal = CFE_EPTSEAL;
74 } else {
75 /*
76 * Newer loaders bundle the handle/ept/eptseal
77 * Note: prom_vec is in the loader's useg
78 * which is still alive in the TLB.
79 */
80 cfe_handle = prom_vec[0];
81 cfe_ept = prom_vec[2];
82 cfe_eptseal = prom_vec[3];
83 }
84 }
85
86 if (cfe_eptseal != CFE_EPTSEAL) {
87 /* too early for panic to do any good */
88 printk(KERN_ERR "CFE's entrypoint seal doesn't match.");
89 while (1) ;
90 }
91
92 cfe_init(cfe_handle, cfe_ept);
93}
94
95static __init void prom_init_console(void)
96{
97 /* Initialize CFE console */
98 cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
99}
100
101static __init void prom_init_cmdline(void)
102{
103 char buf[CL_SIZE];
104
105 /* Get the kernel command line from CFE */
106 if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) {
107 buf[CL_SIZE-1] = 0;
108 strcpy(arcs_cmdline, buf);
109 }
110
111 /* Force a console handover by adding a console= argument if needed,
112 * as CFE is not available anymore later in the boot process. */
113 if ((strstr(arcs_cmdline, "console=")) == NULL) {
114 /* Try to read the default serial port used by CFE */
115 if ((cfe_getenv("BOOT_CONSOLE", buf, CL_SIZE) < 0)
116 || (strncmp("uart", buf, 4)))
117 /* Default to uart0 */
118 strcpy(buf, "uart0");
119
120 /* Compute the new command line */
121 snprintf(arcs_cmdline, CL_SIZE, "%s console=ttyS%c,115200",
122 arcs_cmdline, buf[4]);
123 }
124}
125
126static __init void prom_init_mem(void)
34{ 127{
35 unsigned long mem; 128 unsigned long mem;
36 129
37 /* Figure out memory size by finding aliases */ 130 /* Figure out memory size by finding aliases.
131 *
132 * We should theoretically use the mapping from CFE using cfe_enummem().
133 * However as the BCM47XX is mostly used on low-memory systems, we
134 * want to reuse the memory used by CFE (around 4MB). That means cfe_*
135 * functions stop to work at some point during the boot, we should only
136 * call them at the beginning of the boot.
137 */
38 for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { 138 for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
39 if (*(unsigned long *)((unsigned long)(prom_init) + mem) == 139 if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
40 *(unsigned long *)(prom_init)) 140 *(unsigned long *)(prom_init))
@@ -44,6 +144,15 @@ void __init prom_init(void)
44 add_memory_region(0, mem, BOOT_MEM_RAM); 144 add_memory_region(0, mem, BOOT_MEM_RAM);
45} 145}
46 146
147void __init prom_init(void)
148{
149 prom_init_cfe();
150 prom_init_console();
151 prom_init_cmdline();
152 prom_init_mem();
153}
154
47void __init prom_free_prom_memory(void) 155void __init prom_free_prom_memory(void)
48{ 156{
49} 157}
158