sparc32: add support for run-time patching of leon/sun single instructions

This will be used to handle that MMUREGS has different ASI for SUN and LEON.
This is the infrastructure only - users will come later.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Daniel Hellstrom <daniel@gaisler.com>
Cc: Konrad Eisele <konrad@gaisler.com>
This commit is contained in:
Sam Ravnborg
2012-05-25 21:20:09 +00:00
committed by David S. Miller
parent 4efb55e691
commit 5b8b93c4ab
4 changed files with 72 additions and 16 deletions

View File

@@ -46,6 +46,7 @@
#include <asm/cpudata.h>
#include <asm/setup.h>
#include <asm/cacheflush.h>
#include <asm/sections.h>
#include "kernel.h"
@@ -238,11 +239,34 @@ static void __init per_cpu_patch(void)
}
}
struct leon_1insn_patch_entry {
unsigned int addr;
unsigned int insn;
};
enum sparc_cpu sparc_cpu_model;
EXPORT_SYMBOL(sparc_cpu_model);
struct tt_entry *sparc_ttable;
static __init void leon_patch(void)
{
struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch;
struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end;
/* Default instruction is leon - no patching */
if (sparc_cpu_model == sparc_leon)
return;
while (start < end) {
unsigned long addr = start->addr;
*(unsigned int *)(addr) = start->insn;
flushi(addr);
start++;
}
}
struct tt_entry *sparc_ttable;
struct pt_regs fake_swapper_regs;
/* Called from head_32.S - before we have setup anything
@@ -251,6 +275,23 @@ struct pt_regs fake_swapper_regs;
void __init sparc32_start_kernel(struct linux_romvec *rp)
{
prom_init(rp);
/* Set sparc_cpu_model */
sparc_cpu_model = sun_unknown;
if (!strcmp(&cputypval[0], "sun4m"))
sparc_cpu_model = sun4m;
if (!strcmp(&cputypval[0], "sun4s"))
sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */
if (!strcmp(&cputypval[0], "sun4d"))
sparc_cpu_model = sun4d;
if (!strcmp(&cputypval[0], "sun4e"))
sparc_cpu_model = sun4e;
if (!strcmp(&cputypval[0], "sun4u"))
sparc_cpu_model = sun4u;
if (!strncmp(&cputypval[0], "leon" , 4))
sparc_cpu_model = sparc_leon;
leon_patch();
start_kernel();
}
@@ -270,21 +311,6 @@ void __init setup_arch(char **cmdline_p)
register_console(&prom_early_console);
/* Set sparc_cpu_model */
sparc_cpu_model = sun_unknown;
if (!strcmp(&cputypval[0], "sun4m"))
sparc_cpu_model = sun4m;
if (!strcmp(&cputypval[0], "sun4s"))
sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */
if (!strcmp(&cputypval[0], "sun4d"))
sparc_cpu_model = sun4d;
if (!strcmp(&cputypval[0], "sun4e"))
sparc_cpu_model = sun4e;
if (!strcmp(&cputypval[0], "sun4u"))
sparc_cpu_model = sun4u;
if (!strncmp(&cputypval[0], "leon" , 4))
sparc_cpu_model = sparc_leon;
printk("ARCH: ");
switch(sparc_cpu_model) {
case sun4m: