These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / openbios / drivers / escc.c
index 240043b..1990e79 100644 (file)
@@ -380,12 +380,44 @@ 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];
+    ucell offset;
+    int index;
+    int legacy;
+    
+    int dbdma_offsets[2][2] = {
+        /* ch-b */
+        { 0x6, 0x7 },
+        /* ch-a */
+        { 0x4, 0x5 }
+    };
+    
+    int reg_offsets[2][2][3] = {
+        {
+            /* ch-b */
+            { 0x00, 0x10, 0x40 },
+            /* ch-a */
+            { 0x20, 0x30, 0x50 }
+        },{
+            /* legacy ch-b */
+            { 0x0, 0x2, 0x8 },
+            /* legacy ch-a */
+            { 0x4, 0x6, 0xa }
+        }
+    };
+    
+    switch (esnum) {
+        case 2: index = 1; legacy = 0; break;
+        case 3: index = 0; legacy = 0; break;
+        case 4: index = 1; legacy = 1; break;
+        case 5: index = 0; legacy = 1; break;
+        default: return;
+    }
 
     /* add device */
 
@@ -411,31 +443,49 @@ 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);
+    snprintf(buf, sizeof(buf), "chrp,es%d", esnum);
+    set_property(dnode, "compatible", buf, 9);
 
-    props[0] = IO_ESCC_OFFSET + offset * 0x20;
-    props[1] = 0x00000020;
-    set_property(dnode, "reg", (char *)&props, 2 * sizeof(cell));
+    if (legacy) {
+        offset = IO_ESCC_LEGACY_OFFSET;
+    } else {
+        offset = IO_ESCC_OFFSET;
+    }
 
-    props[0] = addr + IO_ESCC_OFFSET + offset * 0x20;
+    props[0] = offset + reg_offsets[legacy][index][0];
+    props[1] = 0x1;
+    props[2] = offset + reg_offsets[legacy][index][1];
+    props[3] = 0x1;
+    props[4] = offset + reg_offsets[legacy][index][2];
+    props[5] = 0x1;
+    props[6] = 0x8000 + dbdma_offsets[index][0] * 0x100;
+    props[7] = 0x100;
+    props[8] = 0x8000 + dbdma_offsets[index][1] * 0x100;
+    props[9] = 0x100;
+    set_property(dnode, "reg", (char *)&props, 10 * sizeof(cell));
+
+    props[0] = addr + offset + reg_offsets[legacy][index][0];
     OLDWORLD(set_property(dnode, "AAPL,address",
             (char *)&props, 1 * sizeof(cell)));
 
-    props[0] = 0x00000010 - offset;
+    props[0] = 0x10 - index;
     OLDWORLD(set_property(dnode, "AAPL,interrupts",
             (char *)&props, 1 * sizeof(cell)));
 
-    props[0] = (0x24) + offset;
-    props[1] = 0;
+    props[0] = (0x24) + index;
+    props[1] = 0x1;
+    props[2] = dbdma_offsets[index][0];
+    props[3] = 0x0;
+    props[4] = dbdma_offsets[index][1];
+    props[5] = 0x0;
     NEWWORLD(set_property(dnode, "interrupts",
-             (char *)&props, 2 * sizeof(cell)));
+             (char *)&props, 6 * sizeof(cell)));
+
+    set_int_property(dnode, "slot-names", 0);
 
     device_end();
 
-    uart_init_line((unsigned char*)addr + IO_ESCC_OFFSET + offset * 0x20,
+    uart_init_line((unsigned char*)addr + offset + reg_offsets[legacy][index][0],
                    CONFIG_SERIAL_SPEED);
 }
 
@@ -464,13 +514,39 @@ escc_init(const char *path, phys_addr_t addr)
     set_property(dnode, "device_type", "escc",
                  strlen("escc") + 1);
     set_property(dnode, "compatible", "escc\0CHRP,es0", 14);
+    set_property(dnode, "ranges", "", 0);
 
     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);
+    set_property(dnode, "ranges", "", 0);
+
+    fword("finish-device");
+
+    escc_add_channel(buf, "a", addr, 4);
+    escc_add_channel(buf, "b", addr, 5);
 }
 #endif