Use the cookie now set by loader to determine whether the value passed to

PowerPC kernels in r6 is actually metadata from loader(8) or gibberish
left in r6, which is not required to be anything under the
PAPR/ePAPR/CHRP/OF standards, by another boot loader.

Note that, as a result, systems need a new boot loader to boot PPC kernels
after this revision without ending up at a mountroot prompt. New boot
loaders are backwards compatible and can boot older kernels.

Reviewed by:	jhibbits
MFC after:	2 months
This commit is contained in:
Nathan Whitehorn 2017-11-26 03:53:20 +00:00
parent 5e53a4f90f
commit 47f69f4f2b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326220
5 changed files with 33 additions and 8 deletions

View file

@ -51,6 +51,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
20171125:
PowerPC users must update loader(8) by rebuilding world before
installing a new kernel, as the protocol connecting them has
changed. Without the update, loader metadata will not be passed
successfully to the kernel and users will have to enter their
root partition at the kernel mountroot prompt to continue booting.
Newer versions of loader can boot old kernels without issue.
201711xx:
The LOADER_FIREWIRE_SUPPORT build variable as been renamed to
WITH/OUT_LOADER_FIREWIRE. LOADER_{NO_,}GELI_SUPPORT has been renamed

View file

@ -79,13 +79,14 @@ __start:
/* Set up temporary stack pointer */
lwz %r1,8(%r30)
add %r1,%r1,%r30
addi %r1,%r1,(8+TMPSTKSZ-32)
addi %r1,%r1,(8+TMPSTKSZ-40)
/* Relocate self */
stw %r3,16(%r1)
stw %r4,20(%r1)
stw %r5,24(%r1)
stw %r6,28(%r1)
stw %r7,32(%r1)
lwz %r3,0(%r30) /* _DYNAMIC in %r3 */
add %r3,%r3,%r30
@ -99,6 +100,7 @@ __start:
lwz %r4,20(%r1)
lwz %r5,24(%r1)
lwz %r6,28(%r1)
lwz %r7,32(%r1)
/* MD setup */
bl powerpc_init

View file

@ -73,6 +73,7 @@ btext:
* r4: ignored
* r5: OF client interface pointer (or zero)
* r6: Loader metadata pointer (or zero)
* r7: Magic cookie (0xfb5d104d) to indicate that r6 has loader metadata
*/
.text
ASENTRY_NOPROF(__start)
@ -108,6 +109,8 @@ ASENTRY_NOPROF(__start)
std %r4,56(%r1)
std %r5,64(%r1)
std %r6,72(%r1)
std %r7,80(%r1)
bl 1f
.llong _DYNAMIC-.
1: mflr %r3
@ -120,6 +123,7 @@ ASENTRY_NOPROF(__start)
ld %r4,56(%r1)
ld %r5,64(%r1)
ld %r6,72(%r1)
ld %r7,80(%r1)
/* Begin CPU init */
mr %r4,%r2 /* Replace ignored r4 with tocbase for trap handlers */

View file

@ -200,7 +200,8 @@ extern void *int_performance_counter;
("Handler " #handler " too far from interrupt vector base")); \
mtspr(ivor, (uintptr_t)(&handler) & 0xffffUL);
uintptr_t powerpc_init(vm_offset_t fdt, vm_offset_t, vm_offset_t, void *mdp);
uintptr_t powerpc_init(vm_offset_t fdt, vm_offset_t, vm_offset_t, void *mdp,
vm_offset_t mdp_cookie);
void booke_cpu_init(void);
void
@ -346,7 +347,11 @@ booke_init(u_long arg1, u_long arg2)
break;
}
ret = powerpc_init(dtbp, 0, 0, mdp);
/*
* Last element is a magic cookie that indicates that the metadata
* pointer is meaningful.
*/
ret = powerpc_init(dtbp, 0, 0, mdp, (mdp == NULL) ? 0 : 0xfb5d104d);
/* Enable caches */
booke_enable_l1_cache();

View file

@ -154,7 +154,8 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
CTLFLAG_RD, &cacheline_size, 0, "");
uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *);
uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *,
vm_offset_t);
long Maxmem = 0;
long realmem = 0;
@ -232,7 +233,8 @@ void aim_cpu_init(vm_offset_t toc);
void booke_cpu_init(void);
uintptr_t
powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp,
vm_offset_t mdp_cookie)
{
struct pcpu *pc;
struct cpuref bsp;
@ -251,8 +253,11 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
startkernel = __startkernel;
endkernel = __endkernel;
/* Check for ePAPR loader, which puts a magic value into r6 */
if (mdp == (void *)0x65504150)
/*
* If the metadata pointer cookie is not set to the magic value,
* the number in mdp should be treated as nonsense.
*/
if (mdp_cookie != 0xfb5d104d)
mdp = NULL;
#ifdef AIM
@ -352,7 +357,8 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
platform_probe_and_attach();
/*
* Set up real per-cpu data.
* Set up per-cpu data for the BSP now that the platform can tell
* us which that is.
*/
if (platform_smp_get_bsp(&bsp) != 0)
bsp.cr_cpuid = 0;