On 18/08/15 19:17, Cormac O'Brien wrote:
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@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);
I'm slightly curious as to whether things still work with props[1] and props[2] set to 0 here. The reason being that these reference DBDMA serial interrupts which QEMU doesn't (yet) emulate and so it might be better to declare these as zero which should tell the driver to disable the interrupt rather than waiting for something that is non-existent.
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);
- }
Can we also initialise the legacy ports here at the same time, e.g.
if (legacy) { ... ... } else { ... ... }
For QEMU it doesn't necessarily matter since the legacy ports are aliased onto the non-legacy ports, but in case this changes at a later date (or someone is interested to run this on real hardware) then we might as well do this at the same time.
}
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
ATB,
Mark.