Commit | Line | Data |
---|---|---|
aea481da DE |
1 | /* Copyright (C) 1998, Cygnus Solutions |
2 | ||
3 | */ | |
4 | ||
5 | #include "sim-main.h" | |
486c714a | 6 | #include "sim-endian.h" |
aea481da | 7 | |
803f52b9 DE |
8 | #include "sky-device.h" |
9 | #include "sky-vu1.h" | |
10 | #include "sky-libvpe.h" | |
11 | #include "sky-vu.h" | |
9c577d9a IC |
12 | #include "sky-bits.h" |
13 | ||
14 | #include <assert.h> | |
aea481da DE |
15 | |
16 | VectorUnitState vu1_state; | |
17 | ||
04a7f72a IC |
18 | #define sim_warning printf |
19 | ||
f0bb94cd FCE |
20 | static char* vu1_umem_buffer = 0; |
21 | static char* vu1_mem_buffer = 0; | |
aea481da | 22 | |
52793fab | 23 | void init_vu1(void); |
aea481da DE |
24 | void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer); |
25 | ||
9614fb3c | 26 | #if 0 |
733cfc78 IC |
27 | static void dump_mem() { |
28 | int i; | |
29 | typedef int T[2048][4]; | |
30 | T *mem = (T*)&vu1_mem_buffer; | |
31 | ||
32 | for (i = 0; i < 200; i++) { | |
33 | printf("%d: %x %x %x %x\n", i, (*mem)[i][0], (*mem)[i][1], (*mem)[i][2], (*mem)[i][3]); | |
34 | } | |
35 | } | |
9614fb3c | 36 | #endif |
733cfc78 | 37 | |
aea481da | 38 | void |
52793fab | 39 | vu1_issue(void) |
aea481da DE |
40 | { |
41 | if (vu1_state.runState == VU_RUN) | |
42 | vpecallms_cycle(&vu1_state); | |
43 | } | |
44 | ||
52793fab | 45 | static int |
aea481da DE |
46 | vu1_io_read_register_window(device *me, |
47 | void *dest, | |
48 | int space, | |
49 | address_word addr, | |
50 | unsigned nr_bytes, | |
51 | sim_cpu *processor, | |
52 | sim_cia cia) | |
53 | { | |
54 | /* Slow and crappy hack ... */ | |
55 | ||
9c577d9a | 56 | |
aea481da DE |
57 | int i; |
58 | ||
59 | char source_buffer[VU1_REGISTER_WINDOW_SIZE]; | |
60 | char* src; | |
61 | ||
9c577d9a IC |
62 | assert(nr_bytes == 1 || nr_bytes == 2 || nr_bytes == 4 || nr_bytes == 8 || nr_bytes == 16); |
63 | ||
aea481da DE |
64 | memcpy(source_buffer, &vu1_state.regs.VF[0][0], 0x200); /* copy VF registers */ |
65 | for (i = 0; i<16; i++ ) { | |
66 | *(short*)&source_buffer[0x200 + i*16] = vu1_state.regs.VI[i]; | |
67 | } | |
9c577d9a IC |
68 | *(u_long*)&source_buffer[VU1_MST - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MST; |
69 | *(u_long*)&source_buffer[VU1_MMC - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MMC; | |
70 | *(u_long*)&source_buffer[VU1_MCP - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MCP; | |
71 | *(u_long*)&source_buffer[VU1_MR - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MR; | |
72 | *(u_long*)&source_buffer[VU1_MI - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MI; | |
73 | *(u_long*)&source_buffer[VU1_MQ - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MQ; | |
74 | *(u_long*)&source_buffer[VU1_MP - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MP; | |
75 | *(u_long*)&source_buffer[VU1_MTPC - VU1_REGISTER_WINDOW_START] = vu1_state.regs.MTPC; | |
76 | ||
77 | { | |
78 | u_long stat; | |
79 | stat = 0; | |
80 | if (vu1_state.runState == VU_RUN || vu1_state.runState == VU_BREAK) | |
81 | SET_BIT(stat, VPU_STAT_VBS1_BIT); | |
82 | ||
f0bb94cd | 83 | *(u_long*)&source_buffer[VPE1_STAT - VU1_REGISTER_WINDOW_START] = H2T_4(stat); |
9c577d9a | 84 | } |
aea481da | 85 | |
f0bb94cd FCE |
86 | *(u_long*)&source_buffer[VU1_CIA - VU1_REGISTER_WINDOW_START] = H2T_4(vu1_state.junk._vpepc); |
87 | /* XXX: other H2T_N's needed around here. */ | |
04a7f72a | 88 | |
486c714a | 89 | #if 0 |
52793fab IC |
90 | printf("%s: Read: %x, %d, dest: %x, space: %d, %x!\n", me->name, (int)addr, nr_bytes, (int)dest, space, *(int*)&(vu1_state.regs.VPE_STAT)); |
91 | printf(" vu1_state.regs.VPE_STAT = %x\n", *(int*)&(vu1_state.regs.VPE_STAT)); | |
486c714a | 92 | #endif |
aea481da DE |
93 | |
94 | if (addr + nr_bytes > VU1_REGISTER_WINDOW_END) { | |
95 | fprintf(stderr, "Error: Read past end of vu1 register window!!!\n"); | |
96 | exit(1); | |
97 | } | |
98 | ||
99 | src = &source_buffer[0] + (addr - VU1_REGISTER_WINDOW_START); | |
100 | memcpy(dest, src, nr_bytes); | |
101 | return nr_bytes; | |
102 | } | |
103 | ||
52793fab | 104 | static int |
aea481da DE |
105 | vu1_io_write_register_window(device *me, |
106 | const void *source, | |
107 | int space, | |
108 | address_word addr, | |
109 | unsigned nr_bytes, | |
110 | sim_cpu *processor, | |
111 | sim_cia cia) | |
112 | { | |
113 | char *dest; | |
114 | ||
04a7f72a IC |
115 | assert(nr_bytes == 4); |
116 | ||
117 | if (addr == VPE1_STAT) { | |
118 | /* Do nothing, read only register. */ | |
119 | sim_warning("vu1: Write to read/only register at address %lx.\n", (u_long)addr); | |
aea481da | 120 | return nr_bytes; |
04a7f72a | 121 | } else if (addr == VU1_MST) { |
486c714a | 122 | /* Magic switch to set _TOP register */ |
486c714a IC |
123 | vu1_state.junk._TOP = T2H_4(*(int*)source); |
124 | return nr_bytes; | |
04a7f72a | 125 | } else if (addr == VU1_CIA) { |
f62dff78 | 126 | vu1_state.junk.pc = vu1_state.junk._vpepc = T2H_4(*(int*)source); |
04a7f72a IC |
127 | vu1_state.runState = VU_RUN; |
128 | vu1_state.junk.eflag = 0; | |
129 | vu1_state.junk.peflag = 0; | |
130 | return nr_bytes; | |
131 | } | |
132 | ||
133 | /* Everything else does nothing... */ | |
134 | sim_warning("vu1: Write to unimplemented control register at address %lx.\n", (u_long)addr); | |
135 | return nr_bytes; | |
aea481da | 136 | |
486c714a | 137 | /*printf("%s: Write: %x, %d, source: %x, space: %d!\n", me->name, (int)addr, nr_bytes, (int)source, space);*/ |
aea481da DE |
138 | |
139 | if (addr + nr_bytes > VU1_REGISTER_WINDOW_END) { | |
140 | fprintf(stderr, "Error: Read past end of vu1 register window!!!\n"); | |
141 | exit(1); | |
142 | } | |
143 | ||
144 | dest = ((char*) (&vu1_state.regs)) + (addr - VU1_REGISTER_WINDOW_START); | |
145 | ||
146 | memcpy(dest, source, nr_bytes); | |
147 | ||
148 | return nr_bytes; | |
149 | } | |
150 | ||
151 | device vu1_device = | |
152 | { | |
153 | "vu1", | |
154 | &vu1_io_read_register_window, | |
155 | &vu1_io_write_register_window | |
156 | }; | |
157 | ||
158 | void | |
159 | vu1_init(SIM_DESC sd) | |
160 | { | |
161 | ||
162 | sim_core_attach (sd, | |
163 | NULL, | |
164 | 0 /*level*/, | |
165 | access_read_write, | |
166 | 0 /*space ???*/, | |
167 | VU1_REGISTER_WINDOW_START, | |
168 | VU1_REGISTER_WINDOW_SIZE /*nr_bytes*/, | |
169 | 0 /*modulo*/, | |
170 | &vu1_device, | |
171 | NULL /*buffer*/); | |
172 | ||
f0bb94cd | 173 | vu1_umem_buffer = zalloc(VU1_MEM0_SIZE); |
aea481da DE |
174 | sim_core_attach (sd, |
175 | NULL, | |
176 | 0 /*level*/, | |
177 | access_read_write, | |
178 | 0 /*space ???*/, | |
179 | VU1_MEM0_WINDOW_START, | |
180 | VU1_MEM0_SIZE /*nr_bytes*/, | |
181 | 0 /*modulo*/, | |
182 | 0 /*device*/, | |
f0bb94cd | 183 | vu1_umem_buffer /*buffer*/); |
aea481da | 184 | |
f0bb94cd | 185 | vu1_mem_buffer = zalloc(VU1_MEM1_SIZE); |
aea481da DE |
186 | sim_core_attach (sd, |
187 | NULL, | |
188 | 0 /*level*/, | |
189 | access_read_write, | |
190 | 0 /*space ???*/, | |
191 | VU1_MEM1_WINDOW_START, | |
192 | VU1_MEM1_SIZE /*nr_bytes*/, | |
193 | 0 /*modulo*/, | |
194 | 0 /*device*/, | |
f0bb94cd | 195 | vu1_mem_buffer /*buffer*/); |
aea481da DE |
196 | |
197 | init_vu1(); | |
198 | /*initvpe();*/ | |
199 | vpecallms_init(&vu1_state); | |
200 | } | |
201 | ||
202 | /****************************************************************************/ | |
203 | /* */ | |
204 | /* Sony Computer Entertainment CONFIDENTIAL */ | |
205 | /* (C) 1997 Sony Computer Entertainment Inc. All Rights Reserved */ | |
206 | /* */ | |
207 | /* VPE1 simulator */ | |
208 | /* */ | |
209 | /****************************************************************************/ | |
210 | ||
211 | #include <stdio.h> | |
212 | #include <sys/types.h> | |
213 | #include <strings.h> | |
72db5610 | 214 | #include "sky-libvpe.h" |
aea481da DE |
215 | |
216 | char ifilename[64] = "vu.bin"; | |
217 | char ofilename[64] = ""; | |
218 | char pfilename[64] = ""; | |
219 | ||
52793fab | 220 | static void abend2(char *fmt, char* p) { |
aea481da DE |
221 | fprintf(stderr, fmt, p); |
222 | exit(1); | |
223 | } | |
224 | ||
486c714a | 225 | void getoption(VectorUnitState* state); |
aea481da | 226 | |
52793fab | 227 | void init_vu1(void) { |
aea481da DE |
228 | init_vu(&vu1_state, &vu1_umem_buffer[0], &vu1_mem_buffer[0]); |
229 | } | |
230 | ||
231 | void init_vu(VectorUnitState *state, char* umem_buffer, char* mem_buffer) | |
232 | { | |
233 | FILE *fp; | |
234 | int i, j; | |
235 | u_long data[4]; | |
236 | ||
237 | /* set up memory buffers */ | |
238 | state->uMEM = (uMEM_Entry_Type *) umem_buffer; | |
239 | state->MEM = (MEM_Entry_Type*) mem_buffer; | |
240 | ||
241 | /* set up run state */ | |
242 | state->runState = VU_READY; | |
243 | ||
244 | /* read option */ | |
486c714a | 245 | getoption(state); |
aea481da DE |
246 | |
247 | /* read instruction file (mandatory) */ | |
248 | if (*ifilename) { | |
dde66fa7 IC |
249 | if((fp = fopen(ifilename, "r")) != NULL) { |
250 | for (i = 0; fread(&data[0], 4, 1, fp) != 0; i++) { | |
251 | fread(&data[1], 4, 1, fp); | |
252 | LoadMMem(state, i, data, 1); | |
253 | } | |
254 | fclose(fp); | |
aea481da | 255 | } |
aea481da DE |
256 | } |
257 | ||
258 | /* PKE dirven simvpe */ | |
259 | if (*pfilename) { | |
260 | /* initpke(pfilename); */ | |
261 | initvpe(&vu1_state); | |
262 | /* while (simpke() != -1) | |
263 | simvpe(); */ | |
264 | } | |
265 | ||
266 | /* conventional simvpe */ | |
267 | else { | |
268 | initvpe(&vu1_state); | |
269 | /*simvpe();*/ | |
270 | } | |
271 | ||
272 | /* write result memory image (optional) */ | |
273 | if (*ofilename) { | |
274 | if((fp = fopen(ofilename, "w")) == NULL) | |
275 | abend2("%s: can not open\n", ofilename); | |
276 | ||
277 | for(i = 0; i < 2048; i++){ | |
52793fab | 278 | StoreVUMem(state, i, data, 1); |
aea481da DE |
279 | for(j = 0; j < 4; j++) |
280 | fwrite(&data[j], 4, 1, fp); | |
281 | } | |
282 | fclose(fp); | |
283 | } | |
284 | } | |
285 | ||
52793fab | 286 | #if 0 |
aea481da DE |
287 | static void Usage(void) |
288 | { | |
289 | fprintf(stderr, "Usage: simvpe [options]\n"); | |
290 | fprintf(stderr, "\t\t-i instruction-file\n"); | |
291 | fprintf(stderr, "\t\t-o output-memory-file\n"); | |
292 | fprintf(stderr, "\t\t-t PKE-file (text type)\n"); | |
293 | fprintf(stderr, "\t\t-s start-address [default = 0]\n"); | |
294 | fprintf(stderr, "\t\t-d [interactive mode enable: default desable]\n"); | |
295 | fprintf(stderr, "\t\t-v [statistics mode enable: default desable]\n"); | |
296 | fprintf(stderr, "\t\t-p [debug print mode enable: default desable]\n"); | |
297 | } | |
52793fab | 298 | #endif |
aea481da | 299 | |
486c714a | 300 | void getoption(VectorUnitState* state) |
aea481da | 301 | { |
52793fab | 302 | #if 0 |
aea481da DE |
303 | int startline = 0; |
304 | int count = 1; | |
52793fab | 305 | #endif |
aea481da | 306 | |
486c714a IC |
307 | state->junk._is_dbg = 1; |
308 | state->junk._vpepc = 0; | |
309 | state->junk._is_verb = 0; | |
310 | state->junk._is_dump = 0; | |
374ed20d | 311 | state->junk._pgpuif = 4; /* MEMGPUIF */ |
486c714a IC |
312 | state->junk._ITOP = 20; |
313 | state->junk._TOP = 10; | |
aea481da DE |
314 | |
315 | #if 0 | |
316 | while(argc - count){ | |
317 | if(argv[count][0] == '-'){ | |
318 | switch(argv[count][1]){ | |
319 | case 'i': | |
320 | strcpy(ifilename, argv[count+1]); | |
321 | count += 2; | |
322 | break; | |
323 | case 'o': | |
324 | strcpy(ofilename, argv[count+1]); | |
325 | count += 2; | |
326 | break; | |
327 | case 't': | |
328 | strcpy(pfilename, argv[count+1]); | |
329 | count += 2; | |
330 | break; | |
331 | case 's': | |
332 | sscanf(argv[count+1], "%d", &startline); | |
486c714a | 333 | state->junk._vpepc = startline; |
aea481da DE |
334 | count += 2; |
335 | break; | |
336 | case 'd': | |
486c714a | 337 | state->junk._is_dbg = 1; |
aea481da DE |
338 | count += 1; |
339 | break; | |
340 | case 'v': | |
486c714a | 341 | state->junk._is_verb = 1; |
aea481da DE |
342 | count += 1; |
343 | break; | |
344 | case 'p': | |
486c714a | 345 | state->junk._is_dump = 1; |
aea481da DE |
346 | count += 1; |
347 | break; | |
348 | case 'h': | |
349 | case '?': | |
350 | Usage(); | |
351 | exit(1); | |
352 | break; | |
353 | default: | |
354 | Usage(); | |
355 | exit(1); | |
356 | } | |
357 | }else{ | |
358 | Usage(); | |
359 | exit(1); | |
360 | } | |
361 | } | |
362 | #endif | |
363 | } |