First pass at moving sky stuff from ../txvu to mips dir.
[deliverable/binutils-gdb.git] / sim / mips / sky-pke.c
1 /* Copyright (C) 1998, Cygnus Solutions */
2
3 #include "pke.h"
4 #include <stdlib.h>
5
6
7 /* Imported functions */
8
9 void device_error (device *me, char* message); /* device.c */
10
11
12 /* Internal function declarations */
13
14 static int pke_io_read_buffer(device*, void*, int, address_word,
15 unsigned, sim_cpu*, sim_cia);
16 static int pke_io_write_buffer(device*, const void*, int, address_word,
17 unsigned, sim_cpu*, sim_cia);
18 static void pke_issue(struct pke_device*);
19
20
21 /* Static data */
22
23 struct pke_device pke0_device =
24 {
25 { "pke0", &pke_io_read_buffer, &pke_io_write_buffer }, /* device */
26 0, 0, /* ID, flags */
27 PKE0_REGISTER_WINDOW_START, PKE0_FIFO_START, /* memory-mapping addresses */
28 {}, /* regs */
29 NULL, 0, 0, NULL, /* FIFO */
30 0 /* pc */
31 };
32
33
34 struct pke_device pke1_device =
35 {
36 { "pke1", &pke_io_read_buffer, &pke_io_write_buffer }, /* device */
37 1, 0, /* ID, flags */
38 PKE1_REGISTER_WINDOW_START, PKE1_FIFO_START, /* memory-mapping addresses */
39 {}, /* regs */
40 NULL, 0, 0, NULL, /* FIFO */
41 0 /* pc */
42 };
43
44
45
46 /* External functions */
47
48
49 /* Attach PKE0 addresses to main memory */
50
51 void
52 pke0_attach(SIM_DESC sd)
53 {
54 sim_core_attach (sd,
55 NULL,
56 0 /*level*/,
57 access_read_write,
58 0 /*space ???*/,
59 pke0_device.register_memory_addr,
60 PKE_REGISTER_WINDOW_SIZE /*nr_bytes*/,
61 0 /*modulo*/,
62 (device*) &pke0_device,
63 NULL /*buffer*/);
64
65 sim_core_attach (sd,
66 NULL,
67 0 /*level*/,
68 access_read_write,
69 0 /*space ???*/,
70 pke0_device.fifo_memory_addr,
71 sizeof(quadword) /*nr_bytes*/,
72 0 /*modulo*/,
73 (device*) &pke1_device,
74 NULL /*buffer*/);
75 }
76
77
78 /* Attach PKE1 addresses to main memory */
79
80 void
81 pke1_attach(SIM_DESC sd)
82 {
83 sim_core_attach (sd,
84 NULL,
85 0 /*level*/,
86 access_read_write,
87 0 /*space ???*/,
88 pke1_device.register_memory_addr,
89 PKE_REGISTER_WINDOW_SIZE /*nr_bytes*/,
90 0 /*modulo*/,
91 (device*) &pke1_device,
92 NULL /*buffer*/);
93
94 sim_core_attach (sd,
95 NULL,
96 0 /*level*/,
97 access_read_write,
98 0 /*space ???*/,
99 pke1_device.fifo_memory_addr,
100 sizeof(quadword) /*nr_bytes*/,
101 0 /*modulo*/,
102 (device*) &pke1_device,
103 NULL /*buffer*/);
104 }
105
106
107 /* Issue a PKE0 instruction if possible */
108
109 void
110 pke0_issue()
111 {
112 pke_issue(& pke0_device);
113 }
114
115
116 /* Issue a PKE1 instruction if possible */
117
118 void
119 pke1_issue()
120 {
121 pke_issue(& pke0_device);
122 }
123
124
125
126 /* Internal functions */
127
128
129 /* Handle a PKE read; return no. of bytes read */
130
131 int
132 pke_io_read_buffer(device *me_,
133 void *dest,
134 int space,
135 address_word addr,
136 unsigned nr_bytes,
137 sim_cpu *processor,
138 sim_cia cia)
139 {
140 /* downcast to gather embedding pke_device struct */
141 struct pke_device* me = (struct pke_device*) me_;
142
143 /* enforce that an access does not span more than one quadword */
144 address_word low = ADDR_TRUNC_QW(addr);
145 address_word high = ADDR_TRUNC_QW(addr + nr_bytes - 1);
146 if(low != high)
147 return 0;
148
149 /* classify address & handle */
150 if(addr >= me->register_memory_addr &&
151 addr < me->register_memory_addr + PKE_REGISTER_WINDOW_SIZE)
152 {
153 /* register bank */
154 int reg_num = ADDR_TRUNC_QW(addr - me->register_memory_addr) >> 4;
155 int readable = 1;
156
157 /* ensure readibility of register: all okay except PKE1-only ones read on PKE0 */
158 switch(reg_num)
159 {
160 case PKE_REG_BASE:
161 case PKE_REG_OFST:
162 case PKE_REG_TOPS:
163 case PKE_REG_TOP:
164 case PKE_REG_DBF:
165 if(me->pke_number == 0) /* PKE0 cannot access these registers */
166 readable = 0;
167 }
168
169 /* perform read & return */
170 if(readable)
171 {
172 /* find byte-offset inside register bank */
173 int reg_byte = ADDR_OFFSET_QW(addr);
174 void* src = ((unsigned_1*) (& me->regs[reg_num])) + reg_byte;
175 /* copy the bits */
176 memcpy(dest, src, nr_bytes);
177 /* okay */
178 return nr_bytes;
179 }
180 else
181 {
182 /* error */
183 return 0;
184 }
185
186 /* NOTREACHED */
187 }
188 else if(addr >= me->fifo_memory_addr &&
189 addr < me->fifo_memory_addr + sizeof(quadword))
190 {
191 /* FIFO */
192
193 /* XXX: FIFO is not readable. */
194 return 0;
195 }
196
197 /* NOTREACHED */
198 }
199
200
201 /* Handle a PKE read; return no. of bytes written */
202
203 int
204 pke_io_write_buffer(device *me_,
205 const void *src,
206 int space,
207 address_word addr,
208 unsigned nr_bytes,
209 sim_cpu *processor,
210 sim_cia cia)
211 {
212 /* downcast to gather embedding pke_device struct */
213 struct pke_device* me = (struct pke_device*) me_;
214
215 /* enforce that an access does not span more than one quadword */
216 address_word low = ADDR_TRUNC_QW(addr);
217 address_word high = ADDR_TRUNC_QW(addr + nr_bytes - 1);
218 if(low != high)
219 return 0;
220
221 /* classify address & handle */
222 if(addr >= me->register_memory_addr &&
223 addr < me->register_memory_addr + PKE_REGISTER_WINDOW_SIZE)
224 {
225 /* register bank */
226 int reg_num = ADDR_TRUNC_QW(addr - me->register_memory_addr) >> 4;
227 int writeable = 1;
228
229 /* ensure readibility of register: all okay except PKE1-only ones read on PKE0 */
230 switch(reg_num)
231 {
232 case PKE_REG_BASE:
233 case PKE_REG_OFST:
234 case PKE_REG_TOPS:
235 case PKE_REG_TOP:
236 case PKE_REG_DBF:
237 if(me->pke_number == 0) /* PKE0 cannot access these registers */
238 writeable = 0;
239 }
240
241 /* perform write & return */
242 if(writeable)
243 {
244 /* find byte-offset inside register bank */
245 int reg_byte = ADDR_OFFSET_QW(addr);
246 void* dest = ((unsigned_1*) (& me->regs[reg_num])) + reg_byte;
247 /* copy the bits */
248 memcpy(dest, src, nr_bytes);
249 return nr_bytes;
250 }
251 else
252 {
253 /* error */
254 return 0;
255 }
256
257 /* NOTREACHED */
258 }
259 else if(addr >= me->fifo_memory_addr &&
260 addr < me->fifo_memory_addr + sizeof(quadword))
261 {
262 /* FIFO */
263
264 /* assert transfer size == 128 bits */
265 if(nr_bytes != sizeof(quadword))
266 return 0;
267
268 /* ensure FIFO has enough elements */
269 if(me->fifo_num_elements == me->fifo_buffer_size)
270 {
271 /* time to grow */
272 int new_fifo_buffer_size = me->fifo_buffer_size + 20;
273 void* ptr = realloc((void*) me->fifo, new_fifo_buffer_size*sizeof(quadword));
274
275 if(ptr == NULL)
276 {
277 /* oops, cannot enlarge FIFO any more */
278 device_error(me_, "Cannot enlarge FIFO buffer\n");
279 return 0;
280 }
281
282 me->fifo_buffer_size = new_fifo_buffer_size;
283 }
284
285 /* add new quadword at end of FIFO */
286 memcpy(& me->fifo[++me->fifo_num_elements], src, nr_bytes);
287
288 /* okay */
289 return nr_bytes;
290 }
291
292 /* NOTREACHED */
293 }
294
295
296
297 /* Issue & swallow one PKE opcode if possible */
298
299 void
300 pke_issue(struct pke_device* me)
301 {
302
303
304 }
305
306
This page took 0.036857 seconds and 5 git commands to generate.