/[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 9 - (hide annotations)
Sat Oct 6 16:26:06 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC3/dev_clpd6729.c
File MIME type: text/plain
File size: 6598 byte(s)
dynamips-0.2.7-RC3

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

  ViewVC Help
Powered by ViewVC 1.1.26