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>
This commit is contained in:
parent
072a5cff2f
commit
fb1d9be596
@ -54,6 +54,16 @@ struct blackfin_pda { /* Per-processor Data Area */
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct blackfin_initial_pda {
|
||||||
|
void *retx;
|
||||||
|
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
||||||
|
void *dcplb_doublefault_addr;
|
||||||
|
void *icplb_doublefault_addr;
|
||||||
|
void *retx_doublefault;
|
||||||
|
unsigned seqstat_doublefault;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
extern struct blackfin_pda cpu_pda[];
|
extern struct blackfin_pda cpu_pda[];
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
@ -138,6 +138,16 @@ int main(void)
|
|||||||
DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault));
|
DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault));
|
||||||
DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault));
|
DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* PDA initial management */
|
||||||
|
DEFINE(PDA_INIT_RETX, offsetof(struct blackfin_initial_pda, retx));
|
||||||
|
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
||||||
|
DEFINE(PDA_INIT_DF_DCPLB, offsetof(struct blackfin_initial_pda, dcplb_doublefault_addr));
|
||||||
|
DEFINE(PDA_INIT_DF_ICPLB, offsetof(struct blackfin_initial_pda, icplb_doublefault_addr));
|
||||||
|
DEFINE(PDA_INIT_DF_SEQSTAT, offsetof(struct blackfin_initial_pda, seqstat_doublefault));
|
||||||
|
DEFINE(PDA_INIT_DF_RETX, offsetof(struct blackfin_initial_pda, retx_doublefault));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* Inter-core lock (in L2 SRAM) */
|
/* Inter-core lock (in L2 SRAM) */
|
||||||
DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot));
|
DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot));
|
||||||
|
@ -54,8 +54,7 @@ EXPORT_SYMBOL(mtd_size);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
char __initdata command_line[COMMAND_LINE_SIZE];
|
char __initdata command_line[COMMAND_LINE_SIZE];
|
||||||
void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat,
|
struct blackfin_initial_pda __initdata initial_pda;
|
||||||
*init_saved_icplb_fault_addr, *init_saved_dcplb_fault_addr;
|
|
||||||
|
|
||||||
/* boot memmap, for parsing "memmap=" */
|
/* boot memmap, for parsing "memmap=" */
|
||||||
#define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */
|
#define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */
|
||||||
@ -957,13 +956,16 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n");
|
printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n");
|
||||||
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
||||||
/* We assume the crashing kernel, and the current symbol table match */
|
/* We assume the crashing kernel, and the current symbol table match */
|
||||||
printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n",
|
printk(KERN_EMERG " While handling exception (EXCAUSE = %#x) at %pF\n",
|
||||||
(int)init_saved_seqstat & SEQSTAT_EXCAUSE, init_saved_retx);
|
initial_pda.seqstat_doublefault & SEQSTAT_EXCAUSE,
|
||||||
printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr);
|
initial_pda.retx_doublefault);
|
||||||
printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr);
|
printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n",
|
||||||
|
initial_pda.dcplb_doublefault_addr);
|
||||||
|
printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n",
|
||||||
|
initial_pda.icplb_doublefault_addr);
|
||||||
#endif
|
#endif
|
||||||
printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
|
printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
|
||||||
init_retx);
|
initial_pda.retx);
|
||||||
} else if (_bfin_swrst & RESET_WDOG)
|
} else if (_bfin_swrst & RESET_WDOG)
|
||||||
printk(KERN_INFO "Recovering from Watchdog event\n");
|
printk(KERN_INFO "Recovering from Watchdog event\n");
|
||||||
else if (_bfin_swrst & RESET_SOFTWARE)
|
else if (_bfin_swrst & RESET_SOFTWARE)
|
||||||
|
@ -76,37 +76,25 @@ ENTRY(_coreb_trampoline_start)
|
|||||||
SSYNC;
|
SSYNC;
|
||||||
|
|
||||||
/* in case of double faults, save a few things */
|
/* in case of double faults, save a few things */
|
||||||
p0.l = _init_retx_coreb;
|
p1.l = _initial_pda_coreb;
|
||||||
p0.h = _init_retx_coreb;
|
p1.h = _initial_pda_coreb;
|
||||||
R0 = RETX;
|
r4 = RETX;
|
||||||
[P0] = R0;
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
||||||
/* Only save these if we are storing them,
|
/* Only save these if we are storing them,
|
||||||
* This happens here, since L1 gets clobbered
|
* This happens here, since L1 gets clobbered
|
||||||
* below
|
* below
|
||||||
*/
|
*/
|
||||||
GET_PDA(p0, r0);
|
GET_PDA(p0, r0);
|
||||||
r5 = [p0 + PDA_DF_RETX];
|
r0 = [p0 + PDA_DF_RETX];
|
||||||
p1.l = _init_saved_retx_coreb;
|
r1 = [p0 + PDA_DF_DCPLB];
|
||||||
p1.h = _init_saved_retx_coreb;
|
r2 = [p0 + PDA_DF_ICPLB];
|
||||||
[p1] = r5;
|
r3 = [p0 + PDA_DF_SEQSTAT];
|
||||||
|
[p1 + PDA_INIT_DF_RETX] = r0;
|
||||||
r5 = [p0 + PDA_DF_DCPLB];
|
[p1 + PDA_INIT_DF_DCPLB] = r1;
|
||||||
p1.l = _init_saved_dcplb_fault_addr_coreb;
|
[p1 + PDA_INIT_DF_ICPLB] = r2;
|
||||||
p1.h = _init_saved_dcplb_fault_addr_coreb;
|
[p1 + PDA_INIT_DF_SEQSTAT] = r3;
|
||||||
[p1] = r5;
|
|
||||||
|
|
||||||
r5 = [p0 + PDA_DF_ICPLB];
|
|
||||||
p1.l = _init_saved_icplb_fault_addr_coreb;
|
|
||||||
p1.h = _init_saved_icplb_fault_addr_coreb;
|
|
||||||
[p1] = r5;
|
|
||||||
|
|
||||||
r5 = [p0 + PDA_DF_SEQSTAT];
|
|
||||||
p1.l = _init_saved_seqstat_coreb;
|
|
||||||
p1.h = _init_saved_seqstat_coreb;
|
|
||||||
[p1] = r5;
|
|
||||||
#endif
|
#endif
|
||||||
|
[p1 + PDA_INIT_RETX] = r4;
|
||||||
|
|
||||||
/* Initialize stack pointer */
|
/* Initialize stack pointer */
|
||||||
sp.l = lo(INITIAL_STACK);
|
sp.l = lo(INITIAL_STACK);
|
||||||
|
@ -85,37 +85,25 @@ ENTRY(__start)
|
|||||||
SSYNC;
|
SSYNC;
|
||||||
|
|
||||||
/* in case of double faults, save a few things */
|
/* in case of double faults, save a few things */
|
||||||
p0.l = _init_retx;
|
p1.l = _initial_pda;
|
||||||
p0.h = _init_retx;
|
p1.h = _initial_pda;
|
||||||
R0 = RETX;
|
r4 = RETX;
|
||||||
[P0] = R0;
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
||||||
/* Only save these if we are storing them,
|
/* Only save these if we are storing them,
|
||||||
* This happens here, since L1 gets clobbered
|
* This happens here, since L1 gets clobbered
|
||||||
* below
|
* below
|
||||||
*/
|
*/
|
||||||
GET_PDA(p0, r0);
|
GET_PDA(p0, r0);
|
||||||
r5 = [p0 + PDA_DF_RETX];
|
r0 = [p0 + PDA_DF_RETX];
|
||||||
p1.l = _init_saved_retx;
|
r1 = [p0 + PDA_DF_DCPLB];
|
||||||
p1.h = _init_saved_retx;
|
r2 = [p0 + PDA_DF_ICPLB];
|
||||||
[p1] = r5;
|
r3 = [p0 + PDA_DF_SEQSTAT];
|
||||||
|
[p1 + PDA_INIT_DF_RETX] = r0;
|
||||||
r5 = [p0 + PDA_DF_DCPLB];
|
[p1 + PDA_INIT_DF_DCPLB] = r1;
|
||||||
p1.l = _init_saved_dcplb_fault_addr;
|
[p1 + PDA_INIT_DF_ICPLB] = r2;
|
||||||
p1.h = _init_saved_dcplb_fault_addr;
|
[p1 + PDA_INIT_DF_SEQSTAT] = r3;
|
||||||
[p1] = r5;
|
|
||||||
|
|
||||||
r5 = [p0 + PDA_DF_ICPLB];
|
|
||||||
p1.l = _init_saved_icplb_fault_addr;
|
|
||||||
p1.h = _init_saved_icplb_fault_addr;
|
|
||||||
[p1] = r5;
|
|
||||||
|
|
||||||
r5 = [p0 + PDA_DF_SEQSTAT];
|
|
||||||
p1.l = _init_saved_seqstat;
|
|
||||||
p1.h = _init_saved_seqstat;
|
|
||||||
[p1] = r5;
|
|
||||||
#endif
|
#endif
|
||||||
|
[p1 + PDA_INIT_RETX] = r4;
|
||||||
|
|
||||||
/* Initialize stack pointer */
|
/* Initialize stack pointer */
|
||||||
sp.l = _init_thread_union + THREAD_SIZE;
|
sp.l = _init_thread_union + THREAD_SIZE;
|
||||||
|
@ -45,9 +45,7 @@ struct corelock_slot corelock __attribute__ ((__section__(".l2.bss")));
|
|||||||
unsigned long blackfin_iflush_l1_entry[NR_CPUS];
|
unsigned long blackfin_iflush_l1_entry[NR_CPUS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb,
|
struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
|
||||||
*init_saved_seqstat_coreb, *init_saved_icplb_fault_addr_coreb,
|
|
||||||
*init_saved_dcplb_fault_addr_coreb;
|
|
||||||
|
|
||||||
#define BFIN_IPI_RESCHEDULE 0
|
#define BFIN_IPI_RESCHEDULE 0
|
||||||
#define BFIN_IPI_CALL_FUNC 1
|
#define BFIN_IPI_CALL_FUNC 1
|
||||||
@ -369,13 +367,16 @@ void __cpuinit secondary_start_kernel(void)
|
|||||||
if (_bfin_swrst & SWRST_DBL_FAULT_B) {
|
if (_bfin_swrst & SWRST_DBL_FAULT_B) {
|
||||||
printk(KERN_EMERG "CoreB Recovering from DOUBLE FAULT event\n");
|
printk(KERN_EMERG "CoreB Recovering from DOUBLE FAULT event\n");
|
||||||
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
#ifdef CONFIG_DEBUG_DOUBLEFAULT
|
||||||
printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n",
|
printk(KERN_EMERG " While handling exception (EXCAUSE = %#x) at %pF\n",
|
||||||
(int)init_saved_seqstat_coreb & SEQSTAT_EXCAUSE, init_saved_retx_coreb);
|
initial_pda_coreb.seqstat_doublefault & SEQSTAT_EXCAUSE,
|
||||||
printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr_coreb);
|
initial_pda_coreb.retx_doublefault);
|
||||||
printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr_coreb);
|
printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n",
|
||||||
|
initial_pda_coreb.dcplb_doublefault_addr);
|
||||||
|
printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n",
|
||||||
|
initial_pda_coreb.icplb_doublefault_addr);
|
||||||
#endif
|
#endif
|
||||||
printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
|
printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
|
||||||
init_retx_coreb);
|
initial_pda_coreb.retx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user