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:
parent
f49d5cb80d
commit
1c2924af1f
@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#ifdef __sparc64__
|
#ifdef __sparc64__
|
||||||
#include <machine/bus_private.h>
|
#include <machine/bus_private.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <machine/cpu.h>
|
||||||
|
|
||||||
#include <dev/ofw/openfirm.h>
|
#include <dev/ofw/openfirm.h>
|
||||||
#include <dev/ofw/ofw_bus.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) {
|
if (pmap_bootstrapped) {
|
||||||
sc->fb_flags &= ~FB_FLAG_NOWRITE;
|
sc->fb_flags &= ~FB_FLAG_NOWRITE;
|
||||||
ofwfb_initialize(vd);
|
ofwfb_initialize(vd);
|
||||||
|
vd->vd_driver->vd_blank(vd, TC_BLACK);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -490,11 +492,6 @@ ofwfb_init(struct vt_device *vd)
|
|||||||
OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase,
|
OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase,
|
||||||
NULL);
|
NULL);
|
||||||
sc->fb.fb_pbase = sc->fb.fb_vbase & ~DMAP_BASE_ADDRESS;
|
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
|
#else
|
||||||
/* No ability to interpret assigned-addresses otherwise */
|
/* No ability to interpret assigned-addresses otherwise */
|
||||||
return (CN_DEAD);
|
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);
|
ofwfb_initialize(vd);
|
||||||
vt_fb_init(vd);
|
vt_fb_init(vd);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user