[OpenBIOS] [PATCH 3/5] ppc: add ESCC legacy support

Cormac O'Brien cormac at c-obrien.org
Tue Aug 18 18:17:31 CET 2015


Mac OS 9 requires that the host provide escc-legacy serial ports, so we add them
here to get further in the boot process.

Signed-off-by: Cormac O'Brien <cormac at c-obrien.org>
---
 drivers/escc.c | 85 +++++++++++++++++++++++++++++++++++++++++++++-------------
 drivers/escc.h |  2 ++
 drivers/pci.c  |  6 +++++
 3 files changed, 75 insertions(+), 18 deletions(-)

diff --git a/drivers/escc.c b/drivers/escc.c
index 240043b..972b06a 100644
--- a/drivers/escc.c
+++ b/drivers/escc.c
@@ -380,12 +380,22 @@ ob_zs_init(phys_addr_t base, uint64_t offset, int intr, int slave, int keyboard)
 
 static void
 escc_add_channel(const char *path, const char *node, phys_addr_t addr,
-                 uint32_t offset)
+                 int esnum)
 {
     char buf[64], tty[32];
     phandle_t dnode, aliases;
-    int len;
-    cell props[2];
+
+    cell props[10];
+    int offset;
+    int legacy;
+
+    switch (esnum) {
+    case 2: offset = 1; legacy = 0; break;
+    case 3: offset = 0; legacy = 0; break;
+    case 4: offset = 1; legacy = 1; break;
+    case 5: offset = 0; legacy = 1; break;
+    default: return;
+    }
 
     /* add device */
 
@@ -411,16 +421,28 @@ escc_add_channel(const char *path, const char *node, phys_addr_t addr,
     set_property(dnode, "device_type", "serial",
                  strlen("serial") + 1);
 
-    snprintf(buf, sizeof(buf), "ch-%s", node);
-    len = strlen(buf) + 1;
-    snprintf(buf + len, sizeof(buf) - len, "CHRP,es2");
-    set_property(dnode, "compatible", buf, len + 9);
-
-    props[0] = IO_ESCC_OFFSET + offset * 0x20;
-    props[1] = 0x00000020;
-    set_property(dnode, "reg", (char *)&props, 2 * sizeof(cell));
+    snprintf(buf, sizeof(buf), "chrp,es%d", esnum);
+    set_property(dnode, "compatible", buf, 9);
+
+    if (legacy) {
+        props[0] = IO_ESCC_LEGACY_OFFSET + offset * 0x4;
+        props[1] = 0x00000001;
+        props[2] = IO_ESCC_LEGACY_OFFSET + offset * 0x4 + 2;
+        props[3] = 0x00000001;
+        props[4] = IO_ESCC_LEGACY_OFFSET + offset * 0x4 + 6;
+        props[5] = 0x00000001;
+        set_property(dnode, "reg", (char *)&props, 6 * sizeof(cell));
+    } else {
+        props[0] = IO_ESCC_OFFSET + offset * 0x20;
+        props[1] = 0x00000020;
+        set_property(dnode, "reg", (char *)&props, 2 * sizeof(cell));
+    }
 
-    props[0] = addr + IO_ESCC_OFFSET + offset * 0x20;
+    if (legacy) {
+        props[0] = addr + IO_ESCC_LEGACY_OFFSET + offset * 0x4;
+    } else {
+        props[0] = addr + IO_ESCC_OFFSET + offset * 0x20;
+    }
     OLDWORLD(set_property(dnode, "AAPL,address",
             (char *)&props, 1 * sizeof(cell)));
 
@@ -429,14 +451,17 @@ escc_add_channel(const char *path, const char *node, phys_addr_t addr,
             (char *)&props, 1 * sizeof(cell)));
 
     props[0] = (0x24) + offset;
-    props[1] = 0;
+    props[1] = 4 + (offset * 2);
+    props[2] = 5 + (offset * 2);
     NEWWORLD(set_property(dnode, "interrupts",
-             (char *)&props, 2 * sizeof(cell)));
+             (char *)&props, 3 * sizeof(cell)));
 
     device_end();
 
-    uart_init_line((unsigned char*)addr + IO_ESCC_OFFSET + offset * 0x20,
-                   CONFIG_SERIAL_SPEED);
+    if (!legacy) {
+        uart_init_line((unsigned char*)addr + IO_ESCC_OFFSET + offset * 0x20,
+                       CONFIG_SERIAL_SPEED);
+    }
 }
 
 void
@@ -467,10 +492,34 @@ escc_init(const char *path, phys_addr_t addr)
 
     fword("finish-device");
 
-    escc_add_channel(buf, "a", addr, 1);
-    escc_add_channel(buf, "b", addr, 0);
+    escc_add_channel(buf, "a", addr, 2);
+    escc_add_channel(buf, "b", addr, 3);
 
     escc_serial_dev = (unsigned char *)addr + IO_ESCC_OFFSET +
                  (CONFIG_SERIAL_PORT ? 0 : 0x20);
+
+    push_str(path);
+    fword("find-device");
+    fword("new-device");
+
+    push_str("escc-legacy");
+    fword("device-name");
+
+    snprintf(buf, sizeof(buf), "%s/escc-legacy", path);
+
+    dnode = find_dev(buf);
+
+    set_int_property(dnode, "#address-cells", 1);
+    props[0] = __cpu_to_be32(IO_ESCC_LEGACY_OFFSET);
+    props[1] = __cpu_to_be32(IO_ESCC_LEGACY_SIZE);
+    set_property(dnode, "reg", (char *)&props, sizeof(props));
+    set_property(dnode, "device_type", "escc-legacy",
+                 strlen("escc-legacy") + 1);
+    set_property(dnode, "compatible", "chrp,es1", 9);
+
+    fword("finish-device");
+
+    escc_add_channel(buf, "a", addr, 4);
+    escc_add_channel(buf, "b", addr, 5);
 }
 #endif
diff --git a/drivers/escc.h b/drivers/escc.h
index caaf00d..e73f267 100644
--- a/drivers/escc.h
+++ b/drivers/escc.h
@@ -1,6 +1,8 @@
 
 #define IO_ESCC_SIZE    0x00001000
 #define IO_ESCC_OFFSET  0x00013000
+#define IO_ESCC_LEGACY_SIZE    0x00001000
+#define IO_ESCC_LEGACY_OFFSET  0x00012000
 
 #define ZS_REGS         8
 
diff --git a/drivers/pci.c b/drivers/pci.c
index 366f4a1..a68e9dc 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -1420,6 +1420,12 @@ static void ob_pci_host_set_interrupt_map(phandle_t host)
         target_node = find_dev("/pci/mac-io/escc/ch-b");
         set_int_property(target_node, "interrupt-parent", dnode);
 
+        target_node = find_dev("/pci/mac-io/escc-legacy/ch-a");
+        set_int_property(target_node, "interrupt-parent", dnode);
+
+        target_node = find_dev("/pci/mac-io/escc-legacy/ch-b");
+        set_int_property(target_node, "interrupt-parent", dnode);
+
         /* QEMU only emulates 2 of the 3 ata buses currently */
         /* On a new world Mac these are not numbered but named by the
          * ATA version they support. Thus we have: ata-3, ata-3, ata-4
-- 
2.5.0




More information about the OpenBIOS mailing list