aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-05-29 23:12:51 -0400
committerMike Frysinger <vapier@gentoo.org>2011-07-23 01:10:43 -0400
commitfb1d9be5967fff0a3c93b06304fd992e3c438b7f (patch)
tree0c1c8a2fe6ad2b9c52bdc4a58e0f396058dc75c3
parent072a5cff2fcaa4648c98bea6d549fac7ee4174fe (diff)
Blackfin: optimize double fault boot checking
This moves the double fault data used at boot time into a single struct which can then easily be addressed with indexed loads rather than having to explicitly load multiple addresses. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--arch/blackfin/include/asm/pda.h10
-rw-r--r--arch/blackfin/kernel/asm-offsets.c10
-rw-r--r--arch/blackfin/kernel/setup.c16
-rw-r--r--arch/blackfin/mach-bf561/secondary.S36
-rw-r--r--arch/blackfin/mach-common/head.S36
-rw-r--r--arch/blackfin/mach-common/smp.c17
6 files changed, 62 insertions, 63 deletions
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h
index d49bb261d9b7..28c2498c9c98 100644
--- a/arch/blackfin/include/asm/pda.h
+++ b/arch/blackfin/include/asm/pda.h
@@ -54,6 +54,16 @@ struct blackfin_pda { /* Per-processor Data Area */
54#endif 54#endif
55}; 55};
56 56
57struct blackfin_initial_pda {
58 void *retx;
59#ifdef CONFIG_DEBUG_DOUBLEFAULT
60 void *dcplb_doublefault_addr;
61 void *icplb_doublefault_addr;
62 void *retx_doublefault;
63 unsigned seqstat_doublefault;
64#endif
65};
66
57extern struct blackfin_pda cpu_pda[]; 67extern struct blackfin_pda cpu_pda[];
58 68
59#endif /* __ASSEMBLY__ */ 69#endif /* __ASSEMBLY__ */
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index bd32c09b9349..17e35465a416 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -138,6 +138,16 @@ int main(void)
138 DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault)); 138 DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault));
139 DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault)); 139 DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault));
140#endif 140#endif
141
142 /* PDA initial management */
143 DEFINE(PDA_INIT_RETX, offsetof(struct blackfin_initial_pda, retx));
144#ifdef CONFIG_DEBUG_DOUBLEFAULT
145 DEFINE(PDA_INIT_DF_DCPLB, offsetof(struct blackfin_initial_pda, dcplb_doublefault_addr));
146 DEFINE(PDA_INIT_DF_ICPLB, offsetof(struct blackfin_initial_pda, icplb_doublefault_addr));
147 DEFINE(PDA_INIT_DF_SEQSTAT, offsetof(struct blackfin_initial_pda, seqstat_doublefault));
148 DEFINE(PDA_INIT_DF_RETX, offsetof(struct blackfin_initial_pda, retx_doublefault));
149#endif
150
141#ifdef CONFIG_SMP 151#ifdef CONFIG_SMP
142 /* Inter-core lock (in L2 SRAM) */ 152 /* Inter-core lock (in L2 SRAM) */
143 DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot)); 153 DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot));
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 536bd9d7e0cf..dfa2525a442d 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -54,8 +54,7 @@ EXPORT_SYMBOL(mtd_size);
54#endif 54#endif
55 55
56char __initdata command_line[COMMAND_LINE_SIZE]; 56char __initdata command_line[COMMAND_LINE_SIZE];
57void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, 57struct blackfin_initial_pda __initdata initial_pda;
58 *init_saved_icplb_fault_addr, *init_saved_dcplb_fault_addr;
59 58
60/* boot memmap, for parsing "memmap=" */ 59/* boot memmap, for parsing "memmap=" */
61#define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ 60#define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */
@@ -957,13 +956,16 @@ void __init setup_arch(char **cmdline_p)
957 printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n"); 956 printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n");
958#ifdef CONFIG_DEBUG_DOUBLEFAULT 957#ifdef CONFIG_DEBUG_DOUBLEFAULT
959 /* We assume the crashing kernel, and the current symbol table match */ 958 /* We assume the crashing kernel, and the current symbol table match */
960 printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n", 959 printk(KERN_EMERG " While handling exception (EXCAUSE = %#x) at %pF\n",
961 (int)init_saved_seqstat & SEQSTAT_EXCAUSE, init_saved_retx); 960 initial_pda.seqstat_doublefault & SEQSTAT_EXCAUSE,
962 printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr); 961 initial_pda.retx_doublefault);
963 printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr); 962 printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n",
963 initial_pda.dcplb_doublefault_addr);
964 printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n",
965 initial_pda.icplb_doublefault_addr);
964#endif 966#endif
965 printk(KERN_NOTICE " The instruction at %pF caused a double exception\n", 967 printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
966 init_retx); 968 initial_pda.retx);
967 } else if (_bfin_swrst & RESET_WDOG) 969 } else if (_bfin_swrst & RESET_WDOG)
968 printk(KERN_INFO "Recovering from Watchdog event\n"); 970 printk(KERN_INFO "Recovering from Watchdog event\n");
969 else if (_bfin_swrst & RESET_SOFTWARE) 971 else if (_bfin_swrst & RESET_SOFTWARE)
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index 348c9191d19f..01e5408620ac 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -76,37 +76,25 @@ ENTRY(_coreb_trampoline_start)
76 SSYNC; 76 SSYNC;
77 77
78 /* in case of double faults, save a few things */ 78 /* in case of double faults, save a few things */
79 p0.l = _init_retx_coreb; 79 p1.l = _initial_pda_coreb;
80 p0.h = _init_retx_coreb; 80 p1.h = _initial_pda_coreb;
81 R0 = RETX; 81 r4 = RETX;
82 [P0] = R0;
83
84#ifdef CONFIG_DEBUG_DOUBLEFAULT 82#ifdef CONFIG_DEBUG_DOUBLEFAULT
85 /* Only save these if we are storing them, 83 /* Only save these if we are storing them,
86 * This happens here, since L1 gets clobbered 84 * This happens here, since L1 gets clobbered
87 * below 85 * below
88 */ 86 */
89 GET_PDA(p0, r0); 87 GET_PDA(p0, r0);
90 r5 = [p0 + PDA_DF_RETX]; 88 r0 = [p0 + PDA_DF_RETX];
91 p1.l = _init_saved_retx_coreb; 89 r1 = [p0 + PDA_DF_DCPLB];
92 p1.h = _init_saved_retx_coreb; 90 r2 = [p0 + PDA_DF_ICPLB];
93 [p1] = r5; 91 r3 = [p0 + PDA_DF_SEQSTAT];
94 92 [p1 + PDA_INIT_DF_RETX] = r0;
95 r5 = [p0 + PDA_DF_DCPLB]; 93 [p1 + PDA_INIT_DF_DCPLB] = r1;
96 p1.l = _init_saved_dcplb_fault_addr_coreb; 94 [p1 + PDA_INIT_DF_ICPLB] = r2;
97 p1.h = _init_saved_dcplb_fault_addr_coreb; 95 [p1 + PDA_INIT_DF_SEQSTAT] = r3;
98 [p1] = r5;
99
100 r5 = [p0 + PDA_DF_ICPLB];
101 p1.l = _init_saved_icplb_fault_addr_coreb;
102 p1.h = _init_saved_icplb_fault_addr_coreb;
103 [p1] = r5;
104
105 r5 = [p0 + PDA_DF_SEQSTAT];
106 p1.l = _init_saved_seqstat_coreb;
107 p1.h = _init_saved_seqstat_coreb;
108 [p1] = r5;
109#endif 96#endif
97 [p1 + PDA_INIT_RETX] = r4;
110 98
111 /* Initialize stack pointer */ 99 /* Initialize stack pointer */
112 sp.l = lo(INITIAL_STACK); 100 sp.l = lo(INITIAL_STACK);
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index 76de5724c1e3..8b4d98854403 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -85,37 +85,25 @@ ENTRY(__start)
85 SSYNC; 85 SSYNC;
86 86
87 /* in case of double faults, save a few things */ 87 /* in case of double faults, save a few things */
88 p0.l = _init_retx; 88 p1.l = _initial_pda;
89 p0.h = _init_retx; 89 p1.h = _initial_pda;
90 R0 = RETX; 90 r4 = RETX;
91 [P0] = R0;
92
93#ifdef CONFIG_DEBUG_DOUBLEFAULT 91#ifdef CONFIG_DEBUG_DOUBLEFAULT
94 /* Only save these if we are storing them, 92 /* Only save these if we are storing them,
95 * This happens here, since L1 gets clobbered 93 * This happens here, since L1 gets clobbered
96 * below 94 * below
97 */ 95 */
98 GET_PDA(p0, r0); 96 GET_PDA(p0, r0);
99 r5 = [p0 + PDA_DF_RETX]; 97 r0 = [p0 + PDA_DF_RETX];
100 p1.l = _init_saved_retx; 98 r1 = [p0 + PDA_DF_DCPLB];
101 p1.h = _init_saved_retx; 99 r2 = [p0 + PDA_DF_ICPLB];
102 [p1] = r5; 100 r3 = [p0 + PDA_DF_SEQSTAT];
103 101 [p1 + PDA_INIT_DF_RETX] = r0;
104 r5 = [p0 + PDA_DF_DCPLB]; 102 [p1 + PDA_INIT_DF_DCPLB] = r1;
105 p1.l = _init_saved_dcplb_fault_addr; 103 [p1 + PDA_INIT_DF_ICPLB] = r2;
106 p1.h = _init_saved_dcplb_fault_addr; 104 [p1 + PDA_INIT_DF_SEQSTAT] = r3;
107 [p1] = r5;
108
109 r5 = [p0 + PDA_DF_ICPLB];
110 p1.l = _init_saved_icplb_fault_addr;
111 p1.h = _init_saved_icplb_fault_addr;
112 [p1] = r5;
113
114 r5 = [p0 + PDA_DF_SEQSTAT];
115 p1.l = _init_saved_seqstat;
116 p1.h = _init_saved_seqstat;
117 [p1] = r5;
118#endif 105#endif
106 [p1 + PDA_INIT_RETX] = r4;
119 107
120 /* Initialize stack pointer */ 108 /* Initialize stack pointer */
121 sp.l = _init_thread_union + THREAD_SIZE; 109 sp.l = _init_thread_union + THREAD_SIZE;
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 35e7e1eb0188..1c143a4de5f5 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -45,9 +45,7 @@ struct corelock_slot corelock __attribute__ ((__section__(".l2.bss")));
45unsigned long blackfin_iflush_l1_entry[NR_CPUS]; 45unsigned long blackfin_iflush_l1_entry[NR_CPUS];
46#endif 46#endif
47 47
48void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, 48struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
49 *init_saved_seqstat_coreb, *init_saved_icplb_fault_addr_coreb,
50 *init_saved_dcplb_fault_addr_coreb;
51 49
52#define BFIN_IPI_RESCHEDULE 0 50#define BFIN_IPI_RESCHEDULE 0
53#define BFIN_IPI_CALL_FUNC 1 51#define BFIN_IPI_CALL_FUNC 1
@@ -369,13 +367,16 @@ void __cpuinit secondary_start_kernel(void)
369 if (_bfin_swrst & SWRST_DBL_FAULT_B) { 367 if (_bfin_swrst & SWRST_DBL_FAULT_B) {
370 printk(KERN_EMERG "CoreB Recovering from DOUBLE FAULT event\n"); 368 printk(KERN_EMERG "CoreB Recovering from DOUBLE FAULT event\n");
371#ifdef CONFIG_DEBUG_DOUBLEFAULT 369#ifdef CONFIG_DEBUG_DOUBLEFAULT
372 printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n", 370 printk(KERN_EMERG " While handling exception (EXCAUSE = %#x) at %pF\n",
373 (int)init_saved_seqstat_coreb & SEQSTAT_EXCAUSE, init_saved_retx_coreb); 371 initial_pda_coreb.seqstat_doublefault & SEQSTAT_EXCAUSE,
374 printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr_coreb); 372 initial_pda_coreb.retx_doublefault);
375 printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr_coreb); 373 printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n",
374 initial_pda_coreb.dcplb_doublefault_addr);
375 printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n",
376 initial_pda_coreb.icplb_doublefault_addr);
376#endif 377#endif
377 printk(KERN_NOTICE " The instruction at %pF caused a double exception\n", 378 printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
378 init_retx_coreb); 379 initial_pda_coreb.retx);
379 } 380 }
380 381
381 /* 382 /*