Commit c4b1fcc0f9594cae64d5bf172548a522db0c2545

Authored by bellard
1 parent 0f35920c

added I/O API - io port API change - added multiple network interface support - …

…redirect serial port to a pseudo terminal if using graphical mode


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@663 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 349 additions and 286 deletions
@@ -39,6 +39,7 @@ @@ -39,6 +39,7 @@
39 #include <sys/poll.h> 39 #include <sys/poll.h>
40 #include <errno.h> 40 #include <errno.h>
41 #include <sys/wait.h> 41 #include <sys/wait.h>
  42 +#include <pty.h>
42 43
43 #include <sys/ioctl.h> 44 #include <sys/ioctl.h>
44 #include <sys/socket.h> 45 #include <sys/socket.h>
@@ -81,6 +82,7 @@ const char *bios_dir = CONFIG_QEMU_SHAREDIR; @@ -81,6 +82,7 @@ const char *bios_dir = CONFIG_QEMU_SHAREDIR;
81 char phys_ram_file[1024]; 82 char phys_ram_file[1024];
82 CPUState *global_env; 83 CPUState *global_env;
83 CPUState *cpu_single_env; 84 CPUState *cpu_single_env;
  85 +void *ioport_opaque[MAX_IOPORTS];
84 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; 86 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
85 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; 87 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
86 BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD]; 88 BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
@@ -93,11 +95,14 @@ int boot_device = &#39;c&#39;; @@ -93,11 +95,14 @@ int boot_device = &#39;c&#39;;
93 static int ram_size; 95 static int ram_size;
94 static char network_script[1024]; 96 static char network_script[1024];
95 int pit_min_timer_count = 0; 97 int pit_min_timer_count = 0;
  98 +int nb_nics;
  99 +NetDriverState nd_table[MAX_NICS];
  100 +SerialState *serial_console;
96 101
97 /***********************************************************/ 102 /***********************************************************/
98 /* x86 io ports */ 103 /* x86 io ports */
99 104
100 -uint32_t default_ioport_readb(CPUState *env, uint32_t address) 105 +uint32_t default_ioport_readb(void *opaque, uint32_t address)
101 { 106 {
102 #ifdef DEBUG_UNUSED_IOPORT 107 #ifdef DEBUG_UNUSED_IOPORT
103 fprintf(stderr, "inb: port=0x%04x\n", address); 108 fprintf(stderr, "inb: port=0x%04x\n", address);
@@ -105,7 +110,7 @@ uint32_t default_ioport_readb(CPUState *env, uint32_t address) @@ -105,7 +110,7 @@ uint32_t default_ioport_readb(CPUState *env, uint32_t address)
105 return 0xff; 110 return 0xff;
106 } 111 }
107 112
108 -void default_ioport_writeb(CPUState *env, uint32_t address, uint32_t data) 113 +void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
109 { 114 {
110 #ifdef DEBUG_UNUSED_IOPORT 115 #ifdef DEBUG_UNUSED_IOPORT
111 fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data); 116 fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
@@ -113,21 +118,21 @@ void default_ioport_writeb(CPUState *env, uint32_t address, uint32_t data) @@ -113,21 +118,21 @@ void default_ioport_writeb(CPUState *env, uint32_t address, uint32_t data)
113 } 118 }
114 119
115 /* default is to make two byte accesses */ 120 /* default is to make two byte accesses */
116 -uint32_t default_ioport_readw(CPUState *env, uint32_t address) 121 +uint32_t default_ioport_readw(void *opaque, uint32_t address)
117 { 122 {
118 uint32_t data; 123 uint32_t data;
119 - data = ioport_read_table[0][address & (MAX_IOPORTS - 1)](env, address);  
120 - data |= ioport_read_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1) << 8; 124 + data = ioport_read_table[0][address & (MAX_IOPORTS - 1)](opaque, address);
  125 + data |= ioport_read_table[0][(address + 1) & (MAX_IOPORTS - 1)](opaque, address + 1) << 8;
121 return data; 126 return data;
122 } 127 }
123 128
124 -void default_ioport_writew(CPUState *env, uint32_t address, uint32_t data) 129 +void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
125 { 130 {
126 - ioport_write_table[0][address & (MAX_IOPORTS - 1)](env, address, data & 0xff);  
127 - ioport_write_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1, (data >> 8) & 0xff); 131 + ioport_write_table[0][address & (MAX_IOPORTS - 1)](opaque, address, data & 0xff);
  132 + ioport_write_table[0][(address + 1) & (MAX_IOPORTS - 1)](opaque, address + 1, (data >> 8) & 0xff);
128 } 133 }
129 134
130 -uint32_t default_ioport_readl(CPUState *env, uint32_t address) 135 +uint32_t default_ioport_readl(void *opaque, uint32_t address)
131 { 136 {
132 #ifdef DEBUG_UNUSED_IOPORT 137 #ifdef DEBUG_UNUSED_IOPORT
133 fprintf(stderr, "inl: port=0x%04x\n", address); 138 fprintf(stderr, "inl: port=0x%04x\n", address);
@@ -135,7 +140,7 @@ uint32_t default_ioport_readl(CPUState *env, uint32_t address) @@ -135,7 +140,7 @@ uint32_t default_ioport_readl(CPUState *env, uint32_t address)
135 return 0xffffffff; 140 return 0xffffffff;
136 } 141 }
137 142
138 -void default_ioport_writel(CPUState *env, uint32_t address, uint32_t data) 143 +void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
139 { 144 {
140 #ifdef DEBUG_UNUSED_IOPORT 145 #ifdef DEBUG_UNUSED_IOPORT
141 fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data); 146 fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
@@ -157,38 +162,52 @@ void init_ioports(void) @@ -157,38 +162,52 @@ void init_ioports(void)
157 } 162 }
158 163
159 /* size is the word size in byte */ 164 /* size is the word size in byte */
160 -int register_ioport_read(int start, int length, IOPortReadFunc *func, int size) 165 +int register_ioport_read(int start, int length, int size,
  166 + IOPortReadFunc *func, void *opaque)
