diff options
Diffstat (limited to 'qemu/roms/openbios/drivers/escc.c')
-rw-r--r-- | qemu/roms/openbios/drivers/escc.c | 112 |
1 files changed, 94 insertions, 18 deletions
diff --git a/qemu/roms/openbios/drivers/escc.c b/qemu/roms/openbios/drivers/escc.c index 240043be3..1990e798d 100644 --- a/qemu/roms/openbios/drivers/escc.c +++ b/qemu/roms/openbios/drivers/escc.c @@ -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 |