/[dynamips]/trunk/dev_clpd6729.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_clpd6729.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Sat Oct 6 16:06:49 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC3/dev_clpd6729.c
File MIME type: text/plain
File size: 6138 byte(s)
dynamips-0.2.6-RC3

1 dpavlin 1 /*
2     * Cisco C7200 (Predator) simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot. All rights reserved.
4     *
5     * Cirrus Logic PD6729 PCI-to-PCMCIA host adapter.
6     *
7     * TODO: finish the code! (especially extended registers)
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13     #include <time.h>
14     #include <errno.h>
15    
16     #include "mips64.h"
17     #include "dynamips.h"
18     #include "memory.h"
19     #include "device.h"
20     #include "pci_dev.h"
21     #include "pci_io.h"
22    
23     #define DEBUG_ACCESS 0
24    
25     /* Cirrus Logic PD6729 PCI vendor/product codes */
26     #define CLPD6729_PCI_VENDOR_ID 0x1013
27     #define CLPD6729_PCI_PRODUCT_ID 0x1100
28    
29     #define CLPD6729_REG_CHIP_REV 0x00 /* Chip Revision */
30     #define CLPD6729_REG_INT_STATUS 0x01 /* Interface Status */
31     #define CLPD6729_REG_POWER_CTRL 0x02 /* Power Control */
32     #define CLPD6729_REG_INTGEN_CTRL 0x03 /* Interrupt & General Control */
33     #define CLPD6729_REG_CARD_STATUS 0x04 /* Card Status Change */
34     #define CLPD6729_REG_FIFO_CTRL 0x17 /* FIFO Control */
35     #define CLPD6729_REG_EXT_INDEX 0x2E /* Extended Index */
36    
37     /* CLPD6729 private data */
38     struct clpd6729_data {
39     vm_obj_t vm_obj;
40     struct vdevice dev;
41     struct pci_device *pci_dev;
42     struct pci_io_device *pci_io_dev;
43    
44     /* VM objects present in slots (typically, PCMCIA disks...) */
45     vm_obj_t *slot_obj[2];
46    
47     /* Base registers */
48     m_uint8_t base_index;
49     m_uint8_t base_regs[256];
50     };
51    
52     /* Handle access to a base register */
53     static void clpd6729_base_reg_access(cpu_mips_t *cpu,struct clpd6729_data *d,
54     u_int op_type,m_uint64_t *data)
55     {
56     u_int slot_id,reg;
57    
58     #if DEBUG_ACCESS
59     if (op_type == MTS_READ) {
60     cpu_log(cpu,"CLPD6729","reading reg 0x%2.2x at pc=0x%llx\n",
61     d->base_index,cpu->pc);
62     } else {
63     cpu_log(cpu,"CLPD6729","writing reg 0x%2.2x, data=0x%llx at pc=0x%llx\n",
64     d->base_index,*data,cpu->pc);
65     }
66     #endif
67    
68     if (op_type == MTS_READ)
69     *data = 0;
70    
71     /* Reserved registers */
72     if (d->base_index >= 0x80)
73     return;
74    
75     /*
76     * Socket A regs: 0x00 to 0x3f
77     * Socket B regs: 0x40 to 0x7f
78     */
79     if (d->base_index >= 0x40) {
80     slot_id = 1;
81     reg = d->base_index - 0x40;
82     } else {
83     slot_id = 0;
84     reg = d->base_index;
85     }
86    
87     switch(reg) {
88     case CLPD6729_REG_CHIP_REV:
89     if (op_type == MTS_READ)
90     *data = 0x48;
91     break;
92    
93     case CLPD6729_REG_INT_STATUS:
94     if (op_type == MTS_READ) {
95     if (d->slot_obj[slot_id])
96     *data = 0xEF;
97     else
98     *data = 0x80;
99     }
100     break;
101    
102     case CLPD6729_REG_INTGEN_CTRL:
103     if (op_type == MTS_READ)
104     *data = 0x40;
105     break;
106    
107     case CLPD6729_REG_EXT_INDEX:
108     if (op_type == MTS_WRITE) {
109     cpu_log(cpu,"CLPD6729","ext reg index 0x%2.2llx at pc=0x%llx\n",
110     *data,cpu->pc);
111     }
112     break;
113    
114     case CLPD6729_REG_FIFO_CTRL:
115     if (op_type == MTS_READ)
116     *data = 0x80; /* FIFO is empty */
117     break;
118    
119     default:
120     if (op_type == MTS_READ)
121     *data = d->base_regs[d->base_index];
122     else
123     d->base_regs[d->base_index] = (m_uint8_t)(*data);
124     }
125     }
126    
127     /*
128     * dev_clpd6729_io_access()
129     */
130     static void *dev_clpd6729_io_access(cpu_mips_t *cpu,struct vdevice *dev,
131     m_uint32_t offset,u_int op_size,
132     u_int op_type,m_uint64_t *data)
133     {
134     struct clpd6729_data *d = dev->priv_data;
135    
136     #if DEBUG_ACCESS
137     if (op_type == MTS_READ) {
138     cpu_log(cpu,dev->name,"reading at offset 0x%x, pc=0x%llx\n",
139     offset,cpu->pc);
140     } else {
141     cpu_log(cpu,dev->name,"writing at offset 0x%x, pc=0x%llx, data=0x%llx\n",
142     offset,cpu->pc,*data);
143     }
144     #endif
145    
146     switch(offset) {
147     case 0:
148     /* Data register */
149     clpd6729_base_reg_access(cpu,d,op_type,data);
150     break;
151    
152     case 1:
153     /* Index register */
154     if (op_type == MTS_READ)
155     *data = d->base_index;
156     else
157     d->base_index = *data;
158     break;
159     }
160    
161     return NULL;
162     }
163    
164     /* Shutdown a CLPD6729 device */
165     void dev_clpd6729_shutdown(vm_instance_t *vm,struct clpd6729_data *d)
166     {
167     if (d != NULL) {
168     /* Remove the PCI device */
169     pci_dev_remove(d->pci_dev);
170    
171     /* Remove the PCI I/O device */
172     pci_io_remove(d->pci_io_dev);
173    
174     /* Free the structure itself */
175     free(d);
176     }
177     }
178    
179     /*
180     * dev_clpd6729_init()
181     */
182     int dev_clpd6729_init(vm_instance_t *vm,
183     struct pci_bus *pci_bus,int pci_device,
184     struct pci_io_data *pci_io_data,
185     m_uint32_t io_start,m_uint32_t io_end)
186     {
187     struct clpd6729_data *d;
188    
189     /* Allocate the private data structure */
190     if (!(d = malloc(sizeof(*d)))) {
191     fprintf(stderr,"CLPD6729: unable to create device.\n");
192     return(-1);
193     }
194    
195     memset(d,0,sizeof(*d));
196     vm_object_init(&d->vm_obj);
197     d->vm_obj.name = "clpd6729";
198     d->vm_obj.data = d;
199     d->vm_obj.shutdown = (vm_shutdown_t)dev_clpd6729_shutdown;
200    
201     dev_init(&d->dev);
202     d->dev.name = "clpd6729";
203     d->dev.priv_data = d;
204    
205     d->pci_io_dev = pci_io_add(pci_io_data,io_start,io_end,&d->dev,
206     dev_clpd6729_io_access);
207    
208     d->pci_dev = pci_dev_add(pci_bus,"clpd6729",
209     CLPD6729_PCI_VENDOR_ID,CLPD6729_PCI_PRODUCT_ID,
210     pci_device,0,-1,&d->dev,NULL,NULL,NULL);
211    
212     if (!d->pci_io_dev || !d->pci_dev) {
213     fprintf(stderr,"CLPD6729: unable to create PCI devices.\n");
214     dev_clpd6729_shutdown(vm,d);
215     return(-1);
216     }
217    
218     vm_object_add(vm,&d->vm_obj);
219    
220     /* PCMCIA disk test */
221     if (vm->pcmcia_disk_size[0])
222     d->slot_obj[0] = dev_pcmcia_disk_init(vm,"disk0",0x40000000ULL,0x4000000,
223 dpavlin 4 vm->pcmcia_disk_size[0],0);
224 dpavlin 1
225     if (vm->pcmcia_disk_size[1])
226     d->slot_obj[1] = dev_pcmcia_disk_init(vm,"disk1",0x44000000ULL,0x4000000,
227 dpavlin 4 vm->pcmcia_disk_size[1],0);
228 dpavlin 1 return(0);
229     }

  ViewVC Help
Powered by ViewVC 1.1.26