/[dynamips]/trunk/dev_i8254x.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/dev_i8254x.c

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

upstream/dynamips-0.2.7-RC1/dev_i8254x.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC upstream/dynamips-0.2.8-RC1/dev_i8254x.c revision 11 by dpavlin, Sat Oct 6 16:33:40 2007 UTC
# Line 2  Line 2 
2   * Cisco router simulation platform.   * Cisco router simulation platform.
3   * Copyright (C) 2007 Christophe Fillot.  All rights reserved.   * Copyright (C) 2007 Christophe Fillot.  All rights reserved.
4   *   *
5   * Intel i8254x (Livengood) FastEthernet chip emulation.   * Intel i8254x (Wiseman/Livengood) Ethernet chip emulation.
6   */   */
7    
8  #include <stdio.h>  #include <stdio.h>
# Line 27  Line 27 
27    
28  /* Debugging flags */  /* Debugging flags */
29  #define DEBUG_MII_REGS   0  #define DEBUG_MII_REGS   0
30  #define DEBUG_ACCESS     1  #define DEBUG_ACCESS     0
31  #define DEBUG_TRANSMIT   0  #define DEBUG_TRANSMIT   0
32  #define DEBUG_RECEIVE    0  #define DEBUG_RECEIVE    0
33  #define DEBUG_UNKNOWN    1  #define DEBUG_UNKNOWN    0
34    
35  /* Intel i8254x PCI vendor/product codes */  /* Intel i8254x PCI vendor/product codes */
36  #define I8254X_PCI_VENDOR_ID    0x8086  #define I8254X_PCI_VENDOR_ID    0x8086
# Line 68  Line 68 
68  #define I8254X_REG_RDLEN     0x2808  /* RX Descriptor Length */  #define I8254X_REG_RDLEN     0x2808  /* RX Descriptor Length */
69  #define I8254X_REG_RDH       0x2810  /* RX Descriptor Head */  #define I8254X_REG_RDH       0x2810  /* RX Descriptor Head */
70  #define I8254X_REG_RDT       0x2818  /* RX Descriptor Tail */  #define I8254X_REG_RDT       0x2818  /* RX Descriptor Tail */
 #define I82542_REG_RDH       0x0120  /* RDH for i82542 */  
 #define I82542_REG_RDT       0x0128  /* RDT for i82542 */  
71  #define I8254X_REG_RDTR      0x2820  /* RX Delay Timer Register */  #define I8254X_REG_RDTR      0x2820  /* RX Delay Timer Register */
72  #define I8254X_REG_RXDCTL    0x3828  /* RX Descriptor Control */  #define I8254X_REG_RXDCTL    0x3828  /* RX Descriptor Control */
73  #define I8254X_REG_RADV      0x282c  /* RX Int. Absolute Delay Timer */  #define I8254X_REG_RADV      0x282c  /* RX Int. Absolute Delay Timer */
# Line 81  Line 79 
79  #define I8254X_REG_TDLEN     0x3808  /* TX Descriptor Length */  #define I8254X_REG_TDLEN     0x3808  /* TX Descriptor Length */
80  #define I8254X_REG_TDH       0x3810  /* TX Descriptor Head */  #define I8254X_REG_TDH       0x3810  /* TX Descriptor Head */
81  #define I8254X_REG_TDT       0x3818  /* TX Descriptor Tail */  #define I8254X_REG_TDT       0x3818  /* TX Descriptor Tail */
 #define I82542_REG_TDH       0x0430  /* TDH for i82542 */  
 #define I82542_REG_TDT       0x0438  /* TDT for i82542 */  
