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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
From 159aad211bf918f2b582f8a12622bf02fb7dd64f Mon Sep 17 00:00:00 2001
From: Jerry Pei <jerry.pei@enea.com>
Date: Mon, 23 Apr 2012 14:20:03 +0800
Subject: [PATCH 2/7] Patch to head_44x.S to support lsi acp3448v2
Signed-off-by: Jerry Pei <jerry.pei@enea.com>
---
arch/powerpc/kernel/head_44x.S | 130 ++++++++++++++++++++++++++++++++++++---
1 files changed, 120 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 5e12b74..ac8d20e 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -26,6 +26,8 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
+ *
+ * These patches add ACP3400 support signed-off-by: john.jacques@lsi.com
*/
#include <linux/init.h>
@@ -41,6 +43,8 @@
#include <asm/synch.h>
#include "head_booke.h"
+#undef TLBERRORCOUNTER
+/*#define TLBERRORCOUNTER*/
/* As with the other PowerPC ports, it is expected that when code
* execution begins here, the following registers contain valid, yet
@@ -93,6 +97,30 @@ _ENTRY(_start);
bl early_init
+#ifdef CONFIG_RELOCATABLE
+ /*
+ * r25 will contain RPN/ERPN for the start address of memory
+ *
+ * Add the difference between KERNELBASE and PAGE_OFFSET to the
+ * start of physical memory to get kernstart_addr.
+ */
+ lis r3,kernstart_addr@ha
+ la r3,kernstart_addr@l(r3)
+
+ lis r4,KERNELBASE@h
+ ori r4,r4,KERNELBASE@l
+ lis r5,PAGE_OFFSET@h
+ ori r5,r5,PAGE_OFFSET@l
+ subf r4,r5,r4
+
+ rlwinm r6,r25,0,28,31 /* ERPN */
+ rlwinm r7,r25,0,0,3 /* RPN - assuming 256 MB page size */
+ add r7,r7,r4
+
+ stw r6,0(r3)
+ stw r7,4(r3)
+#endif
+
/*
* Decide what sort of machine this is and initialize the MMU.
*/
@@ -449,6 +477,15 @@ finish_tlb_load_44x:
mtspr SPRN_SPRG_WSCRATCH1,r11
mtspr SPRN_SPRG_WSCRATCH2,r12
mtspr SPRN_SPRG_WSCRATCH3,r13
+ /* ZZZ */
+#ifdef TLBERRORCOUNTER
+ lis r10,dtlb_misses@h
+ ori r10,r10,dtlb_misses@l
+ lwzu r11,0(r10)
+ addi r11,r11,1
+ stwu r11,0(r10)
+#endif
+ /* ZZZ */
mfcr r11
mtspr SPRN_SPRG_WSCRATCH4,r11
mfspr r10,SPRN_DEAR /* Get faulting address */
@@ -546,6 +583,15 @@ finish_tlb_load_44x:
mtspr SPRN_SPRG_WSCRATCH1,r11
mtspr SPRN_SPRG_WSCRATCH2,r12
mtspr SPRN_SPRG_WSCRATCH3,r13
+ /* ZZZ */
+#ifdef TLBERRORCOUNTER
+ lis r10,itlb_misses@h
+ ori r10,r10,itlb_misses@l
+ lwzu r11,0(r10)
+ addi r11,r11,1
+ stwu r11,0(r10)
+#endif
+ /* ZZZ */
mfcr r11
mtspr SPRN_SPRG_WSCRATCH4,r11
mfspr r10,SPRN_SRR0 /* Get faulting address */
@@ -704,6 +750,7 @@ _GLOBAL(set_context)
stw r4, 0x4(r5)
#endif
mtspr SPRN_PID,r3
+ PPC476_ERR_MTPID()
isync /* Force context change */
blr
@@ -718,9 +765,12 @@ _GLOBAL(init_cpu_state)
/* We use the PVR to differenciate 44x cores from 476 */
mfspr r3,SPRN_PVR
srwi r3,r3,16
- cmplwi cr0,r3,PVR_476@h
+ cmplwi cr0,r3,PVR_476X2@h /* some x2 had a non-standard PVR */
beq head_start_47x
- cmplwi cr0,r3,PVR_476_ISS@h
+
+ /* All other 476 cores have a 0x5 as the 4th nibble */
+ rlwinm r3,r3,0,28,31
+ cmplwi cr0,r3,PVR_476@h
beq head_start_47x
#endif /* CONFIG_PPC_47x */
@@ -1001,9 +1051,6 @@ clear_utlb_entry:
lis r3,PAGE_OFFSET@h
ori r3,r3,PAGE_OFFSET@l
- /* Kernel is at the base of RAM */
- li r4, 0 /* Load the kernel physical address */
-
/* Load the kernel PID = 0 */
li r0,0
mtspr SPRN_PID,r0
@@ -1013,9 +1060,8 @@ clear_utlb_entry:
clrrwi r3,r3,12 /* Mask off the effective page number */
ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M
- /* Word 1 */
- clrrwi r4,r4,12 /* Mask off the real page number */
- /* ERPN is 0 for first 4GB page */
+ /* Word 1 - use r25. RPN is the same as the original entry */
+
/* Word 2 */
li r5,0
ori r5,r5,PPC47x_TLB2_S_RWX
@@ -1026,7 +1072,7 @@ clear_utlb_entry:
/* We write to way 0 and bolted 0 */
lis r0,0x8800
tlbwe r3,r0,0
- tlbwe r4,r0,1
+ tlbwe r25,r0,1
tlbwe r5,r0,2
/*
@@ -1057,6 +1103,7 @@ clear_utlb_entry:
tlbwe r24,r23,2
isync /* Clear out the shadow TLB entries */
+#ifndef CONFIG_ACP
#ifdef CONFIG_PPC_EARLY_DEBUG_44x
/* Add UART mapping for early debug. */
@@ -1083,6 +1130,54 @@ clear_utlb_entry:
/* Force context change */
isync
#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
+#endif /* CONFIG_ACP */
+
+#ifdef CONFIG_ACP
+ /* Add bolted entries for I/O. */
+
+ /* Word 0 */
+ lis r3,(0xf0000000)@h
+ ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_1M
+
+ /* Word 1 */
+ lis r4,(0x00400000)@h
+ ori r4,r4,0x20
+
+ /* Word 2 */
+ li r5,(PPC47x_TLB2_SW | PPC47x_TLB2_SR | PPC47x_TLB2_I | PPC47x_TLB2_G)
+
+ /* Bolted in way 0, bolt slot 4, we -hope- we don't hit the same
+ * congruence class as the kernel, we need to make sure of it at
+ * some point
+ */
+ lis r0,0x8d00
+ tlbwe r3,r0,0
+ tlbwe r4,r0,1
+ tlbwe r5,r0,2
+
+ /* Word 0 */
+ lis r3,(0xf0100000)@h
+ ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_1M
+
+ /* Word 1 */
+ lis r4,(0x00500000)@h
+ ori r4,r4,0x20
+
+ /* Word 2 */
+ li r5,(PPC47x_TLB2_SW | PPC47x_TLB2_SR | PPC47x_TLB2_I | PPC47x_TLB2_G)
+
+ /* Bolted in way 0, bolt slot 4, we -hope- we don't hit the same
+ * congruence class as the kernel, we need to make sure of it at
+ * some point
+ */
+ lis r0,0x8c00
+ tlbwe r3,r0,0
+ tlbwe r4,r0,1
+ tlbwe r5,r0,2
+
+ /* Force context change */
+ isync
+#endif /* CONFIG_ACP */
/* Establish the interrupt vector offsets */
SET_IVOR(0, CriticalInput);
@@ -1111,6 +1206,15 @@ clear_utlb_entry:
mtspr SPRN_CCR0,r3
isync
+ /* XXX DD1.1 workaround, trap on dcbz & dcbf. We pre-configure
+ * IOCR1 and 2 but we don't enable them in IOCCR, this will
+ * be done on kernel entry/exit
+ */
+ LOAD_REG_IMMEDIATE(r3, (31 << 26) | ( 86 << 1)) /* dcbf */
+ LOAD_REG_IMMEDIATE(r4, (31 << 26) | (1014 << 1)) /* dcbz */
+ mtspr SPRN_IOCR1, r3
+ mtspr SPRN_IOCR2, r4
+
#endif /* CONFIG_PPC_47x */
/*
@@ -1124,7 +1228,13 @@ head_start_common:
lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
mtspr SPRN_IVPR,r4
- addis r22,r22,KERNELBASE@h
+ /*
+ * If the kernel was loaded at a non-zero 256 MB page, we need to
+ * mask off the most significant 4 bits to get the relative address
+ * from the start of physical memory
+ */
+ rlwinm r22,r22,0,4,31
+ addis r22,r22,PAGE_OFFSET@h
mtlr r22
isync
blr
--
1.7.0.4
|