/[dynamips]/trunk/dev_c2600_pci.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_c2600_pci.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide annotations)
Sat Oct 6 16:33:40 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.8-RC1/dev_c2600_pci.c
File MIME type: text/plain
File size: 5560 byte(s)
dynamips-0.2.8-RC1

1 dpavlin 7 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * Cisco 2600 PCI controller.
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11    
12     #include "utils.h"
13     #include "net.h"
14     #include "cpu.h"
15     #include "vm.h"
16     #include "dynamips.h"
17     #include "memory.h"
18     #include "device.h"
19     #include "net_io.h"
20    
21     /* Debugging flags */
22     #define DEBUG_ACCESS 0
23     #define DEBUG_UNKNOWN 1
24 dpavlin 11 #define DEBUG_PCI 1
25 dpavlin 7
26 dpavlin 11 #define C2600_PCI_BRIDGE_VENDOR_ID 0x10ee
27     #define C2600_PCI_BRIDGE_PRODUCT_ID 0x4013
28    
29     /* C2600 PCI controller */
30 dpavlin 7 struct c2600_pci_data {
31     char *name;
32     vm_obj_t vm_obj;
33     struct vdevice dev;
34     struct pci_device *pci_dev;
35     vm_instance_t *vm;
36    
37     struct pci_bus *bus;
38 dpavlin 11 m_uint32_t bridge_bar0,bridge_bar1;
39 dpavlin 7 };
40    
41     /*
42     * dev_c2600_pci_access()
43     */
44     void *dev_c2600_pci_access(cpu_gen_t *cpu,struct vdevice *dev,
45     m_uint32_t offset,u_int op_size,u_int op_type,
46     m_uint64_t *data)
47     {
48     struct c2600_pci_data *d = dev->priv_data;
49 dpavlin 11 struct pci_device *pci_dev;
50     u_int bus,device,function,reg;
51 dpavlin 7
52     if (op_type == MTS_READ)
53     *data = 0x0;
54    
55 dpavlin 11 bus = 0;
56     device = (offset >> 12) & 0x0F;
57     function = (offset >> 8) & 0x07;
58     reg = offset & 0xFF;
59 dpavlin 7
60 dpavlin 11 /* Find the corresponding PCI device */
61     pci_dev = pci_dev_lookup(d->bus,bus,device,function);
62 dpavlin 7
63 dpavlin 11 #if DEBUG_PCI
64     if (op_type == MTS_READ) {
65     cpu_log(cpu,"PCI","read request at pc=0x%llx: "
66     "bus=%d,device=%d,function=%d,reg=0x%2.2x\n",
67     cpu_get_pc(cpu), bus, device, function, reg);
68     } else {
69     cpu_log(cpu,"PCI","write request (data=0x%8.8llx) at pc=0x%llx: "
70     "bus=%d,device=%d,function=%d,reg=0x%2.2x\n",
71     *data, cpu_get_pc(cpu), bus, device, function, reg);
72     }
73     #endif
74    
75     if (!pci_dev) {
76     if (op_type == MTS_READ) {
77     cpu_log(cpu,"PCI","read request for unknown device at pc=0x%llx "
78     "(bus=%d,device=%d,function=%d,reg=0x%2.2x).\n",
79     cpu_get_pc(cpu), bus, device, function, reg);
80     } else {
81     cpu_log(cpu,"PCI","write request (data=0x%8.8llx) for unknown device "
82     "at pc=0x%llx (bus=%d,device=%d,function=%d,reg=0x%2.2x).\n",
83     *data, cpu_get_pc(cpu), bus, device, function, reg);
84     }
85    
86     /* Returns an invalid device ID */
87     if ((op_type == MTS_READ) && (reg == PCI_REG_ID))
88     *data = 0xffffffff;
89     } else {
90     if (op_type == MTS_WRITE) {
91     if (pci_dev->write_register != NULL)
92     pci_dev->write_register(cpu,pci_dev,reg,*data);
93     } else {
94     if (reg == PCI_REG_ID)
95     *data = (pci_dev->product_id << 16) | pci_dev->vendor_id;
96     else {
97     if (pci_dev->read_register != NULL)
98     *data = pci_dev->read_register(cpu,pci_dev,reg);
99 dpavlin 7 }
100 dpavlin 11 }
101 dpavlin 7 }
102    
103     return NULL;
104     }
105    
106     /* Shutdown the c2600 PCI controller device */
107     void dev_c2600_pci_shutdown(vm_instance_t *vm,struct c2600_pci_data *d)
108     {
109     if (d != NULL) {
110     /* Remove the device */
111     dev_remove(vm,&d->dev);
112    
113     /* Free the structure itself */
114     free(d);
115     }
116     }
117    
118 dpavlin 11 /* PCI bridge read access */
119     static m_uint32_t dev_c2600_pci_bridge_read(cpu_gen_t *cpu,
120     struct pci_device *dev,
121     int reg)
122     {
123     struct c2600_pci_data *d = dev->priv_data;
124    
125     switch(reg) {
126     case 0x10:
127     return(d->bridge_bar0);
128     case 0x14:
129     return(d->bridge_bar1);
130     default:
131     return(0);
132     }
133     }
134    
135     /* PCI bridge read access */
136     static void dev_c2600_pci_bridge_write(cpu_gen_t *cpu,struct pci_device *dev,
137     int reg,m_uint32_t value)
138     {
139     struct c2600_pci_data *d = dev->priv_data;
140    
141     switch(reg) {
142     case 0x10:
143     /* BAR0 must be at 0x00000000 for correct RAM access */
144     if (value != 0x00000000) {
145     vm_error(d->vm,"C2600_PCI",
146     "Trying to set bridge BAR0 at 0x%8.8x!\n",
147     value);
148     }
149     d->bridge_bar0 = value;
150     break;
151     case 0x14:
152     /* BAR1 = byte swapped zone */
153     if (!d->bridge_bar1) {
154     d->bridge_bar1 = value;
155    
156     /* XXX */
157     dev_bswap_init(d->vm,"pci_bswap",d->bridge_bar1,0x10000000,
158     0x00000000);
159     }
160     break;
161     }
162     }
163    
164 dpavlin 7 /* Create the c2600 PCI controller device */
165     int dev_c2600_pci_init(vm_instance_t *vm,char *name,
166     m_uint64_t paddr,m_uint32_t len,
167     struct pci_bus *bus)
168     {
169     struct c2600_pci_data *d;
170    
171     if (!(d = malloc(sizeof(*d)))) {
172     fprintf(stderr,"c2600_pci: unable to create device data.\n");
173     return(-1);
174     }
175    
176     memset(d,0,sizeof(*d));
177     d->name = name;
178     d->vm = vm;
179     d->bus = bus;
180    
181     vm_object_init(&d->vm_obj);
182     d->vm_obj.name = name;
183     d->vm_obj.data = d;
184     d->vm_obj.shutdown = (vm_shutdown_t)dev_c2600_pci_shutdown;
185    
186     dev_init(&d->dev);
187     d->dev.name = name;
188     d->dev.priv_data = d;
189     d->dev.phys_addr = paddr;
190     d->dev.phys_len = len;
191     d->dev.handler = dev_c2600_pci_access;
192    
193 dpavlin 11 pci_dev_add(d->bus,"pci_bridge",
194     C2600_PCI_BRIDGE_VENDOR_ID,C2600_PCI_BRIDGE_PRODUCT_ID,
195     15,0,-1,d,
196     NULL,
197     dev_c2600_pci_bridge_read,
198     dev_c2600_pci_bridge_write);
199    
200 dpavlin 7 /* Map this device to the VM */
201     vm_bind_device(vm,&d->dev);
202     vm_object_add(vm,&d->vm_obj);
203     return(0);
204     }
205    

  ViewVC Help
Powered by ViewVC 1.1.26