/[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

Contents of /trunk/dev_gt64k.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (11 years, 10 months ago) by dpavlin
File MIME type: text/plain
File size: 17635 byte(s)
make working copy

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