|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.