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

Commit f6771dbb authored by Ralf Baechle's avatar Ralf Baechle
Browse files

[MIPS] Fix shadow register support.



Shadow register support would not possibly have worked on multicore
systems.  The support code for it was also depending not on MIPS R2 but
VSMP or SMTC kernels even though it makes perfect sense with UP kernels.

SR sets are a scarce resource and the expected usage pattern is that
users actually hardcode the register set numbers in their code.  So fix
the allocator by ditching it.  Move the remaining CPU probe bits into
the generic CPU probe.

Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent efb9ca08
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -1409,7 +1409,6 @@ config MIPS_MT_SMP
	depends on SYS_SUPPORTS_MULTITHREADING
	select CPU_MIPSR2_IRQ_VI
	select CPU_MIPSR2_IRQ_EI
	select CPU_MIPSR2_SRS
	select MIPS_MT
	select NR_CPUS_DEFAULT_2
	select SMP
@@ -1426,7 +1425,6 @@ config MIPS_MT_SMTC
	select GENERIC_CLOCKEVENTS_BROADCAST
	select CPU_MIPSR2_IRQ_VI
	select CPU_MIPSR2_IRQ_EI
	select CPU_MIPSR2_SRS
	select MIPS_MT
	select NR_CPUS_DEFAULT_8
	select SMP
@@ -1453,7 +1451,6 @@ config MIPS_VPE_LOADER
	depends on SYS_SUPPORTS_MULTITHREADING
	select CPU_MIPSR2_IRQ_VI
	select CPU_MIPSR2_IRQ_EI
	select CPU_MIPSR2_SRS
	select MIPS_MT
	help
	  Includes a loader for loading an elf relocatable object
@@ -1582,12 +1579,6 @@ config CPU_MIPSR2_IRQ_VI
config CPU_MIPSR2_IRQ_EI
	bool

#
# Shadow registers are an R2 feature
#
config CPU_MIPSR2_SRS
	bool

config CPU_HAS_SYNC
	bool
	depends on !CPU_R3000
+5 −0
Original line number Diff line number Diff line
@@ -943,6 +943,11 @@ __init void cpu_probe(void)
	}

	__cpu_name[cpu] = cpu_to_name(c);

	if (cpu_has_mips_r2)
		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
	else
		c->srsets = 1;
}

__init void cpu_report(void)
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
		      cpu_has_dsp ? " dsp" : "",
		      cpu_has_mipsmt ? " mt" : ""
		);
	seq_printf(m, "shadow register sets\t: %d\n",
		       cpu_data[n].srsets);

	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
	        cpu_has_vce ? "%u" : "not available");
+3 −65
Original line number Diff line number Diff line
@@ -1100,59 +1100,6 @@ void *set_except_vector(int n, void *addr)
	return (void *)old_handler;
}

#ifdef CONFIG_CPU_MIPSR2_SRS
/*
 * MIPSR2 shadow register set allocation
 * FIXME: SMP...
 */

static struct shadow_registers {
	/*
	 * Number of shadow register sets supported
	 */
	unsigned long sr_supported;
	/*
	 * Bitmap of allocated shadow registers
	 */
	unsigned long sr_allocated;
} shadow_registers;

static void mips_srs_init(void)
{
	shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
	printk(KERN_INFO "%ld MIPSR2 register sets available\n",
	       shadow_registers.sr_supported);
	shadow_registers.sr_allocated = 1;	/* Set 0 used by kernel */
}

int mips_srs_max(void)
{
	return shadow_registers.sr_supported;
}

int mips_srs_alloc(void)
{
	struct shadow_registers *sr = &shadow_registers;
	int set;

again:
	set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported);
	if (set >= sr->sr_supported)
		return -1;

	if (test_and_set_bit(set, &sr->sr_allocated))
		goto again;

	return set;
}

void mips_srs_free(int set)
{
	struct shadow_registers *sr = &shadow_registers;

	clear_bit(set, &sr->sr_allocated);
}

static asmlinkage void do_default_vi(void)
{
	show_regs(get_irq_regs());
@@ -1163,6 +1110,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
{
	unsigned long handler;
	unsigned long old_handler = vi_handlers[n];
	int srssets = current_cpu_data.srsets;
	u32 *w;
	unsigned char *b;

@@ -1178,7 +1126,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)

	b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);

	if (srs >= mips_srs_max())
	if (srs >= srssets)
		panic("Shadow register set %d not supported", srs);

	if (cpu_has_veic) {
@@ -1186,7 +1134,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
			board_bind_eic_interrupt(n, srs);
	} else if (cpu_has_vint) {
		/* SRSMap is only defined if shadow sets are implemented */
		if (mips_srs_max() > 1)
		if (srssets > 1)
			change_c0_srsmap(0xf << n*4, srs << n*4);
	}

@@ -1253,14 +1201,6 @@ void *set_vi_handler(int n, vi_handler_t addr)
	return set_vi_srs_handler(n, addr, 0);
}

#else

static inline void mips_srs_init(void)
{
}

#endif /* CONFIG_CPU_MIPSR2_SRS */

/*
 * This is used by native signal handling
 */
@@ -1503,8 +1443,6 @@ void __init trap_init(void)
	else
		ebase = CAC_BASE;

	mips_srs_init();

	per_cpu_trap_init();

	/*
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ struct cpuinfo_mips {
	struct cache_desc	dcache;	/* Primary D or combined I/D cache */
	struct cache_desc	scache;	/* Secondary cache */
	struct cache_desc	tcache;	/* Tertiary/split secondary cache */
	int			srsets;	/* Shadow register sets */
#if defined(CONFIG_MIPS_MT_SMTC)
	/*
	 * In the MIPS MT "SMTC" model, each TC is considered