Build failure in sim/rx/gdb-if.c on windows
[deliverable/binutils-gdb.git] / sim / mips / sim-main.c
1 /* Copyright (C) 1998, Cygnus Solutions
2
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 3 of the License, or
6 (at your option) any later version.
7
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.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, see <http://www.gnu.org/licenses/>.
15
16 */
17
18
19 #ifndef SIM_MAIN_C
20 #define SIM_MAIN_C
21
22 #include "sim-main.h"
23 #include "sim-assert.h"
24
25
26 /*---------------------------------------------------------------------------*/
27 /*-- simulator engine -------------------------------------------------------*/
28 /*---------------------------------------------------------------------------*/
29
30
31 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
32 (revision 3.1) */
33 /* Translate a virtual address to a physical address and cache
34 coherence algorithm describing the mechanism used to resolve the
35 memory reference. Given the virtual address vAddr, and whether the
36 reference is to Instructions ot Data (IorD), find the corresponding
37 physical address (pAddr) and the cache coherence algorithm (CCA)
38 used to resolve the reference. If the virtual address is in one of
39 the unmapped address spaces the physical address and the CCA are
40 determined directly by the virtual address. If the virtual address
41 is in one of the mapped address spaces then the TLB is used to
42 determine the physical address and access type; if the required
43 translation is not present in the TLB or the desired access is not
44 permitted the function fails and an exception is taken.
45
46 NOTE: Normally (RAW == 0), when address translation fails, this
47 function raises an exception and does not return. */
48
49 INLINE_SIM_MAIN
50 (int)
51 address_translation (SIM_DESC sd,
52 sim_cpu * cpu,
53 address_word cia,
54 address_word vAddr,
55 int IorD,
56 int LorS,
57 address_word * pAddr,
58 int *CCA,
59 int raw)
60 {
61 int res = -1; /* TRUE : Assume good return */
62
63 #ifdef DEBUG
64 sim_io_printf (sd, "AddressTranslation(0x%s,%s,%s,...);\n", pr_addr (vAddr), (IorD ? "isDATA" : "isINSTRUCTION"), (LorS ? "iSTORE" : "isLOAD"));
65 #endif
66
67 /* Check that the address is valid for this memory model */
68
69 /* For a simple (flat) memory model, we simply pass virtual
70 addressess through (mostly) unchanged. */
71 vAddr &= 0xFFFFFFFF;
72
73 *pAddr = vAddr; /* default for isTARGET */
74 *CCA = Uncached; /* not used for isHOST */
75
76 return (res);
77 }
78
79
80
81 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
82 (revision 3.1) */
83 /* Prefetch data from memory. Prefetch is an advisory instruction for
84 which an implementation specific action is taken. The action taken
85 may increase performance, but must not change the meaning of the
86 program, or alter architecturally-visible state. */
87
88 INLINE_SIM_MAIN (void)
89 prefetch (SIM_DESC sd,
90 sim_cpu *cpu,
91 address_word cia,
92 int CCA,
93 address_word pAddr,
94 address_word vAddr,
95 int DATA,
96 int hint)
97 {
98 #ifdef DEBUG
99 sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
100 #endif /* DEBUG */
101
102 /* For our simple memory model we do nothing */
103 return;
104 }
105
106 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
107 (revision 3.1) */
108 /* Load a value from memory. Use the cache and main memory as
109 specified in the Cache Coherence Algorithm (CCA) and the sort of
110 access (IorD) to find the contents of AccessLength memory bytes
111 starting at physical location pAddr. The data is returned in the
112 fixed width naturally-aligned memory element (MemElem). The
113 low-order two (or three) bits of the address and the AccessLength
114 indicate which of the bytes within MemElem needs to be given to the
115 processor. If the memory access type of the reference is uncached
116 then only the referenced bytes are read from memory and valid
117 within the memory element. If the access type is cached, and the
118 data is not present in cache, an implementation specific size and
119 alignment block of memory is read and loaded into the cache to
120 satisfy a load reference. At a minimum, the block is the entire
121 memory element. */
122 INLINE_SIM_MAIN (void)
123 load_memory (SIM_DESC SD,
124 sim_cpu *CPU,
125 address_word cia,
126 uword64* memvalp,
127 uword64* memval1p,
128 int CCA,
129 unsigned int AccessLength,
130 address_word pAddr,
131 address_word vAddr,
132 int IorD)
133 {
134 uword64 value = 0;
135 uword64 value1 = 0;
136
137 #ifdef DEBUG
138 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"));
139 #endif /* DEBUG */
140
141 #if defined(WARN_MEM)
142 if (CCA != uncached)
143 sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
144 #endif /* WARN_MEM */
145
146 if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
147 {
148 /* In reality this should be a Bus Error */
149 sim_io_error (SD, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
150 AccessLength,
151 (LOADDRMASK + 1) << 3,
152 pr_addr (pAddr));
153 }
154
155 #if defined(TRACE)
156 dotrace (SD, CPU, tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
157 #endif /* TRACE */
158
159 /* Read the specified number of bytes from memory. Adjust for
160 host/target byte ordering/ Align the least significant byte
161 read. */
162
163 switch (AccessLength)
164 {
165 case AccessLength_QUADWORD:
166 {
167 unsigned_16 val = sim_core_read_aligned_16 (CPU, cia, read_map, pAddr);
168 value1 = VH8_16 (val);
169 value = VL8_16 (val);
170 break;
171 }
172 case AccessLength_DOUBLEWORD:
173 value = sim_core_read_aligned_8 (CPU, cia, read_map, pAddr);
174 break;
175 case AccessLength_SEPTIBYTE:
176 value = sim_core_read_misaligned_7 (CPU, cia, read_map, pAddr);
177 break;
178 case AccessLength_SEXTIBYTE:
179 value = sim_core_read_misaligned_6 (CPU, cia, read_map, pAddr);
180 break;
181 case AccessLength_QUINTIBYTE:
182 value = sim_core_read_misaligned_5 (CPU, cia, read_map, pAddr);
183 break;
184 case AccessLength_WORD:
185 value = sim_core_read_aligned_4 (CPU, cia, read_map, pAddr);
186 break;
187 case AccessLength_TRIPLEBYTE:
188 value = sim_core_read_misaligned_3 (CPU, cia, read_map, pAddr);
189 break;
190 case AccessLength_HALFWORD:
191 value = sim_core_read_aligned_2 (CPU, cia, read_map, pAddr);
192 break;
193 case AccessLength_BYTE:
194 value = sim_core_read_aligned_1 (CPU, cia, read_map, pAddr);
195 break;
196 default:
197 abort ();
198 }
199
200 #ifdef DEBUG
201 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
202 (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
203 #endif /* DEBUG */
204
205 /* See also store_memory. Position data in correct byte lanes. */
206 if (AccessLength <= LOADDRMASK)
207 {
208 if (BigEndianMem)
209 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
210 shifted to the most significant byte position. */
211 value <<= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
212 else
213 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
214 is already in the correct postition. */
215 value <<= ((pAddr & LOADDRMASK) * 8);
216 }
217
218 #ifdef DEBUG
219 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
220 pr_uword64(value1),pr_uword64(value));
221 #endif /* DEBUG */
222
223 *memvalp = value;
224 if (memval1p) *memval1p = value1;
225 }
226
227
228 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
229 (revision 3.1) */
230 /* Store a value to memory. The specified data is stored into the
231 physical location pAddr using the memory hierarchy (data caches and
232 main memory) as specified by the Cache Coherence Algorithm
233 (CCA). The MemElem contains the data for an aligned, fixed-width
234 memory element (word for 32-bit processors, doubleword for 64-bit
235 processors), though only the bytes that will actually be stored to
236 memory need to be valid. The low-order two (or three) bits of pAddr
237 and the AccessLength field indicates which of the bytes within the
238 MemElem data should actually be stored; only these bytes in memory
239 will be changed. */
240
241 INLINE_SIM_MAIN (void)
242 store_memory (SIM_DESC SD,
243 sim_cpu *CPU,
244 address_word cia,
245 int CCA,
246 unsigned int AccessLength,
247 uword64 MemElem,
248 uword64 MemElem1, /* High order 64 bits */
249 address_word pAddr,
250 address_word vAddr)
251 {
252 #ifdef DEBUG
253 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));
254 #endif /* DEBUG */
255
256 #if defined(WARN_MEM)
257 if (CCA != uncached)
258 sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
259 #endif /* WARN_MEM */
260
261 if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
262 sim_io_error (SD, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
263 AccessLength,
264 (LOADDRMASK + 1) << 3,
265 pr_addr(pAddr));
266
267 #if defined(TRACE)
268 dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
269 #endif /* TRACE */
270
271 #ifdef DEBUG
272 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
273 #endif /* DEBUG */
274
275 /* See also load_memory. Position data in correct byte lanes. */
276 if (AccessLength <= LOADDRMASK)
277 {
278 if (BigEndianMem)
279 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
280 shifted to the most significant byte position. */
281 MemElem >>= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
282 else
283 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
284 is already in the correct postition. */
285 MemElem >>= ((pAddr & LOADDRMASK) * 8);
286 }
287
288 #ifdef DEBUG
289 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
290 #endif /* DEBUG */
291
292 switch (AccessLength)
293 {
294 case AccessLength_QUADWORD:
295 {
296 unsigned_16 val = U16_8 (MemElem1, MemElem);
297 sim_core_write_aligned_16 (CPU, cia, write_map, pAddr, val);
298 break;
299 }
300 case AccessLength_DOUBLEWORD:
301 sim_core_write_aligned_8 (CPU, cia, write_map, pAddr, MemElem);
302 break;
303 case AccessLength_SEPTIBYTE:
304 sim_core_write_misaligned_7 (CPU, cia, write_map, pAddr, MemElem);
305 break;
306 case AccessLength_SEXTIBYTE:
307 sim_core_write_misaligned_6 (CPU, cia, write_map, pAddr, MemElem);
308 break;
309 case AccessLength_QUINTIBYTE:
310 sim_core_write_misaligned_5 (CPU, cia, write_map, pAddr, MemElem);
311 break;
312 case AccessLength_WORD:
313 sim_core_write_aligned_4 (CPU, cia, write_map, pAddr, MemElem);
314 break;
315 case AccessLength_TRIPLEBYTE:
316 sim_core_write_misaligned_3 (CPU, cia, write_map, pAddr, MemElem);
317 break;
318 case AccessLength_HALFWORD:
319 sim_core_write_aligned_2 (CPU, cia, write_map, pAddr, MemElem);
320 break;
321 case AccessLength_BYTE:
322 sim_core_write_aligned_1 (CPU, cia, write_map, pAddr, MemElem);
323 break;
324 default:
325 abort ();
326 }
327
328 return;
329 }
330
331
332 INLINE_SIM_MAIN (unsigned32)
333 ifetch32 (SIM_DESC SD,
334 sim_cpu *CPU,
335 address_word cia,
336 address_word vaddr)
337 {
338 /* Copy the action of the LW instruction */
339 address_word mask = LOADDRMASK;
340 address_word access = AccessLength_WORD;
341 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
342 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
343 unsigned int byte;
344 address_word paddr;
345 int uncached;
346 unsigned64 memval;
347
348 if ((vaddr & access) != 0)
349 SignalExceptionInstructionFetch ();
350 AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
351 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
352 LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
353 byte = ((vaddr & mask) ^ bigendiancpu);
354 return (memval >> (8 * byte));
355 }
356
357
358 INLINE_SIM_MAIN (unsigned16)
359 ifetch16 (SIM_DESC SD,
360 sim_cpu *CPU,
361 address_word cia,
362 address_word vaddr)
363 {
364 /* Copy the action of the LH instruction */
365 address_word mask = LOADDRMASK;
366 address_word access = AccessLength_HALFWORD;
367 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
368 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
369 unsigned int byte;
370 address_word paddr;
371 int uncached;
372 unsigned64 memval;
373
374 if ((vaddr & access) != 0)
375 SignalExceptionInstructionFetch ();
376 AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
377 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
378 LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
379 byte = ((vaddr & mask) ^ bigendiancpu);
380 return (memval >> (8 * byte));
381 }
382
383
384
385 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
386 /* Order loads and stores to synchronise shared memory. Perform the
387 action necessary to make the effects of groups of synchronizable
388 loads and stores indicated by stype occur in the same order for all
389 processors. */
390 INLINE_SIM_MAIN (void)
391 sync_operation (SIM_DESC sd,
392 sim_cpu *cpu,
393 address_word cia,
394 int stype)
395 {
396 #ifdef DEBUG
397 sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
398 #endif /* DEBUG */
399 return;
400 }
401
402 INLINE_SIM_MAIN (void)
403 cache_op (SIM_DESC SD,
404 sim_cpu *CPU,
405 address_word cia,
406 int op,
407 address_word pAddr,
408 address_word vAddr,
409 unsigned int instruction)
410 {
411 #if 1 /* stop warning message being displayed (we should really just remove the code) */
412 static int icache_warning = 1;
413 static int dcache_warning = 1;
414 #else
415 static int icache_warning = 0;
416 static int dcache_warning = 0;
417 #endif
418
419 /* If CP0 is not useable (User or Supervisor mode) and the CP0
420 enable bit in the Status Register is clear - a coprocessor
421 unusable exception is taken. */
422 #if 0
423 sim_io_printf(SD,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
424 #endif
425
426 switch (op & 0x3) {
427 case 0: /* instruction cache */
428 switch (op >> 2) {
429 case 0: /* Index Invalidate */
430 case 1: /* Index Load Tag */
431 case 2: /* Index Store Tag */
432 case 4: /* Hit Invalidate */
433 case 5: /* Fill */
434 case 6: /* Hit Writeback */
435 if (!icache_warning)
436 {
437 sim_io_eprintf(SD,"Instruction CACHE operation %d to be coded\n",(op >> 2));
438 icache_warning = 1;
439 }
440 break;
441
442 default:
443 SignalException(ReservedInstruction,instruction);
444 break;
445 }
446 break;
447
448 case 1: /* data cache */
449 case 3: /* secondary data cache */
450 switch (op >> 2) {
451 case 0: /* Index Writeback Invalidate */
452 case 1: /* Index Load Tag */
453 case 2: /* Index Store Tag */
454 case 3: /* Create Dirty */
455 case 4: /* Hit Invalidate */
456 case 5: /* Hit Writeback Invalidate */
457 case 6: /* Hit Writeback */
458 if (!dcache_warning)
459 {
460 sim_io_eprintf(SD,"Data CACHE operation %d to be coded\n",(op >> 2));
461 dcache_warning = 1;
462 }
463 break;
464
465 default:
466 SignalException(ReservedInstruction,instruction);
467 break;
468 }
469 break;
470
471 default: /* unrecognised cache ID */
472 SignalException(ReservedInstruction,instruction);
473 break;
474 }
475
476 return;
477 }
478
479
480 INLINE_SIM_MAIN (void)
481 pending_tick (SIM_DESC SD,
482 sim_cpu *CPU,
483 address_word cia)
484 {
485 if (PENDING_TRACE)
486 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);
487 if (PENDING_OUT != PENDING_IN)
488 {
489 int loop;
490 int index = PENDING_OUT;
491 int total = PENDING_TOTAL;
492 if (PENDING_TOTAL == 0)
493 sim_engine_abort (SD, CPU, cia, "PENDING_DRAIN - Mis-match on pending update pointers\n");
494 for (loop = 0, index = PENDING_OUT;
495 (loop < total);
496 loop++, index = (index + 1) % PSLOTS)
497 {
498 if (PENDING_SLOT_DEST[index] != NULL)
499 {
500 PENDING_SLOT_DELAY[index] -= 1;
501 if (PENDING_SLOT_DELAY[index] == 0)
502 {
503 if (PENDING_TRACE)
504 sim_io_eprintf (SD, "PENDING_DRAIN - drained - index %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
505 index,
506 (unsigned long) PENDING_SLOT_DEST[index],
507 PENDING_SLOT_BIT[index],
508 (unsigned long) PENDING_SLOT_VALUE[index],
509 PENDING_SLOT_SIZE[index]);
510 if (PENDING_SLOT_BIT[index] >= 0)
511 switch (PENDING_SLOT_SIZE[index])
512 {
513 case 4:
514 if (PENDING_SLOT_VALUE[index])
515 *(unsigned32*)PENDING_SLOT_DEST[index] |=
516 BIT32 (PENDING_SLOT_BIT[index]);
517 else
518 *(unsigned32*)PENDING_SLOT_DEST[index] &=
519 BIT32 (PENDING_SLOT_BIT[index]);
520 break;
521 case 8:
522 if (PENDING_SLOT_VALUE[index])
523 *(unsigned64*)PENDING_SLOT_DEST[index] |=
524 BIT64 (PENDING_SLOT_BIT[index]);
525 else
526 *(unsigned64*)PENDING_SLOT_DEST[index] &=
527 BIT64 (PENDING_SLOT_BIT[index]);
528 break;
529 }
530 else
531 switch (PENDING_SLOT_SIZE[index])
532 {
533 case 4:
534 *(unsigned32*)PENDING_SLOT_DEST[index] =
535 PENDING_SLOT_VALUE[index];
536 break;
537 case 8:
538 *(unsigned64*)PENDING_SLOT_DEST[index] =
539 PENDING_SLOT_VALUE[index];
540 break;
541 }
542 if (PENDING_OUT == index)
543 {
544 PENDING_SLOT_DEST[index] = NULL;
545 PENDING_OUT = (PENDING_OUT + 1) % PSLOTS;
546 PENDING_TOTAL--;
547 }
548 }
549 else if (PENDING_TRACE && PENDING_SLOT_DELAY[index] > 0)
550 sim_io_eprintf (SD, "PENDING_DRAIN - queued - index %d, delay %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
551 index, PENDING_SLOT_DELAY[index],
552 (unsigned long) PENDING_SLOT_DEST[index],
553 PENDING_SLOT_BIT[index],
554 (unsigned long) PENDING_SLOT_VALUE[index],
555 PENDING_SLOT_SIZE[index]);
556
557 }
558 }
559 }
560 }
561
562
563 #endif
This page took 0.040457 seconds and 4 git commands to generate.