Annotation of cf/dev_c3725_iofpga.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Cisco 3725 simulation platform.
        !             3:  * Copyright (c) 2006 Christophe Fillot ([email protected])
        !             4:  *
        !             5:  * This is very similar to c2691.
        !             6:  */
        !             7: 
        !             8: #include <stdio.h>
        !             9: #include <stdlib.h>
        !            10: #include <string.h>
        !            11: #include <unistd.h>
        !            12: #include <sys/types.h>
        !            13: #include <termios.h>
        !            14: #include <fcntl.h>
        !            15: #include <pthread.h>
        !            16: 
        !            17: #include "ptask.h"
        !            18: #include "mips64.h"
        !            19: #include "dynamips.h"
        !            20: #include "memory.h"
        !            21: #include "device.h"
        !            22: #include "dev_vtty.h"
        !            23: #include "nmc93c46.h"
        !            24: #include "dev_c3725.h"
        !            25: 
        !            26: /* Debugging flags */
        !            27: #define DEBUG_UNKNOWN   1
        !            28: #define DEBUG_ACCESS    0
        !            29: 
        !            30: /* Definitions for Mainboard EEPROM */
        !            31: #define EEPROM_MB_DOUT  3
        !            32: #define EEPROM_MB_DIN   2
        !            33: #define EEPROM_MB_CLK   1
        !            34: #define EEPROM_MB_CS    0
        !            35: 
        !            36: /* Definitions for Network Modules EEPROM */
        !            37: #define EEPROM_NM_DOUT  7
        !            38: #define EEPROM_NM_DIN   6
        !            39: #define EEPROM_NM_CLK   2
        !            40: #define EEPROM_NM_CS    4
        !            41: 
        !            42: #define C3725_NET_IRQ_CLEARING_DELAY  16
        !            43: 
        !            44: /* IO FPGA structure */
        !            45: struct iofpga_data {
        !            46:    vm_obj_t vm_obj;
        !            47:    struct vdevice dev;
        !            48:    c3725_t *router;
        !            49:    
        !            50:    /* 
        !            51:     * Used to introduce a "delay" before clearing the network interrupt
        !            52:     * on 3620/3640 platforms. Added due to a packet loss when using an 
        !            53:     * Ethernet NM on these platforms.
        !            54:     *
        !            55:     * Anyway, we should rely on the device information with appropriate IRQ
        !            56:     * routing.
        !            57:     */
        !            58:    int net_irq_clearing_count;
        !            59: 
        !            60:    /* Interrupt mask*/
        !            61:    m_uint16_t intr_mask;
        !            62: };
        !            63: 
        !            64: /* Mainboard EEPROM definition */
        !            65: static const struct nmc93c46_eeprom_def eeprom_mb_def = {
        !            66:    EEPROM_MB_CLK, EEPROM_MB_CS,
        !            67:    EEPROM_MB_DIN, EEPROM_MB_DOUT,
        !            68: };
        !            69: 
        !            70: /* Mainboard EEPROM */
        !            71: static const struct nmc93c46_group eeprom_mb_group = {
        !            72:    1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
        !            73: };
        !            74: 
        !            75: /* NM EEPROM definition */
        !            76: static const struct nmc93c46_eeprom_def eeprom_nm_def = {
        !            77:    EEPROM_NM_CLK, EEPROM_NM_CS,
        !            78:    EEPROM_NM_DIN, EEPROM_NM_DOUT,
        !            79: };
        !            80: 
        !            81: /* NM EEPROM */
        !            82: static const struct nmc93c46_group eeprom_nm_group = {
        !            83:    1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
        !            84: };
        !            85: 
        !            86: /*
        !            87:  * dev_c3725_iofpga_access()
        !            88:  */
        !            89: static void *
        !            90: dev_c3725_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,
        !            91:                         m_uint32_t offset,u_int op_size,u_int op_type,
        !            92:                         m_uint64_t *data)
        !            93: {
        !            94:    struct iofpga_data *d = dev->priv_data;
        !            95: 
        !            96:    if (op_type == MTS_READ)
        !            97:       *data = 0x0;
        !            98: 
        !            99: #if DEBUG_ACCESS
        !           100:    if (op_type == MTS_READ) {
        !           101:       cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
        !           102:               offset,cpu->pc,op_size);
        !           103:    } else {
        !           104:       cpu_log(cpu,"IO_FPGA",
        !           105:               "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
        !           106:               offset,cpu->pc,*data,op_size);
        !           107:    }
        !           108: #endif
        !           109: 
        !           110:    switch(offset) {
        !           111:       /*
        !           112:        * Platform type ? 
        !           113:        * (other values than 0 cause crashes or lot of errors).
        !           114:        */
        !           115:       case 0x36:
        !           116:           if (op_type == MTS_READ)
        !           117:              *data = 0x0000;
        !           118:           break;
        !           119: 
        !           120:       /* Mainboard EEPROM */
        !           121:       case 0x0e:
        !           122:          if (op_type == MTS_WRITE)
        !           123:             nmc93c46_write(&d->router->mb_eeprom_group,(u_int)(*data));
        !           124:          else
        !           125:             *data = nmc93c46_read(&d->router->mb_eeprom_group);
        !           126:          break;
        !           127: 
        !           128:       case 0x12:
        !           129:          /* 
        !           130:           * Bit 0: 1=No WIC in slot 0 ?
        !           131:           * Bit 1: 1=No WIC in slot 1 ?
        !           132:           * Bit 2: 1=No WIC in slot 2 ?
        !           133:           */
        !           134:          if (op_type == MTS_READ)
        !           135:             *data = 0x0007;
        !           136:          break;
        !           137: 
        !           138:       case 0x14:
        !           139:          if (op_type == MTS_READ)
        !           140:             *data = 0xFFFF;
        !           141:          break;
        !           142: 
        !           143:       case 0x18:
        !           144:          if (op_type == MTS_READ)
        !           145:             *data = 0xFFFF;
        !           146:          break;
        !           147: 
        !           148:       /* wic/vwic related */
        !           149:       case 0x40:
        !           150:          if (op_type == MTS_READ)
        !           151:             *data = 0x0004;
        !           152:          break;
        !           153: 
        !           154:       /* WIC related: 16-bit data */
        !           155:       case 0x42:
        !           156:          break;
        !           157: 
        !           158:       /* NM Slot 1 EEPROM */
        !           159:       case 0x44:
        !           160:          if (op_type == MTS_WRITE)
        !           161:             nmc93c46_write(&d->router->nm_eeprom_group[0],(u_int)(*data));
        !           162:          else
        !           163:             *data = nmc93c46_read(&d->router->nm_eeprom_group[0]);
        !           164:          break;
        !           165: 
        !           166:       /* NM Slot 2 EEPROM */
        !           167:       case 0x46:
        !           168:          if (op_type == MTS_WRITE)
        !           169:             nmc93c46_write(&d->router->nm_eeprom_group[1],(u_int)(*data));
        !           170:          else
        !           171:             *data = nmc93c46_read(&d->router->nm_eeprom_group[1]);
        !           172:          break;
        !           173: 
        !           174:       /* AIM EEPROM #0 */
        !           175:       case 0x48:
        !           176:          if (op_type == MTS_READ)
        !           177:             *data = 0xFFFF;
        !           178:          break;
        !           179: 
        !           180:       /* AIM EEPROM #1 */
        !           181:       case 0x4a:
        !           182:          if (op_type == MTS_READ)
        !           183:             *data = 0xFFFF;
        !           184:          break;
        !           185: 
        !           186:       /* 
        !           187:        * NM Presence.
        !           188:        * 
        !           189:        * Bit  7: 0=NM present in slot 1.
        !           190:        * Bit 11: 0=NM present in slot 2.
        !           191:        * Other bits unknown.
        !           192:        */
        !           193:       case 0x20:       
        !           194:          if (op_type == MTS_READ) {
        !           195:             *data = 0xFFFF;
        !           196: 
        !           197:             if (c3725_nm_check_eeprom(d->router,1))
        !           198:                *data &= ~0x0008;
        !           199: 
        !           200:             if (c3725_nm_check_eeprom(d->router,2))
        !           201:                *data &= ~0x0800;
        !           202:          }
        !           203:          break;
        !           204: 
        !           205:       /* ??? */
        !           206:       case 0x24:
        !           207:          break;
        !           208: 
        !           209:       /* Intr Mask (sh platform) */
        !           210:       case 0x30:
        !           211:          if (op_type == MTS_READ)
        !           212:             *data = d->intr_mask;
        !           213:          else
        !           214:             d->intr_mask = *data;
        !           215:          break;
        !           216: 
        !           217:       /* 
        !           218:        * Network interrupt status.
        !           219:        *
        !           220:        * Bit 0: 0 = GT96100 Ethernet ports.
        !           221:        * Other bits unknown.
        !           222:        */
        !           223:       case 0x26:
        !           224:          if (op_type == MTS_READ)
        !           225:             *data = 0xFFFE;
        !           226:          break;
        !           227: 
        !           228:       /* 
        !           229:        * Network interrupt status.
        !           230:        *
        !           231:        * Bit 0: 0 = NM in Slot 1.
        !           232:        * Bit 8: 0 = NM in Slot 2.
        !           233:        * Other bits unknown.
        !           234:        */
        !           235:       case 0x28:
        !           236:          if (op_type == MTS_READ) {
        !           237:             *data = 0xFFEE;
        !           238: 
        !           239:             if (++d->net_irq_clearing_count == C3725_NET_IRQ_CLEARING_DELAY) {
        !           240:                vm_clear_irq(d->router->vm,C3725_NETIO_IRQ);
        !           241:                d->net_irq_clearing_count = 0;
        !           242:             }
        !           243:          }
        !           244:          break;
        !           245: 
        !           246:       case 0x2c:
        !           247:          if (op_type == MTS_READ)
        !           248:             *data = 0xFFFF;
        !           249:          break;
        !           250: 
        !           251:       /* OIR interrupt but not supported (IRQ 6) */
        !           252:       case 0x2e:
        !           253:          if (op_type == MTS_READ)
        !           254:             *data = 0xFFFF;
        !           255:          break;
        !           256: 
        !           257:       /* 
        !           258:        * Environmental monitor, determined with "sh env all". 
        !           259:        *
        !           260:        * Bit 0: 1 = Fan Error
        !           261:        * Bit 1: 1 = Fan Error
        !           262:        * Bit 2: 1 = Over-temperature
        !           263:        * Bit 3: ???
        !           264:        * Bit 4: 0 = RPS present.
        !           265:        * Bit 5: 0 = Input Voltage status failure.
        !           266:        * Bit 6: 1 = Thermal status failure.
        !           267:        * Bit 7: 1 = DC Output Voltage status failure.
        !           268:        */
        !           269:       case 0x3a:
        !           270:          if (op_type == MTS_READ)
        !           271:             *data = 0x0020;
        !           272:          break;
        !           273: 
        !           274:       /*
        !           275:        * Bit 0: Slot0 Compact Flash presence.
        !           276:        * Bit 1: System Compact Flash presence.
        !           277:        */
        !           278:       case 0x3c:
        !           279:          if (op_type == MTS_READ) {
        !           280:             *data = 0xFFFF;
        !           281: 
        !           282:             /* System Flash ? */
        !           283:             if (cpu->vm->pcmcia_disk_size[0])
        !           284:                *data &= ~0x02;
        !           285: 
        !           286:             /* Slot0 Flash ? */
        !           287:             if (cpu->vm->pcmcia_disk_size[1])
        !           288:                *data &= ~0x01;
        !           289:          }
        !           290:          break;           
        !           291: 
        !           292: #if DEBUG_UNKNOWN
        !           293:       default:
        !           294:          if (op_type == MTS_READ) {
        !           295:             cpu_log(cpu,"IO_FPGA",
        !           296:                     "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
        !           297:                     offset,cpu->pc,op_size);
        !           298:          } else {
        !           299:             cpu_log(cpu,"IO_FPGA",
        !           300:                     "write to unknown addr 0x%x, value=0x%llx, "
        !           301:                     "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);
        !           302:          }
        !           303: #endif
        !           304:    }
        !           305: 
        !           306:    return NULL;
        !           307: }
        !           308: 
        !           309: /* Initialize EEPROM groups */
        !           310: void c3725_init_eeprom_groups(c3725_t *router)
        !           311: {
        !           312:    /* Initialize Mainboard EEPROM */
        !           313:    router->mb_eeprom_group = eeprom_mb_group;
        !           314:    router->mb_eeprom_group.eeprom[0] = &router->mb_eeprom;
        !           315:    router->mb_eeprom.data = NULL;
        !           316:    router->mb_eeprom.len  = 0;
        !           317: 
        !           318:    /* EEPROM for NM slot 1 */
        !           319:    router->nm_eeprom_group[0] = eeprom_nm_group;
        !           320:    router->nm_eeprom_group[0].eeprom[0] = &router->nm_bay[1].eeprom;
        !           321: 
        !           322:    /* EEPROM for NM slot 2 */
        !           323:    router->nm_eeprom_group[1] = eeprom_nm_group;
        !           324:    router->nm_eeprom_group[1].eeprom[0] = &router->nm_bay[2].eeprom;
        !           325: }
        !           326: 
        !           327: /* Shutdown the IO FPGA device */
        !           328: void dev_c3725_iofpga_shutdown(vm_instance_t *vm,struct iofpga_data *d)
        !           329: {
        !           330:    if (d != NULL) {
        !           331:       /* Remove the device */
        !           332:       dev_remove(vm,&d->dev);
        !           333: 
        !           334:       /* Free the structure itself */
        !           335:       free(d);
        !           336:    }
        !           337: }
        !           338: 
        !           339: /*
        !           340:  * dev_c3725_iofpga_init()
        !           341:  */
        !           342: int dev_c3725_iofpga_init(c3725_t *router,m_uint64_t paddr,m_uint32_t len)
        !           343: {
        !           344:    vm_instance_t *vm = router->vm;
        !           345:    struct iofpga_data *d;
        !           346: 
        !           347:    /* Allocate private data structure */
        !           348:    if (!(d = malloc(sizeof(*d)))) {
        !           349:       fprintf(stderr,"IO_FPGA: out of memory\n");
        !           350:       return(-1);
        !           351:    }
        !           352: 
        !           353:    memset(d,0,sizeof(*d));
        !           354:    d->router = router;
        !           355: 
        !           356:    vm_object_init(&d->vm_obj);
        !           357:    d->vm_obj.name = "io_fpga";
        !           358:    d->vm_obj.data = d;
        !           359:    d->vm_obj.shutdown = (vm_shutdown_t)dev_c3725_iofpga_shutdown;
        !           360: 
        !           361:    /* Set device properties */
        !           362:    dev_init(&d->dev);
        !           363:    d->dev.name      = "io_fpga";
        !           364:    d->dev.phys_addr = paddr;
        !           365:    d->dev.phys_len  = len;
        !           366:    d->dev.priv_data = d;
        !           367:    d->dev.handler   = dev_c3725_iofpga_access;
        !           368: 
        !           369:    /* Map this device to the VM */
        !           370:    vm_bind_device(router->vm,&d->dev);
        !           371:    vm_object_add(vm,&d->vm_obj);
        !           372:    return(0);
        !           373: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.