1 /* Copyright (C) 1998, Cygnus Solutions
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "sim-assert.h"
33 /*---------------------------------------------------------------------------*/
34 /*-- simulator engine -------------------------------------------------------*/
35 /*---------------------------------------------------------------------------*/
37 /* start-sanitize-sky */
40 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
43 /* Translate a virtual address to a physical address and cache
44 coherence algorithm describing the mechanism used to resolve the
45 memory reference. Given the virtual address vAddr, and whether the
46 reference is to Instructions ot Data (IorD), find the corresponding
47 physical address (pAddr) and the cache coherence algorithm (CCA)
48 used to resolve the reference. If the virtual address is in one of
49 the unmapped address spaces the physical address and the CCA are
50 determined directly by the virtual address. If the virtual address
51 is in one of the mapped address spaces then the TLB is used to
52 determine the physical address and access type; if the required
53 translation is not present in the TLB or the desired access is not
54 permitted the function fails and an exception is taken.
56 NOTE: Normally (RAW == 0), when address translation fails, this
57 function raises an exception and does not return. */
59 /* This implementation is for the MIPS R4000 family. See MIPS RISC
60 Architecture, Kane & Heinrich, Chapter 4. It is no good for any
61 of the 2000, 3000, or 6000 family.
63 One possible error in the K&H book of note. K&H has the PFN entry
64 in the TLB as being 24 bits. The high-order 4 bits would seem to be
65 unused, as the PFN is only 20-bits long. The 5900 manual shows
66 this as a 20-bit field. At any rate, the high order 4 bits are
72 /* A place to remember the last cache hit. */
73 static r4000_tlb_entry_t
*last_hit
= 0;
75 /* Try to match a single TLB entry. Three possibilities.
76 1. No match, returns 0
77 2. Match w/o exception, pAddr and CCA set, returns 1
78 3. Match w/ exception, in which case tlb_try_match does not return.
81 tlb_try_match (SIM_DESC SD
, sim_cpu
*CPU
, address_word cia
, r4000_tlb_entry_t
* entry
, unsigned32 asid
, unsigned32 vAddr
, address_word
* pAddr
, int *CCA
, int LorS
)
83 unsigned32 page_mask
, vpn2_mask
;
84 page_mask
= (entry
->mask
& 0x01ffe000);
85 vpn2_mask
= ~(page_mask
| 0x00001fff);
87 if ((vAddr
& vpn2_mask
) == (entry
->hi
& vpn2_mask
)
88 && ((entry
->hi
& TLB_HI_ASID_MASK
) == asid
89 || (entry
->hi
& TLB_HI_G_MASK
) != 0))
91 /* OK. Now, do we match lo0, or lo1? */
92 unsigned32 offset_mask
, vpn_lo_mask
, vpn_mask
, lo
;
94 offset_mask
= (page_mask
>> 1) | 0xfff;
95 vpn_lo_mask
= offset_mask
+ 1;
96 vpn_mask
= ~(offset_mask
);
98 ASSERT(vpn_lo_mask
== (-vpn2_mask
) >> 1);
99 ASSERT(vpn_mask
^ vpn_lo_mask
== vpn2_mask
);
101 if ((vAddr
& vpn_lo_mask
) == 0)
110 /* Warn upon attempted use of scratchpad RAM */
111 if(entry
->lo0
& TLB_LO_S_MASK
)
114 "Warning: no scratchpad RAM: virtual 0x%08x maps to physical 0x%08x.\n",
115 vAddr
, (vAddr
& offset_mask
));
117 /* act as if this is a valid, read/write page. */
118 lo
= TLB_LO_V_MASK
| TLB_LO_D_MASK
;
120 /* alternately, act as if this TLB entry is not a match */
124 if ((lo
& TLB_LO_V_MASK
) == 0)
126 COP0_BADVADDR
= vAddr
;
127 COP0_CONTEXT_set_BADVPN2((vAddr
& 0xffffe) >> 19); /* Top 19 bits */
128 COP0_ENTRYHI
= (vAddr
& 0xffffe) | asid
;
129 COP0_RANDOM
= rand()%(TLB_SIZE
- COP0_WIRED
) + COP0_WIRED
;
131 SignalExceptionTLBInvalidLoad ();
133 SignalExceptionTLBInvalidStore ();
134 ASSERT(0); /* Signal should never return. */
137 if ((lo
& TLB_LO_D_MASK
) == 0 && (LorS
== isSTORE
))
139 COP0_BADVADDR
= vAddr
;
140 COP0_CONTEXT_set_BADVPN2((vAddr
& 0xffffe) >> 19); /* Top 19 bits */
141 COP0_ENTRYHI
= (vAddr
& 0xffffe) | asid
;
142 COP0_RANDOM
= rand()%(TLB_SIZE
- COP0_WIRED
) + COP0_WIRED
;
143 SignalExceptionTLBModification ();
144 ASSERT(0); /* Signal should never return. */
147 /* Ignore lo.C rule for Cache access */
149 *pAddr
= (((lo
& 0x03ffffc0) << 6) & (~offset_mask
)) + (vAddr
& offset_mask
);
150 *CCA
= Uncached
; /* FOR NOW, no CCA support. */
152 last_hit
= entry
; /* Remember last hit. */
154 return 1; /* Match */
157 return 0; /* No Match */
161 dump_tlb(SIM_DESC SD
, sim_cpu
*CPU
, address_word cia
) {
164 /* Now linear search for a match. */
166 for (i
= 0; i
< TLB_SIZE
; i
++)
168 sim_io_eprintf(SD
, "%2d: %08x %08x %08x %08x\n", i
, TLB
[i
].mask
, TLB
[i
].hi
,
169 TLB
[i
].lo0
, TLB
[i
].lo1
);
174 INLINE_SIM_MAIN (void)
175 tlb_lookup (SIM_DESC SD
, sim_cpu
* CPU
, address_word cia
, unsigned32 vAddr
, address_word
* pAddr
, int *CCA
, int LorS
)
177 r4000_tlb_entry_t
*p
;
181 asid
= COP0_ENTRYHI
& 0x000000ff;
183 /* Test last hit first. More code, but probably faster on average. */
186 if (tlb_try_match (SD
, CPU
, cia
, last_hit
, asid
, vAddr
, pAddr
, CCA
, LorS
))
190 /* Now linear search for a match. */
191 for (p
= &TLB
[0]; p
< &TLB
[TLB_SIZE
]; p
++)
193 if (tlb_try_match (SD
, CPU
, cia
, p
, asid
, vAddr
, pAddr
, CCA
, LorS
))
197 /* No match, raise a TLB refill exception. */
198 COP0_BADVADDR
= vAddr
;
199 COP0_CONTEXT_set_BADVPN2((vAddr
& 0xffffe) >> 19); /* Top 19 bits */
200 COP0_ENTRYHI
= (vAddr
& 0xffffe) | asid
;
201 COP0_RANDOM
= rand()%(TLB_SIZE
- COP0_WIRED
) + COP0_WIRED
;
204 sim_io_eprintf(SD
, "TLB Refill exception at address 0x%0x\n", vAddr
);
205 dump_tlb(SD
, CPU
, cia
);
209 SignalExceptionTLBRefillLoad ();
211 SignalExceptionTLBRefillStore ();
212 ASSERT(0); /* Signal should never return. */
216 INLINE_SIM_MAIN (int)
217 address_translation (SIM_DESC SD
,
223 address_word
* pAddr
,
227 unsigned32 operating_mode
;
228 unsigned32 asid
, vpn
, offset
, offset_bits
;
231 sim_io_printf (sd
, "AddressTranslation(0x%s,%s,%s,...);\n", pr_addr (vAddr
), (IorD
? "isDATA" : "isINSTRUCTION"), (LorS
? "iSTORE" : "isLOAD"));
236 /* Determine operating mode. */
237 operating_mode
= SR_KSU
;
238 if (SR
& status_ERL
|| SR
& status_EXL
)
239 operating_mode
= ksu_kernel
;
241 switch (operating_mode
)
244 sim_io_eprintf (SD
, "Invalid operating mode SR.KSU == 0x3. Treated as 0x0.\n");
245 operating_mode
= ksu_kernel
;
248 /* Map and return for kseg0 and kseg1. */
249 if ((vAddr
& 0xc0000000) == 0x80000000)
251 ASSERT (0x80000000 <= vAddr
&& vAddr
< 0xc0000000);
252 if (vAddr
< 0xa0000000)
254 /* kseg0: Unmapped, Cached */
255 *pAddr
= vAddr
- 0x80000000;
256 *CCA
= Uncached
; /* For now, until cache model is supported. */
261 /* kseg1: Unmapped, Uncached */
262 *pAddr
= vAddr
- 0xa0000000;
271 /* Address error for 0x80000000->0xbfffffff and 0xe00000000->0xffffffff. */
272 unsigned32 top_three
= vAddr
& 0xe0000000;
273 if (top_three
!= 0x00000000 && top_three
!= 0xc0000000)
276 SignalExceptionAddressLoad ();
278 SignalExceptionAddressStore ();
279 ASSERT(0); /* Signal should never return. */
286 if (vAddr
& 0x80000000)
289 SignalExceptionAddressLoad ();
291 SignalExceptionAddressStore ();
292 ASSERT(0); /* Signal should never return. */
301 /* OK. If we got this far, we're ready to use the normal virtual->physical memory mapping. */
302 tlb_lookup (SD
, CPU
, cia
, vAddr
, pAddr
, CCA
, LorS
);
304 /* If the preceding call returns, a match was found, and CCA and pAddr have been set. */
308 #else /* TARGET_SKY */
309 /* end-sanitize-sky */
311 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
313 /* Translate a virtual address to a physical address and cache
314 coherence algorithm describing the mechanism used to resolve the
315 memory reference. Given the virtual address vAddr, and whether the
316 reference is to Instructions ot Data (IorD), find the corresponding
317 physical address (pAddr) and the cache coherence algorithm (CCA)
318 used to resolve the reference. If the virtual address is in one of
319 the unmapped address spaces the physical address and the CCA are
320 determined directly by the virtual address. If the virtual address
321 is in one of the mapped address spaces then the TLB is used to
322 determine the physical address and access type; if the required
323 translation is not present in the TLB or the desired access is not
324 permitted the function fails and an exception is taken.
326 NOTE: Normally (RAW == 0), when address translation fails, this
327 function raises an exception and does not return. */
331 address_translation (SIM_DESC sd
,
337 address_word
* pAddr
,
341 int res
= -1; /* TRUE : Assume good return */
344 sim_io_printf (sd
, "AddressTranslation(0x%s,%s,%s,...);\n", pr_addr (vAddr
), (IorD
? "isDATA" : "isINSTRUCTION"), (LorS
? "iSTORE" : "isLOAD"));
347 /* Check that the address is valid for this memory model */
349 /* For a simple (flat) memory model, we simply pass virtual
350 addressess through (mostly) unchanged. */
353 *pAddr
= vAddr
; /* default for isTARGET */
354 *CCA
= Uncached
; /* not used for isHOST */
359 /* start-sanitize-sky */
360 #endif /* !TARGET_SKY */
361 /* end-sanitize-sky */
364 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
366 /* Prefetch data from memory. Prefetch is an advisory instruction for
367 which an implementation specific action is taken. The action taken
368 may increase performance, but must not change the meaning of the
369 program, or alter architecturally-visible state. */
371 INLINE_SIM_MAIN (void)
372 prefetch (SIM_DESC sd
,
382 sim_io_printf(sd
,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA
,pr_addr(pAddr
),pr_addr(vAddr
),DATA
,hint
);
385 /* For our simple memory model we do nothing */
389 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
391 /* Load a value from memory. Use the cache and main memory as
392 specified in the Cache Coherence Algorithm (CCA) and the sort of
393 access (IorD) to find the contents of AccessLength memory bytes
394 starting at physical location pAddr. The data is returned in the
395 fixed width naturally-aligned memory element (MemElem). The
396 low-order two (or three) bits of the address and the AccessLength
397 indicate which of the bytes within MemElem needs to be given to the
398 processor. If the memory access type of the reference is uncached
399 then only the referenced bytes are read from memory and valid
400 within the memory element. If the access type is cached, and the
401 data is not present in cache, an implementation specific size and
402 alignment block of memory is read and loaded into the cache to
403 satisfy a load reference. At a minimum, the block is the entire
405 INLINE_SIM_MAIN (void)
406 load_memory (SIM_DESC SD
,
412 unsigned int AccessLength
,
421 sim_io_printf(sd
,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp
,memval1p
,CCA
,AccessLength
,pr_addr(pAddr
),pr_addr(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"));
424 #if defined(WARN_MEM)
426 sim_io_eprintf(sd
,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
427 #endif /* WARN_MEM */
430 /* IGEN performs this test in ifetch16() / ifetch32() */
431 /* If instruction fetch then we need to check that the two lo-order
432 bits are zero, otherwise raise a InstructionFetch exception: */
433 if ((IorD
== isINSTRUCTION
)
434 && ((pAddr
& 0x3) != 0)
435 && (((pAddr
& 0x1) != 0) || ((vAddr
& 0x1) == 0)))
436 SignalExceptionInstructionFetch ();
439 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
441 /* In reality this should be a Bus Error */
442 sim_io_error (SD
, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
444 (LOADDRMASK
+ 1) << 3,
449 dotrace (SD
, CPU
, tracefh
,((IorD
== isDATA
) ? 0 : 2),(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"load%s",((IorD
== isDATA
) ? "" : " instruction"));
452 /* Read the specified number of bytes from memory. Adjust for
453 host/target byte ordering/ Align the least significant byte
456 switch (AccessLength
)
458 case AccessLength_QUADWORD
:
460 unsigned_16 val
= sim_core_read_aligned_16 (CPU
, NULL_CIA
, read_map
, pAddr
);
461 value1
= VH8_16 (val
);
462 value
= VL8_16 (val
);
465 case AccessLength_DOUBLEWORD
:
466 value
= sim_core_read_aligned_8 (CPU
, NULL_CIA
,
469 case AccessLength_SEPTIBYTE
:
470 value
= sim_core_read_misaligned_7 (CPU
, NULL_CIA
,
473 case AccessLength_SEXTIBYTE
:
474 value
= sim_core_read_misaligned_6 (CPU
, NULL_CIA
,
477 case AccessLength_QUINTIBYTE
:
478 value
= sim_core_read_misaligned_5 (CPU
, NULL_CIA
,
481 case AccessLength_WORD
:
482 value
= sim_core_read_aligned_4 (CPU
, NULL_CIA
,
485 case AccessLength_TRIPLEBYTE
:
486 value
= sim_core_read_misaligned_3 (CPU
, NULL_CIA
,
489 case AccessLength_HALFWORD
:
490 value
= sim_core_read_aligned_2 (CPU
, NULL_CIA
,
493 case AccessLength_BYTE
:
494 value
= sim_core_read_aligned_1 (CPU
, NULL_CIA
,
502 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
503 (int)(pAddr
& LOADDRMASK
),pr_uword64(value1
),pr_uword64(value
));
506 /* See also store_memory. Position data in correct byte lanes. */
507 if (AccessLength
<= LOADDRMASK
)
510 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
511 shifted to the most significant byte position. */
512 value
<<= (((LOADDRMASK
- (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
514 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
515 is already in the correct postition. */
516 value
<<= ((pAddr
& LOADDRMASK
) * 8);
520 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
521 pr_uword64(value1
),pr_uword64(value
));
525 if (memval1p
) *memval1p
= value1
;
529 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
531 /* Store a value to memory. The specified data is stored into the
532 physical location pAddr using the memory hierarchy (data caches and
533 main memory) as specified by the Cache Coherence Algorithm
534 (CCA). The MemElem contains the data for an aligned, fixed-width
535 memory element (word for 32-bit processors, doubleword for 64-bit
536 processors), though only the bytes that will actually be stored to
537 memory need to be valid. The low-order two (or three) bits of pAddr
538 and the AccessLength field indicates which of the bytes within the
539 MemElem data should actually be stored; only these bytes in memory
542 INLINE_SIM_MAIN (void)
543 store_memory (SIM_DESC SD
,
547 unsigned int AccessLength
,
549 uword64 MemElem1
, /* High order 64 bits */
554 sim_io_printf(sd
,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA
,AccessLength
,pr_uword64(MemElem
),pr_uword64(MemElem1
),pr_addr(pAddr
),pr_addr(vAddr
));
557 #if defined(WARN_MEM)
559 sim_io_eprintf(sd
,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
560 #endif /* WARN_MEM */
562 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
563 sim_io_error (SD
, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
565 (LOADDRMASK
+ 1) << 3,
569 dotrace (SD
, CPU
, tracefh
,1,(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"store");
573 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr
& LOADDRMASK
),pr_uword64(MemElem1
),pr_uword64(MemElem
));
576 /* See also load_memory. Position data in correct byte lanes. */
577 if (AccessLength
<= LOADDRMASK
)
580 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
581 shifted to the most significant byte position. */
582 MemElem
>>= (((LOADDRMASK
- (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
584 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
585 is already in the correct postition. */
586 MemElem
>>= ((pAddr
& LOADDRMASK
) * 8);
590 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift
,pr_uword64(MemElem1
),pr_uword64(MemElem
));
593 switch (AccessLength
)
595 case AccessLength_QUADWORD
:
597 unsigned_16 val
= U16_8 (MemElem1
, MemElem
);
598 sim_core_write_aligned_16 (CPU
, NULL_CIA
, write_map
, pAddr
, val
);
601 case AccessLength_DOUBLEWORD
:
602 sim_core_write_aligned_8 (CPU
, NULL_CIA
,
603 write_map
, pAddr
, MemElem
);
605 case AccessLength_SEPTIBYTE
:
606 sim_core_write_misaligned_7 (CPU
, NULL_CIA
,
607 write_map
, pAddr
, MemElem
);
609 case AccessLength_SEXTIBYTE
:
610 sim_core_write_misaligned_6 (CPU
, NULL_CIA
,
611 write_map
, pAddr
, MemElem
);
613 case AccessLength_QUINTIBYTE
:
614 sim_core_write_misaligned_5 (CPU
, NULL_CIA
,
615 write_map
, pAddr
, MemElem
);
617 case AccessLength_WORD
:
618 sim_core_write_aligned_4 (CPU
, NULL_CIA
,
619 write_map
, pAddr
, MemElem
);
621 case AccessLength_TRIPLEBYTE
:
622 sim_core_write_misaligned_3 (CPU
, NULL_CIA
,
623 write_map
, pAddr
, MemElem
);
625 case AccessLength_HALFWORD
:
626 sim_core_write_aligned_2 (CPU
, NULL_CIA
,
627 write_map
, pAddr
, MemElem
);
629 case AccessLength_BYTE
:
630 sim_core_write_aligned_1 (CPU
, NULL_CIA
,
631 write_map
, pAddr
, MemElem
);
641 INLINE_SIM_MAIN (unsigned32
)
642 ifetch32 (SIM_DESC SD
,
647 /* Copy the action of the LW instruction */
648 address_word mask
= LOADDRMASK
;
649 address_word access
= AccessLength_WORD
;
650 address_word reverseendian
= (ReverseEndian
? (mask
^ access
) : 0);
651 address_word bigendiancpu
= (BigEndianCPU
? (mask
^ access
) : 0);
657 if ((vaddr
& access
) != 0)
658 SignalExceptionInstructionFetch ();
659 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &uncached
, isTARGET
, isREAL
);
660 paddr
= ((paddr
& ~mask
) | ((paddr
& mask
) ^ reverseendian
));
661 LoadMemory (&memval
, NULL
, uncached
, access
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
662 byte
= ((vaddr
& mask
) ^ bigendiancpu
);
663 return (memval
>> (8 * byte
));
667 INLINE_SIM_MAIN (unsigned16
)
668 ifetch16 (SIM_DESC SD
,
673 /* Copy the action of the LH instruction */
674 address_word mask
= LOADDRMASK
;
675 address_word access
= AccessLength_HALFWORD
;
676 address_word reverseendian
= (ReverseEndian
? (mask
^ access
) : 0);
677 address_word bigendiancpu
= (BigEndianCPU
? (mask
^ access
) : 0);
683 if ((vaddr
& access
) != 0)
684 SignalExceptionInstructionFetch ();
685 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &uncached
, isTARGET
, isREAL
);
686 paddr
= ((paddr
& ~mask
) | ((paddr
& mask
) ^ reverseendian
));
687 LoadMemory (&memval
, NULL
, uncached
, access
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
688 byte
= ((vaddr
& mask
) ^ bigendiancpu
);
689 return (memval
>> (8 * byte
));
694 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
695 /* Order loads and stores to synchronise shared memory. Perform the
696 action necessary to make the effects of groups of synchronizable
697 loads and stores indicated by stype occur in the same order for all
699 INLINE_SIM_MAIN (void)
700 sync_operation (SIM_DESC sd
,
706 sim_io_printf(sd
,"SyncOperation(%d) : TODO\n",stype
);
711 INLINE_SIM_MAIN (void)
712 cache_op (SIM_DESC SD
,
718 unsigned int instruction
)
720 #if 1 /* stop warning message being displayed (we should really just remove the code) */
721 static int icache_warning
= 1;
722 static int dcache_warning
= 1;
724 static int icache_warning
= 0;
725 static int dcache_warning
= 0;
728 /* If CP0 is not useable (User or Supervisor mode) and the CP0
729 enable bit in the Status Register is clear - a coprocessor
730 unusable exception is taken. */
732 sim_io_printf(SD
,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia
));
736 case 0: /* instruction cache */
738 case 0: /* Index Invalidate */
739 case 1: /* Index Load Tag */
740 case 2: /* Index Store Tag */
741 case 4: /* Hit Invalidate */
743 case 6: /* Hit Writeback */
746 sim_io_eprintf(SD
,"Instruction CACHE operation %d to be coded\n",(op
>> 2));
752 SignalException(ReservedInstruction
,instruction
);
757 case 1: /* data cache */
759 case 0: /* Index Writeback Invalidate */
760 case 1: /* Index Load Tag */
761 case 2: /* Index Store Tag */
762 case 3: /* Create Dirty */
763 case 4: /* Hit Invalidate */
764 case 5: /* Hit Writeback Invalidate */
765 case 6: /* Hit Writeback */
768 sim_io_eprintf(SD
,"Data CACHE operation %d to be coded\n",(op
>> 2));
774 SignalException(ReservedInstruction
,instruction
);
779 default: /* unrecognised cache ID */
780 SignalException(ReservedInstruction
,instruction
);
788 INLINE_SIM_MAIN (void)
789 pending_tick (SIM_DESC SD
,
794 sim_io_eprintf (SD
, "PENDING_DRAIN - 0x%lx - pending_in = %d, pending_out = %d, pending_total = %d\n", (unsigned long) cia
, PENDING_IN
, PENDING_OUT
, PENDING_TOTAL
);
795 if (PENDING_OUT
!= PENDING_IN
)
798 int index
= PENDING_OUT
;
799 int total
= PENDING_TOTAL
;
800 if (PENDING_TOTAL
== 0)
801 sim_engine_abort (SD
, CPU
, cia
, "PENDING_DRAIN - Mis-match on pending update pointers\n");
802 for (loop
= 0, index
= PENDING_OUT
;
804 loop
++, index
= (index
+ 1) % PSLOTS
)
806 if (PENDING_SLOT_DEST
[index
] != NULL
)
808 PENDING_SLOT_DELAY
[index
] -= 1;
809 if (PENDING_SLOT_DELAY
[index
] == 0)
812 sim_io_eprintf (SD
, "PENDING_DRAIN - drained - index %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
814 (unsigned long) PENDING_SLOT_DEST
[index
],
815 PENDING_SLOT_BIT
[index
],
816 (unsigned long) PENDING_SLOT_VALUE
[index
],
817 PENDING_SLOT_SIZE
[index
]);
818 if (PENDING_SLOT_BIT
[index
] >= 0)
819 switch (PENDING_SLOT_SIZE
[index
])
822 if (PENDING_SLOT_VALUE
[index
])
823 *(unsigned32
*)PENDING_SLOT_DEST
[index
] |=
824 BIT32 (PENDING_SLOT_BIT
[index
]);
826 *(unsigned32
*)PENDING_SLOT_DEST
[index
] &=
827 BIT32 (PENDING_SLOT_BIT
[index
]);
830 if (PENDING_SLOT_VALUE
[index
])
831 *(unsigned64
*)PENDING_SLOT_DEST
[index
] |=
832 BIT64 (PENDING_SLOT_BIT
[index
]);
834 *(unsigned64
*)PENDING_SLOT_DEST
[index
] &=
835 BIT64 (PENDING_SLOT_BIT
[index
]);
839 switch (PENDING_SLOT_SIZE
[index
])
842 *(unsigned32
*)PENDING_SLOT_DEST
[index
] =
843 PENDING_SLOT_VALUE
[index
];
846 *(unsigned64
*)PENDING_SLOT_DEST
[index
] =
847 PENDING_SLOT_VALUE
[index
];
850 if (PENDING_OUT
== index
)
852 PENDING_SLOT_DEST
[index
] = NULL
;
853 PENDING_OUT
= (PENDING_OUT
+ 1) % PSLOTS
;
857 else if (PENDING_TRACE
&& PENDING_SLOT_DELAY
[index
] > 0)
858 sim_io_eprintf (SD
, "PENDING_DRAIN - queued - index %d, delay %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
859 index
, PENDING_SLOT_DELAY
[index
],
860 (unsigned long) PENDING_SLOT_DEST
[index
],
861 PENDING_SLOT_BIT
[index
],
862 (unsigned long) PENDING_SLOT_VALUE
[index
],
863 PENDING_SLOT_SIZE
[index
]);