82  #define I8254X_REG_TIDV      0x3820  /* TX Interrupt Delay Value */  #define I8254X_REG_TIDV      0x3820  /* TX Interrupt Delay Value */
83  #define I8254X_REG_TXDCTL    0x3828  /* TX Descriptor Control */  #define I8254X_REG_TXDCTL    0x3828  /* TX Descriptor Control */
84  #define I8254X_REG_TADV      0x382c  /* TX Absolute Interrupt Delay Value */  #define I8254X_REG_TADV      0x382c  /* TX Absolute Interrupt Delay Value */
# Line 90  Line 86 
86    
87  #define I8254X_REG_RXCSUM    0x5000  /* RX Checksum Control */  #define I8254X_REG_RXCSUM    0x5000  /* RX Checksum Control */
88    
89    /* Register list for i8254x */
90    #define I82542_REG_RDTR      0x0108  /* RX Delay Timer Register */
91    #define I82542_REG_RDBAL     0x0110  /* RX Descriptor Base Address Low */
92    #define I82542_REG_RDBAH     0x0114  /* RX Descriptor Base Address High */
93    #define I82542_REG_RDLEN     0x0118  /* RX Descriptor Length */
94    #define I82542_REG_RDH       0x0120  /* RDH for i82542 */
95    #define I82542_REG_RDT       0x0128  /* RDT for i82542 */
96    #define I82542_REG_TDBAL     0x0420  /* TX Descriptor Base Address Low */
97    #define I82542_REG_TDBAH     0x0424  /* TX Descriptor Base Address Low */
98    #define I82542_REG_TDLEN     0x0428  /* TX Descriptor Length */
99    #define I82542_REG_TDH       0x0430  /* TDH for i82542 */
100    #define I82542_REG_TDT       0x0438  /* TDT for i82542 */
101    
102  /* CTRL - Control Register (0x0000) */  /* CTRL - Control Register (0x0000) */
103  #define I8254X_CTRL_FD               0x00000001  /* Full Duplex */  #define I8254X_CTRL_FD               0x00000001  /* Full Duplex */
# Line 239  Line 247 
247  #define I8254X_RXDESC_EOP       0x00000002  /* End Of Packet */  #define I8254X_RXDESC_EOP       0x00000002  /* End Of Packet */
248  #define I8254X_RXDESC_DD        0x00000001  /* Descriptor Done */  #define I8254X_RXDESC_DD        0x00000001  /* Descriptor Done */
249    
   
   
250  /* Intel i8254x private data */  /* Intel i8254x private data */
251  struct i8254x_data {  struct i8254x_data {
252     char *name;     char *name;
# Line 275  struct i8254x_data { Line 281  struct i8254x_data {
281     /* Extended Control Register */     /* Extended Control Register */
282     m_uint32_t ctrl_ext;     m_uint32_t ctrl_ext;
283    
284       /* Flow Control registers */
285       m_uint32_t fcal,fcah,fct;
286    
287       /* RX Delay Timer */
288       m_uint32_t rdtr;
289    
290     /* RX/TX Control Registers */     /* RX/TX Control Registers */
291     m_uint32_t rctl,tctl;     m_uint32_t rctl,tctl;
292    
# Line 342  static m_uint16_t mii_reg_read(struct i8 Line 354  static m_uint16_t mii_reg_read(struct i8
354        case 0x05:        case 0x05:
355           return(0x41e1);           return(0x41e1);
356        case 0x06:        case 0x06:
357           return(0x1);           return(0x0001);
358        case 0x11:        case 0x11:
359           return(0x4700);           return(0x4700);
360        default:        default:
# Line 463  static inline void dev_i8254x_update_irq Line 475  static inline void dev_i8254x_update_irq
475  {  {
476     if (d->icr & d->imr)     if (d->icr & d->imr)
477        pci_dev_trigger_irq(d->vm,d->pci_dev);        pci_dev_trigger_irq(d->vm,d->pci_dev);
478       else
479          pci_dev_clear_irq(d->vm,d->pci_dev);
480  }  }
481    
482  /* Compute RX buffer size */  /* Compute RX buffer size */
# Line 532  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 546  void *dev_i8254x_access(cpu_gen_t *cpu,s
546     LVG_LOCK(d);     LVG_LOCK(d);
547    
548     switch(offset) {     switch(offset) {
549    #if 0 /* TODO */
550          case 0x180:
551             if (op_type == MTS_READ)
552                *data = 0xFFFFFFFF; //0xDC004020; //1 << 31;
553             break;
554    #endif
555    
556        /* Link is Up and Full Duplex */        /* Link is Up and Full Duplex */
557        case I8254X_REG_STATUS:        case I8254X_REG_STATUS:
558           if (op_type == MTS_READ)           if (op_type == MTS_READ)
559              *data = I8254X_STATUS_LU | I8254X_STATUS_FD ;              *data = I8254X_STATUS_LU | I8254X_STATUS_FD;
560           break;           break;
561    
562        /* Device Control Register */        /* Device Control Register */
# Line 643  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 664  void *dev_i8254x_access(cpu_gen_t *cpu,s
664    
665        /* RX Descriptor Base Address Low */        /* RX Descriptor Base Address Low */
666        case I8254X_REG_RDBAL:        case I8254X_REG_RDBAL:
667          case I82542_REG_RDBAL:
668           if (op_type == MTS_WRITE) {           if (op_type == MTS_WRITE) {
669              d->rx_addr &= 0xFFFFFFFF00000000ULL;              d->rx_addr &= 0xFFFFFFFF00000000ULL;
670              d->rx_addr |= (m_uint32_t)(*data);              d->rx_addr |= (m_uint32_t)(*data);
# Line 653  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 675  void *dev_i8254x_access(cpu_gen_t *cpu,s
675    
676        /* RX Descriptor Base Address High */        /* RX Descriptor Base Address High */
677        case I8254X_REG_RDBAH:        case I8254X_REG_RDBAH:
678          case I82542_REG_RDBAH:
679           if (op_type == MTS_WRITE) {           if (op_type == MTS_WRITE) {
680              d->rx_addr &= 0x00000000FFFFFFFFULL;              d->rx_addr &= 0x00000000FFFFFFFFULL;
681              d->rx_addr |= *data << 32;              d->rx_addr |= *data << 32;
# Line 663  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 686  void *dev_i8254x_access(cpu_gen_t *cpu,s
686    
687        /* TX Descriptor Base Address Low */        /* TX Descriptor Base Address Low */
688        case I8254X_REG_TDBAL:        case I8254X_REG_TDBAL:
689          case I82542_REG_TDBAL:
690           if (op_type == MTS_WRITE) {           if (op_type == MTS_WRITE) {
691              d->tx_addr &= 0xFFFFFFFF00000000ULL;              d->tx_addr &= 0xFFFFFFFF00000000ULL;
692              d->tx_addr |= (m_uint32_t)(*data);              d->tx_addr |= (m_uint32_t)(*data);
# Line 673  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 697  void *dev_i8254x_access(cpu_gen_t *cpu,s
697    
698        /* TX Descriptor Base Address High */        /* TX Descriptor Base Address High */
699        case I8254X_REG_TDBAH:        case I8254X_REG_TDBAH:
700          case I82542_REG_TDBAH:
701           if (op_type == MTS_WRITE) {           if (op_type == MTS_WRITE) {
702              d->tx_addr &= 0x00000000FFFFFFFFULL;              d->tx_addr &= 0x00000000FFFFFFFFULL;
703              d->tx_addr |= *data << 32;              d->tx_addr |= *data << 32;
# Line 683  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 708  void *dev_i8254x_access(cpu_gen_t *cpu,s
708                
709        /* RX Descriptor Length */        /* RX Descriptor Length */
710        case I8254X_REG_RDLEN:        case I8254X_REG_RDLEN:
711          case I82542_REG_RDLEN:
712           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
713              d->rdlen = *data & 0xFFF80;              d->rdlen = *data & 0xFFF80;
714           else           else
# Line 691  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 717  void *dev_i8254x_access(cpu_gen_t *cpu,s
717    
718        /* TX Descriptor Length */        /* TX Descriptor Length */
719        case I8254X_REG_TDLEN:        case I8254X_REG_TDLEN:
720          case I82542_REG_TDLEN:
721           if (op_type == MTS_WRITE)           if (op_type == MTS_WRITE)
722              d->tdlen = *data & 0xFFF80;              d->tdlen = *data & 0xFFF80;
723           else           else
# Line 733  void *dev_i8254x_access(cpu_gen_t *cpu,s Line 760  void *dev_i8254x_access(cpu_gen_t *cpu,s
760              *data = d->tdt;              *data = d->tdt;
761           break;           break;
762    
763          /* Flow Control Address Low */
764          case I8254X_REG_FCAL:
765             if (op_type == MTS_WRITE)
766                d->fcal = *data;
767             else
768                *data = d->fcal;
769             break;
770    
771          /* Flow Control Address High */
772          case I8254X_REG_FCAH:
773             if (op_type == MTS_WRITE)
774                d->fcah = *data & 0xFFFF;
775             else
776                *data = d->fcah;
777             break;
778    
779          /* Flow Control Type */
780          case I8254X_REG_FCT:
781             if (op_type == MTS_WRITE)
782                d->fct = *data & 0xFFFF;
783             else
784                *data = d->fct;
785             break;
786    
787          /* RX Delay Timer */
788          case I8254X_REG_RDTR:
789          case I82542_REG_RDTR:
790             if (op_type == MTS_WRITE)
791                d->rdtr = *data & 0xFFFF;
792             else
793                *data = d->rdtr;
794             break;
795    
796  #if DEBUG_UNKNOWN  #if DEBUG_UNKNOWN
797        default:        default:
798           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
# Line 785  static int dev_i8254x_handle_txring(stru Line 845  static int dev_i8254x_handle_txring(stru
845        return(FALSE);        return(FALSE);
846    
847     LVG_LOCK(d);     LVG_LOCK(d);
848      
849     /* Empty packet for now */     /* Empty packet for now */
850     pkt_ptr = d->tx_buffer;     pkt_ptr = d->tx_buffer;
851     tot_len = 0;     tot_len = 0;
# Line 799  static int dev_i8254x_handle_txring(stru Line 859  static int dev_i8254x_handle_txring(stru
859        buf_addr = ((m_uint64_t)txd.tdes[1] << 32) | txd.tdes[0];        buf_addr = ((m_uint64_t)txd.tdes[1] << 32) | txd.tdes[0];
860        buf_len  = txd.tdes[2] & I8254X_TXDESC_LEN_MASK;        buf_len  = txd.tdes[2] & I8254X_TXDESC_LEN_MASK;
861    
862          //printf("COPYING DATA FROM 0x%8.8llx\n",buf_addr);
863        norm_len = normalize_size(buf_len,4,0);        norm_len = normalize_size(buf_len,4,0);
864        physmem_copy_from_vm(d->vm,pkt_ptr,buf_addr,norm_len);        physmem_copy_from_vm(d->vm,pkt_ptr,buf_addr,norm_len);
865        mem_bswap32(pkt_ptr,norm_len);        mem_bswap32(pkt_ptr,norm_len);
# Line 819  static int dev_i8254x_handle_txring(stru Line 880  static int dev_i8254x_handle_txring(stru
880    
881        /* End of packet ? */        /* End of packet ? */
882        if (txd.tdes[2] & I8254X_TXDESC_EOP) {        if (txd.tdes[2] & I8254X_TXDESC_EOP) {
883    #if DEBUG_TRANSMIT
884             LVG_LOG(d,"sending packet of %u bytes\n",tot_len);
885             mem_dump(log_file,d->tx_buffer,tot_len);
886    #endif
887           netio_send(d->nio,d->tx_buffer,tot_len);           netio_send(d->nio,d->tx_buffer,tot_len);
888           break;           break;
889        }        }
# Line 950  static int dev_i8254x_handle_rxring(neti Line 1015  static int dev_i8254x_handle_rxring(neti
1015   * Read a PCI register.   * Read a PCI register.
1016   */   */
1017  static m_uint32_t pci_i8254x_read(cpu_gen_t *cpu,struct pci_device *dev,  static m_uint32_t pci_i8254x_read(cpu_gen_t *cpu,struct pci_device *dev,
1018                                      int reg)                                    int reg)
1019  {  {
1020     struct i8254x_data *d = dev->priv_data;     struct i8254x_data *d = dev->priv_data;
1021    
# Line 962  static m_uint32_t pci_i8254x_read(cpu_ge Line 1027  static m_uint32_t pci_i8254x_read(cpu_ge
1027        case 0x00:        case 0x00:
1028           return((I8254X_PCI_PRODUCT_ID << 16) | I8254X_PCI_VENDOR_ID);           return((I8254X_PCI_PRODUCT_ID << 16) | I8254X_PCI_VENDOR_ID);
1029        case 0x08:        case 0x08:
1030           return(0x02000002);           return(0x02000003);
1031        case PCI_REG_BAR0:        case PCI_REG_BAR0:
1032           return(d->dev->phys_addr);           return(d->dev->phys_addr);
1033        default:        default:
# Line 976  static m_uint32_t pci_i8254x_read(cpu_ge Line 1041  static m_uint32_t pci_i8254x_read(cpu_ge
1041   * Write a PCI register.   * Write a PCI register.
1042   */   */
1043  static void pci_i8254x_write(cpu_gen_t *cpu,struct pci_device *dev,  static void pci_i8254x_write(cpu_gen_t *cpu,struct pci_device *dev,
1044                                 int reg,m_uint32_t value)                               int reg,m_uint32_t value)
1045  {  {
1046     struct i8254x_data *d = dev->priv_data;     struct i8254x_data *d = dev->priv_data;
1047    

Legend:
Removed from v.7  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26