Page MenuHomeFreeBSD

D20640.diff
No OneTemporary

D20640.diff

Index: head/sys/dev/vt/hw/ofwfb/ofwfb.c
===================================================================
--- head/sys/dev/vt/hw/ofwfb/ofwfb.c
+++ head/sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -90,9 +90,15 @@
static int
ofwfb_probe(struct vt_device *vd)
{
+ int disabled;
phandle_t chosen, node;
ihandle_t stdout;
char buf[64];
+
+ disabled = 0;
+ TUNABLE_INT_FETCH("hw.ofwfb.disable", &disabled);
+ if (disabled)
+ return (CN_DEAD);
chosen = OF_finddevice("/chosen");
if (chosen == -1)
Index: head/sys/powerpc/ofw/ofw_real.c
===================================================================
--- head/sys/powerpc/ofw/ofw_real.c
+++ head/sys/powerpc/ofw/ofw_real.c
@@ -168,7 +168,45 @@
static caddr_t of_bounce_virt;
static off_t of_bounce_offset;
static size_t of_bounce_size;
+
+/*
+ * To be able to use OFW console on PPC, that requires real mode OFW,
+ * the mutex that guards the mapping/unmapping of virtual to physical
+ * buffers (of_real_mtx) must be of SPIN type. This is needed because
+ * kernel console first locks a SPIN mutex before calling OFW real.
+ * By default, of_real_mtx is a sleepable mutex. To make it of SPIN
+ * type, use the following tunnable:
+ * machdep.ofw.mtx_spin=1
+ *
+ * Besides that, a few more tunables are needed to select and use the
+ * OFW console with real mode OFW.
+ *
+ * In order to disable the use of OFW FrameBuffer and fallback to the
+ * OFW console, use:
+ * hw.ofwfb.disable=1
+ *
+ * To disable the use of FDT (that doesn't support OFW read/write methods)
+ * and use real OFW instead, unset the following loader variable:
+ * unset usefdt
+ *
+ * OFW is put in quiesce state in early kernel boot, which usually disables
+ * OFW read/write capabilities (in QEMU write continue to work, but
+ * read doesn't). To avoid OFW quiesce, use:
+ * debug.quiesce_ofw=0
+ *
+ * Note that disabling OFW quiesce can cause conflicts between kernel and
+ * OFW trying to control the same hardware. Thus, it must be used with care.
+ * Some conflicts can be avoided by disabling kernel drivers with hints.
+ * For instance, to disable a xhci controller and an USB keyboard connected
+ * to it, that may be already being used for input by OFW, use:
+ * hint.xhci.0.disabled=1
+ */
+
static struct mtx of_bounce_mtx;
+static struct mtx of_spin_mtx;
+static struct mtx *of_real_mtx;
+static void (*of_mtx_lock)(void);
+static void (*of_mtx_unlock)(void);
extern int ofw_real_mode;
@@ -182,16 +220,40 @@
ofw_real_bounce_alloc, NULL);
static void
+ofw_real_mtx_lock_spin(void)
+{
+ mtx_lock_spin(of_real_mtx);
+}
+
+static void
+ofw_real_mtx_lock(void)
+{
+ mtx_lock(of_real_mtx);
+}
+
+static void
+ofw_real_mtx_unlock_spin(void)
+{
+ mtx_unlock_spin(of_real_mtx);
+}
+
+static void
+ofw_real_mtx_unlock(void)
+{
+ mtx_unlock(of_real_mtx);
+}
+
+static void
ofw_real_start(void)
{
- mtx_lock(&of_bounce_mtx);
+ (*of_mtx_lock)();
of_bounce_offset = 0;
}
-
+
static void
ofw_real_stop(void)
{
- mtx_unlock(&of_bounce_mtx);
+ (*of_mtx_unlock)();
}
static void
@@ -228,7 +290,7 @@
* we have a 32-bit virtual address to give OF.
*/
- if (!ofw_real_mode && (!hw_direct_map || DMAP_BASE_ADDRESS != 0))
+ if (!ofw_real_mode && (!hw_direct_map || DMAP_BASE_ADDRESS != 0))
pmap_kenter(of_bounce_phys, of_bounce_phys);
mtx_unlock(&of_bounce_mtx);
@@ -240,7 +302,7 @@
static char emergency_buffer[255];
cell_t phys;
- mtx_assert(&of_bounce_mtx, MA_OWNED);
+ mtx_assert(of_real_mtx, MA_OWNED);
if (of_bounce_virt == NULL) {
/*
@@ -290,7 +352,7 @@
static void
ofw_real_unmap(cell_t physaddr, void *buf, size_t len)
{
- mtx_assert(&of_bounce_mtx, MA_OWNED);
+ mtx_assert(of_real_mtx, MA_OWNED);
if (of_bounce_virt == NULL)
return;
@@ -306,9 +368,24 @@
static int
ofw_real_init(ofw_t ofw, void *openfirm)
{
- openfirmware = (int (*)(void *))openfirm;
+ int mtx_spin;
+ openfirmware = (int (*)(void *))openfirm;
mtx_init(&of_bounce_mtx, "OF Bounce Page", NULL, MTX_DEF);
+
+ mtx_spin = 0;
+ TUNABLE_INT_FETCH("machdep.ofw.mtx_spin", &mtx_spin);
+ if (mtx_spin) {
+ mtx_init(&of_spin_mtx, "OF Real", NULL, MTX_SPIN);
+ of_real_mtx = &of_spin_mtx;
+ of_mtx_lock = ofw_real_mtx_lock_spin;
+ of_mtx_unlock = ofw_real_mtx_unlock_spin;
+ } else {
+ of_real_mtx = &of_bounce_mtx;
+ of_mtx_lock = ofw_real_mtx_lock;
+ of_mtx_unlock = ofw_real_mtx_unlock;
+ }
+
of_bounce_virt = NULL;
return (0);
}
Index: head/sys/powerpc/pseries/platform_chrp.c
===================================================================
--- head/sys/powerpc/pseries/platform_chrp.c
+++ head/sys/powerpc/pseries/platform_chrp.c
@@ -133,6 +133,7 @@
static int
chrp_attach(platform_t plat)
{
+ int quiesce;
#ifdef __powerpc64__
int i;
@@ -175,7 +176,10 @@
chrp_cpuref_init();
/* Some systems (e.g. QEMU) need Open Firmware to stand down */
- ofw_quiesce();
+ quiesce = 1;
+ TUNABLE_INT_FETCH("debug.quiesce_ofw", &quiesce);
+ if (quiesce)
+ ofw_quiesce();
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 19, 7:56 AM (20 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15935387
Default Alt Text
D20640.diff (4 KB)

Event Timeline