Commit aefd9461 authored by Guo Ren's avatar Guo Ren
Browse files

csky: Fixup cpu speculative execution to IO area



For the memory size ( > 512MB, < 1GB), the MSA setting is:

 - SSEG0: PHY_START        , PHY_START + 512MB
 - SSEG1: PHY_START + 512MB, PHY_START + 1GB

But the real memory is no more than 1GB, there is a gap between the
end size of memory and border of 1GB. CPU could speculatively
execute to that gap and if the gap of the bus couldn't respond to
the CPU request, then the crash will happen.

Now make the setting with:

 - SSEG0: PHY_START        , PHY_START + 512MB (no change)
 - SSEG1: Disabled (We use highmem to use the memory of 512MB~1GB)

We also deprecated zhole_szie[] settings, it's only used by arm
style CPUs. All memory gap should use Reserved setting of dts in
csky system.

Signed-off-by: default avatarGuo Ren <guoren@linux.alibaba.com>
parent 8f6bb793
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -172,10 +172,7 @@
	addi	r6, 0xe
	cpwcr	r6, cpcr30

	lsri	r6, 28
	addi	r6, 2
	lsli	r6, 28
	addi	r6, 0xe
	movi	r6, 0
	cpwcr	r6, cpcr31
.endm

+2 −5
Original line number Diff line number Diff line
@@ -290,11 +290,8 @@
	addi	r6, 0x1ce
	mtcr	r6, cr<30, 15> /* Set MSA0 */

	lsri	r6, 28
	addi	r6, 2
	lsli	r6, 28
	addi	r6, 0x1ce
	mtcr	r6, cr<31, 15> /* Set MSA1 */
	movi    r6, 0
	mtcr	r6, cr<31, 15> /* Clr MSA1 */

	/* enable MMU */
	mfcr    r6, cr18
+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@ END(_start)
ENTRY(_start_smp_secondary)
	SETUP_MMU

	/* copy msa1 from CPU0 */
	lrw     r6, secondary_msa1
	ld.w	r6, (r6, 0)
	mtcr	r6, cr<31, 15>

	/* set stack point */
	lrw     r6, secondary_stack
	ld.w	r6, (r6, 0)
+14 −49
Original line number Diff line number Diff line
@@ -24,26 +24,9 @@ struct screen_info screen_info = {
};
#endif

phys_addr_t __init_memblock memblock_end_of_REG0(void)
{
	return (memblock.memory.regions[0].base +
		memblock.memory.regions[0].size);
}

phys_addr_t __init_memblock memblock_start_of_REG1(void)
{
	return memblock.memory.regions[1].base;
}

size_t __init_memblock memblock_size_of_REG1(void)
{
	return memblock.memory.regions[1].size;
}

static void __init csky_memblock_init(void)
{
	unsigned long zone_size[MAX_NR_ZONES];
	unsigned long zhole_size[MAX_NR_ZONES];
	signed long size;

	memblock_reserve(__pa(_stext), _end - _stext);
@@ -54,54 +37,36 @@ static void __init csky_memblock_init(void)
	memblock_dump_all();

	memset(zone_size, 0, sizeof(zone_size));
	memset(zhole_size, 0, sizeof(zhole_size));

	min_low_pfn = PFN_UP(memblock_start_of_DRAM());
	max_pfn	    = PFN_DOWN(memblock_end_of_DRAM());

	max_low_pfn = PFN_UP(memblock_end_of_REG0());
	if (max_low_pfn == 0)
		max_low_pfn = max_pfn;
	max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM());

	size = max_pfn - min_low_pfn;

	if (memblock.memory.cnt > 1) {
	if (size <= PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET))
		zone_size[ZONE_NORMAL] = size;
	else if (size < PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) {
		zone_size[ZONE_NORMAL] =
			PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn;
		zhole_size[ZONE_NORMAL] =
			PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn;
				PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET);
		max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
	} else {
		if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET))
			zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn;
		else {
		zone_size[ZONE_NORMAL] =
				PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
		max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
		}
		write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE);
	}

#ifdef CONFIG_HIGHMEM
	size = 0;
	if (memblock.memory.cnt > 1) {
		size = PFN_DOWN(memblock_size_of_REG1());
		highstart_pfn = PFN_DOWN(memblock_start_of_REG1());
	} else {
		size = max_pfn - min_low_pfn -
			PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
		highstart_pfn =  min_low_pfn +
			PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
	}

	if (size > 0)
		zone_size[ZONE_HIGHMEM] = size;
	zone_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;

	highstart_pfn = max_low_pfn;
	highend_pfn   = max_pfn;
#endif
	memblock_set_current_limit(PFN_PHYS(max_low_pfn));

	dma_contiguous_reserve(0);

	free_area_init_node(0, zone_size, min_low_pfn, zhole_size);
	free_area_init_node(0, zone_size, min_low_pfn, NULL);
}

void __init setup_arch(char **cmdline_p)
+3 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ volatile unsigned int secondary_hint;
volatile unsigned int secondary_ccr;
volatile unsigned int secondary_stack;

unsigned long secondary_msa1;

int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
	unsigned long mask = 1 << cpu;
@@ -167,6 +169,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
		(unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8;
	secondary_hint = mfcr("cr31");
	secondary_ccr  = mfcr("cr18");
	secondary_msa1 = read_mmu_msa1();

	/*
	 * Because other CPUs are in reset status, we must flush data