1 |
dpavlin |
1 |
/* |
2 |
dpavlin |
7 |
* Cisco router simulation platform. |
3 |
dpavlin |
1 |
* Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) |
4 |
|
|
*/ |
5 |
|
|
|
6 |
|
|
#ifndef __DEVICE_H__ |
7 |
|
|
#define __DEVICE_H__ |
8 |
|
|
|
9 |
|
|
#include <sys/types.h> |
10 |
|
|
#include "utils.h" |
11 |
|
|
#include "cpu.h" |
12 |
|
|
#include "net_io.h" |
13 |
|
|
#include "vm.h" |
14 |
|
|
|
15 |
|
|
/* Device Flags */ |
16 |
dpavlin |
7 |
#define VDEVICE_FLAG_NO_MTS_MMAP 0x01 /* Prevent MMAPed access by MTS */ |
17 |
|
|
#define VDEVICE_FLAG_CACHING 0x02 /* Device does support caching */ |
18 |
|
|
#define VDEVICE_FLAG_REMAP 0x04 /* Physical address remapping */ |
19 |
|
|
#define VDEVICE_FLAG_SYNC 0x08 /* Forced sync */ |
20 |
|
|
#define VDEVICE_FLAG_SPARSE 0x10 /* Sparse device */ |
21 |
|
|
#define VDEVICE_FLAG_GHOST 0x20 /* Ghost device */ |
22 |
dpavlin |
1 |
|
23 |
dpavlin |
7 |
#define VDEVICE_PTE_DIRTY 0x01 |
24 |
|
|
|
25 |
|
|
typedef void *(*dev_handler_t)(cpu_gen_t *cpu,struct vdevice *dev, |
26 |
dpavlin |
1 |
m_uint32_t offset,u_int op_size,u_int op_type, |
27 |
|
|
m_uint64_t *data); |
28 |
|
|
|
29 |
|
|
/* Virtual Device */ |
30 |
|
|
struct vdevice { |
31 |
|
|
char *name; |
32 |
|
|
u_int id; |
33 |
|
|
m_uint64_t phys_addr; |
34 |
|
|
m_uint32_t phys_len; |
35 |
|
|
m_iptr_t host_addr; |
36 |
|
|
void *priv_data; |
37 |
|
|
int flags; |
38 |
|
|
int fd; |
39 |
|
|
dev_handler_t handler; |
40 |
dpavlin |
7 |
m_iptr_t *sparse_map; |
41 |
dpavlin |
1 |
struct vdevice *next,**pprev; |
42 |
|
|
}; |
43 |
|
|
|
44 |
|
|
/* PCI part */ |
45 |
|
|
#include "pci_dev.h" |
46 |
|
|
|
47 |
|
|
/* device access function */ |
48 |
|
|
static forced_inline |
49 |
dpavlin |
7 |
void *dev_access_fast(cpu_gen_t *cpu,u_int dev_id,m_uint32_t offset, |
50 |
dpavlin |
1 |
u_int op_size,u_int op_type,m_uint64_t *data) |
51 |
|
|
{ |
52 |
|
|
struct vdevice *dev = cpu->vm->dev_array[dev_id]; |
53 |
|
|
|
54 |
|
|
if (unlikely(!dev)) { |
55 |
|
|
cpu_log(cpu,"dev_access_fast","null handler (dev_id=%u,offset=0x%x)\n", |
56 |
|
|
dev_id,offset); |
57 |
|
|
return NULL; |
58 |
|
|
} |
59 |
|
|
|
60 |
dpavlin |
8 |
#if DEBUG_DEV_PERF_CNT |
61 |
|
|
cpu->dev_access_counter++; |
62 |
|
|
#endif |
63 |
|
|
|
64 |
dpavlin |
1 |
return(dev->handler(cpu,dev,offset,op_size,op_type,data)); |
65 |
|
|
} |
66 |
|
|
|
67 |
|
|
/* Get device by ID */ |
68 |
|
|
struct vdevice *dev_get_by_id(vm_instance_t *vm,u_int dev_id); |
69 |
|
|
|
70 |
|
|
/* Get device by name */ |
71 |
|
|
struct vdevice *dev_get_by_name(vm_instance_t *vm,char *name); |
72 |
|
|
|
73 |
|
|
/* Device lookup by physical address */ |
74 |
|
|
struct vdevice *dev_lookup(vm_instance_t *vm,m_uint64_t phys_addr,int cached); |
75 |
|
|
|
76 |
|
|
/* Find the next device after the specified address */ |
77 |
|
|
struct vdevice *dev_lookup_next(vm_instance_t *vm,m_uint64_t phys_addr, |
78 |
|
|
struct vdevice *dev_start,int cached); |
79 |
|
|
|
80 |
|
|
/* Initialize a device */ |
81 |
|
|
void dev_init(struct vdevice *dev); |
82 |
|
|
|
83 |
|
|
/* Allocate a device */ |
84 |
|
|
struct vdevice *dev_create(char *name); |
85 |
|
|
|
86 |
|
|
/* Remove a device */ |
87 |
|
|
void dev_remove(vm_instance_t *vm,struct vdevice *dev); |
88 |
|
|
|
89 |
|
|
/* Show properties of a device */ |
90 |
|
|
void dev_show(struct vdevice *dev); |
91 |
|
|
|
92 |
|
|
/* Show the device list */ |
93 |
|
|
void dev_show_list(vm_instance_t *vm); |
94 |
|
|
|
95 |
|
|
/* device access function */ |
96 |
dpavlin |
7 |
void *dev_access(cpu_gen_t *cpu,u_int dev_id,m_uint32_t offset, |
97 |
dpavlin |
1 |
u_int op_size,u_int op_type,m_uint64_t *data); |
98 |
|
|
|
99 |
dpavlin |
4 |
/* Synchronize memory for a memory-mapped (mmap) device */ |
100 |
|
|
int dev_sync(struct vdevice *dev); |
101 |
|
|
|
102 |
dpavlin |
1 |
/* Remap a device at specified physical address */ |
103 |
|
|
struct vdevice *dev_remap(char *name,struct vdevice *orig, |
104 |
|
|
m_uint64_t paddr,m_uint32_t len); |
105 |
|
|
|
106 |
|
|
/* Create a RAM device */ |
107 |
dpavlin |
7 |
struct vdevice *dev_create_ram(vm_instance_t *vm,char *name, |
108 |
|
|
int sparse,char *filename, |
109 |
dpavlin |
1 |
m_uint64_t paddr,m_uint32_t len); |
110 |
|
|
|
111 |
dpavlin |
4 |
/* Create a ghosted RAM device */ |
112 |
|
|
struct vdevice * |
113 |
dpavlin |
7 |
dev_create_ghost_ram(vm_instance_t *vm,char *name,int sparse,char *filename, |
114 |
dpavlin |
4 |
m_uint64_t paddr,m_uint32_t len); |
115 |
|
|
|
116 |
dpavlin |
1 |
/* Create a memory alias */ |
117 |
|
|
struct vdevice *dev_create_ram_alias(vm_instance_t *vm,char *name,char *orig, |
118 |
|
|
m_uint64_t paddr,m_uint32_t len); |
119 |
|
|
|
120 |
dpavlin |
7 |
/* Initialize a sparse device */ |
121 |
|
|
int dev_sparse_init(struct vdevice *dev); |
122 |
|
|
|
123 |
|
|
/* Shutdown sparse device structures */ |
124 |
|
|
int dev_sparse_shutdown(struct vdevice *dev); |
125 |
|
|
|
126 |
|
|
/* Get an host address for a sparse device */ |
127 |
|
|
m_iptr_t dev_sparse_get_host_addr(vm_instance_t *vm,struct vdevice *dev, |
128 |
|
|
m_uint64_t paddr,u_int op_type,int *cow); |
129 |
|
|
|
130 |
dpavlin |
1 |
/* Create a dummy console */ |
131 |
|
|
int dev_create_dummy_console(vm_instance_t *vm); |
132 |
|
|
|
133 |
|
|
/* Initialized a zeroed memory zone */ |
134 |
|
|
int dev_zero_init(vm_instance_t *vm,char *name, |
135 |
|
|
m_uint64_t paddr,m_uint32_t len); |
136 |
|
|
|
137 |
dpavlin |
7 |
/* Initialized a byte-swap device */ |
138 |
|
|
int dev_bswap_init(vm_instance_t *vm,char *name, |
139 |
|
|
m_uint64_t paddr,m_uint32_t len,m_uint64_t remap_addr); |
140 |
|
|
|
141 |
dpavlin |
1 |
/* Initialize a RAM zone */ |
142 |
dpavlin |
4 |
int dev_ram_init(vm_instance_t *vm,char *name,int use_mmap,int delete_file, |
143 |
dpavlin |
7 |
char *alternate_name,int sparse, |
144 |
|
|
m_uint64_t paddr,m_uint32_t len); |
145 |
dpavlin |
1 |
|
146 |
dpavlin |
4 |
/* Initialize a ghosted RAM zone */ |
147 |
dpavlin |
7 |
int dev_ram_ghost_init(vm_instance_t *vm,char *name,int sparse,char *filename, |
148 |
dpavlin |
4 |
m_uint64_t paddr,m_uint32_t len); |
149 |
|
|
|
150 |
dpavlin |
1 |
/* Create the NVRAM device */ |
151 |
|
|
int dev_nvram_init(vm_instance_t *vm,char *name, |
152 |
|
|
m_uint64_t paddr,m_uint32_t len, |
153 |
|
|
u_int *conf_reg); |
154 |
|
|
|
155 |
|
|
/* Create a 8 Mb bootflash */ |
156 |
|
|
int dev_bootflash_init(vm_instance_t *vm,char *name, |
157 |
|
|
m_uint64_t paddr,m_uint32_t len); |
158 |
|
|
|
159 |
dpavlin |
4 |
/* Create a Flash device */ |
160 |
|
|
vm_obj_t *dev_flash_init(vm_instance_t *vm,char *name, |
161 |
|
|
m_uint64_t paddr,m_uint32_t len); |
162 |
dpavlin |
1 |
|
163 |
dpavlin |
4 |
/* Copy data directly to a flash device */ |
164 |
|
|
int dev_flash_copy_data(vm_obj_t *obj,m_uint32_t offset, |
165 |
|
|
u_char *ptr,ssize_t len); |
166 |
dpavlin |
1 |
|
167 |
|
|
/* dev_dec21050_init() */ |
168 |
|
|
int dev_dec21050_init(struct pci_bus *pci_bus,int pci_device, |
169 |
|
|
struct pci_bus *sec_bus); |
170 |
|
|
|
171 |
|
|
/* dev_dec21052_init() */ |
172 |
|
|
int dev_dec21052_init(struct pci_bus *pci_bus,int pci_device, |
173 |
|
|
struct pci_bus *sec_bus); |
174 |
|
|
|
175 |
|
|
/* dev_dec21150_init() */ |
176 |
|
|
int dev_dec21150_init(struct pci_bus *pci_bus,int pci_device, |
177 |
|
|
struct pci_bus *sec_bus); |
178 |
|
|
|
179 |
|
|
/* dev_dec21152_init() */ |
180 |
|
|
int dev_dec21152_init(struct pci_bus *pci_bus,int pci_device, |
181 |
|
|
struct pci_bus *sec_bus); |
182 |
|
|
|
183 |
dpavlin |
7 |
/* dev_dec21154_init() */ |
184 |
|
|
int dev_dec21154_init(struct pci_bus *pci_bus,int pci_device, |
185 |
|
|
struct pci_bus *sec_bus); |
186 |
|
|
|
187 |
dpavlin |
1 |
/* dev_pericom_init() */ |
188 |
|
|
int dev_pericom_init(struct pci_bus *pci_bus,int pci_device, |
189 |
|
|
struct pci_bus *sec_bus); |
190 |
|
|
|
191 |
dpavlin |
4 |
/* dev_ti2050b_init() */ |
192 |
|
|
int dev_ti2050b_init(struct pci_bus *pci_bus,int pci_device, |
193 |
|
|
struct pci_bus *sec_bus); |
194 |
|
|
|
195 |
dpavlin |
1 |
/* Create an AP1011 Sturgeon HyperTransport-PCI Bridge */ |
196 |
|
|
int dev_ap1011_init(struct pci_bus *pci_bus,int pci_device, |
197 |
|
|
struct pci_bus *sec_bus); |
198 |
|
|
|
199 |
dpavlin |
7 |
/* dev_plx6520cb_init() */ |
200 |
|
|
int dev_plx6520cb_init(struct pci_bus *pci_bus,int pci_device, |
201 |
|
|
struct pci_bus *sec_bus); |
202 |
|
|
|
203 |
dpavlin |
1 |
/* dev_clpd6729_init() */ |
204 |
|
|
int dev_clpd6729_init(vm_instance_t *vm, |
205 |
|
|
struct pci_bus *pci_bus,int pci_device, |
206 |
|
|
struct pci_io_data *pci_io_data, |
207 |
|
|
m_uint32_t io_start,m_uint32_t io_end); |
208 |
|
|
|
209 |
|
|
/* Create a NS16552 device */ |
210 |
|
|
int dev_ns16552_init(vm_instance_t *vm,m_uint64_t paddr,m_uint32_t len, |
211 |
dpavlin |
2 |
u_int reg_div,u_int irq,vtty_t *vtty_A,vtty_t *vtty_B); |
212 |
dpavlin |
1 |
|
213 |
|
|
/* Initialize an SRAM device */ |
214 |
|
|
int dev_c7200_sram_init(vm_instance_t *vm,char *name, |
215 |
|
|
m_uint64_t paddr,m_uint32_t len, |
216 |
|
|
struct pci_bus *pci_bus,int pci_device); |
217 |
|
|
|
218 |
|
|
/* Initialize a PCMCIA disk */ |
219 |
|
|
vm_obj_t *dev_pcmcia_disk_init(vm_instance_t *vm,char *name, |
220 |
|
|
m_uint64_t paddr,m_uint32_t len, |
221 |
dpavlin |
4 |
u_int disk_size,int mode); |
222 |
dpavlin |
1 |
|
223 |
dpavlin |
7 |
/* Get the device associated with a PCMCIA disk object */ |
224 |
|
|
struct vdevice *dev_pcmcia_disk_get_device(vm_obj_t *obj); |
225 |
|
|
|
226 |
dpavlin |
1 |
/* Create SB-1 system control devices */ |
227 |
|
|
int dev_sb1_init(vm_instance_t *vm); |
228 |
|
|
|
229 |
|
|
/* Create SB-1 I/O devices */ |
230 |
|
|
int dev_sb1_io_init(vm_instance_t *vm,u_int duart_irq); |
231 |
|
|
|
232 |
|
|
/* Create the SB-1 PCI bus configuration zone */ |
233 |
|
|
int dev_sb1_pci_init(vm_instance_t *vm,char *name,m_uint64_t paddr); |
234 |
|
|
|
235 |
|
|
/* dev_sb1_duart_init() */ |
236 |
|
|
int dev_sb1_duart_init(vm_instance_t *vm,m_uint64_t paddr,m_uint32_t len); |
237 |
|
|
|
238 |
|
|
/* remote control device */ |
239 |
|
|
int dev_remote_control_init(vm_instance_t *vm,m_uint64_t paddr,m_uint32_t len); |
240 |
|
|
|
241 |
|
|
#endif |