161 { 167 {
162 int i, bsize; 168 int i, bsize;
163 169
164 - if (size == 1) 170 + if (size == 1) {
165 bsize = 0; 171 bsize = 0;
166 - else if (size == 2) 172 + } else if (size == 2) {
167 bsize = 1; 173 bsize = 1;
168 - else if (size == 4) 174 + } else if (size == 4) {
169 bsize = 2; 175 bsize = 2;
170 - else 176 + } else {
  177 + hw_error("register_ioport_read: invalid size");
171 return -1; 178 return -1;
172 - for(i = start; i < start + length; i += size) 179 + }
  180 + for(i = start; i < start + length; i += size) {
173 ioport_read_table[bsize][i] = func; 181 ioport_read_table[bsize][i] = func;
  182 + if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
  183 + hw_error("register_ioport_read: invalid opaque");
  184 + ioport_opaque[i] = opaque;
  185 + }
174 return 0; 186 return 0;
175 } 187 }
176 188
177 /* size is the word size in byte */ 189 /* size is the word size in byte */
178 -int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size) 190 +int register_ioport_write(int start, int length, int size,
  191 + IOPortWriteFunc *func, void *opaque)
179 { 192 {
180 int i, bsize; 193 int i, bsize;
181 194
182 - if (size == 1) 195 + if (size == 1) {
183 bsize = 0; 196 bsize = 0;
184 - else if (size == 2) 197 + } else if (size == 2) {
185 bsize = 1; 198 bsize = 1;
186 - else if (size == 4) 199 + } else if (size == 4) {
187 bsize = 2; 200 bsize = 2;
188 - else 201 + } else {
  202 + hw_error("register_ioport_write: invalid size");
189 return -1; 203 return -1;
190 - for(i = start; i < start + length; i += size) 204 + }
  205 + for(i = start; i < start + length; i += size) {
191 ioport_write_table[bsize][i] = func; 206 ioport_write_table[bsize][i] = func;
  207 + if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
  208 + hw_error("register_ioport_read: invalid opaque");
  209 + ioport_opaque[i] = opaque;
  210 + }
192 return 0; 211 return 0;
193 } 212 }
194 213
@@ -238,32 +257,38 @@ int load_image(const char *filename, uint8_t *addr) @@ -238,32 +257,38 @@ int load_image(const char *filename, uint8_t *addr)
238 257
239 void cpu_outb(CPUState *env, int addr, int val) 258 void cpu_outb(CPUState *env, int addr, int val)
240 { 259 {
241 - ioport_write_table[0][addr & (MAX_IOPORTS - 1)](env, addr, val); 260 + addr &= (MAX_IOPORTS - 1);
  261 + ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
242 } 262 }
243 263
244 void cpu_outw(CPUState *env, int addr, int val) 264 void cpu_outw(CPUState *env, int addr, int val)
245 { 265 {
246 - ioport_write_table[1][addr & (MAX_IOPORTS - 1)](env, addr, val); 266 + addr &= (MAX_IOPORTS - 1);
  267 + ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
247 } 268 }
248 269
249 void cpu_outl(CPUState *env, int addr, int val) 270 void cpu_outl(CPUState *env, int addr, int val)
250 { 271 {
251 - ioport_write_table[2][addr & (MAX_IOPORTS - 1)](env, addr, val); 272 + addr &= (MAX_IOPORTS - 1);
  273 + ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
252 } 274 }
253 275
254 int cpu_inb(CPUState *env, int addr) 276 int cpu_inb(CPUState *env, int addr)
255 { 277 {
256 - return ioport_read_table[0][addr & (MAX_IOPORTS - 1)](env, addr); 278 + addr &= (MAX_IOPORTS - 1);
  279 + return ioport_read_table[0][addr](ioport_opaque[addr], addr);
257 } 280 }
258 281
259 int cpu_inw(CPUState *env, int addr) 282 int cpu_inw(CPUState *env, int addr)
260 { 283 {
261 - return ioport_read_table[1][addr & (MAX_IOPORTS - 1)](env, addr); 284 + addr &= (MAX_IOPORTS - 1);
  285 + return ioport_read_table[1][addr](ioport_opaque[addr], addr);
262 } 286 }
263 287
264 int cpu_inl(CPUState *env, int addr) 288 int cpu_inl(CPUState *env, int addr)
265 { 289 {
266 - return ioport_read_table[2][addr & (MAX_IOPORTS - 1)](env, addr); 290 + addr &= (MAX_IOPORTS - 1);
  291 + return ioport_read_table[2][addr](ioport_opaque[addr], addr);
267 } 292 }
268 293
269 /***********************************************************/ 294 /***********************************************************/
@@ -389,171 +414,34 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) @@ -389,171 +414,34 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
389 return res.ll; 414 return res.ll;
390 } 415 }
391 416
392 -#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */  
393 -static int term_got_escape, term_command;  
394 -static unsigned char term_cmd_buf[128];  
395 -  
396 -typedef struct term_cmd_t {  
397 - const unsigned char *name;  
398 - void (*handler)(unsigned char *params);  
399 -} term_cmd_t;  
400 -  
401 -static void do_change_cdrom (unsigned char *params);  
402 -static void do_change_fd0 (unsigned char *params);  
403 -static void do_change_fd1 (unsigned char *params);  
404 -  
405 -static term_cmd_t term_cmds[] = {  
406 - { "changecd", &do_change_cdrom, },  
407 - { "changefd0", &do_change_fd0, },  
408 - { "changefd1", &do_change_fd1, },  
409 - { NULL, NULL, },  
410 -};  
411 -  
412 -void term_print_help(void)  
413 -{  
414 - printf("\n"  
415 - "C-a h print this help\n"  
416 - "C-a x exit emulatior\n"  
417 - "C-a d switch on/off debug log\n"  
418 - "C-a s save disk data back to file (if -snapshot)\n"  
419 - "C-a b send break (magic sysrq)\n"  
420 - "C-a c send qemu internal command\n"  
421 - "C-a C-a send C-a\n"  
422 - );  
423 -}  
424 -  
425 -static void do_change_cdrom (unsigned char *params)  
426 -{  
427 - /* Dunno how to do it... */  
428 -}  
429 -  
430 -static void do_change_fd (int fd, unsigned char *params)  
431 -{  
432 - unsigned char *name_start, *name_end, *ros;  
433 - int ro;  
434 -  
435 - for (name_start = params;  
436 - isspace(*name_start); name_start++)  
437 - continue;  
438 - if (*name_start == '\0')  
439 - return;  
440 - for (name_end = name_start;  
441 - !isspace(*name_end) && *name_end != '\0'; name_end++)  
442 - continue;  
443 - for (ros = name_end + 1; isspace(*ros); ros++)  
444 - continue;  
445 - if (ros[0] == 'r' && ros[1] == 'o')  
446 - ro = 1;  
447 - else  
448 - ro = 0;  
449 - *name_end = '\0';  
450 - printf("Change fd %d to %s (%s)\n", fd, name_start, params);  
451 - fdctrl_disk_change(fd, name_start, ro);  
452 -}  
453 -  
454 -static void do_change_fd0 (unsigned char *params)  
455 -{  
456 - do_change_fd(0, params);  
457 -}  
458 -  
459 -static void do_change_fd1 (unsigned char *params)  
460 -{  
461 - do_change_fd(1, params);  
462 -} 417 +/***********************************************************/
  418 +/* serial device */
