summaryrefslogtreecommitdiff
path: root/target/linux/brcm47xx/patches-2.6.25/800-fix_cfe_detection.patch
blob: 63a71f05f4192c25eda3dd76709c9579f797f77c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -32,6 +32,7 @@
 #include <asm/fw/cfe/cfe_error.h>
 
 static int cfe_cons_handle;
+static void (* __prom_putchar)(char c);
 
 const char *get_system_type(void)
 {
@@ -40,65 +41,40 @@ const char *get_system_type(void)
 
 void prom_putchar(char c)
 {
+	if (__prom_putchar)
+		__prom_putchar(c);
+}
+
+void prom_putchar_cfe(char c)
+{
 	while (cfe_write(cfe_cons_handle, &c, 1) == 0)
 		;
 }
 
-static __init void prom_init_cfe(void)
+static __init int prom_init_cfe(void)
 {
 	uint32_t cfe_ept;
 	uint32_t cfe_handle;
 	uint32_t cfe_eptseal;
-	int argc = fw_arg0;
-	char **envp = (char **) fw_arg2;
-	int *prom_vec = (int *) fw_arg3;
-
-	/*
-	 * Check if a loader was used; if NOT, the 4 arguments are
-	 * what CFE gives us (handle, 0, EPT and EPTSEAL)
-	 */
-	if (argc < 0) {
-		cfe_handle = (uint32_t)argc;
-		cfe_ept = (uint32_t)envp;
-		cfe_eptseal = (uint32_t)prom_vec;
-	} else {
-		if ((int)prom_vec < 0) {
-			/*
-			 * Old loader; all it gives us is the handle,
-			 * so use the "known" entrypoint and assume
-			 * the seal.
-			 */
-			cfe_handle = (uint32_t)prom_vec;
-			cfe_ept = 0xBFC00500;
-			cfe_eptseal = CFE_EPTSEAL;
-		} else {
-			/*
-			 * Newer loaders bundle the handle/ept/eptseal
-			 * Note: prom_vec is in the loader's useg
-			 * which is still alive in the TLB.
-			 */
-			cfe_handle = prom_vec[0];
-			cfe_ept = prom_vec[2];
-			cfe_eptseal = prom_vec[3];
-		}
-	}
 
-	if (cfe_eptseal != CFE_EPTSEAL) {
-		/* too early for panic to do any good */
-		printk(KERN_ERR "CFE's entrypoint seal doesn't match.");
-		while (1) ;
-	}
+	cfe_eptseal = (uint32_t) fw_arg3;
+	cfe_handle = (uint32_t) fw_arg0;
+	cfe_ept = (uint32_t) fw_arg2;
+
+	if (cfe_eptseal != CFE_EPTSEAL)
+		return -1;
 
 	cfe_init(cfe_handle, cfe_ept);
+	return 0;
 }
 
-static __init void prom_init_console(void)
+static __init void prom_init_console_cfe(void)
 {
 	/* Initialize CFE console */
 	cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
 }
 
-static __init void prom_init_cmdline(void)
+static __init void prom_init_cmdline_cfe(void)
 {
 	char buf[CL_SIZE];
 
@@ -146,9 +122,12 @@ static __init void prom_init_mem(void)
 
 void __init prom_init(void)
 {
-	prom_init_cfe();
-	prom_init_console();
-	prom_init_cmdline();
+	if (prom_init_cfe() == 0) {
+		prom_init_console_cfe();
+		prom_init_cmdline_cfe();
+		__prom_putchar = prom_putchar_cfe;
+	}
+
 	prom_init_mem();
 }