summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armvirt.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-04-08 19:25:03 -0400
committerGravatar bunnei2014-04-08 19:25:03 -0400
commit63e46abdb8764bc97e91bae862c8d461e61b1965 (patch)
treee73f4aa25d7b4015a265e7bbfb6004dab7561027 /src/core/arm/interpreter/armvirt.cpp
parentfixed some license headers that I missed (diff)
downloadyuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.gz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.xz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.zip
got rid of 'src' folders in each sub-project
Diffstat (limited to 'src/core/arm/interpreter/armvirt.cpp')
-rw-r--r--src/core/arm/interpreter/armvirt.cpp680
1 files changed, 680 insertions, 0 deletions
diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp
new file mode 100644
index 000000000..a072b73be
--- /dev/null
+++ b/src/core/arm/interpreter/armvirt.cpp
@@ -0,0 +1,680 @@
1/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* This file contains a complete ARMulator memory model, modelling a
19"virtual memory" system. A much simpler model can be found in armfast.c,
20and that model goes faster too, but has a fixed amount of memory. This
21model's memory has 64K pages, allocated on demand from a 64K entry page
22table. The routines PutWord and GetWord implement this. Pages are never
23freed as they might be needed again. A single area of memory may be
24defined to generate aborts. */
25
26#include "armdefs.h"
27#include "skyeye_defs.h"
28//#include "code_cov.h"
29
30#ifdef VALIDATE /* for running the validate suite */
31#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
32#define ABORTS 1
33#endif
34
35/* #define ABORTS */
36
37#ifdef ABORTS /* the memory system will abort */
38/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
39 For the new test suite Abort between 8 Mbytes and 26 Mbytes */
40/* #define LOWABORT 32 * 1024
41#define HIGHABORT 32 * 1024 * 1024 */
42#define LOWABORT 8 * 1024 * 1024
43#define HIGHABORT 26 * 1024 * 1024
44
45#endif
46
47#define NUMPAGES 64 * 1024
48#define PAGESIZE 64 * 1024
49#define PAGEBITS 16
50#define OFFSETBITS 0xffff
51//chy 2003-08-19: seems no use ????
52int SWI_vector_installed = FALSE;
53extern ARMword skyeye_cachetype;
54
55/***************************************************************************\
56* Get a byte into Virtual Memory, maybe allocating the page *
57\***************************************************************************/
58static fault_t
59GetByte (ARMul_State * state, ARMword address, ARMword * data)
60{
61 fault_t fault;
62
63 fault = mmu_read_byte (state, address, data);
64 if (fault) {
65//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
66// printf("SKYEYE: GetByte fault %d \n", fault);
67 }
68 return fault;
69}
70
71/***************************************************************************\
72* Get a halfword into Virtual Memory, maybe allocating the page *
73\***************************************************************************/
74static fault_t
75GetHalfWord (ARMul_State * state, ARMword address, ARMword * data)
76{
77 fault_t fault;
78
79 fault = mmu_read_halfword (state, address, data);
80 if (fault) {
81//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
82// printf("SKYEYE: GetHalfWord fault %d \n", fault);
83 }
84 return fault;
85}
86
87/***************************************************************************\
88* Get a Word from Virtual Memory, maybe allocating the page *
89\***************************************************************************/
90
91static fault_t
92GetWord (ARMul_State * state, ARMword address, ARMword * data)
93{
94 fault_t fault;
95
96 fault = mmu_read_word (state, address, data);
97 if (fault) {
98//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
99#if 0
100/* XXX */ extern int hack;
101 hack = 1;
102#endif
103#if 0
104 printf ("mmu_read_word at 0x%08x: ", address);
105 switch (fault) {
106 case ALIGNMENT_FAULT:
107 printf ("ALIGNMENT_FAULT");
108 break;
109 case SECTION_TRANSLATION_FAULT:
110 printf ("SECTION_TRANSLATION_FAULT");
111 break;
112 case PAGE_TRANSLATION_FAULT:
113 printf ("PAGE_TRANSLATION_FAULT");
114 break;
115 case SECTION_DOMAIN_FAULT:
116 printf ("SECTION_DOMAIN_FAULT");
117 break;
118 case SECTION_PERMISSION_FAULT:
119 printf ("SECTION_PERMISSION_FAULT");
120 break;
121 case SUBPAGE_PERMISSION_FAULT:
122 printf ("SUBPAGE_PERMISSION_FAULT");
123 break;
124 default:
125 printf ("Unrecognized fault number!");
126 }
127 printf ("\tpc = 0x%08x\n", state->Reg[15]);
128#endif
129 }
130 return fault;
131}
132
133//2003-07-10 chy: lyh change
134/****************************************************************************\
135 * Load a Instrion Word into Virtual Memory *
136\****************************************************************************/
137static fault_t
138LoadInstr (ARMul_State * state, ARMword address, ARMword * instr)
139{
140 fault_t fault;
141 fault = mmu_load_instr (state, address, instr);
142 return fault;
143 //if (fault)
144 // log_msg("load_instr fault = %d, address = %x\n", fault, address);
145}
146
147/***************************************************************************\
148* Put a byte into Virtual Memory, maybe allocating the page *
149\***************************************************************************/
150static fault_t
151PutByte (ARMul_State * state, ARMword address, ARMword data)
152{
153 fault_t fault;
154
155 fault = mmu_write_byte (state, address, data);
156 if (fault) {
157//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
158// printf("SKYEYE: PutByte fault %d \n", fault);
159 }
160 return fault;
161}
162
163/***************************************************************************\
164* Put a halfword into Virtual Memory, maybe allocating the page *
165\***************************************************************************/
166static fault_t
167PutHalfWord (ARMul_State * state, ARMword address, ARMword data)
168{
169 fault_t fault;
170
171 fault = mmu_write_halfword (state, address, data);
172 if (fault) {
173//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
174// printf("SKYEYE: PutHalfWord fault %d \n", fault);
175 }
176 return fault;
177}
178
179/***************************************************************************\
180* Put a Word into Virtual Memory, maybe allocating the page *
181\***************************************************************************/
182
183static fault_t
184PutWord (ARMul_State * state, ARMword address, ARMword data)
185{
186 fault_t fault;
187
188 fault = mmu_write_word (state, address, data);
189 if (fault) {
190//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
191#if 0
192/* XXX */ extern int hack;
193 hack = 1;
194#endif
195#if 0
196 printf ("mmu_write_word at 0x%08x: ", address);
197 switch (fault) {
198 case ALIGNMENT_FAULT:
199 printf ("ALIGNMENT_FAULT");
200 break;
201 case SECTION_TRANSLATION_FAULT:
202 printf ("SECTION_TRANSLATION_FAULT");
203 break;
204 case PAGE_TRANSLATION_FAULT:
205 printf ("PAGE_TRANSLATION_FAULT");
206 break;
207 case SECTION_DOMAIN_FAULT:
208 printf ("SECTION_DOMAIN_FAULT");
209 break;
210 case SECTION_PERMISSION_FAULT:
211 printf ("SECTION_PERMISSION_FAULT");
212 break;
213 case SUBPAGE_PERMISSION_FAULT:
214 printf ("SUBPAGE_PERMISSION_FAULT");
215 break;
216 default:
217 printf ("Unrecognized fault number!");
218 }
219 printf ("\tpc = 0x%08x\n", state->Reg[15]);
220#endif
221 }
222 return fault;
223}
224
225/***************************************************************************\
226* Initialise the memory interface *
227\***************************************************************************/
228
229unsigned
230ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize)
231{
232 return TRUE;
233}
234
235/***************************************************************************\
236* Remove the memory interface *
237\***************************************************************************/
238
239void
240ARMul_MemoryExit (ARMul_State * state)
241{
242}
243
244/***************************************************************************\
245* ReLoad Instruction *
246\***************************************************************************/
247
248ARMword
249ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
250{
251 ARMword data;
252 fault_t fault;
253
254#ifdef ABORTS
255 if (address >= LOWABORT && address < HIGHABORT) {
256 ARMul_PREFETCHABORT (address);
257 return ARMul_ABORTWORD;
258 }
259 else {
260 ARMul_CLEARABORT;
261 }
262#endif
263#if 0
264 /* do profiling for code coverage */
265 if (skyeye_config.code_cov.prof_on)
266 cov_prof(EXEC_FLAG, address);
267#endif
268#if 1
269 if ((isize == 2) && (address & 0x2)) {
270 ARMword lo, hi;
271 if (!(skyeye_cachetype == INSTCACHE))
272 fault = GetHalfWord (state, address, &lo);
273 else
274 fault = LoadInstr (state, address, &lo);
275#if 0
276 if (!fault) {
277 if (!(skyeye_cachetype == INSTCACHE))
278 fault = GetHalfWord (state, address + isize, &hi);
279 else
280 fault = LoadInstr (state, address + isize, &hi);
281
282 }
283#endif
284 if (fault) {
285 ARMul_PREFETCHABORT (address);
286 return ARMul_ABORTWORD;
287 }
288 else {
289 ARMul_CLEARABORT;
290 }
291 return lo;
292#if 0
293 if (state->bigendSig == HIGH)
294 return (lo << 16) | (hi >> 16);
295 else
296 return ((hi & 0xFFFF) << 16) | (lo >> 16);
297#endif
298 }
299#endif
300 if (!(skyeye_cachetype == INSTCACHE))
301 fault = GetWord (state, address, &data);
302 else
303 fault = LoadInstr (state, address, &data);
304
305 if (fault) {
306
307 /* dyf add for s3c6410 no instcache temporary 2010.9.17 */
308 if (!(skyeye_cachetype == INSTCACHE)) {
309 /* set translation fault on prefetch abort */
310 state->mmu.fault_statusi = fault & 0xFF;
311 state->mmu.fault_address = address;
312 }
313 /* add end */
314
315 ARMul_PREFETCHABORT (address);
316 return ARMul_ABORTWORD;
317 }
318 else {
319 ARMul_CLEARABORT;
320 }
321
322 return data;
323}
324
325/***************************************************************************\
326* Load Instruction, Sequential Cycle *
327\***************************************************************************/
328
329ARMword
330ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
331{
332 state->NumScycles++;
333
334#ifdef HOURGLASS
335 if ((state->NumScycles & HOURGLASS_RATE) == 0) {
336 HOURGLASS;
337 }
338#endif
339
340 return ARMul_ReLoadInstr (state, address, isize);
341}
342
343/***************************************************************************\
344* Load Instruction, Non Sequential Cycle *
345\***************************************************************************/
346
347ARMword
348ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
349{
350 state->NumNcycles++;
351
352 return ARMul_ReLoadInstr (state, address, isize);
353}
354
355/***************************************************************************\
356* Read Word (but don't tell anyone!) *
357\***************************************************************************/
358
359ARMword
360ARMul_ReadWord (ARMul_State * state, ARMword address)
361{
362 ARMword data;
363 fault_t fault;
364
365#ifdef ABORTS
366 if (address >= LOWABORT && address < HIGHABORT) {
367 ARMul_DATAABORT (address);
368 return ARMul_ABORTWORD;
369 }
370 else {
371 ARMul_CLEARABORT;
372 }
373#endif
374
375 fault = GetWord (state, address, &data);
376 if (fault) {
377 state->mmu.fault_status =
378 (fault | (state->mmu.last_domain << 4)) & 0xFF;
379 state->mmu.fault_address = address;
380 ARMul_DATAABORT (address);
381 return ARMul_ABORTWORD;
382 }
383 else {
384 ARMul_CLEARABORT;
385 }
386 return data;
387}
388
389/***************************************************************************\
390* Load Word, Sequential Cycle *
391\***************************************************************************/
392
393ARMword
394ARMul_LoadWordS (ARMul_State * state, ARMword address)
395{
396 state->NumScycles++;
397
398 return ARMul_ReadWord (state, address);
399}
400
401/***************************************************************************\
402* Load Word, Non Sequential Cycle *
403\***************************************************************************/
404
405ARMword
406ARMul_LoadWordN (ARMul_State * state, ARMword address)
407{
408 state->NumNcycles++;
409
410 return ARMul_ReadWord (state, address);
411}
412
413/***************************************************************************\
414* Load Halfword, (Non Sequential Cycle) *
415\***************************************************************************/
416
417ARMword
418ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
419{
420 ARMword data;
421 fault_t fault;
422
423 state->NumNcycles++;
424 fault = GetHalfWord (state, address, &data);
425
426 if (fault) {
427 state->mmu.fault_status =
428 (fault | (state->mmu.last_domain << 4)) & 0xFF;
429 state->mmu.fault_address = address;
430 ARMul_DATAABORT (address);
431 return ARMul_ABORTWORD;
432 }
433 else {
434 ARMul_CLEARABORT;
435 }
436
437 return data;
438
439}
440
441/***************************************************************************\
442* Read Byte (but don't tell anyone!) *
443\***************************************************************************/
444int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult)
445{
446 ARMword data;
447 fault_t fault;
448 fault = GetByte (state, address, &data);
449 if (fault) {
450 *presult=-1; fault=ALIGNMENT_FAULT; return fault;
451 }else{
452 *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault;
453 }
454}
455
456
457ARMword
458ARMul_ReadByte (ARMul_State * state, ARMword address)
459{
460 ARMword data;
461 fault_t fault;
462
463 fault = GetByte (state, address, &data);
464
465 if (fault) {
466 state->mmu.fault_status =
467 (fault | (state->mmu.last_domain << 4)) & 0xFF;
468 state->mmu.fault_address = address;
469 ARMul_DATAABORT (address);
470 return ARMul_ABORTWORD;
471 }
472 else {
473 ARMul_CLEARABORT;
474 }
475
476 return data;
477
478}
479
480/***************************************************************************\
481* Load Byte, (Non Sequential Cycle) *
482\***************************************************************************/
483
484ARMword
485ARMul_LoadByte (ARMul_State * state, ARMword address)
486{
487 state->NumNcycles++;
488
489 return ARMul_ReadByte (state, address);
490}
491
492/***************************************************************************\
493* Write Word (but don't tell anyone!) *
494\***************************************************************************/
495
496void
497ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
498{
499 fault_t fault;
500
501#ifdef ABORTS
502 if (address >= LOWABORT && address < HIGHABORT) {
503 ARMul_DATAABORT (address);
504 return;
505 }
506 else {
507 ARMul_CLEARABORT;
508 }
509#endif
510
511 fault = PutWord (state, address, data);
512 if (fault) {
513 state->mmu.fault_status =
514 (fault | (state->mmu.last_domain << 4)) & 0xFF;
515 state->mmu.fault_address = address;
516 ARMul_DATAABORT (address);
517 return;
518 }
519 else {
520 ARMul_CLEARABORT;
521 }
522}
523
524/***************************************************************************\
525* Store Word, Sequential Cycle *
526\***************************************************************************/
527
528void
529ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
530{
531 state->NumScycles++;
532
533 ARMul_WriteWord (state, address, data);
534}
535
536/***************************************************************************\
537* Store Word, Non Sequential Cycle *
538\***************************************************************************/
539
540void
541ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
542{
543 state->NumNcycles++;
544
545 ARMul_WriteWord (state, address, data);
546}
547
548/***************************************************************************\
549* Store HalfWord, (Non Sequential Cycle) *
550\***************************************************************************/
551
552void
553ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
554{
555 fault_t fault;
556 state->NumNcycles++;
557 fault = PutHalfWord (state, address, data);
558 if (fault) {
559 state->mmu.fault_status =
560 (fault | (state->mmu.last_domain << 4)) & 0xFF;
561 state->mmu.fault_address = address;
562 ARMul_DATAABORT (address);
563 return;
564 }
565 else {
566 ARMul_CLEARABORT;
567 }
568}
569
570//chy 2006-04-15
571int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data)
572{
573 fault_t fault;
574 fault = PutByte (state, address, data);
575 if (fault)
576 return 1;
577 else
578 return 0;
579}
580/***************************************************************************\
581* Write Byte (but don't tell anyone!) *
582\***************************************************************************/
583//chy 2003-07-10, add real write byte fun
584void
585ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
586{
587 fault_t fault;
588 fault = PutByte (state, address, data);
589 if (fault) {
590 state->mmu.fault_status =
591 (fault | (state->mmu.last_domain << 4)) & 0xFF;
592 state->mmu.fault_address = address;
593 ARMul_DATAABORT (address);
594 return;
595 }
596 else {
597 ARMul_CLEARABORT;
598 }
599}
600
601/***************************************************************************\
602* Store Byte, (Non Sequential Cycle) *
603\***************************************************************************/
604
605void
606ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
607{
608 state->NumNcycles++;
609
610#ifdef VALIDATE
611 if (address == TUBE) {
612 if (data == 4)
613 state->Emulate = FALSE;
614 else
615 (void) putc ((char) data, stderr); /* Write Char */
616 return;
617 }
618#endif
619
620 ARMul_WriteByte (state, address, data);
621}
622
623/***************************************************************************\
624* Swap Word, (Two Non Sequential Cycles) *
625\***************************************************************************/
626
627ARMword
628ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
629{
630 ARMword temp;
631
632 state->NumNcycles++;
633
634 temp = ARMul_ReadWord (state, address);
635
636 state->NumNcycles++;
637
638 PutWord (state, address, data);
639
640 return temp;
641}
642
643/***************************************************************************\
644* Swap Byte, (Two Non Sequential Cycles) *
645\***************************************************************************/
646
647ARMword
648ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
649{
650 ARMword temp;
651
652 temp = ARMul_LoadByte (state, address);
653 ARMul_StoreByte (state, address, data);
654
655 return temp;
656}
657
658/***************************************************************************\
659* Count I Cycles *
660\***************************************************************************/
661
662void
663ARMul_Icycles (ARMul_State * state, unsigned number,
664 ARMword address)
665{
666 state->NumIcycles += number;
667 ARMul_CLEARABORT;
668}
669
670/***************************************************************************\
671* Count C Cycles *
672\***************************************************************************/
673
674void
675ARMul_Ccycles (ARMul_State * state, unsigned number,
676 ARMword address)
677{
678 state->NumCcycles += number;
679 ARMul_CLEARABORT;
680}