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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (12 years ago) by dpavlin
File MIME type: text/plain
File size: 2965 byte(s)
make working copy

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4 *
5 * PCI I/O space.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <sys/types.h>
13
14 #include "cpu.h"
15 #include "vm.h"
16 #include "dynamips.h"
17 #include "memory.h"
18 #include "device.h"
19 #include "pci_io.h"
20
21 /* Debugging flags */
22 #define DEBUG_ACCESS 0
23
24 /* Add a new PCI I/O device */
25 struct pci_io_device *pci_io_add(struct pci_io_data *d,
26 m_uint32_t start,m_uint32_t end,
27 struct vdevice *dev,dev_handler_t handler)
28 {
29 struct pci_io_device *p;
30
31 if (!(p = malloc(sizeof(*p)))) {
32 fprintf(stderr,"pci_io_add: unable to create a new device.\n");
33 return NULL;
34 }
35
36 p->start = start;
37 p->end = end;
38 p->real_dev = dev;
39 p->handler = handler;
40
41 p->next = d->dev_list;
42 p->pprev = &d->dev_list;
43
44 if (d->dev_list != NULL)
45 d->dev_list->pprev = &p->next;
46
47 d->dev_list = p;
48 return p;
49 }
50
51 /* Remove a PCI I/O device */
52 void pci_io_remove(struct pci_io_device *dev)
53 {
54 if (dev != NULL) {
55 if (dev->next)
56 dev->next->pprev = dev->pprev;
57
58 *(dev->pprev) = dev->next;
59 free(dev);
60 }
61 }
62
63 /*
64 * pci_io_access()
65 */
66 static void *pci_io_access(cpu_gen_t *cpu,struct vdevice *dev,
67 m_uint32_t offset,u_int op_size,u_int op_type,
68 m_uint64_t *data)
69 {
70 struct pci_io_data *d = dev->priv_data;
71 struct pci_io_device *p;
72
73 #if DEBUG_ACCESS
74 if (op_type == MTS_READ) {
75 cpu_log(cpu,"PCI_IO","read request at pc=0x%llx, offset=0x%x\n",
76 cpu_get_pc(cpu),offset);
77 } else {
78 cpu_log(cpu,"PCI_IO",
79 "write request (data=0x%llx) at pc=0x%llx, offset=0x%x\n",
80 *data,cpu_get_pc(cpu),offset);
81 }
82 #endif
83
84 if (op_type == MTS_READ)
85 *data = 0;
86
87 for(p=d->dev_list;p;p=p->next)
88 if ((offset >= p->start) && (offset <= p->end)) {
89 return(p->handler(cpu,p->real_dev,(offset - p->start),
90 op_size,op_type,data));
91 }
92
93 return NULL;
94 }
95
96 /* Remove PCI I/O space */
97 void pci_io_data_remove(vm_instance_t *vm,struct pci_io_data *d)
98 {
99 if (d != NULL) {
100 /* Remove the device */
101 dev_remove(vm,&d->dev);
102
103 /* Free the structure itself */
104 free(d);
105 }
106 }
107
108 /* Initialize PCI I/O space */
109 struct pci_io_data *pci_io_data_init(vm_instance_t *vm,m_uint64_t paddr)
110 {
111 struct pci_io_data *d;
112
113 /* Allocate the PCI I/O data structure */
114 if (!(d = malloc(sizeof(*d)))) {
115 fprintf(stderr,"PCI_IO: out of memory\n");
116 return NULL;
117 }
118
119 memset(d,0,sizeof(*d));
120 dev_init(&d->dev);
121 d->dev.name = "pci_io";
122 d->dev.priv_data = d;
123 d->dev.phys_addr = paddr;
124 d->dev.phys_len = 2 * 1048576;
125 d->dev.handler = pci_io_access;
126
127 /* Map this device to the VM */
128 vm_bind_device(vm,&d->dev);
129 return(d);
130 }

  ViewVC Help
Powered by ViewVC 1.1.26