📄 dev_gt.c
字号:
channel->ctrl &= ~GT_DMA_FETCH_NEXT;}/* Handle control register of a DMA channel */static void gt_dma_handle_ctrl(struct gt_data *gt_data,int chan_id){ struct dma_channel *channel = >_data->dma[chan_id]; vm_instance_t *vm = gt_data->vm; int done; if (channel->ctrl & GT_DMA_FETCH_NEXT) { if (channel->nrptr == 0) { vm_log(vm,"GT_DMA","trying to load a NULL DMA record...\n"); return; } gt_dma_fetch_rec(vm,channel); } if (channel->ctrl & GT_DMA_CHAN_ENABLE) { do { done = TRUE;#if DEBUG_DMA vm_log(vm,"GT_DMA", "starting transfer from 0x%x to 0x%x (size=%u bytes)\n", channel->src_addr,channel->dst_addr, channel->byte_count & 0xFFFF);#endif physmem_dma_transfer(vm,channel->src_addr,channel->dst_addr, channel->byte_count & 0xFFFF); /* chained mode */ if (!(channel->ctrl & GT_DMA_CHAIN_MODE)) { if (channel->nrptr) { gt_dma_fetch_rec(vm,channel); done = FALSE; } } }while(!done);#if DEBUG_DMA vm_log(vm,"GT_DMA","finished transfer.\n");#endif /* Trigger DMA interrupt */ gt_data->int_cause_reg |= 1 << (4 + chan_id); gt_data->gt_update_irq_status(gt_data); }}#define DMA_REG(ch,reg_name) \ if (op_type == MTS_WRITE) \ gt_data->dma[ch].reg_name = *data; \ else \ *data = gt_data->dma[ch].reg_name;/* Handle a DMA channel */static int gt_dma_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 gt_data *gt_data = dev->priv_data; switch(offset) { /* DMA Source Address */ case 0x810: DMA_REG(0,src_addr); return(1); case 0x814: DMA_REG(1,src_addr); return(1); case 0x818: DMA_REG(2,src_addr); return(1); case 0x81c: DMA_REG(3,src_addr); return(1); /* DMA Destination Address */ case 0x820: DMA_REG(0,dst_addr); return(1); case 0x824: DMA_REG(1,dst_addr); return(1); case 0x828: DMA_REG(2,dst_addr); return(1); case 0x82c: DMA_REG(3,dst_addr); return(1); /* DMA Next Record Pointer */ case 0x830: gt_data->dma[0].cdptr = *data; DMA_REG(0,nrptr); return(1); case 0x834: gt_data->dma[1].cdptr = *data; DMA_REG(1,nrptr); return(1); case 0x838: gt_data->dma[2].cdptr = *data; DMA_REG(2,nrptr); return(1); case 0x83c: gt_data->dma[3].cdptr = *data; DMA_REG(3,nrptr); return(1); /* DMA Channel Control */ case 0x840: DMA_REG(0,ctrl); if (op_type == MTS_WRITE) gt_dma_handle_ctrl(gt_data,0); return(1); case 0x844: DMA_REG(1,ctrl); if (op_type == MTS_WRITE) gt_dma_handle_ctrl(gt_data,1); return(1); case 0x848: DMA_REG(2,ctrl); if (op_type == MTS_WRITE) gt_dma_handle_ctrl(gt_data,2); return(1); case 0x84c: DMA_REG(3,ctrl); if (op_type == MTS_WRITE) gt_dma_handle_ctrl(gt_data,3); return(1); } return(0);}/* * dev_gt64010_access() */void *dev_gt64010_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 gt_data *gt_data = dev->priv_data; if (op_type == MTS_READ) { *data = 0; } else { *data = swap32(*data); } if (gt_dma_access(cpu,dev,offset,op_size,op_type,data) != 0) goto done; switch(offset) { /* ===== DRAM Settings (completely faked, 128 Mb) ===== */ case 0x008: /* ras10_low */ if (op_type == MTS_READ) *data = 0x000; break; case 0x010: /* ras10_high */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x018: /* ras32_low */ if (op_type == MTS_READ) *data = 0x080; break; case 0x020: /* ras32_high */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x400: /* ras0_low */ if (op_type == MTS_READ) *data = 0x00; break; case 0x404: /* ras0_high */ if (op_type == MTS_READ) *data = 0xFF; break; case 0x408: /* ras1_low */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x40c: /* ras1_high */ if (op_type == MTS_READ) *data = 0x00; break; case 0x410: /* ras2_low */ if (op_type == MTS_READ) *data = 0x00; break; case 0x414: /* ras2_high */ if (op_type == MTS_READ) *data = 0xFF; break; case 0x418: /* ras3_low */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x41c: /* ras3_high */ if (op_type == MTS_READ) *data = 0x00; break; case 0xc08: /* pci0_cs10 */ if (op_type == MTS_READ) *data = 0xFFF; break; case 0xc0c: /* pci0_cs32 */ if (op_type == MTS_READ) *data = 0xFFF; break; case 0xc00: /* pci_cmd */ if (op_type == MTS_READ) *data = 0x00008001; break; /* ===== Interrupt Cause Register ===== */ case 0xc18: if (op_type == MTS_READ) { *data = gt_data->int_cause_reg; } else { gt_data->int_cause_reg &= *data; gt64k_update_irq_status(gt_data); } break; /* ===== Interrupt Mask Register ===== */ case 0xc1c: if (op_type == MTS_READ) *data = gt_data->int_mask_reg; else { gt_data->int_mask_reg = *data; gt64k_update_irq_status(gt_data); } break; /* ===== PCI Configuration ===== */ case PCI_BUS_ADDR: /* pci configuration address (0xcf8) */ pci_dev_addr_handler(cpu,gt_data->bus[0],op_type,FALSE,data); break; case PCI_BUS_DATA: /* pci data address (0xcfc) */ pci_dev_data_handler(cpu,gt_data->bus[0],op_type,FALSE,data); break;#if DEBUG_UNKNOWN default: if (op_type == MTS_READ) { cpu_log(cpu,"GT64010","read from addr 0x%x, pc=0x%llx\n", offset,cpu_get_pc(cpu)); } else { cpu_log(cpu,"GT64010","write to addr 0x%x, value=0x%llx, " "pc=0x%llx\n",offset,*data,cpu_get_pc(cpu)); }#endif } done: if (op_type == MTS_READ) *data = swap32(*data); return NULL;}/* * dev_gt64120_access() */void *dev_gt64120_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 gt_data *gt_data = dev->priv_data; if (op_type == MTS_READ) { *data = 0; } else { *data = swap32(*data); } if (gt_dma_access(cpu,dev,offset,op_size,op_type,data) != 0) goto done; switch(offset) { case 0x008: /* ras10_low */ if (op_type == MTS_READ) *data = 0x000; break; case 0x010: /* ras10_high */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x018: /* ras32_low */ if (op_type == MTS_READ) *data = 0x100; break; case 0x020: /* ras32_high */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x400: /* ras0_low */ if (op_type == MTS_READ) *data = 0x00; break; case 0x404: /* ras0_high */ if (op_type == MTS_READ) *data = 0xFF; break; case 0x408: /* ras1_low */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x40c: /* ras1_high */ if (op_type == MTS_READ) *data = 0x00; break; case 0x410: /* ras2_low */ if (op_type == MTS_READ) *data = 0x00; break; case 0x414: /* ras2_high */ if (op_type == MTS_READ) *data = 0xFF; break; case 0x418: /* ras3_low */ if (op_type == MTS_READ) *data = 0x7F; break; case 0x41c: /* ras3_high */ if (op_type == MTS_READ) *data = 0x00; break; case 0xc08: /* pci0_cs10 */ if (op_type == MTS_READ) *data = 0xFFF; break; case 0xc0c: /* pci0_cs32 */ if (op_type == MTS_READ) *data = 0xFFF; break; case 0xc00: /* pci_cmd */ if (op_type == MTS_READ) *data = 0x00008001; break; /* ===== Interrupt Cause Register ===== */ case 0xc18: if (op_type == MTS_READ) *data = gt_data->int_cause_reg; else { gt_data->int_cause_reg &= *data; gt64k_update_irq_status(gt_data); } break; /* ===== Interrupt Mask Register ===== */ case 0xc1c: if (op_type == MTS_READ) { *data = gt_data->int_mask_reg; } else { gt_data->int_mask_reg = *data; gt64k_update_irq_status(gt_data); } break; /* ===== PCI Bus 1 ===== */ case 0xcf0: pci_dev_addr_handler(cpu,gt_data->bus[1],op_type,FALSE,data); break; case 0xcf4: pci_dev_data_handler(cpu,gt_data->bus[1],op_type,FALSE,data); break; /* ===== PCI Bus 0 ===== */ case PCI_BUS_ADDR: /* pci configuration address (0xcf8) */ pci_dev_addr_handler(cpu,gt_data->bus[0],op_type,FALSE,data); break; case PCI_BUS_DATA: /* pci data address (0xcfc) */ pci_dev_data_handler(cpu,gt_data->bus[0],op_type,FALSE,data); break;#if DEBUG_UNKNOWN default: if (op_type == MTS_READ) { cpu_log(cpu,"GT64120","read from addr 0x%x, pc=0x%llx\n", offset,cpu_get_pc(cpu)); } else { cpu_log(cpu,"GT64120","write to addr 0x%x, value=0x%llx, " "pc=0x%llx\n",offset,*data,cpu_get_pc(cpu)); }#endif } done: if (op_type == MTS_READ) *data = swap32(*data); return NULL;}/* ======================================================================== *//* GT96k Interrupts *//* ======================================================================== */static void gt96k_update_irq_status(struct gt_data *d){ /* Interrupt0* active ? */ if ((d->int_cause_reg & d->int0_main_mask_reg) || (d->int_high_cause_reg & d->int0_high_mask_reg)) { d->int_cause_reg |= 1 << 30; vm_set_irq(d->vm,d->int0_irq); } else { d->int_cause_reg &= ~(1 << 30); vm_clear_irq(d->vm,d->int0_irq); } /* Interrupt1* active ? */ if ((d->int_cause_reg & d->int1_main_mask_reg) || (d->int_high_cause_reg & d->int1_high_mask_reg)) { d->int_cause_reg |= 1 << 31; vm_set_irq(d->vm,d->int1_irq); } else { d->int_cause_reg &= ~(1 << 31); vm_clear_irq(d->vm,d->int1_irq); } /* SerInt0* active ? */ if (d->ser_cause_reg & d->serint0_mask_reg) { vm_set_irq(d->vm,d->serint0_irq); } else { vm_clear_irq(d->vm,d->serint0_irq); } /* SerInt1* active ? */ if (d->ser_cause_reg & d->serint1_mask_reg) { vm_set_irq(d->vm,d->serint1_irq); } else { vm_clear_irq(d->vm,d->serint1_irq); }}/* ======================================================================== *//* SDMA (Serial DMA) *//* ======================================================================== *//* Update SDMA interrupt status */static void gt_sdma_update_int_status(struct gt_data *d){ /* Update general SDMA status */ if (d->sdma_cause_reg & d->sdma_mask_reg) { d->ser_cause_reg |= GT_SCR_SDMA_SUM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -