--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c Thu Nov 12 14:39:23 2009 -0800
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c Tue Jan 26 13:03:40 2010 +0000
@@ -26,6 +26,7 @@
#include "devtree.h"
#include "hw/boards.h"
#include "libfdt/libfdt.h"
+#include "qemu-char.h"
#define BADF(fmt, args...) \
do { fprintf(stderr, "error: " fmt , ##args); exit(1);} while (0)
@@ -413,7 +414,15 @@
if (propstr) {
i = sscanf(propstr, "serial%d", &n);
if (i == 1 && n >= 0 && n < MAX_SERIAL_PORTS)
+ {
+ if (!serial_hds[n])
+ {
+ const char* target = fdt_getprop_string(dt, node, "target");
+ if (target)
+ serial_hds[n] = qemu_chr_open(propstr, target);
+ }
d->chardev = serial_hds[n];
+ }
}
}
find_properties(d);
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py Thu Nov 12 14:39:23 2009 -0800
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py Tue Jan 26 13:03:40 2010 +0000
@@ -1,4 +1,6 @@
import qemu
+import os
+import sys
class syborg_serial(qemu.devclass):
REG_ID = 0
@@ -127,6 +129,57 @@
regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)]
irqs = 1
name = "syborg,serial"
- properties = {"fifo-size":16, "chardev":None}
+ properties = {"fifo-size":16, "chardev":None, "target": ""}
qemu.register_device(syborg_serial)
+
+class syborg_modem(syborg_serial):
+
+ def create(self):
+ syborg_serial.create(self)
+
+ # Find the path of the emulator executable
+ path = os.path.dirname(sys.executable)
+ executable = os.getenv("SVP_MODEM_EXECUTABLE")
+ if None == executable:
+ executable = self.modem_executable
+
+ executable_name = executable
+ fq_executable = os.path.join(path, executable_name)
+ print(fq_executable)
+
+ if not os.path.exists(fq_executable):
+ executable_name = executable + ".exe"
+ fq_executable = os.path.join(path, executable_name)
+
+ if not os.path.exists(fq_executable):
+ sys.exit("Could not locate modem executable '" + executable + "' in '" + path + "'!\n")
+
+ # Attempt to find the correct port from the target spec
+ target = self.properties["target"]
+
+ if not(target.startswith("tcp:") or target.startswith("udp:")):
+ sys.exit("Modem device is not accessed via an acceptable socket.")
+
+ target = target[4:]
+ port_start_idx = target.find(":");
+ port_end_idx = target.find(",")
+ if -1 == port_start_idx:
+ sys.exit("Could not extract port number from modem target spec!")
+
+ port = ""
+ if -1 == port_end_idx:
+ port = target[port_start_idx + 1:]
+ else:
+ port = target[port_start_idx + 1:port_end_idx]
+
+ os.spawnl(os.P_NOWAIT, fq_executable, executable_name, "-p", port)
+ self.chardev.handle_connect()
+
+ # Name property override.
+ name = "syborg,serial,modem"
+
+ # Default modem executable
+ modem_executable = "phonesim"
+
+qemu.register_device(syborg_modem)
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c Thu Nov 12 14:39:23 2009 -0800
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c Tue Jan 26 13:03:40 2010 +0000
@@ -1072,6 +1072,17 @@
return 0;
}
+static PyObject *qemu_py_chardev_handle_connect(qemu_py_chardev *self,
+ PyObject *args)
+{
+ if (!self->chr)
+ Py_RETURN_NONE;
+
+ qemu_chr_connect(self->chr);
+
+ Py_RETURN_NONE;
+}
+
static PyObject *qemu_py_chardev_set_handlers(qemu_py_chardev *self,
PyObject *args, PyObject *kwds)
{
@@ -1147,6 +1158,9 @@
};
static PyMethodDef qemu_py_chardev_methods[] = {
+ {"handle_connect", (PyCFunction)qemu_py_chardev_handle_connect,
+ METH_NOARGS,
+ "Handle character device connect if required"},
{"set_handlers", (PyCFunction)qemu_py_chardev_set_handlers,
METH_VARARGS|METH_KEYWORDS,
"Set event handlers"},
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c Thu Nov 12 14:39:23 2009 -0800
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c Tue Jan 26 13:03:40 2010 +0000
@@ -123,6 +123,12 @@
}
}
+void qemu_chr_connect(CharDriverState *s)
+{
+ if (s->chr_connect)
+ s->chr_connect(s);
+}
+
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
{
return s->chr_write(s, buf, len);
@@ -605,6 +611,20 @@
return qemu_chr_open_fd(-1, fd_out);
}
+static CharDriverState *qemu_chr_open_tempfile_out(const char *temp_file)
+{
+ CharDriverState *ret = NULL;
+ const char *temp_format = "/tmp/%s";
+ char *fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file)));
+ if (fname)
+ {
+ sprintf(fname, temp_format, temp_file);
+ ret = qemu_chr_open_file_out(fname);
+ qemu_free(fname);
+ }
+ return ret;
+}
+
static CharDriverState *qemu_chr_open_pipe(const char *filename)
{
int fd_in, fd_out;
@@ -1757,6 +1777,29 @@
return qemu_chr_open_win_file(fd_out);
}
+
+static CharDriverState *qemu_chr_open_win_tempfile_out(const char *temp_file)
+{
+ CharDriverState *ret = NULL;
+ char* fname;
+ const char* temp_format = "%s\\%s";
+ const char* temp_path;
+
+ temp_path = getenv("TEMP");
+ if (temp_path)
+ {
+ fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file) + strlen(temp_format)));
+ if (fname)
+ {
+ sprintf(fname, temp_format, temp_path, temp_file);
+ ret = qemu_chr_open_win_file_out(fname);
+ qemu_free(fname);
+ }
+ }
+
+ return ret;
+}
+
#endif /* !_WIN32 */
/***********************************************************/
@@ -1886,6 +1929,8 @@
int do_telnetopt;
int do_nodelay;
int is_unix;
+ int wait_connect;
+ int device_handles_connect;
} TCPCharDriver;
static void tcp_chr_accept(void *opaque);
@@ -2063,6 +2108,26 @@
tcp_chr_connect(chr);
}
+static void tcp_chr_do_connect(CharDriverState* chr)
+{
+ TCPCharDriver *driver = (TCPCharDriver*)chr->opaque;
+ if (driver->device_handles_connect)
+ {
+ if (-1 != driver->listen_fd)
+ {
+ printf("QEMU waiting for connection...\n");
+ tcp_chr_accept(chr);
+ socket_set_nonblock(driver->listen_fd);
+ }
+ else
+ {
+ driver->connected = 1;
+ socket_set_nodelay(driver->fd);
+ tcp_chr_connect(chr);
+ }
+ }
+}
+
static void tcp_chr_close(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
@@ -2083,6 +2148,7 @@
int is_listen = 0;
int is_waitconnect = 1;
int do_nodelay = 0;
+ int is_device_handles_connect = 0;
const char *ptr;
ptr = host_str;
@@ -2096,6 +2162,8 @@
do_nodelay = 1;
} else if (!strncmp(ptr,"to=",3)) {
/* nothing, inet_listen() parses this one */;
+ } else if (!strncmp(ptr, "devicehandlesconnect", 20) && !is_unix) {
+ is_device_handles_connect = 1;
} else {
printf("Unknown option: %s\n", ptr);
goto fail;
@@ -2107,6 +2175,7 @@
chr = qemu_mallocz(sizeof(CharDriverState));
if (!chr)
goto fail;
+
s = qemu_mallocz(sizeof(TCPCharDriver));
if (!s)
goto fail;
@@ -2147,10 +2216,13 @@
s->listen_fd = -1;
s->is_unix = is_unix;
s->do_nodelay = do_nodelay && !is_unix;
+ s->wait_connect = is_waitconnect;
+ s->device_handles_connect = is_device_handles_connect;
chr->opaque = s;
chr->chr_write = tcp_chr_write;
chr->chr_close = tcp_chr_close;
+ chr->chr_connect = tcp_chr_do_connect;
if (is_listen) {
s->listen_fd = fd;
@@ -2158,13 +2230,17 @@
if (is_telnet)
s->do_telnetopt = 1;
} else {
- s->connected = 1;
s->fd = fd;
- socket_set_nodelay(fd);
- tcp_chr_connect(chr);
+
+ if (!is_device_handles_connect)
+ {
+ s->connected = 1;
+ socket_set_nodelay(fd);
+ tcp_chr_connect(chr);
+ }
}
- if (is_listen && is_waitconnect) {
+ if (is_listen && is_waitconnect && !is_device_handles_connect) {
printf("QEMU waiting for connection on: %s\n",
chr->filename ? chr->filename : host_str);
tcp_chr_accept(chr);
@@ -2220,6 +2296,8 @@
chr = qemu_chr_open_tcp(p, 0, 1);
} else if (strstart(filename, "file:", &p)) {
chr = qemu_chr_open_file_out(p);
+ } else if (strstart(filename, "tempfile:", &p)) {
+ chr = qemu_chr_open_tempfile_out(p);
} else if (strstart(filename, "pipe:", &p)) {
chr = qemu_chr_open_pipe(p);
} else if (!strcmp(filename, "pty")) {
@@ -2252,6 +2330,9 @@
if (strstart(filename, "file:", &p)) {
chr = qemu_chr_open_win_file_out(p);
} else
+ if (strstart(filename, "tempfile:", &p)) {
+ chr = qemu_chr_open_win_tempfile_out(p);
+ } else
if (strstart(filename, "stdio", &p)) {
return qemu_chr_open_win_stdio(filename);
} else
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h Thu Nov 12 14:39:23 2009 -0800
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h Tue Jan 26 13:03:40 2010 +0000
@@ -46,6 +46,7 @@
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
void (*chr_update_read_handler)(struct CharDriverState *s);
int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
+ void (*chr_connect)(struct CharDriverState *s);
IOEventHandler *chr_event;
IOCanRWHandler *chr_can_read;
IOReadHandler *chr_read;
@@ -64,6 +65,7 @@
CharDriverState *qemu_chr_open(const char *label, const char *filename);
void qemu_chr_close(CharDriverState *chr);
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
+void qemu_chr_connect(CharDriverState *s);
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
void qemu_chr_send_event(CharDriverState *s, int event);
void qemu_chr_add_handlers(CharDriverState *s,
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c Thu Nov 12 14:39:23 2009 -0800
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c Tue Jan 26 13:03:40 2010 +0000
@@ -4666,14 +4666,12 @@
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
monitor_device = "vc";
-
- serial_devices[0] = "vc:80Cx24C";
- for(i = 1; i < MAX_SERIAL_PORTS; i++)
+
+ for(i = 0; i < MAX_SERIAL_PORTS; i++)
serial_devices[i] = NULL;
serial_device_index = 0;
-
- parallel_devices[0] = "vc:640x480";
- for(i = 1; i < MAX_PARALLEL_PORTS; i++)
+
+ for(i = 0; i < MAX_PARALLEL_PORTS; i++)
parallel_devices[i] = NULL;
parallel_device_index = 0;