463 419
464 -static void term_treat_command(void) 420 +int serial_open_device(void)
465 { 421 {
466 - unsigned char *cmd_start, *cmd_end;  
467 - int i; 422 + char slave_name[1024];
  423 + int master_fd, slave_fd;
468 424
469 - for (cmd_start = term_cmd_buf; isspace(*cmd_start); cmd_start++)  
470 - continue;  
471 - for (cmd_end = cmd_start;  
472 - !isspace(*cmd_end) && *cmd_end != '\0'; cmd_end++)  
473 - continue;  
474 - for (i = 0; term_cmds[i].name != NULL; i++) {  
475 - if (strlen(term_cmds[i].name) == (cmd_end - cmd_start) &&  
476 - memcmp(term_cmds[i].name, cmd_start, cmd_end - cmd_start) == 0) {  
477 - (*term_cmds[i].handler)(cmd_end + 1);  
478 - return;  
479 - }  
480 - }  
481 - *cmd_end = '\0';  
482 - printf("Unknown term command: %s\n", cmd_start);  
483 -}  
484 -  
485 -extern FILE *logfile;  
486 -  
487 -/* called when a char is received */  
488 -void term_received_byte(int ch)  
489 -{  
490 - if (term_command) {  
491 - if (ch == '\n' || ch == '\r' || term_command == 127) {  
492 - printf("\n");  
493 - term_treat_command();  
494 - term_command = 0;  
495 - } else {  
496 - if (ch == 0x7F || ch == 0x08) {  
497 - if (term_command > 1) {  
498 - term_cmd_buf[--term_command - 1] = '\0';  
499 - printf("\r "  
500 - " ");  
501 - printf("\r> %s", term_cmd_buf);  
502 - }  
503 - } else if (ch > 0x1f) {  
504 - term_cmd_buf[term_command++ - 1] = ch;  
505 - term_cmd_buf[term_command - 1] = '\0';  
506 - printf("\r> %s", term_cmd_buf);  
507 - }  
508 - fflush(stdout);  
509 - }  
510 - } else if (term_got_escape) {  
511 - term_got_escape = 0;  
512 - switch(ch) {  
513 - case 'h':  
514 - term_print_help();  
515 - break;  
516 - case 'x':  
517 - exit(0);  
518 - break;  
519 - case 's':  
520 - {  
521 - int i;  
522 - for (i = 0; i < MAX_DISKS; i++) {  
523 - if (bs_table[i])  
524 - bdrv_commit(bs_table[i]);  
525 - }  
526 - }  
527 - break;  
528 - case 'b':  
529 - serial_receive_break();  
530 - break;  
531 - case 'c':  
532 - printf("> ");  
533 - fflush(stdout);  
534 - term_command = 1;  
535 - break;  
536 - case 'd':  
537 - cpu_set_log(CPU_LOG_ALL);  
538 - break;  
539 - case TERM_ESCAPE:  
540 - goto send_char;  
541 - }  
542 - } else if (ch == TERM_ESCAPE) {  
543 - term_got_escape = 1; 425 + if (serial_console == NULL && nographic) {
  426 + /* use console for serial port */
  427 + return 0;
544 } else { 428 } else {
545 - send_char:  
546 - serial_receive_byte(ch); 429 + if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
  430 + fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
  431 + return -1;
  432 + }
  433 + fprintf(stderr, "Serial port redirected to %s\n", slave_name);
  434 + return master_fd;
547 } 435 }
548 } 436 }
549 437
550 /***********************************************************/ 438 /***********************************************************/
551 /* Linux network device redirector */ 439 /* Linux network device redirector */
552 440
553 -int net_init(void) 441 +static int tun_open(char *ifname, int ifname_size)
554 { 442 {
555 struct ifreq ifr; 443 struct ifreq ifr;
556 - int fd, ret, pid, status; 444 + int fd, ret;
557 445
558 fd = open("/dev/net/tun", O_RDWR); 446 fd = open("/dev/net/tun", O_RDWR);
559 if (fd < 0) { 447 if (fd < 0) {
@@ -570,32 +458,62 @@ int net_init(void) @@ -570,32 +458,62 @@ int net_init(void)
570 return -1; 458 return -1;
571 } 459 }
572 printf("Connected to host network interface: %s\n", ifr.ifr_name); 460 printf("Connected to host network interface: %s\n", ifr.ifr_name);
  461 + pstrcpy(ifname, ifname_size, ifr.ifr_name);
573 fcntl(fd, F_SETFL, O_NONBLOCK); 462 fcntl(fd, F_SETFL, O_NONBLOCK);
574 - net_fd = fd; 463 + return fd;
  464 +}
575 465
576 - /* try to launch network init script */  
577 - pid = fork();  
578 - if (pid >= 0) {  
579 - if (pid == 0) {  
580 - execl(network_script, network_script, ifr.ifr_name, NULL);  
581 - exit(1); 466 +static int net_init(void)
  467 +{
  468 + int pid, status, launch_script, i;
  469 + NetDriverState *nd;
  470 + char *args[MAX_NICS + 2];
  471 + char **parg;
  472 +
  473 + launch_script = 0;
  474 + for(i = 0; i < nb_nics; i++) {
  475 + nd = &nd_table[i];
  476 + if (nd->fd < 0) {
  477 + nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
  478 + if (nd->fd >= 0)
  479 + launch_script = 1;
582 } 480 }
583 - while (waitpid(pid, &status, 0) != pid);  
584 - if (!WIFEXITED(status) ||  
585 - WEXITSTATUS(status) != 0) {  
586 - fprintf(stderr, "%s: could not launch network script for '%s'\n",  
587 - network_script, ifr.ifr_name); 481 + }
  482 +
  483 + if (launch_script) {
  484 + /* try to launch network init script */
  485 + pid = fork();
  486 + if (pid >= 0) {
  487 + if (pid == 0) {
  488 + parg = args;
  489 + *parg++ = network_script;
  490 + for(i = 0; i < nb_nics; i++) {
  491 + nd = &nd_table[i];
  492 + if (nd->fd >= 0) {
  493 + *parg++ = nd->ifname;
  494 + }
  495 + }
  496 + *parg++ = NULL;
  497 + execv(network_script, args);
  498 + exit(1);
  499 + }
  500 + while (waitpid(pid, &status, 0) != pid);
  501 + if (!WIFEXITED(status) ||
  502 + WEXITSTATUS(status) != 0) {
  503 + fprintf(stderr, "%s: could not launch network script\n",
  504 + network_script);
  505 + }
588 } 506 }
589 } 507 }
590 return 0; 508 return 0;
591 } 509 }
592 510
593 -void net_send_packet(int net_fd, const uint8_t *buf, int size) 511 +void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
594 { 512 {
595 #ifdef DEBUG_NE2000 513 #ifdef DEBUG_NE2000
596 printf("NE2000: sending packet size=%d\n", size); 514 printf("NE2000: sending packet size=%d\n", size);
597 #endif 515 #endif
598 - write(net_fd, buf, size); 516 + write(nd->fd, buf, size);
599 } 517 }
600 518
601 /***********************************************************/ 519 /***********************************************************/
@@ -702,6 +620,37 @@ static void host_alarm_handler(int host_signum, siginfo_t *info, @@ -702,6 +620,37 @@ static void host_alarm_handler(int host_signum, siginfo_t *info,
702 } 620 }
703 } 621 }
704 622
  623 +#define MAX_IO_HANDLERS 64
  624 +
  625 +typedef struct IOHandlerRecord {
  626 + int fd;
  627 + IOCanRWHandler *fd_can_read;
  628 + IOReadHandler *fd_read;
  629 + void *opaque;
  630 + /* temporary data */
  631 + struct pollfd *ufd;
  632 + int max_size;
  633 +} IOHandlerRecord;
  634 +
  635 +static IOHandlerRecord io_handlers[MAX_IO_HANDLERS];
  636 +static int nb_io_handlers = 0;
  637 +
  638 +int add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
  639 + IOReadHandler *fd_read, void *opaque)
  640 +{
  641 + IOHandlerRecord *ioh;
  642 +
  643 + if (nb_io_handlers >= MAX_IO_HANDLERS)
  644 + return -1;
  645 + ioh = &io_handlers[nb_io_handlers];
  646 + ioh->fd = fd;
  647 + ioh->fd_can_read = fd_can_read;
  648 + ioh->fd_read = fd_read;
  649 + ioh->opaque = opaque;
  650 + nb_io_handlers++;
  651 + return 0;
  652 +}
  653 +
