summaryrefslogtreecommitdiff
path: root/init.c
diff options
context:
space:
mode:
authorJason Thorpe <thorpej@me.com>2021-06-02 20:53:17 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-06-06 13:26:29 -0700
commit5e915346477f4f2f33345c7dbe711be828b58730 (patch)
tree4b7eea9639a68b7a5dddf8272ffb3a8b582d8303 /init.c
parentb5bee8227775b91e12c0b6635977d44f2d7fa376 (diff)
downloadqemu-palcode-5e915346477f4f2f33345c7dbe711be828b58730.zip
qemu-palcode-5e915346477f4f2f33345c7dbe711be828b58730.tar.gz
qemu-palcode-5e915346477f4f2f33345c7dbe711be828b58730.tar.bz2
Fixes for secondary CPU start-up.
Changes to make secondary CPU start-up work on NetBSD, which depends on some specific behavior in the architecture specification: - Change the internal swppal() function to take the new VPTPTR and Procedure Value as explicit arguments. Adapt do_start() to the new the new swppal() signature. - In do_start_wait(), extract the new VPTPTR and PV from the relevant HWRPB fields, which will have been initialized by the OS, and pass them to swppal(). - In the SWPPAL PAL call, get the value to stuff into PV (r27) from a4 (r20), and add a comment describing why this implementation detail is allowed by the architecture specification. Signed-off-by: Jason Thorpe <thorpej@me.com> Message-Id: <20210603035317.6814-9-thorpej@me.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'init.c')
-rw-r--r--init.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/init.c b/init.c
index 1451785..6edfdf2 100644
--- a/init.c
+++ b/init.c
@@ -288,14 +288,16 @@ init_i8259 (void)
}
static void __attribute__((noreturn))
-swppal(void *entry, void *pcb)
+swppal(void *entry, void *pcb, unsigned long vptptr, unsigned long pv)
{
register int variant __asm__("$16") = 2; /* OSF/1 PALcode */
register void *pc __asm__("$17") = entry;
register unsigned long pa_pcb __asm__("$18") = PA(pcb);
- register unsigned long vptptr __asm__("$19") = VPTPTR;
+ register unsigned long newvptptr __asm__("$19") = vptptr;
+ register unsigned long newpv __asm__("$20") = pv;
- asm("call_pal 0x0a" : : "r"(variant), "r"(pc), "r"(pa_pcb), "r"(vptptr));
+ asm("call_pal 0x0a" : :
+ "r"(variant), "r"(pc), "r"(pa_pcb), "r"(newvptptr), "r"(newpv));
__builtin_unreachable ();
}
@@ -313,7 +315,9 @@ do_start(unsigned long memsize, void (*kernel_entry)(void), unsigned long cpus)
pci_setup();
vgahw_init();
- swppal(kernel_entry ? kernel_entry : do_console, &pcb);
+ void *new_pc = kernel_entry ? kernel_entry : do_console;
+
+ swppal(new_pc, &pcb, VPTPTR, (unsigned long)new_pc);
}
void
@@ -328,14 +332,16 @@ do_start_wait(unsigned long cpuid)
{
/* ??? The only message I know of is "START\r\n".
I can't be bothered to verify more than 4 characters. */
- /* ??? The Linux kernel fills in, but does not require,
- CPU_restart_data. It just sets that to the same address
- as CPU_restart itself. Our swppal *does* put the PC into
- $26 and $27, the latter of which the kernel does rely upon. */
+
+ /* Use use a private extension to SWPPAL to get the
+ CPU_restart_data into $27. Linux fills it in, but does
+ not require it. Other operating systems, however, do use
+ CPU_restart_data as part of secondary CPU start-up. */
unsigned int len = hwrpb.processor[cpuid].ipc_buffer[0];
unsigned int msg = hwrpb.processor[cpuid].ipc_buffer[1];
void *CPU_restart = hwrpb.hwrpb.CPU_restart;
+ unsigned long CPU_restart_data = hwrpb.hwrpb.CPU_restart_data;
__sync_synchronize();
hwrpb.hwrpb.rxrdy = 0;
@@ -343,7 +349,8 @@ do_start_wait(unsigned long cpuid)
{
/* Set bootstrap in progress */
hwrpb.processor[cpuid].flags |= 1;
- swppal(CPU_restart, hwrpb.processor[cpuid].hwpcb);
+ swppal(CPU_restart, hwrpb.processor[cpuid].hwpcb,
+ hwrpb.hwrpb.vptb, CPU_restart_data);
}
}
}