diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-05-29 23:12:51 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2011-07-23 01:10:43 -0400 |
commit | fb1d9be5967fff0a3c93b06304fd992e3c438b7f (patch) | |
tree | 0c1c8a2fe6ad2b9c52bdc4a58e0f396058dc75c3 | |
parent | 072a5cff2fcaa4648c98bea6d549fac7ee4174fe (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.h | 10 | ||||
-rw-r--r-- | arch/blackfin/kernel/asm-offsets.c | 10 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 16 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/secondary.S | 36 | ||||
-rw-r--r-- | arch/blackfin/mach-common/head.S | 36 | ||||
-rw-r--r-- | arch/blackfin/mach-common/smp.c | 17 |
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 | ||
57 | struct 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 | |||
57 | extern struct blackfin_pda cpu_pda[]; | 67 | extern 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 | ||
56 | char __initdata command_line[COMMAND_LINE_SIZE]; | 56 | char __initdata command_line[COMMAND_LINE_SIZE]; |
57 | void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, | 57 | struct 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"))); | |||
45 | unsigned long blackfin_iflush_l1_entry[NR_CPUS]; | 45 | unsigned long blackfin_iflush_l1_entry[NR_CPUS]; |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, | 48 | struct 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 | /* |