Skip to content

Commit

Permalink
[MIPS] Fix shadow register support.
Browse files Browse the repository at this point in the history
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: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
ralfbaechle committed Nov 15, 2007
1 parent efb9ca0 commit f6771db
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 74 deletions.
9 changes: 0 additions & 9 deletions arch/mips/Kconfig
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions arch/mips/kernel/cpu-probe.c
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/kernel/proc.c
Expand Up @@ -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");
Expand Down
68 changes: 3 additions & 65 deletions arch/mips/kernel/traps.c
Expand Up @@ -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());
Expand All @@ -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;

Expand All @@ -1178,15 +1126,15 @@ 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) {
if (board_bind_eic_interrupt)
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);
}

Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -1503,8 +1443,6 @@ void __init trap_init(void)
else
ebase = CAC_BASE;

mips_srs_init();

per_cpu_trap_init();

/*
Expand Down
1 change: 1 addition & 0 deletions include/asm-mips/cpu-info.h
Expand Up @@ -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
Expand Down

0 comments on commit f6771db

Please sign in to comment.