Avoid writing to the frame buffer in early boot on PowerPC if the CPU's

MMU is disabled.

This expands some earlier logic and avoids a number of potential problems:
1. The CPU may not be able to access the framebuffer in real mode (real
   mode does not necessarily encompass all available memory, especially
   under a hypervisor).
2. Real mode accesses generally assume cacheability, so it might not
   even have worked.
3. The difference in cacheability between real mode and later (and
   potentially earlier) points in the boot with the MMU on may cause
   ERAT parity problems, resulting in a machine check.

This fixes real-mode (usefdt=1) early boot on the G5 iMac, which was
previously broken as a result of issue #3. Late boot will require some
other fixups.
This commit is contained in:
Nathan Whitehorn 2018-05-19 22:04:54 +00:00
parent ba6ce3a34b
commit 4f75b93007

View File

@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#ifdef __sparc64__
#include <machine/bus_private.h>
#endif
#include <machine/cpu.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
@ -138,6 +139,7 @@ ofwfb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
if (pmap_bootstrapped) {
sc->fb_flags &= ~FB_FLAG_NOWRITE;
ofwfb_initialize(vd);
vd->vd_driver->vd_blank(vd, TC_BLACK);
} else {
return;
}
@ -490,11 +492,6 @@ ofwfb_init(struct vt_device *vd)
OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase,
NULL);
sc->fb.fb_pbase = sc->fb.fb_vbase & ~DMAP_BASE_ADDRESS;
#ifdef __powerpc64__
/* Real mode under a hypervisor probably doesn't cover FB */
if (!(mfmsr() & (PSL_HV | PSL_DR)))
sc->fb.fb_flags |= FB_FLAG_NOWRITE;
#endif
#else
/* No ability to interpret assigned-addresses otherwise */
return (CN_DEAD);
@ -502,6 +499,17 @@ ofwfb_init(struct vt_device *vd)
}
#if defined(__powerpc__)
/*
* If we are running on PowerPC in real mode (supported only on AIM
* CPUs), the frame buffer may be inaccessible (real mode does not
* necessarily cover all RAM) and may also be mapped with the wrong
* cache properties (all real mode accesses are assumed cacheable).
* Just don't write to it for the time being.
*/
if (!(cpu_features & PPC_FEATURE_BOOKE) && !(mfmsr() & PSL_DR))
sc->fb.fb_flags |= FB_FLAG_NOWRITE;
#endif
ofwfb_initialize(vd);
vt_fb_init(vd);