summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/drivers/escc.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/drivers/escc.c')
-rw-r--r--qemu/roms/openbios/drivers/escc.c112
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