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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Sat Oct 6 16:01:44 2007 UTC (13 years ago) by dpavlin
File MIME type: text/plain
File size: 5267 byte(s)
import 0.2.5 from upstream

1 dpavlin 1 /*
2     * Cisco C7200 (Predator) Simulation Platform.
3     * Copyright (C) 2005,2006 Christophe Fillot. All rights reserved.
4     *
5     * PLX PCI9060 - PCI bus master interface chip.
6     *
7     * This is very basic, it has been designed to allow the C7200 PA-POS-OC3
8     * to work.
9     */
10    
11     #include <stdio.h>
12     #include <stdlib.h>
13     #include <string.h>
14    
15     #include "mips64.h"
16     #include "dynamips.h"
17     #include "memory.h"
18     #include "device.h"
19     #include "pci_dev.h"
20    
21     #define DEBUG_ACCESS 1
22    
23     /* PLX9060 vendor/product codes */
24     #define PLX9060_PCI_VENDOR_ID 0x10b5
25     #define PLX9060_PCI_PRODUCT_ID 0x9060
26    
27     #define PLX9060_S0_RANGE_DEFAULT 0xFFF00000
28     #define PLX9060_S0_RANGE_DECODE_MASK 0xFFFFFFF0
29    
30     /* PLX9060 data */
31     struct plx9060_data {
32     /* Device name */
33     char *name;
34    
35     /* Virtual machine and object info */
36     vm_instance_t *vm;
37     vm_obj_t vm_obj;
38    
39     /* Virtual PLX device */
40     struct vdevice plx_dev;
41     struct pci_device *pci_plx_dev;
42    
43     /* Managed device */
44     struct vdevice *dev;
45    
46     /* Space 0 properties */
47     m_uint32_t space0_lbaddr;
48     m_uint32_t space0_range;
49     };
50    
51     /* Log a PLX message */
52     #define PLX_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
53    
54     /* Map space 0 */
55     static void plx9060_map_space0(struct plx9060_data *d)
56     {
57     d->dev->phys_len = 1+(~(d->space0_range & PLX9060_S0_RANGE_DECODE_MASK));
58     vm_map_device(d->vm,d->dev,d->space0_lbaddr);
59    
60     PLX_LOG(d,"device mapped at 0x%llx, size=0x%x\n",
61     d->dev->phys_addr,d->dev->phys_len);
62     }
63    
64     /* PLX9060 access */
65     void *dev_plx9060_access(cpu_mips_t *cpu,struct vdevice *dev,
66     m_uint32_t offset,u_int op_size,u_int op_type,
67     m_uint64_t *data)
68     {
69     struct plx9060_data *d = dev->priv_data;
70    
71     if (op_type == MTS_READ)
72     *data = 0;
73    
74     switch(offset) {
75     case 0x00:
76     if (op_type == MTS_WRITE) {
77     d->space0_range = *data;
78     plx9060_map_space0(d);
79     } else {
80     *data = d->space0_range;
81     }
82     break;
83    
84     default:
85     if (op_type == MTS_READ) {
86     cpu_log(cpu,d->name,
87     "read from unhandled addr 0x%x, pc=0x%llx (size=%u)\n",
88     offset,cpu->pc,op_size);
89     } else {
90     cpu_log(cpu,d->name,
91     "write to handled addr 0x%x, value=0x%llx, "
92     "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);
93     }
94     }
95    
96     return NULL;
97     }
98    
99     /*
100     * pci_plx9060_read()
101     */
102     static m_uint32_t pci_plx9060_read(cpu_mips_t *cpu,struct pci_device *dev,
103     int reg)
104     {
105     struct plx9060_data *d = dev->priv_data;
106    
107     #if DEBUG_ACCESS
108     PLX_LOG(d,"read PLX PCI register 0x%x\n",reg);
109     #endif
110     switch(reg) {
111     case PCI_REG_BAR0:
112     return(d->plx_dev.phys_addr);
113     case PCI_REG_BAR2:
114     return(d->space0_lbaddr);
115     default:
116     return(0);
117     }
118     }
119    
120     /*
121     * pci_plx9060_cs_write()
122     */
123     static void pci_plx9060_write(cpu_mips_t *cpu,struct pci_device *dev,
124     int reg,m_uint32_t value)
125     {
126     struct plx9060_data *d = dev->priv_data;
127    
128     #if DEBUG_ACCESS
129     PLX_LOG(d,"write 0x%x to PLX PCI register 0x%x\n",value,reg);
130     #endif
131    
132     switch(reg) {
133     case PCI_REG_BAR0:
134     vm_map_device(cpu->vm,&d->plx_dev,(m_uint64_t)value);
135     PLX_LOG(d,"PLX registers are mapped at 0x%x\n",value);
136     break;
137     case PCI_REG_BAR2:
138     d->space0_lbaddr = value;
139     plx9060_map_space0(d);
140     break;
141     }
142     }
143    
144     /* Shutdown a PLX9060 device */
145     void dev_plx9060_shutdown(vm_instance_t *vm,struct plx9060_data *d)
146     {
147     if (d != NULL) {
148     /* Unbind the managed device */
149     vm_unbind_device(vm,d->dev);
150    
151     /* Remove the PLX device */
152     dev_remove(vm,&d->plx_dev);
153    
154     /* Remove the PCI PLX device */
155     pci_dev_remove(d->pci_plx_dev);
156    
157     /* Free the structure itself */
158     free(d);
159     }
160     }
161    
162     /* Create a PLX9060 device */
163     vm_obj_t *dev_plx9060_init(vm_instance_t *vm,char *name,
164     struct pci_bus *pci_bus,int pci_device,
165     struct vdevice *dev)
166     {
167     struct plx9060_data *d;
168    
169     if (!dev)
170     return NULL;
171    
172     /* Allocate the private data structure */
173     if (!(d = malloc(sizeof(*d)))) {
174     fprintf(stderr,"PLX9060: unable to create device.\n");
175     return NULL;
176     }
177    
178     memset(d,0,sizeof(*d));
179     vm_object_init(&d->vm_obj);
180     d->vm_obj.name = name;
181     d->vm_obj.data = d;
182     d->vm_obj.shutdown = (vm_shutdown_t)dev_plx9060_shutdown;
183    
184     d->vm = vm;
185     d->dev = dev;
186     d->name = name;
187     d->space0_range = PLX9060_S0_RANGE_DEFAULT;
188    
189     dev_init(&d->plx_dev);
190     d->plx_dev.name = name;
191     d->plx_dev.priv_data = d;
192     d->plx_dev.phys_addr = 0;
193     d->plx_dev.phys_len = 0x1000;
194     d->plx_dev.handler = dev_plx9060_access;
195    
196     /* Add PLX as a PCI device */
197     d->pci_plx_dev = pci_dev_add(pci_bus,name,
198     PLX9060_PCI_VENDOR_ID,PLX9060_PCI_PRODUCT_ID,
199     pci_device,0,-1,d,
200     NULL,pci_plx9060_read,pci_plx9060_write);
201    
202     if (!d->pci_plx_dev) {
203     fprintf(stderr,"%s (PLX9060): unable to create PCI device.\n",name);
204     goto err_pci_dev;
205     }
206    
207     vm_object_add(vm,&d->vm_obj);
208     return(&d->vm_obj);
209    
210     err_pci_dev:
211     free(d);
212     return NULL;
213     }

  ViewVC Help
Powered by ViewVC 1.1.26