705 /* main execution loop */ 654 /* main execution loop */
706 655
707 CPUState *cpu_gdbstub_get_env(void *opaque) 656 CPUState *cpu_gdbstub_get_env(void *opaque)
@@ -711,12 +660,10 @@ CPUState *cpu_gdbstub_get_env(void *opaque) @@ -711,12 +660,10 @@ CPUState *cpu_gdbstub_get_env(void *opaque)
711 660
712 int main_loop(void *opaque) 661 int main_loop(void *opaque)
713 { 662 {
714 - struct pollfd ufds[3], *pf, *serial_ufd, *gdb_ufd;  
715 -#if defined (TARGET_I386)  
716 - struct pollfd *net_ufd;  
717 -#endif  
718 - int ret, n, timeout, serial_ok;  
719 - uint8_t ch; 663 + struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf, *gdb_ufd;
  664 + int ret, n, timeout, serial_ok, max_size, i;
  665 + uint8_t buf[4096];
  666 + IOHandlerRecord *ioh;
720 CPUState *env = global_env; 667 CPUState *env = global_env;
721 668
722 if (!term_inited) { 669 if (!term_inited) {
@@ -747,24 +694,26 @@ int main_loop(void *opaque) @@ -747,24 +694,26 @@ int main_loop(void *opaque)
747 timeout = 10; 694 timeout = 10;
748 else 695 else
749 timeout = 0; 696 timeout = 0;
  697 +
750 /* poll any events */ 698 /* poll any events */
751 - serial_ufd = NULL;  
752 pf = ufds; 699 pf = ufds;
753 - if (serial_ok && serial_can_receive()) {  
754 - serial_ufd = pf;  
755 - pf->fd = 0;  
756 - pf->events = POLLIN;  
757 - pf++;  
758 - }  
759 -#if defined (TARGET_I386)  
760 - net_ufd = NULL;  
761 - if (net_fd > 0 && ne2000_can_receive()) {  
762 - net_ufd = pf;  
763 - pf->fd = net_fd;  
764 - pf->events = POLLIN;  
765 - pf++; 700 + ioh = io_handlers;
  701 + for(i = 0; i < nb_io_handlers; i++) {
  702 + max_size = ioh->fd_can_read(ioh->opaque);
  703 + if (max_size > 0) {
  704 + if (max_size > sizeof(buf))
  705 + max_size = sizeof(buf);
  706 + pf->fd = ioh->fd;
  707 + pf->events = POLLIN;
  708 + ioh->ufd = pf;
  709 + pf++;
  710 + } else {
  711 + ioh->ufd = NULL;
  712 + }
  713 + ioh->max_size = max_size;
  714 + ioh++;
766 } 715 }
767 -#endif 716 +
768 gdb_ufd = NULL; 717 gdb_ufd = NULL;
769 if (gdbstub_fd > 0) { 718 if (gdbstub_fd > 0) {
770 gdb_ufd = pf; 719 gdb_ufd = pf;
@@ -775,29 +724,17 @@ int main_loop(void *opaque) @@ -775,29 +724,17 @@ int main_loop(void *opaque)
775 724
776 ret = poll(ufds, pf - ufds, timeout); 725 ret = poll(ufds, pf - ufds, timeout);
777 if (ret > 0) { 726 if (ret > 0) {
778 - if (serial_ufd && (serial_ufd->revents & POLLIN)) {  
779 - n = read(0, &ch, 1);  
780 - if (n == 1) {  
781 - term_received_byte(ch);  
782 - } else {  
783 - /* Closed, stop polling. */  
784 - serial_ok = 0;  
785 - }  
786 - }  
787 -#if defined (TARGET_I386)  
788 - if (net_ufd && (net_ufd->revents & POLLIN)) {  
789 - uint8_t buf[MAX_ETH_FRAME_SIZE];  
790 -  
791 - n = read(net_fd, buf, MAX_ETH_FRAME_SIZE);  
792 - if (n > 0) {  
793 - if (n < 60) {  
794 - memset(buf + n, 0, 60 - n);  
795 - n = 60; 727 + ioh = io_handlers;
  728 + for(i = 0; i < nb_io_handlers; i++) {
  729 + pf = ioh->ufd;
  730 + if (pf) {
  731 + n = read(ioh->fd, buf, ioh->max_size);
  732 + if (n > 0) {
  733 + ioh->fd_read(ioh->opaque, buf, n);
796 } 734 }
797 - ne2000_receive(buf, n);  
798 } 735 }
  736 + ioh++;
799 } 737 }
800 -#endif  
801 if (gdb_ufd && (gdb_ufd->revents & POLLIN)) { 738 if (gdb_ufd && (gdb_ufd->revents & POLLIN)) {
802 uint8_t buf[1]; 739 uint8_t buf[1];
803 /* stop emulation if requested by gdb */ 740 /* stop emulation if requested by gdb */
@@ -845,15 +782,18 @@ void help(void) @@ -845,15 +782,18 @@ void help(void)
845 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n" 782 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
846 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n" 783 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
847 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" 784 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
848 - "-cdrom file use 'file' as IDE cdrom 2 image\n" 785 + "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
849 "-boot [a|b|c|d] boot on floppy (a, b), hard disk (c) or CD-ROM (d)\n" 786 "-boot [a|b|c|d] boot on floppy (a, b), hard disk (c) or CD-ROM (d)\n"
850 "-snapshot write to temporary files instead of disk image files\n" 787 "-snapshot write to temporary files instead of disk image files\n"
851 "-m megs set virtual RAM size to megs MB\n" 788 "-m megs set virtual RAM size to megs MB\n"
  789 + "-nographic disable graphical output and redirect serial I/Os to console\n"
  790 + "\n"
  791 + "Network options:\n"
852 "-n script set network init script [default=%s]\n" 792 "-n script set network init script [default=%s]\n"
853 - "-tun-fd fd this fd talks to tap/tun, use it.\n"  
854 - "-nographic disable graphical output\n" 793 + "-nics n simulate 'n' network interfaces [default=1]\n"
  794 + "-tun-fd fd0[,...] use these fds as already opened tap/tun interfaces\n"
855 "\n" 795 "\n"
856 - "Linux boot specific (does not require PC BIOS):\n" 796 + "Linux boot specific:\n"
857 "-kernel bzImage use 'bzImage' as kernel image\n" 797 "-kernel bzImage use 'bzImage' as kernel image\n"
858 "-append cmdline use 'cmdline' as kernel command line\n" 798 "-append cmdline use 'cmdline' as kernel command line\n"
859 "-initrd file use 'file' as initial ram disk\n" 799 "-initrd file use 'file' as initial ram disk\n"
@@ -904,7 +844,8 @@ struct option long_options[] = { @@ -904,7 +844,8 @@ struct option long_options[] = {
904 { "boot", 1, NULL, 0, }, 844 { "boot", 1, NULL, 0, },
905 { "fda", 1, NULL, 0, }, 845 { "fda", 1, NULL, 0, },
906 { "fdb", 1, NULL, 0, }, 846 { "fdb", 1, NULL, 0, },
907 - { "no-code-copy", 0, NULL, 0}, 847 + { "no-code-copy", 0, NULL, 0 },
  848 + { "nics", 1, NULL, 0 },
908 { NULL, 0, NULL, 0 }, 849 { NULL, 0, NULL, 0 },
909 }; 850 };
910 851
@@ -931,7 +872,7 @@ static uint8_t *signal_stack; @@ -931,7 +872,7 @@ static uint8_t *signal_stack;
931 872
932 int main(int argc, char **argv) 873 int main(int argc, char **argv)
933 { 874 {
934 - int c, i, use_gdbstub, gdbstub_port, long_index; 875 + int c, i, use_gdbstub, gdbstub_port, long_index, has_cdrom;
935 int snapshot, linux_boot; 876 int snapshot, linux_boot;
936 struct sigaction act; 877 struct sigaction act;
937 struct itimerval itv; 878 struct itimerval itv;
@@ -940,6 +881,7 @@ int main(int argc, char **argv) @@ -940,6 +881,7 @@ int main(int argc, char **argv)
940 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; 881 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
941 const char *kernel_filename, *kernel_cmdline; 882 const char *kernel_filename, *kernel_cmdline;
942 DisplayState *ds = &display_state; 883 DisplayState *ds = &display_state;
  884 + int cyls, heads, secs;
943 885
944 /* we never want that malloc() uses mmap() */ 886 /* we never want that malloc() uses mmap() */
945 mallopt(M_MMAP_THRESHOLD, 4096 * 1024); 887 mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
@@ -950,15 +892,29 @@ int main(int argc, char **argv) @@ -950,15 +892,29 @@ int main(int argc, char **argv)
950 hd_filename[i] = NULL; 892 hd_filename[i] = NULL;
951 ram_size = 32 * 1024 * 1024; 893 ram_size = 32 * 1024 * 1024;
952 vga_ram_size = VGA_RAM_SIZE; 894 vga_ram_size = VGA_RAM_SIZE;
953 -#if defined (TARGET_I386)  
954 pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT); 895 pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
955 -#endif  
956 use_gdbstub = 0; 896 use_gdbstub = 0;
957 gdbstub_port = DEFAULT_GDBSTUB_PORT; 897 gdbstub_port = DEFAULT_GDBSTUB_PORT;
958 snapshot = 0; 898 snapshot = 0;
959 nographic = 0; 899 nographic = 0;
960 kernel_filename = NULL; 900 kernel_filename = NULL;
961 kernel_cmdline = ""; 901 kernel_cmdline = "";
  902 + has_cdrom = 1;
  903 + cyls = heads = secs = 0;
  904 +
  905 + nb_nics = 1;
  906 + for(i = 0; i < MAX_NICS; i++) {
  907 + NetDriverState *nd = &nd_table[i];
  908 + nd->fd = -1;
  909 + /* init virtual mac address */
  910 + nd->macaddr[0] = 0x52;
  911 + nd->macaddr[1] = 0x54;
  912 + nd->macaddr[2] = 0x00;
  913 + nd->macaddr[3] = 0x12;
  914 + nd->macaddr[4] = 0x34;
  915 + nd->macaddr[5] = 0x56 + i;
  916 + }
  917 +
962 for(;;) { 918 for(;;) {
963 c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index); 919 c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);
964 if (c == -1) 920 if (c == -1)
@@ -980,7 +936,6 @@ int main(int argc, char **argv) @@ -980,7 +936,6 @@ int main(int argc, char **argv)
980 break; 936 break;
981 case 4: 937 case 4:
982 { 938 {
983 - int cyls, heads, secs;  
984 const char *p; 939 const char *p;
985 p = optarg; 940 p = optarg;
986 cyls = strtol(p, (char **)&p, 0); 941 cyls = strtol(p, (char **)&p, 0);
@@ -992,10 +947,10 @@ int main(int argc, char **argv) @@ -992,10 +947,10 @@ int main(int argc, char **argv)
992 goto chs_fail; 947 goto chs_fail;
993 p++; 948 p++;
994 secs = strtol(p, (char **)&p, 0); 949 secs = strtol(p, (char **)&p, 0);
995 - if (*p != '\0')  
996 - goto chs_fail;  
997 - ide_set_geometry(0, cyls, heads, secs);  
998 - chs_fail: ; 950 + if (*p != '\0') {
  951 + chs_fail:
  952 + cyls = 0;
  953 + }
999 } 954 }
1000 break; 955 break;
1001 case 5: 956 case 5:
@@ -1007,20 +962,38 @@ int main(int argc, char **argv) @@ -1007,20 +962,38 @@ int main(int argc, char **argv)
1007 case 7: 962 case 7:
1008 kernel_cmdline = optarg; 963 kernel_cmdline = optarg;
1009 break; 964 break;
1010 -#if defined (TARGET_I386)  
1011 case 8: 965 case 8:
1012 - net_fd = atoi(optarg); 966 + {
  967 + const char *p;
  968 + int fd;
  969 + p = optarg;
  970 + nb_nics = 0;
  971 + for(;;) {
  972 + fd = strtol(p, (char **)&p, 0);
  973 + nd_table[nb_nics].fd = fd;
  974 + snprintf(nd_table[nb_nics].ifname,
  975 + sizeof(nd_table[nb_nics].ifname),
  976 + "fd%d", nb_nics);
  977 + nb_nics++;
  978 + if (*p == ',') {
  979 + p++;
  980 + } else if (*p != '\0') {
  981 + fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_nics);
  982 + exit(1);
  983 + }
  984 + }
  985 + }
1013 break; 986 break;
1014 -#endif  
1015 case 9: 987 case 9:
1016 hd_filename[2] = optarg; 988 hd_filename[2] = optarg;
  989 + has_cdrom = 0;
1017 break; 990 break;
1018 case 10: 991 case 10:
1019 hd_filename[3] = optarg; 992 hd_filename[3] = optarg;
1020 break; 993 break;
1021 case 11: 994 case 11:
1022 hd_filename[2] = optarg; 995 hd_filename[2] = optarg;
1023 - ide_set_cdrom(2, 1); 996 + has_cdrom = 1;
1024 break; 997 break;
1025 case 12: 998 case 12:
1026 boot_device = optarg[0]; 999 boot_device = optarg[0];
@@ -1039,6 +1012,13 @@ int main(int argc, char **argv) @@ -1039,6 +1012,13 @@ int main(int argc, char **argv)
1039 case 15: 1012 case 15:
1040 code_copy_enabled = 0; 1013 code_copy_enabled = 0;
1041 break; 1014 break;
  1015 + case 16:
  1016 + nb_nics = atoi(optarg);
  1017 + if (nb_nics < 1 || nb_nics > MAX_NICS) {
  1018 + fprintf(stderr, "qemu: invalid number of network interfaces\n");
  1019 + exit(1);
  1020 + }
  1021 + break;
1042 } 1022 }
1043 break; 1023 break;
1044 case 'h': 1024 case 'h':
@@ -1057,11 +1037,9 @@ int main(int argc, char **argv) @@ -1057,11 +1037,9 @@ int main(int argc, char **argv)
1057 case 'd': 1037 case 'd':
1058 cpu_set_log(CPU_LOG_ALL); 1038 cpu_set_log(CPU_LOG_ALL);
1059 break; 1039 break;
1060 -#if defined (TARGET_I386)  
1061 case 'n': 1040 case 'n':
1062 pstrcpy(network_script, sizeof(network_script), optarg); 1041 pstrcpy(network_script, sizeof(network_script), optarg);
1063 break; 1042 break;
1064 -#endif  
1065 case 's': 1043 case 's':
1066 use_gdbstub = 1; 1044 use_gdbstub = 1;
1067 break; 1045 break;
@@ -1102,11 +1080,8 @@ int main(int argc, char **argv) @@ -1102,11 +1080,8 @@ int main(int argc, char **argv)
1102 setvbuf(stdout, NULL, _IOLBF, 0); 1080 setvbuf(stdout, NULL, _IOLBF, 0);
1103 #endif 1081 #endif
1104 1082
1105 - /* init network tun interface */  
1106 -#if defined (TARGET_I386)  
1107 - if (net_fd < 0)  
1108 - net_init();  
1109 -#endif 1083 + /* init host network redirectors */
  1084 + net_init();
1110 1085
1111 /* init the memory */ 1086 /* init the memory */
1112 phys_ram_size = ram_size + vga_ram_size; 1087 phys_ram_size = ram_size + vga_ram_size;
@@ -1151,15 +1126,49 @@ int main(int argc, char **argv) @@ -1151,15 +1126,49 @@ int main(int argc, char **argv)
1151 } 1126 }
1152 #endif 1127 #endif
1153 1128
  1129 + /* we always create the cdrom drive, even if no disk is there */
  1130 + if (has_cdrom) {
  1131 + bs_table[2] = bdrv_new("cdrom");
  1132 + bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
  1133 + }
  1134 +
1154 /* open the virtual block devices */ 1135 /* open the virtual block devices */
1155 for(i = 0; i < MAX_DISKS; i++) { 1136 for(i = 0; i < MAX_DISKS; i++) {
1156 if (hd_filename[i]) { 1137 if (hd_filename[i]) {
1157 - bs_table[i] = bdrv_open(hd_filename[i], snapshot);  
1158 if (!bs_table[i]) { 1138 if (!bs_table[i]) {
  1139 + char buf[64];
  1140 + snprintf(buf, sizeof(buf), "hd%c", i + 'a');
  1141 + bs_table[i] = bdrv_new(buf);
  1142 + }
  1143 + if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
1159 fprintf(stderr, "qemu: could not open hard disk image '%s\n", 1144 fprintf(stderr, "qemu: could not open hard disk image '%s\n",
1160 hd_filename[i]); 1145 hd_filename[i]);
1161 exit(1); 1146 exit(1);
1162 } 1147 }
  1148 + if (i == 0 && cyls != 0)
  1149 + bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
  1150 + }
  1151 + }
  1152 +
  1153 + /* we always create at least one floppy disk */
  1154 + fd_table[0] = bdrv_new("fda");
  1155 + bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
  1156 +
  1157 + for(i = 0; i < MAX_FD; i++) {
  1158 + if (fd_filename[i]) {
  1159 + if (!fd_table[i]) {
  1160 + char buf[64];
  1161 + snprintf(buf, sizeof(buf), "fd%c", i + 'a');
  1162 + fd_table[i] = bdrv_new(buf);
  1163 + bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
  1164 + }
  1165 + if (fd_filename[i] != '\0') {
  1166 + if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
  1167 + fprintf(stderr, "qemu: could not open floppy disk image '%s\n",
  1168 + fd_filename[i]);
  1169 + exit(1);
  1170 + }
  1171 + }
1163 } 1172 }
1164 } 1173 }
1165 1174
@@ -1190,6 +1199,10 @@ int main(int argc, char **argv) @@ -1190,6 +1199,10 @@ int main(int argc, char **argv)
1190 ppc_init(); 1199 ppc_init();
1191 #endif 1200 #endif
1192 1201
  1202 + /* launched after the device init so that it can display or not a
  1203 + banner */
  1204 + monitor_init();
  1205 +
1193 /* setup cpu signal handlers for MMU / self modifying code handling */ 1206 /* setup cpu signal handlers for MMU / self modifying code handling */
1194 #if !defined(CONFIG_SOFTMMU) 1207 #if !defined(CONFIG_SOFTMMU)
1195 1208
@@ -31,16 +31,16 @@ extern int reset_requested; @@ -31,16 +31,16 @@ extern int reset_requested;
31 extern int64_t ticks_per_sec; 31 extern int64_t ticks_per_sec;
32 extern int pit_min_timer_count; 32 extern int pit_min_timer_count;
33 33
34 -typedef void (IOPortWriteFunc)(struct CPUState *env, uint32_t address, uint32_t data);  
35 -typedef uint32_t (IOPortReadFunc)(struct CPUState *env, uint32_t address); 34 +typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
  35 +typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
36 36
37 -int register_ioport_read(int start, int length, IOPortReadFunc *func, int size);  
38 -int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size); 37 +int register_ioport_read(int start, int length, int size,
  38 + IOPortReadFunc *func, void *opaque);
  39 +int register_ioport_write(int start, int length, int size,
  40 + IOPortWriteFunc *func, void *opaque);
39 int64_t cpu_get_ticks(void); 41 int64_t cpu_get_ticks(void);
40 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c); 42 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
41 43
42 -void net_send_packet(int net_fd, const uint8_t *buf, int size);  
43 -  
44 void hw_error(const char *fmt, ...); 44 void hw_error(const char *fmt, ...);
45 45
46 int load_image(const char *filename, uint8_t *addr); 46 int load_image(const char *filename, uint8_t *addr);
@@ -49,10 +49,37 @@ extern const char *bios_dir; @@ -49,10 +49,37 @@ extern const char *bios_dir;
49 void pstrcpy(char *buf, int buf_size, const char *str); 49 void pstrcpy(char *buf, int buf_size, const char *str);
50 char *pstrcat(char *buf, int buf_size, const char *s); 50 char *pstrcat(char *buf, int buf_size, const char *s);
51 51
  52 +int serial_open_device(void);
  53 +
  54 +/* network redirectors support */
  55 +
  56 +#define MAX_NICS 8
  57 +
  58 +typedef struct NetDriverState {
  59 + int fd;
  60 + uint8_t macaddr[6];
  61 + char ifname[16];
  62 +} NetDriverState;
  63 +
  64 +extern int nb_nics;
  65 +extern NetDriverState nd_table[MAX_NICS];
  66 +
  67 +void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
  68 +
  69 +/* async I/O support */
  70 +
  71 +typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
  72 +typedef int IOCanRWHandler(void *opaque);
  73 +
  74 +int add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
  75 + IOReadHandler *fd_read, void *opaque);
  76 +
52 /* block.c */ 77 /* block.c */
53 typedef struct BlockDriverState BlockDriverState; 78 typedef struct BlockDriverState BlockDriverState;
54 79
55 -BlockDriverState *bdrv_open(const char *filename, int snapshot); 80 +BlockDriverState *bdrv_new(const char *device_name);
  81 +void bdrv_delete(BlockDriverState *bs);
  82 +int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot);
