mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
powerpc: Fixup lwsync at runtime
To allow for a single kernel image on e500 v1/v2/mc we need to fixup lwsync at runtime. On e500v1/v2 lwsync causes an illop so we need to patch up the code. We default to 'sync' since that is always safe and if the cpu is capable we will replace 'sync' with 'lwsync'. We introduce CPU_FTR_LWSYNC as a way to determine at runtime if this is needed. This flag could be moved elsewhere since we dont really use it for the normal CPU_FTR purpose. Finally we only store the relative offset in the fixup section to keep it as small as possible rather than using a full fixup_entry. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
5888da1876
commit
2d1b202762
13 changed files with 133 additions and 28 deletions
|
@ -110,6 +110,22 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
|
|||
}
|
||||
}
|
||||
|
||||
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
|
||||
{
|
||||
unsigned int *start, *end, *dest;
|
||||
|
||||
if (!(value & CPU_FTR_LWSYNC))
|
||||
return ;
|
||||
|
||||
start = fixup_start;
|
||||
end = fixup_end;
|
||||
|
||||
for (; start < end; start++) {
|
||||
dest = (void *)start + *start;
|
||||
patch_instruction(dest, PPC_LWSYNC_INSTR);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FTR_FIXUP_SELFTEST
|
||||
|
||||
#define check(x) \
|
||||
|
@ -295,6 +311,25 @@ static void test_fw_macros(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void test_lwsync_macros(void)
|
||||
{
|
||||
extern void lwsync_fixup_test;
|
||||
extern void end_lwsync_fixup_test;
|
||||
extern void lwsync_fixup_test_expected_LWSYNC;
|
||||
extern void lwsync_fixup_test_expected_SYNC;
|
||||
unsigned long size = &end_lwsync_fixup_test -
|
||||
&lwsync_fixup_test;
|
||||
|
||||
/* The fixups have already been done for us during boot */
|
||||
if (cur_cpu_spec->cpu_features & CPU_FTR_LWSYNC) {
|
||||
check(memcmp(&lwsync_fixup_test,
|
||||
&lwsync_fixup_test_expected_LWSYNC, size) == 0);
|
||||
} else {
|
||||
check(memcmp(&lwsync_fixup_test,
|
||||
&lwsync_fixup_test_expected_SYNC, size) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init test_feature_fixups(void)
|
||||
{
|
||||
printk(KERN_DEBUG "Running feature fixup self-tests ...\n");
|
||||
|
@ -307,6 +342,7 @@ static int __init test_feature_fixups(void)
|
|||
test_alternative_case_with_external_branch();
|
||||
test_cpu_macros();
|
||||
test_fw_macros();
|
||||
test_lwsync_macros();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue