/[dynamips]/upstream/dynamips-0.2.5/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

Contents of /upstream/dynamips-0.2.5/dev_clpd6729.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Sat Oct 6 16:01:44 2007 UTC (12 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 6134 byte(s)
import 0.2.5 from upstream

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 vm->pcmcia_disk_size[0]);
224
225 if (vm->pcmcia_disk_size[1])
226 d->slot_obj[1] = dev_pcmcia_disk_init(vm,"disk1",0x44000000ULL,0x4000000,
227 vm->pcmcia_disk_size[1]);
228 return(0);
229 }

  ViewVC Help
Powered by ViewVC 1.1.26