56 void bdrv_close(BlockDriverState *bs); 83 void bdrv_close(BlockDriverState *bs);
57 int bdrv_read(BlockDriverState *bs, int64_t sector_num, 84 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
58 uint8_t *buf, int nb_sectors); 85 uint8_t *buf, int nb_sectors);
@@ -62,6 +89,27 @@ void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr); @@ -62,6 +89,27 @@ void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
62 int bdrv_commit(BlockDriverState *bs); 89 int bdrv_commit(BlockDriverState *bs);
63 void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size); 90 void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
64 91
  92 +#define BDRV_TYPE_HD 0
  93 +#define BDRV_TYPE_CDROM 1
  94 +#define BDRV_TYPE_FLOPPY 2
  95 +
  96 +void bdrv_set_geometry_hint(BlockDriverState *bs,
  97 + int cyls, int heads, int secs);
  98 +void bdrv_set_type_hint(BlockDriverState *bs, int type);
  99 +void bdrv_get_geometry_hint(BlockDriverState *bs,
  100 + int *pcyls, int *pheads, int *psecs);
  101 +int bdrv_get_type_hint(BlockDriverState *bs);
  102 +int bdrv_is_removable(BlockDriverState *bs);
  103 +int bdrv_is_read_only(BlockDriverState *bs);
  104 +int bdrv_is_inserted(BlockDriverState *bs);
  105 +int bdrv_is_locked(BlockDriverState *bs);
  106 +void bdrv_set_locked(BlockDriverState *bs, int locked);
  107 +void bdrv_set_change_cb(BlockDriverState *bs,
  108 + void (*change_cb)(void *opaque), void *opaque);
  109 +
  110 +void bdrv_info(void);
  111 +BlockDriverState *bdrv_find(const char *name);
  112 +
