Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6345ab1 authored by Sonic Zhang's avatar Sonic Zhang Committed by Mike Frysinger
Browse files

Blackfin: SMP: work around anomaly 05000491



In order to safely work around anomaly 05000491, we have to execute IFLUSH
from L1 instruction sram.  The trouble with multi-core systems is that all
L1 sram is visible only to the active core.  So we can't just place the
functions into L1 and call it directly.  We need to setup a jump table and
place the entry point in external memory.  This will call the right func
based on the active core.

In the process, convert from the manual relocation of a small bit of code
into Core B's L1 to the more general framework we already have in place
for loading arbitrary pieces of code into L1.

Signed-off-by: default avatarSonic Zhang <sonic.zhang@analog.com>
Signed-off-by: default avatarMike Frysinger <vapier@gentoo.org>
parent 6f546bc3
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -850,7 +850,6 @@ config CPLB_SWITCH_TAB_L1
config ICACHE_FLUSH_L1
	bool "Locate icache flush funcs in L1 Inst Memory"
	default y
	depends on !SMP
	help
	  If enabled, the Blackfin icache flushing functions are linked
	  into L1 instruction memory.
+6 −1
Original line number Diff line number Diff line
@@ -17,7 +17,12 @@

#define raw_smp_processor_id()  blackfin_core_id()

extern char coreb_trampoline_start, coreb_trampoline_end;
extern void bfin_relocate_coreb_l1_mem(void);

#if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1)
asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr);
extern unsigned long blackfin_iflush_l1_entry[NR_CPUS];
#endif

struct corelock_slot {
	int lock;
+37 −0
Original line number Diff line number Diff line
@@ -215,11 +215,48 @@ void __init bfin_relocate_l1_mem(void)

	early_dma_memcpy_done();

#if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1)
	blackfin_iflush_l1_entry[0] = (unsigned long)blackfin_icache_flush_range_l1;
#endif

	/* if necessary, copy L2 text/data to L2 SRAM */
	if (L2_LENGTH && l2_len)
		memcpy(_stext_l2, _l2_lma, l2_len);
}

#ifdef CONFIG_SMP
void __init bfin_relocate_coreb_l1_mem(void)
{
	unsigned long text_l1_len = (unsigned long)_text_l1_len;
	unsigned long data_l1_len = (unsigned long)_data_l1_len;
	unsigned long data_b_l1_len = (unsigned long)_data_b_l1_len;

	blackfin_dma_early_init();

	/* if necessary, copy L1 text to L1 instruction SRAM */
	if (L1_CODE_LENGTH && text_l1_len)
		early_dma_memcpy((void *)COREB_L1_CODE_START, _text_l1_lma,
				text_l1_len);

	/* if necessary, copy L1 data to L1 data bank A SRAM */
	if (L1_DATA_A_LENGTH && data_l1_len)
		early_dma_memcpy((void *)COREB_L1_DATA_A_START, _data_l1_lma,
				data_l1_len);

	/* if necessary, copy L1 data B to L1 data bank B SRAM */
	if (L1_DATA_B_LENGTH && data_b_l1_len)
		early_dma_memcpy((void *)COREB_L1_DATA_B_START, _data_b_l1_lma,
				data_b_l1_len);

	early_dma_memcpy_done();

#ifdef CONFIG_ICACHE_FLUSH_L1
	blackfin_iflush_l1_entry[1] = (unsigned long)blackfin_icache_flush_range_l1 -
			(unsigned long)_stext_l1 + COREB_L1_CODE_START;
#endif
}
#endif

#ifdef CONFIG_ROMKERNEL
void __init bfin_relocate_xip_data(void)
{
+1 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ SECTIONS
	{
		. = ALIGN(4);
		__stext_l1 = .;
		*(.l1.text.head)
		*(.l1.text)
#ifdef CONFIG_SCHEDULE_L1
		SCHED_TEXT
+5 −2
Original line number Diff line number Diff line
@@ -13,7 +13,11 @@
#include <asm/asm-offsets.h>
#include <asm/trace.h>

__INIT
/*
 * This code must come first as CoreB is hardcoded (in hardware)
 * to start at the beginning of its L1 instruction memory.
 */
.section .l1.text.head

/* Lay the initial stack into the L1 scratch area of Core B */
#define INITIAL_STACK	(COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
@@ -160,7 +164,6 @@ ENTRY(_coreb_trampoline_start)
.LWAIT_HERE:
	jump .LWAIT_HERE;
ENDPROC(_coreb_trampoline_start)
ENTRY(_coreb_trampoline_end)

#ifdef CONFIG_HOTPLUG_CPU
.section ".text"
Loading