/[qemu]/qemu/vl.c
ViewVC logotype

Diff of /qemu/vl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by bellard, Tue Jun 24 13:42:40 2003 UTC revision 1.2 by bellard, Wed Jun 25 00:07:40 2003 UTC
# Line 21  Line 21 
21  #include <termios.h>  #include <termios.h>
22  #include <sys/poll.h>  #include <sys/poll.h>
23  #include <errno.h>  #include <errno.h>
24    #include <sys/wait.h>
25    
26    #include <sys/ioctl.h>
27    #include <sys/socket.h>
28    #include <linux/if.h>
29    #include <linux/if_tun.h>
30    
31  #include "cpu-i386.h"  #include "cpu-i386.h"
32  #include "disas.h"  #include "disas.h"
33    
34  #define DEBUG_LOGFILE "/tmp/vl.log"  #define DEBUG_LOGFILE "/tmp/vl.log"
35    #define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup"
36    
37  //#define DEBUG_UNUSED_IOPORT  //#define DEBUG_UNUSED_IOPORT
38    
39  #define PHYS_RAM_BASE 0xa8000000  #define PHYS_RAM_BASE 0xa8000000
# Line 225  int register_ioport_writeb(int start, in Line 233  int register_ioport_writeb(int start, in
233      return 0;      return 0;
234  }  }
235    
236    int register_ioport_readw(int start, int length, IOPortReadFunc *func)
237    {
238        int i;
239    
240        for(i = start; i < start + length; i += 2)
241            ioport_readw_table[i] = func;
242        return 0;
243    }
244    
245    int register_ioport_writew(int start, int length, IOPortWriteFunc *func)
246    {
247        int i;
248    
249        for(i = start; i < start + length; i += 2)
250            ioport_writew_table[i] = func;
251        return 0;
252    }
253    
254  void pstrcpy(char *buf, int buf_size, const char *str)  void pstrcpy(char *buf, int buf_size, const char *str)
255  {  {
256      int c;      int c;
# Line 1149  void serial_init(void) Line 1175  void serial_init(void)
1175      term_init();      term_init();
1176  }  }
1177    
1178    /***********************************************************/
1179    /* ne2000 emulation */
1180    
1181    //#define DEBUG_NE2000
1182    
1183    #define NE2000_IOPORT   0x300
1184    #define NE2000_IRQ      9
1185    
1186    #define MAX_ETH_FRAME_SIZE 1514
1187    
1188    #define E8390_CMD       0x00  /* The command register (for all pages) */
1189    /* Page 0 register offsets. */
1190    #define EN0_CLDALO      0x01    /* Low byte of current local dma addr  RD */
1191    #define EN0_STARTPG     0x01    /* Starting page of ring bfr WR */
1192    #define EN0_CLDAHI      0x02    /* High byte of current local dma addr  RD */
1193    #define EN0_STOPPG      0x02    /* Ending page +1 of ring bfr WR */
1194    #define EN0_BOUNDARY    0x03    /* Boundary page of ring bfr RD WR */
1195    #define EN0_TSR         0x04    /* Transmit status reg RD */
1196    #define EN0_TPSR        0x04    /* Transmit starting page WR */
1197    #define EN0_NCR         0x05    /* Number of collision reg RD */
1198    #define EN0_TCNTLO      0x05    /* Low  byte of tx byte count WR */
1199    #define EN0_FIFO        0x06    /* FIFO RD */
1200    #define EN0_TCNTHI      0x06    /* High byte of tx byte count WR */
1201    #define EN0_ISR         0x07    /* Interrupt status reg RD WR */
1202    #define EN0_CRDALO      0x08    /* low byte of current remote dma address RD */
1203    #define EN0_RSARLO      0x08    /* Remote start address reg 0 */
1204    #define EN0_CRDAHI      0x09    /* high byte, current remote dma address RD */
1205    #define EN0_RSARHI      0x09    /* Remote start address reg 1 */
1206    #define EN0_RCNTLO      0x0a    /* Remote byte count reg WR */
1207    #define EN0_RCNTHI      0x0b    /* Remote byte count reg WR */
1208    #define EN0_RSR         0x0c    /* rx status reg RD */
1209    #define EN0_RXCR        0x0c    /* RX configuration reg WR */
1210    #define EN0_TXCR        0x0d    /* TX configuration reg WR */
1211    #define EN0_COUNTER0    0x0d    /* Rcv alignment error counter RD */
1212    #define EN0_DCFG        0x0e    /* Data configuration reg WR */
1213    #define EN0_COUNTER1    0x0e    /* Rcv CRC error counter RD */
1214    #define EN0_IMR         0x0f    /* Interrupt mask reg WR */
1215    #define EN0_COUNTER2    0x0f    /* Rcv missed frame error counter RD */
1216    
1217    #define EN1_PHYS        0x11
1218    #define EN1_CURPAG      0x17
1219    #define EN1_MULT        0x18
1220    
1221    /*  Register accessed at EN_CMD, the 8390 base addr.  */
1222    #define E8390_STOP      0x01    /* Stop and reset the chip */
1223    #define E8390_START     0x02    /* Start the chip, clear reset */
1224    #define E8390_TRANS     0x04    /* Transmit a frame */
1225    #define E8390_RREAD     0x08    /* Remote read */
1226    #define E8390_RWRITE    0x10    /* Remote write  */
1227    #define E8390_NODMA     0x20    /* Remote DMA */
1228    #define E8390_PAGE0     0x00    /* Select page chip registers */
1229    #define E8390_PAGE1     0x40    /* using the two high-order bits */
1230    #define E8390_PAGE2     0x80    /* Page 3 is invalid. */
1231    
1232    /* Bits in EN0_ISR - Interrupt status register */
1233    #define ENISR_RX        0x01    /* Receiver, no error */
1234    #define ENISR_TX        0x02    /* Transmitter, no error */
1235    #define ENISR_RX_ERR    0x04    /* Receiver, with error */
1236    #define ENISR_TX_ERR    0x08    /* Transmitter, with error */
1237    #define ENISR_OVER      0x10    /* Receiver overwrote the ring */
1238    #define ENISR_COUNTERS  0x20    /* Counters need emptying */
1239    #define ENISR_RDC       0x40    /* remote dma complete */
1240    #define ENISR_RESET     0x80    /* Reset completed */
1241    #define ENISR_ALL       0x3f    /* Interrupts we will enable */
1242    
1243    /* Bits in received packet status byte and EN0_RSR*/
1244    #define ENRSR_RXOK      0x01    /* Received a good packet */
1245    #define ENRSR_CRC       0x02    /* CRC error */
1246    #define ENRSR_FAE       0x04    /* frame alignment error */
1247    #define ENRSR_FO        0x08    /* FIFO overrun */
1248    #define ENRSR_MPA       0x10    /* missed pkt */
1249    #define ENRSR_PHY       0x20    /* physical/multicast address */
1250    #define ENRSR_DIS       0x40    /* receiver disable. set in monitor mode */
1251    #define ENRSR_DEF       0x80    /* deferring */
1252    
1253    /* Transmitted packet status, EN0_TSR. */
1254    #define ENTSR_PTX 0x01  /* Packet transmitted without error */
1255    #define ENTSR_ND  0x02  /* The transmit wasn't deferred. */
1256    #define ENTSR_COL 0x04  /* The transmit collided at least once. */
1257    #define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */
1258    #define ENTSR_CRS 0x10  /* The carrier sense was lost. */
1259    #define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */
1260    #define ENTSR_CDH 0x40  /* The collision detect "heartbeat" signal was lost. */
1261    #define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
1262    
1263    #define NE2000_MEM_SIZE 32768
1264    
1265    typedef struct NE2000State {
1266        uint8_t cmd;
1267        uint32_t start;
1268        uint32_t stop;
1269        uint8_t boundary;
1270        uint8_t tsr;
1271        uint8_t tpsr;
1272        uint16_t tcnt;
1273        uint16_t rcnt;
1274        uint32_t rsar;
1275        uint8_t isr;
1276        uint8_t dcfg;
1277        uint8_t imr;
1278        uint8_t phys[6]; /* mac address */
1279        uint8_t curpag;
1280        uint8_t mult[8]; /* multicast mask array */
1281        uint8_t mem[NE2000_MEM_SIZE];
1282    } NE2000State;
1283    
1284    NE2000State ne2000_state;
1285    int net_fd = -1;
1286    char network_script[1024];
1287    
1288    void ne2000_reset(void)
1289    {
1290        NE2000State *s = &ne2000_state;
1291        int i;
1292    
1293        s->isr = ENISR_RESET;
1294        s->mem[0] = 0x52;
1295        s->mem[1] = 0x54;
1296        s->mem[2] = 0x00;
1297        s->mem[3] = 0x12;
1298        s->mem[4] = 0x34;
1299        s->mem[5] = 0x56;
1300        s->mem[14] = 0x57;
1301        s->mem[15] = 0x57;
1302    
1303        /* duplicate prom data */
1304        for(i = 15;i >= 0; i--) {
1305            s->mem[2 * i] = s->mem[i];
1306            s->mem[2 * i + 1] = s->mem[i];
1307        }
1308    }
1309    
1310    void ne2000_update_irq(NE2000State *s)
1311    {
1312        int isr;
1313        isr = s->isr & s->imr;
1314        if (isr)
1315            pic_set_irq(NE2000_IRQ, 1);
1316        else
1317            pic_set_irq(NE2000_IRQ, 0);
1318    }
1319    
1320    int net_init(void)
1321    {
1322        struct ifreq ifr;
1323        int fd, ret, pid, status;
1324        
1325        fd = open("/dev/net/tun", O_RDWR);
1326        if (fd < 0) {
1327            fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1328            return -1;
1329        }
1330        memset(&ifr, 0, sizeof(ifr));
1331        ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1332        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
1333        ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1334        if (ret != 0) {
1335            fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1336            close(fd);
1337            return -1;
1338        }
1339        printf("connected to host network interface: %s\n", ifr.ifr_name);
1340        fcntl(fd, F_SETFL, O_NONBLOCK);
1341        net_fd = fd;
1342    
1343        /* try to launch network init script */
1344        pid = fork();
1345        if (pid >= 0) {
1346            if (pid == 0) {
1347                execl(network_script, network_script, ifr.ifr_name, NULL);
1348                exit(1);
1349            }
1350            while (waitpid(pid, &status, 0) != pid);
1351            if (!WIFEXITED(status) ||
1352                WEXITSTATUS(status) != 0) {
1353                fprintf(stderr, "%s: could not launch network script for '%s'\n",
1354                        network_script, ifr.ifr_name);
1355            }
1356        }
1357        return 0;
1358    }
1359    
1360    void net_send_packet(NE2000State *s, const uint8_t *buf, int size)
1361    {
1362    #ifdef DEBUG_NE2000
1363        printf("NE2000: sending packet size=%d\n", size);
1364    #endif
1365        write(net_fd, buf, size);
1366    }
1367    
1368    /* return true if the NE2000 can receive more data */
1369    int ne2000_can_receive(NE2000State *s)
1370    {
1371        int avail, index, boundary;
1372        
1373        if (s->cmd & E8390_STOP)
1374            return 0;
1375        index = s->curpag << 8;
1376        boundary = s->boundary << 8;
1377        if (index < boundary)
1378            avail = boundary - index;
1379        else
1380            avail = (s->stop - s->start) - (index - boundary);
1381        if (avail < (MAX_ETH_FRAME_SIZE + 4))
1382            return 0;
1383        return 1;
1384    }
1385    
1386    void ne2000_receive(NE2000State *s, uint8_t *buf, int size)
1387    {
1388        uint8_t *p;
1389        int total_len, next, avail, len, index;
1390    
1391    #if defined(DEBUG_NE2000)
1392        printf("NE2000: received len=%d\n", size);
1393    #endif
1394    
1395        index = s->curpag << 8;
1396        /* 4 bytes for header */
1397        total_len = size + 4;
1398        /* address for next packet (4 bytes for CRC) */
1399        next = index + ((total_len + 4 + 255) & ~0xff);
1400        if (next >= s->stop)
1401            next -= (s->stop - s->start);
1402        /* prepare packet header */
1403        p = s->mem + index;
1404        p[0] = ENRSR_RXOK; /* receive status */
1405        p[1] = next >> 8;
1406        p[2] = total_len;
1407        p[3] = total_len >> 8;
1408        index += 4;
1409    
1410        /* write packet data */
1411        while (size > 0) {
1412            avail = s->stop - index;
1413            len = size;
1414            if (len > avail)
1415                len = avail;
1416            memcpy(s->mem + index, buf, len);
1417            buf += len;
1418            index += len;
1419            if (index == s->stop)
1420                index = s->start;
1421            size -= len;
1422        }
1423        s->curpag = next >> 8;
1424        
1425        /* now we can signal we have receive something */
1426        s->isr |= ENISR_RX;
1427        ne2000_update_irq(s);
1428    }
1429    
1430    void ne2000_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
1431    {
1432        NE2000State *s = &ne2000_state;
1433        int offset, page;
1434    
1435        addr &= 0xf;
1436    #ifdef DEBUG_NE2000
1437        printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
1438    #endif
1439        if (addr == E8390_CMD) {
1440            /* control register */
1441            s->cmd = val;
1442            if (val & E8390_START) {
1443                /* test specific case: zero length transfert */
1444                if ((val & (E8390_RREAD | E8390_RWRITE)) &&
1445                    s->rcnt == 0) {
1446                    s->isr |= ENISR_RDC;
1447                    ne2000_update_irq(s);
1448                }
1449                if (val & E8390_TRANS) {
1450                    net_send_packet(s, s->mem + (s->tpsr << 8), s->tcnt);
1451                    /* signal end of transfert */
1452                    s->tsr = ENTSR_PTX;
1453                    s->isr |= ENISR_TX;
1454                    ne2000_update_irq(s);
1455                }
1456            }
1457        } else {
1458            page = s->cmd >> 6;
1459            offset = addr | (page << 4);
1460            switch(offset) {
1461            case EN0_STARTPG:
1462                s->start = val << 8;
1463                break;
1464            case EN0_STOPPG:
1465                s->stop = val << 8;
1466                break;
1467            case EN0_BOUNDARY:
1468                s->boundary = val;
1469                break;
1470            case EN0_IMR:
1471                s->imr = val;
1472                ne2000_update_irq(s);
1473                break;
1474            case EN0_TPSR:
1475                s->tpsr = val;
1476                break;
1477            case EN0_TCNTLO:
1478                s->tcnt = (s->tcnt & 0xff00) | val;
1479                break;
1480            case EN0_TCNTHI:
1481                s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
1482                break;
1483            case EN0_RSARLO:
1484                s->rsar = (s->rsar & 0xff00) | val;
1485                break;
1486            case EN0_RSARHI:
1487                s->rsar = (s->rsar & 0x00ff) | (val << 8);
1488                break;
1489            case EN0_RCNTLO:
1490                s->rcnt = (s->rcnt & 0xff00) | val;
1491                break;
1492            case EN0_RCNTHI:
1493                s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
1494                break;
1495            case EN0_DCFG:
1496                s->dcfg = val;
1497                break;
1498            case EN0_ISR:
1499                s->isr &= ~val;
1500                ne2000_update_irq(s);
1501                break;
1502            case EN1_PHYS ... EN1_PHYS + 5:
1503                s->phys[offset - EN1_PHYS] = val;
1504                break;
1505            case EN1_CURPAG:
1506                s->curpag = val;
1507                break;
1508            case EN1_MULT ... EN1_MULT + 7:
1509                s->mult[offset - EN1_MULT] = val;
1510                break;
1511            }
1512        }
1513    }
1514    
1515    uint32_t ne2000_ioport_read(CPUX86State *env, uint32_t addr)
1516    {
1517        NE2000State *s = &ne2000_state;
1518        int offset, page, ret;
1519    
1520        addr &= 0xf;
1521        if (addr == E8390_CMD) {
1522            ret = s->cmd;
1523        } else {
1524            page = s->cmd >> 6;
1525            offset = addr | (page << 4);
1526            switch(offset) {
1527            case EN0_TSR:
1528                ret = s->tsr;
1529                break;
1530            case EN0_BOUNDARY:
1531                ret = s->boundary;
1532                break;
1533            case EN0_ISR:
1534                ret = s->isr;
1535                break;
1536            case EN1_PHYS ... EN1_PHYS + 5:
1537                ret = s->phys[offset - EN1_PHYS];
1538                break;
1539            case EN1_CURPAG:
1540                ret = s->curpag;
1541                break;
1542            case EN1_MULT ... EN1_MULT + 7:
1543                ret = s->mult[offset - EN1_MULT];
1544                break;
1545            default:
1546                ret = 0x00;
1547                break;
1548            }
1549        }
1550    #ifdef DEBUG_NE2000
1551        printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
1552    #endif
1553        return ret;
1554    }
1555    
1556    void ne2000_asic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
1557    {
1558        NE2000State *s = &ne2000_state;
1559        uint8_t *p;
1560    
1561    #ifdef DEBUG_NE2000
1562        printf("NE2000: asic write val=0x%04x\n", val);
1563    #endif
1564        p = s->mem + s->rsar;
1565        if (s->dcfg & 0x01) {
1566            /* 16 bit access */
1567            p[0] = val;
1568            p[1] = val >> 8;
1569            s->rsar += 2;
1570            s->rcnt -= 2;
1571        } else {
1572            /* 8 bit access */
1573            p[0] = val;
1574            s->rsar++;
1575            s->rcnt--;
1576        }
1577        /* wrap */
1578        if (s->rsar == s->stop)
1579            s->rsar = s->start;
1580        if (s->rcnt == 0) {
1581            /* signal end of transfert */
1582            s->isr |= ENISR_RDC;
1583            ne2000_update_irq(s);
1584        }
1585    }
1586    
1587    uint32_t ne2000_asic_ioport_read(CPUX86State *env, uint32_t addr)
1588    {
1589        NE2000State *s = &ne2000_state;
1590        uint8_t *p;
1591        int ret;
1592    
1593        p = s->mem + s->rsar;
1594        if (s->dcfg & 0x01) {
1595            /* 16 bit access */
1596            ret = p[0] | (p[1] << 8);
1597            s->rsar += 2;
1598            s->rcnt -= 2;
1599        } else {
1600            /* 8 bit access */
1601            ret = p[0];
1602            s->rsar++;
1603            s->rcnt--;
1604        }
1605        /* wrap */
1606        if (s->rsar == s->stop)
1607            s->rsar = s->start;
1608        if (s->rcnt == 0) {
1609            /* signal end of transfert */
1610            s->isr |= ENISR_RDC;
1611            ne2000_update_irq(s);
1612        }
1613    #ifdef DEBUG_NE2000
1614        printf("NE2000: asic read val=0x%04x\n", ret);
1615    #endif
1616        return ret;
1617    }
1618    
1619    void ne2000_reset_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
1620    {
1621        /* nothing to do (end of reset pulse) */
1622    }
1623    
1624    uint32_t ne2000_reset_ioport_read(CPUX86State *env, uint32_t addr)
1625    {
1626        ne2000_reset();
1627        return 0;
1628    }
1629    
1630    void ne2000_init(void)
1631    {
1632        register_ioport_writeb(NE2000_IOPORT, 16, ne2000_ioport_write);
1633        register_ioport_readb(NE2000_IOPORT, 16, ne2000_ioport_read);
1634    
1635        register_ioport_writeb(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write);
1636        register_ioport_readb(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read);
1637        register_ioport_writew(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write);
1638        register_ioport_readw(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read);
1639    
1640        register_ioport_writeb(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write);
1641        register_ioport_readb(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read);
1642        ne2000_reset();
1643    }
1644    
1645    /***********************************************************/
1646  /* cpu signal handler */  /* cpu signal handler */
1647  static void host_segv_handler(int host_signum, siginfo_t *info,  static void host_segv_handler(int host_signum, siginfo_t *info,
1648                                void *puc)                                void *puc)
# Line 1178  void help(void) Line 1672  void help(void)
1672             "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"             "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"
1673             "'initrd' is an initrd image\n"             "'initrd' is an initrd image\n"
1674             "-m megs   set virtual RAM size to megs MB\n"             "-m megs   set virtual RAM size to megs MB\n"
1675               "-n script set network init script [default=%s]\n"
1676             "-d        output log in /tmp/vl.log\n"             "-d        output log in /tmp/vl.log\n"
1677             "\n"             "\n"
1678             "During emulation, use C-a h to get terminal commands:\n"             "During emulation, use C-a h to get terminal commands:\n",
1679             );             DEFAULT_NETWORK_SCRIPT);
1680      term_print_help();      term_print_help();
1681      exit(1);      exit(1);
1682  }  }
# Line 1198  int main(int argc, char **argv) Line 1693  int main(int argc, char **argv)
1693      mallopt(M_MMAP_THRESHOLD, 4096 * 1024);      mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
1694            
1695      phys_ram_size = 32 * 1024 * 1024;      phys_ram_size = 32 * 1024 * 1024;
1696        pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
1697      for(;;) {      for(;;) {
1698          c = getopt(argc, argv, "hm:d");          c = getopt(argc, argv, "hm:dn:");
1699          if (c == -1)          if (c == -1)
1700              break;              break;
1701          switch(c) {          switch(c) {
# Line 1214  int main(int argc, char **argv) Line 1710  int main(int argc, char **argv)
1710          case 'd':          case 'd':
1711              loglevel = 1;              loglevel = 1;
1712              break;              break;
1713            case 'n':
1714                pstrcpy(network_script, sizeof(network_script), optarg);
1715                break;
1716          }          }
1717      }      }
1718      if (optind + 1 >= argc)      if (optind + 1 >= argc)
# Line 1229  int main(int argc, char **argv) Line 1728  int main(int argc, char **argv)
1728          setvbuf(logfile, NULL, _IOLBF, 0);          setvbuf(logfile, NULL, _IOLBF, 0);
1729      }      }
1730    
1731        /* init network tun interface */
1732        net_init();
1733    
1734      /* init the memory */      /* init the memory */
1735      strcpy(phys_ram_file, "/tmp/vlXXXXXX");      strcpy(phys_ram_file, "/tmp/vlXXXXXX");
1736      if (mkstemp(phys_ram_file) < 0) {      if (mkstemp(phys_ram_file) < 0) {
# Line 1294  int main(int argc, char **argv) Line 1796  int main(int argc, char **argv)
1796      pic_init();      pic_init();
1797      pit_init();      pit_init();
1798      serial_init();      serial_init();
1799        ne2000_init();
1800    
1801      /* setup cpu signal handlers for MMU / self modifying code handling */      /* setup cpu signal handlers for MMU / self modifying code handling */
1802      sigfillset(&act.sa_mask);      sigfillset(&act.sa_mask);
# Line 1341  int main(int argc, char **argv) Line 1844  int main(int argc, char **argv)
1844      setitimer(ITIMER_REAL, &itv, NULL);      setitimer(ITIMER_REAL, &itv, NULL);
1845    
1846      for(;;) {      for(;;) {
1847          struct pollfd ufds[1], *pf;          struct pollfd ufds[2], *pf, *serial_ufd, *net_ufd;
1848          int ret, n, timeout;          int ret, n, timeout;
1849          uint8_t ch;          uint8_t ch;
1850    
# Line 1353  int main(int argc, char **argv) Line 1856  int main(int argc, char **argv)
1856          else          else
1857              timeout = 0;              timeout = 0;
1858          /* poll any events */          /* poll any events */
1859            serial_ufd = NULL;
1860            net_ufd = NULL;
1861          pf = ufds;          pf = ufds;
1862          if (!(serial_ports[0].lsr & UART_LSR_DR)) {          if (!(serial_ports[0].lsr & UART_LSR_DR)) {
1863                serial_ufd = pf;
1864              pf->fd = 0;              pf->fd = 0;
1865              pf->events = POLLIN;              pf->events = POLLIN;
1866              pf++;              pf++;
1867          }          }
1868            if (net_fd > 0 && ne2000_can_receive(&ne2000_state)) {
1869                net_ufd = pf;
1870                pf->fd = net_fd;
1871                pf->events = POLLIN;
1872                pf++;
1873            }
1874          ret = poll(ufds, pf - ufds, timeout);          ret = poll(ufds, pf - ufds, timeout);
1875          if (ret > 0) {          if (ret > 0) {
1876              if (ufds[0].revents & POLLIN) {              if (serial_ufd && (serial_ufd->revents & POLLIN)) {
1877                  n = read(0, &ch, 1);                  n = read(0, &ch, 1);
1878                  if (n == 1) {                  if (n == 1) {
1879                      serial_received_byte(&serial_ports[0], ch);                      serial_received_byte(&serial_ports[0], ch);
1880                  }                  }
1881              }              }
1882                if (net_ufd && (net_ufd->revents & POLLIN)) {
1883                    uint8_t buf[MAX_ETH_FRAME_SIZE];
1884    
1885                    n = read(net_fd, buf, MAX_ETH_FRAME_SIZE);
1886                    if (n > 0) {
1887                        if (n < 60) {
1888                            memset(buf + n, 0, 60 - n);
1889                            n = 60;
1890                        }
1891                        ne2000_receive(&ne2000_state, buf, n);
1892                    }
1893                }
1894          }          }
1895    
1896          /* just for testing */          /* just for testing */

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26