65 /* vga.c */ 113 /* vga.c */
66 114
67 #define VGA_RAM_SIZE (4096 * 1024) 115 #define VGA_RAM_SIZE (4096 * 1024)
@@ -97,9 +145,8 @@ void sdl_display_init(DisplayState *ds); @@ -97,9 +145,8 @@ void sdl_display_init(DisplayState *ds);
97 145
98 extern BlockDriverState *bs_table[MAX_DISKS]; 146 extern BlockDriverState *bs_table[MAX_DISKS];
99 147
100 -void ide_init(void);  
101 -void ide_set_geometry(int n, int cyls, int heads, int secs);  
102 -void ide_set_cdrom(int n, int is_cdrom); 148 +void ide_init(int iobase, int iobase2, int irq,
  149 + BlockDriverState *hd0, BlockDriverState *hd1);
103 150
104 /* oss.c */ 151 /* oss.c */
105 typedef enum { 152 typedef enum {
@@ -138,20 +185,13 @@ void SB16_init (void); @@ -138,20 +185,13 @@ void SB16_init (void);
138 #define MAX_FD 2 185 #define MAX_FD 2
139 extern BlockDriverState *fd_table[MAX_FD]; 186 extern BlockDriverState *fd_table[MAX_FD];
140 187
141 -void cmos_register_fd (uint8_t fd0, uint8_t fd1);  
142 void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base, 188 void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
143 - char boot_device);  
144 -int fdctrl_disk_change (int idx, const unsigned char *filename, int ro); 189 + BlockDriverState **fds);
  190 +int fdctrl_get_drive_type(int drive_num);
