📄 dev_mv64460.c
字号:
break; /* Channel registers */ case MV64460_MPSC_CHR1: case MV64460_MPSC_CHR2: case MV64460_MPSC_CHR3: case MV64460_MPSC_CHR4: case MV64460_MPSC_CHR5: case MV64460_MPSC_CHR6: case MV64460_MPSC_CHR7: case MV64460_MPSC_CHR8: case MV64460_MPSC_CHR9: //case MV64460_MPSC_CHR10: reg = (offset - MV64460_MPSC_CHR1) >> 2; if (op_type == MTS_READ) *data = channel->chr[reg]; else channel->chr[reg] = *data; break; case MV64460_MPSC_CHR10: if (op_type == MTS_READ) *data = channel->chr[9] | 0x20; else channel->chr[9] = *data; break; default: /* unknown/unmanaged register */ return(FALSE); } return(TRUE);}/* ======================================================================== *//* Synchronize interrupt states */static void mv64460_int_sync(struct mv64460_data *d){ mv64460_gpio_update_int_status(d); mv64460_sdma_update_int_status(d);}/* * dev_mv64460_access() */void *dev_mv64460_access(cpu_gen_t *cpu,struct vdevice *dev,m_uint32_t offset, u_int op_size,u_int op_type,m_uint64_t *data){ struct mv64460_data *mv_data = dev->priv_data; MV64460_LOCK(mv_data); if (op_type == MTS_READ) { *data = 0; } else { if (op_size == 4) *data = swap32(*data); }#if DEBUG_ACCESS if (op_type == MTS_READ) { cpu_log(cpu,"MV64460", "read access to register 0x%x, pc=0x%llx\n", offset,cpu_get_pc(cpu)); } else { cpu_log(cpu,"MV64460", "write access to register 0x%x, value=0x%llx, pc=0x%llx\n", offset,*data,cpu_get_pc(cpu)); }#endif /* Serial DMA channel registers */ if (mv64460_sdma_access(cpu,dev,offset,op_size,op_type,data) != 0) goto done; /* MPSC registers */ if (mv64460_mpsc_access(cpu,dev,offset,op_size,op_type,data) != 0) goto done; switch(offset) { /* Interrupt Main Cause Low */ case MV64460_REG_ILMCR: if (op_type == MTS_READ) *data = mv_data->intr_lo; break; /* Interrupt Main Cause High */ case MV64460_REG_IHMCR: if (op_type == MTS_READ) *data = mv_data->intr_hi; break; /* CPU_INTn[0] Mask Low */ case MV64460_REG_CPU_INTN0_MASK_LO: if (op_type == MTS_READ) { *data = mv_data->cpu_intn0_mask_lo; } else { mv_data->cpu_intn0_mask_lo = *data; mv64460_int_sync(mv_data); } break; /* CPU_INTn[0] Mask High */ case MV64460_REG_CPU_INTN0_MASK_HI: if (op_type == MTS_READ) { *data = mv_data->cpu_intn0_mask_hi; } else { mv_data->cpu_intn0_mask_hi = *data; mv64460_int_sync(mv_data); } break; /* CPU_INTn[0] Select Cause (read-only) */ case MV64460_REG_CPU_INTN0_SEL_CAUSE: if (op_type == MTS_READ) { *data = mv64460_ic_get_sel_cause(mv_data, mv_data->cpu_intn0_mask_lo, mv_data->cpu_intn0_mask_hi); } break; /* CPU_INTn[1] Mask Low */ case MV64460_REG_CPU_INTN1_MASK_LO: if (op_type == MTS_READ) *data = mv_data->cpu_intn1_mask_lo; else mv_data->cpu_intn1_mask_lo = *data; break; /* CPU_INTn[1] Mask High */ case MV64460_REG_CPU_INTN1_MASK_HI: if (op_type == MTS_READ) *data = mv_data->cpu_intn1_mask_hi; else mv_data->cpu_intn1_mask_hi = *data; break; /* CPU_INTn[1] Select Cause (read-only) */ case MV64460_REG_CPU_INTN1_SEL_CAUSE: if (op_type == MTS_READ) { *data = mv64460_ic_get_sel_cause(mv_data, mv_data->cpu_intn1_mask_lo, mv_data->cpu_intn1_mask_hi); } break; /* INT0n Mask Low */ case MV64460_REG_INT0N_MASK_LO: if (op_type == MTS_READ) *data = mv_data->int0n_mask_lo; else mv_data->int0n_mask_lo = *data; break; /* INT0n Mask High */ case MV64460_REG_INT0N_MASK_HI: if (op_type == MTS_READ) *data = mv_data->int0n_mask_hi; else mv_data->int0n_mask_hi = *data; break; /* INT0n Select Cause (read-only) */ case MV64460_REG_INT0N_SEL_CAUSE: if (op_type == MTS_READ) { *data = mv64460_ic_get_sel_cause(mv_data, mv_data->int0n_mask_lo, mv_data->int0n_mask_hi); } break; /* INT1n Mask Low */ case MV64460_REG_INT1N_MASK_LO: if (op_type == MTS_READ) *data = mv_data->int1n_mask_lo; else mv_data->int1n_mask_lo = *data; break; /* INT1n Mask High */ case MV64460_REG_INT1N_MASK_HI: if (op_type == MTS_READ) *data = mv_data->int1n_mask_hi; else mv_data->int1n_mask_hi = *data; break; /* INT1n Select Cause (read-only) */ case MV64460_REG_INT1N_SEL_CAUSE: if (op_type == MTS_READ) { *data = mv64460_ic_get_sel_cause(mv_data, mv_data->int1n_mask_lo, mv_data->int1n_mask_hi); } break; /* ===== PCI Bus 0 ===== */ case PCI_BUS_ADDR: /* pci configuration address (0xcf8) */ pci_dev_addr_handler(cpu,mv_data->bus[0],op_type,FALSE,data); break; case PCI_BUS_DATA: /* pci data address (0xcfc) */ pci_dev_data_handler(cpu,mv_data->bus[0],op_type,FALSE,data); break; /* ===== PCI Bus 0 ===== */ case 0xc78: /* pci configuration address (0xc78) */ pci_dev_addr_handler(cpu,mv_data->bus[1],op_type,FALSE,data); break; case 0xc7c: /* pci data address (0xc7c) */ pci_dev_data_handler(cpu,mv_data->bus[1],op_type,FALSE,data); break; /* MII */ case 0x2004: if (op_type == MTS_READ) *data = 0x08000000; break; /* GPP interrupt cause */ case MV64460_REG_GPP_INTR_CAUSE: if (op_type == MTS_READ) *data = mv_data->gpp_intr; break; /* GPP interrupt mask0 */ case MV64460_REG_GPP_INTR_MASK0: if (op_type == MTS_READ) { *data = mv_data->gpp_mask0; } else { mv_data->gpp_mask0 = *data; mv64460_gpio_update_int_status(mv_data); } break; /* GPP interrupt mask1 */ case MV64460_REG_GPP_INTR_MASK1: if (op_type == MTS_READ) { *data = mv_data->gpp_mask1; } else { mv_data->gpp_mask1 = *data; mv64460_gpio_update_int_status(mv_data); } break; /* GPP value set */ case MV64460_REG_GPP_VALUE_SET: if (op_type == MTS_WRITE) { mv_data->gpp_intr |= *data; mv64460_gpio_update_int_status(mv_data); } break; /* GPP value clear */ case MV64460_REG_GPP_VALUE_CLEAR: if (op_type == MTS_WRITE) { mv_data->gpp_intr &= ~(*data); mv64460_gpio_update_int_status(mv_data); } break; /* SDMA cause register */ case MV64460_REG_SDMA_CAUSE: if (op_type == MTS_READ) { *data = mv_data->sdma_cause; } else { mv_data->sdma_cause = *data; mv64460_sdma_update_int_status(mv_data); } break; /* SDMA mask register */ case MV64460_REG_SDMA_MASK: if (op_type == MTS_READ) { *data = mv_data->sdma_mask; } else { mv_data->sdma_mask = *data; mv64460_sdma_update_int_status(mv_data); } break; /* Integrated SRAM base address */ case MV64460_REG_SRAM_BASE: if (op_type == MTS_READ) { *data = mv_data->sram_dev.phys_addr << MV64460_SRAM_WIDTH; } else { m_uint64_t sram_addr; sram_addr = *data & MV64460_SRAM_BASE_MASK; sram_addr >>= MV64460_SRAM_BASE_SHIFT; sram_addr <<= MV64460_SRAM_WIDTH; vm_map_device(mv_data->vm,&mv_data->sram_dev,sram_addr); MV64460_LOG(mv_data,"SRAM mapped at 0x%10.10llx\n", mv_data->sram_dev.phys_addr); } break;#if DEBUG_UNKNOWN default: if (op_type == MTS_READ) { cpu_log(cpu,"MV64460","read from addr 0x%x, pc=0x%llx\n", offset,cpu_get_pc(cpu)); } else { cpu_log(cpu,"MV64460","write to addr 0x%x, value=0x%llx, " "pc=0x%llx\n",offset,*data,cpu_get_pc(cpu)); }#endif } done: MV64460_UNLOCK(mv_data); if ((op_type == MTS_READ) && (op_size == 4)) *data = swap32(*data); return NULL;}/* Set value of GPP register */void dev_mv64460_set_gpp_reg(struct mv64460_data *d,m_uint32_t val){ d->gpp_intr = val; mv64460_gpio_update_int_status(d);}/* Set a GPP interrupt */void dev_mv64460_set_gpp_intr(struct mv64460_data *d,u_int irq){ d->gpp_intr |= 1 << irq; mv64460_gpio_update_int_status(d);}/* Clear a GPP interrupt */void dev_mv64460_clear_gpp_intr(struct mv64460_data *d,u_int irq){ d->gpp_intr &= ~(1 << irq); mv64460_gpio_update_int_status(d);}/* * pci_mv64460_read() * * Read a PCI register. */static m_uint32_t pci_mv64460_read(cpu_gen_t *cpu,struct pci_device *dev, int reg){ switch (reg) { default: return(0); }}/* Shutdown a MV64460 system controller */void dev_mv64460_shutdown(vm_instance_t *vm,struct mv64460_data *d){ if (d != NULL) { /* Remove the SRAM */ dev_remove(vm,&d->sram_dev); /* Remove the device */ dev_remove(vm,&d->dev); /* Remove the PCI device */ pci_dev_remove(d->pci_dev); /* Free the structure itself */ free(d); }}/* Create a new MV64460 controller */int dev_mv64460_init(vm_instance_t *vm,char *name, m_uint64_t paddr,m_uint32_t len){ struct mv64460_data *d; int i; if (!(d = malloc(sizeof(*d)))) { fprintf(stderr,"mv64460: unable to create device data.\n"); return(-1); } memset(d,0,sizeof(*d)); pthread_mutex_init(&d->lock,NULL); d->name = name; d->vm = vm; d->bus[0] = vm->pci_bus[0]; d->bus[1] = vm->pci_bus[1]; for(i=0;i<MV64460_SDMA_CHANNELS;i++) d->sdma[i].id = i; vm_object_init(&d->vm_obj); d->vm_obj.name = name; d->vm_obj.data = d; d->vm_obj.shutdown = (vm_shutdown_t)dev_mv64460_shutdown; dev_init(&d->dev); d->dev.name = name; d->dev.priv_data = d; d->dev.phys_addr = paddr; d->dev.phys_len = len; d->dev.handler = dev_mv64460_access; /* Create the SRAM device */ dev_init(&d->sram_dev); d->sram_dev.name = "mv64460_sram"; d->sram_dev.phys_len = MV64460_SRAM_SIZE; d->sram_dev.flags = VDEVICE_FLAG_CACHING; d->sram_dev.host_addr = (m_iptr_t)m_memalign(4096,d->sram_dev.phys_len); if (!d->sram_dev.host_addr) { fprintf(stderr,"mv64460: unable to create SRAM data.\n"); return(-1); } /* Add the controller as a PCI device */ if (!pci_dev_lookup(d->bus[0],0,0,0)) { d->pci_dev = pci_dev_add(d->bus[0],name, PCI_VENDOR_MARVELL,PCI_PRODUCT_MARVELL_MV64460, 0,0,-1,d,NULL,pci_mv64460_read,NULL); if (!d->pci_dev) { fprintf(stderr,"mv64460: unable to create PCI device.\n"); return(-1); } } /* TEST */ pci_dev_add(d->bus[1],name, PCI_VENDOR_MARVELL,PCI_PRODUCT_MARVELL_MV64460, 0,0,-1,d,NULL,pci_mv64460_read,NULL); /* Map this device to the VM */ vm_bind_device(vm,&d->dev); vm_object_add(vm,&d->vm_obj); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -