/[dynamips]/trunk/dev_gt64k.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

Annotation of /trunk/dev_gt64k.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (hide annotations)
Sat Oct 6 16:09:07 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC5/dev_gt64k.c
File MIME type: text/plain
File size: 17635 byte(s)
dynamips-0.2.6-RC5

1 dpavlin 1 /*
2     * Cisco 7200 (Predator) simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * Galileo GT64010/GT64120A system controller.
6     *
7     * The DMA stuff is not complete, only "normal" transfers are working
8     * (source and destination addresses incrementing).
9     *
10     * Also, these transfers are "instantaneous" from a CPU point-of-view: when
11     * a channel is enabled, the transfer is immediately done. So, this is not
12     * very realistic.
13     */
14    
15     #include <stdio.h>
16     #include <stdlib.h>
17     #include <string.h>
18    
19     #include "mips64.h"
20     #include "dynamips.h"
21     #include "memory.h"
22     #include "device.h"
23    
24     #define DEBUG_UNKNOWN 1
25     #define DEBUG_DMA 0
26    
27     #define PCI_VENDOR_GALILEO 0x11ab /* Galileo Technology */
28     #define PCI_PRODUCT_GALILEO_GT64010 0x0146 /* GT-64010 */
29     #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 */
30     #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
31    
32     /* DMA definitions */
33     #define GT64K_DMA_CHANNELS 4
34    
35     #define GT64K_DMA_FLYBY_ENABLE 0x00000001 /* FlyBy Enable */
36     #define GT64K_DMA_FLYBY_RDWR 0x00000002 /* SDRAM Read/Write (FlyBy) */
37     #define GT64K_DMA_SRC_DIR 0x0000000c /* Source Direction */
38     #define GT64K_DMA_DST_DIR 0x00000030 /* Destination Direction */
39     #define GT64K_DMA_DATA_LIMIT 0x000001c0 /* Data Transfer Limit */
40     #define GT64K_DMA_CHAIN_MODE 0x00000200 /* Chained Mode */
41     #define GT64K_DMA_INT_MODE 0x00000400 /* Interrupt Mode */
42     #define GT64K_DMA_TRANS_MODE 0x00000800 /* Transfer Mode */
43     #define GT64K_DMA_CHAN_ENABLE 0x00001000 /* Channel Enable */
44     #define GT64K_DMA_FETCH_NEXT 0x00002000 /* Fetch Next Record */
45     #define GT64K_DMA_ACT_STATUS 0x00004000 /* DMA Activity Status */
46     #define GT64K_DMA_SDA 0x00008000 /* Source/Destination Alignment */
47     #define GT64K_DMA_MDREQ 0x00010000 /* Mask DMA Requests */
48     #define GT64K_DMA_CDE 0x00020000 /* Close Descriptor Enable */
49     #define GT64K_DMA_EOTE 0x00040000 /* End-of-Transfer (EOT) Enable */
50     #define GT64K_DMA_EOTIE 0x00080000 /* EOT Interrupt Enable */
51     #define GT64K_DMA_ABORT 0x00100000 /* Abort DMA Transfer */
52     #define GT64K_DMA_SLP 0x00600000 /* Override Source Address */
53     #define GT64K_DMA_DLP 0x01800000 /* Override Dest Address */
54     #define GT64K_DMA_RLP 0x06000000 /* Override Record Address */
55     #define GT64K_DMA_REQ_SRC 0x10000000 /* DMA Request Source */
56    
57     /* Galileo GT-64k DMA channel */
58     struct dma_channel {
59     m_uint32_t byte_count;
60     m_uint32_t src_addr;
61     m_uint32_t dst_addr;
62     m_uint32_t cdptr;
63     m_uint32_t nrptr;
64     m_uint32_t ctrl;
65     };
66    
67     /* Galileo GT-64k system controller */
68     struct gt64k_data {
69     vm_obj_t vm_obj;
70     struct vdevice dev;
71     struct pci_device *pci_dev;
72     vm_instance_t *vm;
73    
74     struct pci_bus *bus[2];
75     struct dma_channel dma[GT64K_DMA_CHANNELS];
76     m_uint32_t int_cause_reg;
77     m_uint32_t int_mask_reg;
78     };
79    
80     /* Update the interrupt status */
81     static void gt64k_update_irq_status(struct gt64k_data *gt_data)
82     {
83     if (gt_data->pci_dev) {
84     if (gt_data->int_cause_reg & gt_data->int_mask_reg)
85     pci_dev_trigger_irq(gt_data->vm,gt_data->pci_dev);
86     else
87     pci_dev_clear_irq(gt_data->vm,gt_data->pci_dev);
88     }
89     }
90    
91     /* Fetch a DMA record (chained mode) */
92     static void gt64k_dma_fetch_rec(vm_instance_t *vm,struct dma_channel *channel)
93     {
94     m_uint32_t ptr;
95    
96     #if DEBUG_DMA
97     cpu_log(cpu,"GT64K_DMA","fetching record at address 0x%x\n",channel->nrptr);
98     #endif
99    
100     /* fetch the record from RAM */
101     ptr = channel->nrptr;
102     channel->byte_count = swap32(physmem_copy_u32_from_vm(vm,ptr));
103     channel->src_addr = swap32(physmem_copy_u32_from_vm(vm,ptr+0x04));
104     channel->dst_addr = swap32(physmem_copy_u32_from_vm(vm,ptr+0x08));
105     channel->nrptr = swap32(physmem_copy_u32_from_vm(vm,ptr+0x0c));
106    
107     /* clear the "fetch next record bit" */
108     channel->ctrl &= ~GT64K_DMA_FETCH_NEXT;
109     }
110    
111     /* Handle control register of a DMA channel */
112     static void gt64k_dma_handle_ctrl(struct gt64k_data *gt_data,int chan_id)
113     {
114     struct dma_channel *channel = &gt_data->dma[chan_id];
115     vm_instance_t *vm = gt_data->vm;
116     int done;
117    
118     if (channel->ctrl & GT64K_DMA_FETCH_NEXT) {
119     if (channel->nrptr == 0) {
120     vm_log(vm,"GT64K_DMA","trying to load a NULL DMA record...\n");
121     return;
122     }
123    
124     gt64k_dma_fetch_rec(vm,channel);
125     }
126    
127     if (channel->ctrl & GT64K_DMA_CHAN_ENABLE)
128     {
129     do {
130     done = TRUE;
131    
132     #if DEBUG_DMA
133     cpu_log(cpu,"GT64K_DMA",
134     "starting transfer from 0x%x to 0x%x (size=%u bytes)\n",
135     channel->src_addr,channel->dst_addr,
136     channel->byte_count & 0xFFFF);
137     #endif
138     physmem_dma_transfer(vm,channel->src_addr,channel->dst_addr,
139     channel->byte_count & 0xFFFF);
140    
141     /* chained mode */
142     if (!(channel->ctrl & GT64K_DMA_CHAIN_MODE)) {
143     if (channel->nrptr) {
144     gt64k_dma_fetch_rec(vm,channel);
145     done = FALSE;
146     }
147     }
148     }while(!done);
149    
150     /* Trigger DMA interrupt */
151     gt_data->int_cause_reg |= 1 << (4 + chan_id);
152     gt64k_update_irq_status(gt_data);
153     }
154     }
155    
156     #define DMA_REG(ch,reg_name) \
157     if (op_type == MTS_WRITE) \
158     gt_data->dma[ch].reg_name = swap32(*data); \
159     else \
160     *data = swap32(gt_data->dma[ch].reg_name);
161    
162     /* Handle a DMA channel */
163     static int gt64k_dma_access(cpu_mips_t *cpu,struct vdevice *dev,
164     m_uint32_t offset,u_int op_size,u_int op_type,
165     m_uint64_t *data)
166     {
167     struct gt64k_data *gt_data = dev->priv_data;
168    
169     switch(offset) {
170     /* DMA Source Address */
171     case 0x810: DMA_REG(0,src_addr); return(1);
172     case 0x814: DMA_REG(1,src_addr); return(1);
173     case 0x818: DMA_REG(2,src_addr); return(1);
174     case 0x81c: DMA_REG(3,src_addr); return(1);
175    
176     /* DMA Destination Address */
177     case 0x820: DMA_REG(0,dst_addr); return(1);
178     case 0x824: DMA_REG(1,dst_addr); return(1);
179     case 0x828: DMA_REG(2,dst_addr); return(1);
180     case 0x82c: DMA_REG(3,dst_addr); return(1);
181    
182     /* DMA Next Record Pointer */
183     case 0x830:
184     gt_data->dma[0].cdptr = *data;
185     DMA_REG(0,nrptr);
186     return(1);
187    
188     case 0x834:
189     gt_data->dma[1].cdptr = *data;
190     DMA_REG(1,nrptr);
191     return(1);
192    
193     case 0x838:
194     gt_data->dma[2].cdptr = *data;
195     DMA_REG(2,nrptr);
196     return(1);
197    
198     case 0x83c:
199     gt_data->dma[3].cdptr = *data;
200     DMA_REG(3,nrptr);
201     return(1);
202    
203     /* DMA Channel Control */
204     case 0x840:
205     DMA_REG(0,ctrl);
206     if (op_type == MTS_WRITE)
207     gt64k_dma_handle_ctrl(gt_data,0);
208     return(1);
209    
210     case 0x844:
211     DMA_REG(1,ctrl);
212     if (op_type == MTS_WRITE)
213     gt64k_dma_handle_ctrl(gt_data,1);
214     return(1);
215    
216     case 0x848:
217     DMA_REG(2,ctrl);
218     if (op_type == MTS_WRITE)
219     gt64k_dma_handle_ctrl(gt_data,2);
220     return(1);
221    
222     case 0x84c:
223     DMA_REG(3,ctrl);
224     if (op_type == MTS_WRITE)
225     gt64k_dma_handle_ctrl(gt_data,3);
226     return(1);
227     }
228    
229     return(0);
230     }
231    
232     /*
233     * dev_gt64010_access()
234     */
235     void *dev_gt64010_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,
236     u_int op_size,u_int op_type,m_uint64_t *data)
237     {
238     struct gt64k_data *gt_data = dev->priv_data;
239    
240     if (op_type == MTS_READ)
241     *data = 0;
242    
243     if (gt64k_dma_access(cpu,dev,offset,op_size,op_type,data) != 0)
244     return NULL;
245    
246     switch(offset) {
247     /* ===== DRAM Settings (completely faked, 128 Mb) ===== */
248     case 0x008: /* ras10_low */
249     if (op_type == MTS_READ)
250     *data = swap32(0x000);
251     break;
252     case 0x010: /* ras10_high */
253     if (op_type == MTS_READ)
254     *data = swap32(0x7F);
255     break;
256     case 0x018: /* ras32_low */
257     if (op_type == MTS_READ)
258     *data = swap32(0x080);
259     break;
260     case 0x020: /* ras32_high */
261     if (op_type == MTS_READ)
262     *data = swap32(0x7F);
263     break;
264     case 0x400: /* ras0_low */
265     if (op_type == MTS_READ)
266     *data = swap32(0x00);
267     break;
268     case 0x404: /* ras0_high */
269     if (op_type == MTS_READ)
270     *data = swap32(0xFF);
271     break;
272     case 0x408: /* ras1_low */
273     if (op_type == MTS_READ)
274     *data = swap32(0x7F);
275     break;
276     case 0x40c: /* ras1_high */
277     if (op_type == MTS_READ)
278     *data = swap32(0x00);
279     break;
280     case 0x410: /* ras2_low */
281     if (op_type == MTS_READ)
282     *data = swap32(0x00);
283     break;
284     case 0x414: /* ras2_high */
285     if (op_type == MTS_READ)
286     *data = swap32(0xFF);
287     break;
288     case 0x418: /* ras3_low */
289     if (op_type == MTS_READ)
290     *data = swap32(0x7F);
291     break;
292     case 0x41c: /* ras3_high */
293     if (op_type == MTS_READ)
294     *data = swap32(0x00);
295     break;
296     case 0xc08: /* pci0_cs10 */
297     if (op_type == MTS_READ)
298     *data = swap32(0xFFF);
299     break;
300     case 0xc0c: /* pci0_cs32 */
301     if (op_type == MTS_READ)
302     *data = swap32(0xFFF);
303     break;
304    
305     case 0xc00: /* pci_cmd */
306     if (op_type == MTS_READ)
307     *data = swap32(0x00008001);
308     break;
309    
310     /* ===== Interrupt Cause Register ===== */
311     case 0xc18:
312     if (op_type == MTS_READ) {
313     *data = swap32(gt_data->int_cause_reg);
314     } else {
315     gt_data->int_cause_reg &= swap32(*data);
316     gt64k_update_irq_status(gt_data);
317     }
318     break;
319    
320     /* ===== Interrupt Mask Register ===== */
321     case 0xc1c:
322     if (op_type == MTS_READ)
323     *data = swap32(gt_data->int_mask_reg);
324     else {
325     gt_data->int_mask_reg = swap32(*data);
326     gt64k_update_irq_status(gt_data);
327     }
328     break;
329    
330     /* ===== PCI Configuration ===== */
331     case PCI_BUS_ADDR: /* pci configuration address (0xcf8) */
332     pci_dev_addr_handler(cpu,gt_data->bus[0],op_type,TRUE,data);
333     break;
334    
335     case PCI_BUS_DATA: /* pci data address (0xcfc) */
336     pci_dev_data_handler(cpu,gt_data->bus[0],op_type,TRUE,data);
337     break;
338    
339     #if DEBUG_UNKNOWN
340     default:
341     if (op_type == MTS_READ) {
342     cpu_log(cpu,"GT64010","read from addr 0x%x, pc=0x%llx\n",
343     offset,cpu->pc);
344     } else {
345     cpu_log(cpu,"GT64010","write to addr 0x%x, value=0x%llx, "
346     "pc=0x%llx\n",offset,*data,cpu->pc);
347     }
348     #endif
349     }
350    
351     return NULL;
352     }
353    
354     /*
355     * dev_gt64120_access()
356     */
357     void *dev_gt64120_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,
358     u_int op_size,u_int op_type,m_uint64_t *data)
359     {
360     struct gt64k_data *gt_data = dev->priv_data;
361    
362     if (op_type == MTS_READ)
363     *data = 0;
364    
365     if (gt64k_dma_access(cpu,dev,offset,op_size,op_type,data) != 0)
366     return NULL;
367    
368     switch(offset) {
369     case 0x008: /* ras10_low */
370     if (op_type == MTS_READ)
371     *data = swap32(0x000);
372     break;
373     case 0x010: /* ras10_high */
374     if (op_type == MTS_READ)
375     *data = swap32(0x7F);
376     break;
377     case 0x018: /* ras32_low */
378     if (op_type == MTS_READ)
379     *data = swap32(0x100);
380     break;
381     case 0x020: /* ras32_high */
382     if (op_type == MTS_READ)
383     *data = swap32(0x7F);
384     break;
385     case 0x400: /* ras0_low */
386     if (op_type == MTS_READ)
387     *data = swap32(0x00);
388     break;
389     case 0x404: /* ras0_high */
390     if (op_type == MTS_READ)
391     *data = swap32(0xFF);
392     break;
393     case 0x408: /* ras1_low */
394     if (op_type == MTS_READ)
395     *data = swap32(0x7F);
396     break;
397     case 0x40c: /* ras1_high */
398     if (op_type == MTS_READ)
399     *data = swap32(0x00);
400     break;
401     case 0x410: /* ras2_low */
402     if (op_type == MTS_READ)
403     *data = swap32(0x00);
404     break;
405     case 0x414: /* ras2_high */
406     if (op_type == MTS_READ)
407     *data = swap32(0xFF);
408     break;
409     case 0x418: /* ras3_low */
410     if (op_type == MTS_READ)
411     *data = swap32(0x7F);
412     break;
413     case 0x41c: /* ras3_high */
414     if (op_type == MTS_READ)
415     *data = swap32(0x00);
416     break;
417     case 0xc08: /* pci0_cs10 */
418     if (op_type == MTS_READ)
419     *data = swap32(0xFFF);
420     break;
421     case 0xc0c: /* pci0_cs32 */
422     if (op_type == MTS_READ)
423     *data = swap32(0xFFF);
424     break;
425    
426     case 0xc00: /* pci_cmd */
427     if (op_type == MTS_READ)
428     *data = swap32(0x00008001);
429     break;
430    
431     /* ===== Interrupt Cause Register ===== */
432     case 0xc18:
433     if (op_type == MTS_READ)
434     *data = swap32(gt_data->int_cause_reg);
435     else {
436     gt_data->int_cause_reg &= swap32(*data);
437     gt64k_update_irq_status(gt_data);
438     }
439     break;
440    
441     /* ===== Interrupt Mask Register ===== */
442     case 0xc1c:
443     if (op_type == MTS_READ) {
444     *data = swap32(gt_data->int_mask_reg);
445     } else {
446     gt_data->int_mask_reg = swap32(*data);
447     gt64k_update_irq_status(gt_data);
448     }
449     break;
450    
451     /* ===== PCI Bus 1 ===== */
452     case 0xcf0:
453     pci_dev_addr_handler(cpu,gt_data->bus[1],op_type,TRUE,data);
454     break;
455    
456     case 0xcf4:
457     pci_dev_data_handler(cpu,gt_data->bus[1],op_type,TRUE,data);
458     break;
459    
460     /* ===== PCI Bus 0 ===== */
461     case PCI_BUS_ADDR: /* pci configuration address (0xcf8) */
462     pci_dev_addr_handler(cpu,gt_data->bus[0],op_type,TRUE,data);
463     break;
464    
465     case PCI_BUS_DATA: /* pci data address (0xcfc) */
466     pci_dev_data_handler(cpu,gt_data->bus[0],op_type,TRUE,data);
467     break;
468    
469     #if DEBUG_UNKNOWN
470     default:
471     if (op_type == MTS_READ) {
472     cpu_log(cpu,"GT64120","read from addr 0x%x, pc=0x%llx\n",
473     offset,cpu->pc);
474     } else {
475     cpu_log(cpu,"GT64120","write to addr 0x%x, value=0x%llx, "
476     "pc=0x%llx\n",offset,*data,cpu->pc);
477     }
478     #endif
479     }
480    
481     return NULL;
482     }
483    
484     /* Shutdown a GT64k system controller */
485     void dev_gt64k_shutdown(vm_instance_t *vm,struct gt64k_data *d)
486     {
487     if (d != NULL) {
488     /* Remove the device */
489     dev_remove(vm,&d->dev);
490    
491     /* Remove the PCI device */
492     pci_dev_remove(d->pci_dev);
493    
494     /* Free the structure itself */
495     free(d);
496     }
497     }
498    
499     /* Create a new GT64010 controller */
500     int dev_gt64010_init(vm_instance_t *vm,char *name,
501     m_uint64_t paddr,m_uint32_t len,u_int irq)
502     {
503     struct gt64k_data *d;
504    
505     if (!(d = malloc(sizeof(*d)))) {
506     fprintf(stderr,"gt64010: unable to create device data.\n");
507     return(-1);
508     }
509    
510     memset(d,0,sizeof(*d));
511     d->vm = vm;
512     d->bus[0] = vm->pci_bus[0];
513    
514     vm_object_init(&d->vm_obj);
515     d->vm_obj.name = name;
516     d->vm_obj.data = d;
517     d->vm_obj.shutdown = (vm_shutdown_t)dev_gt64k_shutdown;
518    
519     dev_init(&d->dev);
520     d->dev.name = name;
521     d->dev.priv_data = d;
522     d->dev.phys_addr = paddr;
523     d->dev.phys_len = len;
524     d->dev.handler = dev_gt64010_access;
525    
526     /* Add the controller as a PCI device */
527     if (!pci_dev_lookup(d->bus[0],0,0,0)) {
528     d->pci_dev = pci_dev_add(d->bus[0],name,
529     PCI_VENDOR_GALILEO,PCI_PRODUCT_GALILEO_GT64010,
530     0,0,irq,d,NULL,NULL,NULL);
531    
532     if (!d->pci_dev) {
533     fprintf(stderr,"gt64010: unable to create PCI device.\n");
534     return(-1);
535     }
536     }
537    
538     /* Map this device to the VM */
539     vm_bind_device(vm,&d->dev);
540     vm_object_add(vm,&d->vm_obj);
541     return(0);
542     }
543    
544     /*
545     * pci_gt64120_read()
546     *
547     * Read a PCI register.
548     */
549     static m_uint32_t pci_gt64120_read(cpu_mips_t *cpu,struct pci_device *dev,
550     int reg)
551     {
552     switch (reg) {
553     case 0x08:
554     return(0x03008005);
555     default:
556     return(0);
557     }
558     }
559    
560     /* Create a new GT64120 controller */
561     int dev_gt64120_init(vm_instance_t *vm,char *name,
562     m_uint64_t paddr,m_uint32_t len,u_int irq)
563     {
564     struct gt64k_data *d;
565    
566     if (!(d = malloc(sizeof(*d)))) {
567     fprintf(stderr,"gt64120: unable to create device data.\n");
568     return(-1);
569     }
570    
571     memset(d,0,sizeof(*d));
572     d->vm = vm;
573     d->bus[0] = vm->pci_bus[0];
574     d->bus[1] = vm->pci_bus[1];
575    
576     vm_object_init(&d->vm_obj);
577     d->vm_obj.name = name;
578     d->vm_obj.data = d;
579     d->vm_obj.shutdown = (vm_shutdown_t)dev_gt64k_shutdown;
580    
581     dev_init(&d->dev);
582     d->dev.name = name;
583     d->dev.priv_data = d;
584     d->dev.phys_addr = paddr;
585     d->dev.phys_len = len;
586     d->dev.handler = dev_gt64120_access;
587    
588     /* Add the controller as a PCI device */
589     if (!pci_dev_lookup(d->bus[0],0,0,0)) {
590     d->pci_dev = pci_dev_add(d->bus[0],name,
591     PCI_VENDOR_GALILEO,PCI_PRODUCT_GALILEO_GT64120,
592     0,0,irq,d,NULL,pci_gt64120_read,NULL);
593     if (!d->pci_dev) {
594     fprintf(stderr,"gt64120: unable to create PCI device.\n");
595     return(-1);
596     }
597     }
598    
599     /* Map this device to the VM */
600     vm_bind_device(vm,&d->dev);
601     vm_object_add(vm,&d->vm_obj);
602     return(0);
603     }
604    

  ViewVC Help
Powered by ViewVC 1.1.26