145 191
146 /* ne2000.c */ 192 /* ne2000.c */
147 193
148 -#define MAX_ETH_FRAME_SIZE 1514  
149 -  
150 -void ne2000_init(int base, int irq);  
151 -int ne2000_can_receive(void);  
152 -void ne2000_receive(uint8_t *buf, int size);  
153 -  
154 -extern int net_fd; 194 +void ne2000_init(int base, int irq, NetDriverState *nd);
155 195
156 /* pckbd.c */ 196 /* pckbd.c */
157 197
@@ -179,10 +219,14 @@ void rtc_timer(void); @@ -179,10 +219,14 @@ void rtc_timer(void);
179 219
180 /* serial.c */ 220 /* serial.c */
181 221
182 -void serial_init(int base, int irq);  
183 -int serial_can_receive(void);  
184 -void serial_receive_byte(int ch);  
185 -void serial_receive_break(void); 222 +typedef struct SerialState SerialState;
  223 +
  224 +extern SerialState *serial_console;
  225 +
  226 +SerialState *serial_init(int base, int irq, int fd);
  227 +int serial_can_receive(SerialState *s);
  228 +void serial_receive_byte(SerialState *s, int ch);
  229 +void serial_receive_break(SerialState *s);
186 230
187 /* i8259.c */ 231 /* i8259.c */
188 232
@@ -206,7 +250,7 @@ typedef struct PITChannelState { @@ -206,7 +250,7 @@ typedef struct PITChannelState {
206 250
207 extern PITChannelState pit_channels[3]; 251 extern PITChannelState pit_channels[3];
208 252
209 -void pit_init(void); 253 +void pit_init(int base);
210 void pit_set_gate(PITChannelState *s, int val); 254 void pit_set_gate(PITChannelState *s, int val);
211 int pit_get_out(PITChannelState *s); 255 int pit_get_out(PITChannelState *s);
212 int pit_get_out_edges(PITChannelState *s); 256 int pit_get_out_edges(PITChannelState *s);
@@ -217,4 +261,10 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, @@ -217,4 +261,10 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
217 const char *kernel_filename, const char *kernel_cmdline, 261 const char *kernel_filename, const char *kernel_cmdline,
218 const char *initrd_filename); 262 const char *initrd_filename);
219 263
  264 +/* monitor.c */
  265 +void monitor_init(void);
  266 +void term_printf(const char *fmt, ...);
  267 +void term_flush(void);
  268 +void term_print_help(void);
  269 +
220 #endif /* VL_H */ 270 #endif /* VL_H */