ia64/xen-unstable
changeset 7567:32695e99cfc8
This patch is to fix the NIC driven mechanism to make it event
driven. We will also send it to Qemu mailing list.
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
driven. We will also send it to Qemu mailing list.
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Sun Oct 30 16:47:59 2005 +0100 (2005-10-30) |
parents | 8e1bfcb901e5 |
children | 43676a509982 |
files | tools/ioemu/hw/ne2000.c tools/ioemu/hw/pcnet.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/ioemu/vl.h |
line diff
1.1 --- a/tools/ioemu/hw/ne2000.c Sun Oct 30 16:43:05 2005 +0100 1.2 +++ b/tools/ioemu/hw/ne2000.c Sun Oct 30 16:47:59 2005 +0100 1.3 @@ -327,6 +327,7 @@ static void ne2000_ioport_write(void *op 1.4 break; 1.5 } 1.6 } 1.7 + update_select_wakeup_events(); 1.8 } 1.9 1.10 static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) 1.11 @@ -373,6 +374,7 @@ static uint32_t ne2000_ioport_read(void 1.12 break; 1.13 } 1.14 } 1.15 + update_select_wakeup_events(); 1.16 #ifdef DEBUG_NE2000 1.17 printf("NE2000: read addr=0x%x val=%02x\n", addr, ret); 1.18 #endif 1.19 @@ -476,6 +478,7 @@ static void ne2000_asic_ioport_write(voi 1.20 ne2000_mem_writeb(s, s->rsar, val); 1.21 ne2000_dma_update(s, 1); 1.22 } 1.23 + update_select_wakeup_events(); 1.24 } 1.25 1.26 static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) 1.27 @@ -492,6 +495,7 @@ static uint32_t ne2000_asic_ioport_read( 1.28 ret = ne2000_mem_readb(s, s->rsar); 1.29 ne2000_dma_update(s, 1); 1.30 } 1.31 + update_select_wakeup_events(); 1.32 #ifdef DEBUG_NE2000 1.33 printf("NE2000: asic read val=0x%04x\n", ret); 1.34 #endif 1.35 @@ -510,6 +514,7 @@ static void ne2000_asic_ioport_writel(vo 1.36 /* 32 bit access */ 1.37 ne2000_mem_writel(s, s->rsar, val); 1.38 ne2000_dma_update(s, 4); 1.39 + update_select_wakeup_events(); 1.40 } 1.41 1.42 static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr) 1.43 @@ -520,6 +525,7 @@ static uint32_t ne2000_asic_ioport_readl 1.44 /* 32 bit access */ 1.45 ret = ne2000_mem_readl(s, s->rsar); 1.46 ne2000_dma_update(s, 4); 1.47 + update_select_wakeup_events(); 1.48 #ifdef DEBUG_NE2000 1.49 printf("NE2000: asic readl val=0x%04x\n", ret); 1.50 #endif 1.51 @@ -535,6 +541,7 @@ static uint32_t ne2000_reset_ioport_read 1.52 { 1.53 NE2000State *s = opaque; 1.54 ne2000_reset(s); 1.55 + update_select_wakeup_events(); 1.56 return 0; 1.57 } 1.58
2.1 --- a/tools/ioemu/hw/pcnet.c Sun Oct 30 16:43:05 2005 +0100 2.2 +++ b/tools/ioemu/hw/pcnet.c Sun Oct 30 16:47:59 2005 +0100 2.3 @@ -50,7 +50,6 @@ typedef struct PCNetState_st PCNetState; 2.4 struct PCNetState_st { 2.5 PCIDevice dev; 2.6 NetDriverState *nd; 2.7 - QEMUTimer *poll_timer; 2.8 int mmio_io_addr, rap, isr, lnkst; 2.9 target_phys_addr_t rdra, tdra; 2.10 uint8_t prom[16]; 2.11 @@ -640,8 +639,6 @@ static void pcnet_poll_timer(void *opaqu 2.12 { 2.13 PCNetState *s = opaque; 2.14 2.15 - qemu_del_timer(s->poll_timer); 2.16 - 2.17 if (CSR_TDMD(s)) { 2.18 pcnet_transmit(s); 2.19 } 2.20 @@ -660,8 +657,6 @@ static void pcnet_poll_timer(void *opaqu 2.21 } else 2.22 CSR_POLL(s) = t; 2.23 } 2.24 - qemu_mod_timer(s->poll_timer, 2.25 - pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock))); 2.26 } 2.27 } 2.28 2.29 @@ -941,6 +936,7 @@ static void pcnet_ioport_writew(void *op 2.30 } 2.31 } 2.32 pcnet_update_irq(s); 2.33 + update_select_wakeup_events(); 2.34 } 2.35 2.36 static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr) 2.37 @@ -966,6 +962,7 @@ static uint32_t pcnet_ioport_readw(void 2.38 } 2.39 } 2.40 pcnet_update_irq(s); 2.41 + update_select_wakeup_events(); 2.42 #ifdef PCNET_DEBUG_IO 2.43 printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff); 2.44 #endif 2.45 @@ -1000,6 +997,7 @@ static void pcnet_ioport_writel(void *op 2.46 #endif 2.47 } 2.48 pcnet_update_irq(s); 2.49 + update_select_wakeup_events(); 2.50 } 2.51 2.52 static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr) 2.53 @@ -1025,6 +1023,7 @@ static uint32_t pcnet_ioport_readl(void 2.54 } 2.55 } 2.56 pcnet_update_irq(s); 2.57 + update_select_wakeup_events(); 2.58 #ifdef PCNET_DEBUG_IO 2.59 printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val); 2.60 #endif 2.61 @@ -1210,8 +1209,6 @@ void pci_pcnet_init(PCIBus *bus, NetDriv 2.62 pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, 2.63 PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map); 2.64 2.65 - d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d); 2.66 - 2.67 d->nd = nd; 2.68 2.69 pcnet_h_reset(d);
3.1 --- a/tools/ioemu/target-i386-dm/helper2.c Sun Oct 30 16:43:05 2005 +0100 3.2 +++ b/tools/ioemu/target-i386-dm/helper2.c Sun Oct 30 16:47:59 2005 +0100 3.3 @@ -387,12 +387,6 @@ cpu_handle_ioreq(CPUState *env) 3.4 } 3.5 } 3.6 3.7 -void 3.8 -cpu_timer_handler(CPUState *env) 3.9 -{ 3.10 - cpu_handle_ioreq(env); 3.11 -} 3.12 - 3.13 int xc_handle; 3.14 3.15 static __inline__ void atomic_set_bit(long nr, volatile void *addr) 3.16 @@ -413,6 +407,8 @@ destroy_vmx_domain(void) 3.17 fprintf(logfile, "%s failed.!\n", destroy_cmd); 3.18 } 3.19 3.20 +fd_set wakeup_rfds; 3.21 +int highest_fds; 3.22 int main_loop(void) 3.23 { 3.24 fd_set rfds; 3.25 @@ -425,8 +421,9 @@ int main_loop(void) 3.26 extern void main_loop_wait(int); 3.27 3.28 /* Watch stdin (fd 0) to see when it has input. */ 3.29 - FD_ZERO(&rfds); 3.30 - 3.31 + FD_ZERO(&wakeup_rfds); 3.32 + FD_SET(evtchn_fd, &wakeup_rfds); 3.33 + highest_fds = evtchn_fd; 3.34 while (1) { 3.35 if (vm_running) { 3.36 if (shutdown_requested) { 3.37 @@ -441,14 +438,16 @@ int main_loop(void) 3.38 /* Wait up to one seconds. */ 3.39 tv.tv_sec = 0; 3.40 tv.tv_usec = 100000; 3.41 - FD_SET(evtchn_fd, &rfds); 3.42 3.43 env->send_event = 0; 3.44 - retval = select(evtchn_fd+1, &rfds, NULL, NULL, &tv); 3.45 + retval = select(highest_fds+1, &wakeup_rfds, NULL, NULL, &tv); 3.46 if (retval == -1) { 3.47 perror("select"); 3.48 return 0; 3.49 } 3.50 + rfds = wakeup_rfds; 3.51 + FD_ZERO(&wakeup_rfds); 3.52 + FD_SET(evtchn_fd, &wakeup_rfds); 3.53 3.54 #if __WORDSIZE == 32 3.55 #define ULONGLONG_MAX 0xffffffffffffffffULL 3.56 @@ -460,7 +459,10 @@ int main_loop(void) 3.57 #ifdef APIC_SUPPORT 3.58 ioapic_update_EOI(); 3.59 #endif 3.60 - cpu_timer_handler(env); 3.61 + tun_receive_handler(&rfds); 3.62 + if ( FD_ISSET(evtchn_fd, &rfds) ) { 3.63 + cpu_handle_ioreq(env); 3.64 + } 3.65 #ifdef APIC_SUPPORT 3.66 if (ioapic_has_intr()) 3.67 do_ioapic();
4.1 --- a/tools/ioemu/vl.c Sun Oct 30 16:43:05 2005 +0100 4.2 +++ b/tools/ioemu/vl.c Sun Oct 30 16:47:59 2005 +0100 4.3 @@ -1528,7 +1528,7 @@ static void tun_add_read_packet(NetDrive 4.4 IOCanRWHandler *fd_can_read, 4.5 IOReadHandler *fd_read, void *opaque) 4.6 { 4.7 - qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque); 4.8 + qemu_add_fd_event_read_handler(nd->fd, fd_can_read, fd_read, opaque); 4.9 } 4.10 4.11 static int net_tun_init(NetDriverState *nd) 4.12 @@ -1536,11 +1536,13 @@ static int net_tun_init(NetDriverState * 4.13 int pid, status; 4.14 char *args[3]; 4.15 char **parg; 4.16 + extern int highest_fds; 4.17 4.18 nd->fd = tun_open(nd->ifname, sizeof(nd->ifname)); 4.19 if (nd->fd < 0) 4.20 return -1; 4.21 4.22 + if ( nd->fd > highest_fds ) highest_fds = nd->fd; 4.23 /* try to launch network init script */ 4.24 pid = fork(); 4.25 if (pid >= 0) { 4.26 @@ -1628,6 +1630,7 @@ typedef struct IOHandlerRecord { 4.27 } IOHandlerRecord; 4.28 4.29 static IOHandlerRecord *first_io_handler; 4.30 +static IOHandlerRecord *first_eventio_handler; 4.31 4.32 int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 4.33 IOReadHandler *fd_read, void *opaque) 4.34 @@ -1646,6 +1649,23 @@ int qemu_add_fd_read_handler(int fd, IOC 4.35 return 0; 4.36 } 4.37 4.38 +int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read, 4.39 + IOReadHandler *fd_read, void *opaque) 4.40 +{ 4.41 + IOHandlerRecord *ioh; 4.42 + 4.43 + ioh = qemu_mallocz(sizeof(IOHandlerRecord)); 4.44 + if (!ioh) 4.45 + return -1; 4.46 + ioh->fd = fd; 4.47 + ioh->fd_can_read = fd_can_read; 4.48 + ioh->fd_read = fd_read; 4.49 + ioh->opaque = opaque; 4.50 + ioh->next = first_eventio_handler; 4.51 + first_eventio_handler = ioh; 4.52 + return 0; 4.53 +} 4.54 + 4.55 void qemu_del_fd_read_handler(int fd) 4.56 { 4.57 IOHandlerRecord **pioh, *ioh; 4.58 @@ -3257,3 +3277,44 @@ int main(int argc, char **argv) 4.59 quit_timers(); 4.60 return 0; 4.61 } 4.62 + 4.63 +extern fd_set wakeup_rfds; 4.64 +void tun_receive_handler(fd_set *rfds) 4.65 +{ 4.66 + IOHandlerRecord *ioh; 4.67 + static uint8_t buf[4096]; 4.68 + int n, max_size; 4.69 + 4.70 + for (ioh = first_eventio_handler; ioh != NULL; ioh = ioh->next) { 4.71 + if ( FD_ISSET(ioh->fd, rfds) ) { 4.72 + max_size = ioh->fd_can_read(ioh->opaque); 4.73 + if (max_size > 0) { 4.74 + if (max_size > sizeof(buf)) 4.75 + max_size = sizeof(buf); 4.76 + n = read(ioh->fd, buf, max_size); 4.77 + if (n >= 0) { 4.78 + ioh->fd_read(ioh->opaque, buf, n); 4.79 + } 4.80 + } 4.81 + } 4.82 + } 4.83 + update_select_wakeup_events(); 4.84 +} 4.85 + 4.86 +void update_select_wakeup_events(void) 4.87 +{ 4.88 + IOHandlerRecord *ioh; 4.89 + int max_size; 4.90 + 4.91 + for(ioh = first_eventio_handler; ioh != NULL; ioh = ioh->next) { 4.92 + FD_CLR(ioh->fd, &wakeup_rfds); 4.93 + if (ioh->fd_can_read) { 4.94 + max_size = ioh->fd_can_read(ioh->opaque); 4.95 + if (max_size > 0) { 4.96 + FD_SET(ioh->fd, &wakeup_rfds); 4.97 + } 4.98 + } 4.99 + } 4.100 +} 4.101 + 4.102 +
5.1 --- a/tools/ioemu/vl.h Sun Oct 30 16:43:05 2005 +0100 5.2 +++ b/tools/ioemu/vl.h Sun Oct 30 16:47:59 2005 +0100 5.3 @@ -178,6 +178,8 @@ typedef int IOCanRWHandler(void *opaque) 5.4 5.5 int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 5.6 IOReadHandler *fd_read, void *opaque); 5.7 +int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read, 5.8 + IOReadHandler *fd_read, void *opaque); 5.9 void qemu_del_fd_read_handler(int fd); 5.10 5.11 /* character device */ 5.12 @@ -791,5 +793,7 @@ void readline_start(const char *prompt, 5.13 #define DEFAULT_GDBSTUB_PORT 1234 5.14 5.15 int gdbserver_start(int port); 5.16 +void update_select_wakeup_events(void); 5.17 +void tun_receive_handler(); 5.18 5.19 #endif /* VL_H */