Lines Matching refs:cache
1 /* frv cache model.
28 #include "cache.h"
33 frv_cache_init (SIM_CPU *cpu, FRV_CACHE *cache)
45 if (cache->configured_sets == 0)
46 cache->configured_sets = 512;
47 if (cache->configured_ways == 0)
48 cache->configured_ways = 2;
49 if (cache->line_size == 0)
50 cache->line_size = 32;
51 if (cache->memory_latency == 0)
52 cache->memory_latency = 20;
55 if (cache->configured_sets == 0)
56 cache->configured_sets = 128;
57 if (cache->configured_ways == 0)
58 cache->configured_ways = 4;
59 if (cache->line_size == 0)
60 cache->line_size = 64;
61 if (cache->memory_latency == 0)
62 cache->memory_latency = 20;
65 if (cache->configured_sets == 0)
66 cache->configured_sets = 64;
67 if (cache->configured_ways == 0)
68 cache->configured_ways = 4;
69 if (cache->line_size == 0)
70 cache->line_size = 64;
71 if (cache->memory_latency == 0)
72 cache->memory_latency = 20;
76 frv_cache_reconfigure (cpu, cache);
78 /* First allocate the cache storage based on the given dimensions. */
79 elements = cache->sets * cache->ways;
80 cache->tag_storage = (FRV_CACHE_TAG *)
81 zalloc (elements * sizeof (*cache->tag_storage));
82 cache->data_storage = (char *) xmalloc (elements * cache->line_size);
87 cache->pipeline[i].requests = NULL;
88 cache->pipeline[i].status.flush.valid = 0;
89 cache->pipeline[i].status.return_buffer.valid = 0;
90 cache->pipeline[i].status.return_buffer.data
91 = (char *) xmalloc (cache->line_size);
93 cache->pipeline[i].stages[j].request = NULL;
95 cache->BARS.valid = 0;
96 cache->NARS.valid = 0;
98 /* Now set the cache state. */
99 cache->cpu = cpu;
100 cache->statistics.accesses = 0;
101 cache->statistics.hits = 0;
105 frv_cache_term (FRV_CACHE *cache)
107 /* Free the cache storage. */
108 free (cache->tag_storage);
109 free (cache->data_storage);
110 free (cache->pipeline[LS].status.return_buffer.data);
111 free (cache->pipeline[LD].status.return_buffer.data);
114 /* Reset the cache configuration based on registers in the cpu. */
116 frv_cache_reconfigure (SIM_CPU *current_cpu, FRV_CACHE *cache)
127 if (cache == CPU_INSN_CACHE (current_cpu))
131 /* If IHSR8.ICDM is set, then the cache becomes a one way cache. */
134 cache->sets = cache->sets * cache->ways;
135 cache->ways = 1;
141 /* Set the cache to its original settings. */
142 cache->sets = cache->configured_sets;
143 cache->ways = cache->configured_ways;
148 /* Determine whether the given cache is enabled. */
150 frv_cache_enabled (FRV_CACHE *cache)
152 SIM_CPU *current_cpu = cache->cpu;
154 if (GET_HSR0_ICE (hsr0) && cache == CPU_INSN_CACHE (current_cpu))
156 if (GET_HSR0_DCE (hsr0) && cache == CPU_DATA_CACHE (current_cpu))
164 ram_access (FRV_CACHE *cache, USI address)
169 SIM_CPU *current_cpu = cache->cpu;
177 if (cache == CPU_INSN_CACHE (current_cpu))
200 the cache. */
202 non_cache_access (FRV_CACHE *cache, USI address)
206 SIM_CPU *current_cpu = cache->cpu;
215 return 1; /* non-cache access */
220 return 1; /* non-cache access */
221 if (cache == CPU_INSN_CACHE (current_cpu))
224 return 1; /* non-cache access */
227 return 1; /* non-cache access */
232 return 1; /* non-cache access */
233 if (cache == CPU_INSN_CACHE (current_cpu))
236 return 1; /* non-cache access */
239 return 1; /* non-cache access */
245 return ram_access (cache, address);
247 return 0; /* cache-access */
250 /* Find the cache line corresponding to the given address.
257 get_tag (FRV_CACHE *cache, SI address, FRV_CACHE_TAG **return_tag)
266 ++cache->statistics.accesses;
271 set = address & ~(cache->line_size - 1);
272 for (bits = cache->line_size - 1; bits != 0; bits >>= 1)
274 set &= (cache->sets - 1);
280 tag = CACHE_ADDRESS_TAG (cache, address);
281 for (way = 0; way < cache->ways; ++way)
283 found = CACHE_TAG (cache, set, way);
291 ++cache->statistics.hits;
302 write_data_to_memory (FRV_CACHE *cache, SI address, char *data, int length)
304 SIM_CPU *cpu = cache->cpu;
333 /* Write a cache line out to memory. */
335 write_line_to_memory (FRV_CACHE *cache, FRV_CACHE_TAG *tag)
338 int set = CACHE_TAG_SET_NUMBER (cache, tag);
340 for (bits = cache->line_size - 1; bits != 0; bits >>= 1)
343 write_data_to_memory (cache, address, tag->line, cache->line_size);
361 /* Fill the given cache line from memory. */
363 fill_line_from_memory (FRV_CACHE *cache, FRV_CACHE_TAG *tag, SI address)
367 SIM_CPU *current_cpu = cache->cpu;
369 /* If this line is already valid and the cache is in copy-back mode, then
376 write_line_to_memory (cache, tag);
380 int line_index = tag - cache->tag_storage;
381 tag->line = cache->data_storage + (line_index * cache->line_size);
384 line_alignment = cache->line_size - 1;
387 cache->line_size);
388 tag->tag = CACHE_ADDRESS_TAG (cache, address);
394 set_most_recently_used (FRV_CACHE *cache, FRV_CACHE_TAG *tag)
398 FRV_CACHE_TAG *item = cache->tag_storage + CACHE_TAG_SET_START (cache, tag);
399 FRV_CACHE_TAG *limit = item + cache->ways;
407 tag->lru = cache->ways; /* Mark as most recently used. */
412 set_least_recently_used (FRV_CACHE *cache, FRV_CACHE_TAG *tag)
416 FRV_CACHE_TAG *item = cache->tag_storage + CACHE_TAG_SET_START (cache, tag);
417 FRV_CACHE_TAG *limit = item + cache->ways;
432 find_or_retrieve_cache_line (FRV_CACHE *cache, SI address)
434 /* See if this data is already in the cache. */
436 int found = get_tag (cache, address, &tag);
445 fill_line_from_memory (cache, tag, address);
450 set_most_recently_used (cache, tag);
456 copy_line_to_return_buffer (FRV_CACHE *cache, int pipe, FRV_CACHE_TAG *tag,
459 /* A cache line was available for the data.
460 Copy the data from the cache line to the output buffer. */
461 memcpy (cache->pipeline[pipe].status.return_buffer.data,
462 tag->line, cache->line_size);
463 cache->pipeline[pipe].status.return_buffer.address
464 = address & ~(cache->line_size - 1);
465 cache->pipeline[pipe].status.return_buffer.valid = 1;
469 copy_memory_to_return_buffer (FRV_CACHE *cache, int pipe, SI address)
471 address &= ~(cache->line_size - 1);
472 read_data_from_memory (cache->cpu, address,
473 cache->pipeline[pipe].status.return_buffer.data,
474 cache->line_size);
475 cache->pipeline[pipe].status.return_buffer.address = address;
476 cache->pipeline[pipe].status.return_buffer.valid = 1;
480 set_return_buffer_reqno (FRV_CACHE *cache, int pipe, unsigned reqno)
482 cache->pipeline[pipe].status.return_buffer.reqno = reqno;
485 /* Read data from the given cache.
488 frv_cache_read (FRV_CACHE *cache, int pipe, SI address)
492 if (non_cache_access (cache, address))
494 copy_memory_to_return_buffer (cache, pipe, address);
498 tag = find_or_retrieve_cache_line (cache, address);
501 return 0; /* Indicate non-cache-access. */
503 /* A cache line was available for the data.
504 Copy the data from the cache line to the output buffer. */
505 copy_line_to_return_buffer (cache, pipe, tag, address);
510 /* Writes data through the given cache.
514 frv_cache_write (FRV_CACHE *cache, SI address, char *data, unsigned length)
518 /* See if this data is already in the cache. */
519 SIM_CPU *current_cpu = cache->cpu;
523 if (non_cache_access (cache, address))
525 write_data_to_memory (cache, address, data, length);
529 found = get_tag (cache, address, &tag);
531 /* Write the data to the cache line if one was available and if it is
541 fill_line_from_memory (cache, tag, address);
542 line_offset = address & (cache->line_size - 1);
547 set_most_recently_used (cache, tag);
554 write_data_to_memory (cache, address, data, length);
562 /* Preload the cache line containing the given address. Lock the
566 frv_cache_preload (FRV_CACHE *cache, SI address, USI length, int lock)
571 if (non_cache_access (cache, address))
578 cache->line_size - 1);
579 lines = 1 + (offset + length - 1) / cache->line_size;
584 FRV_CACHE_TAG *tag = find_or_retrieve_cache_line (cache, address);
587 address += cache->line_size;
593 /* Unlock the cache line containing the given address.
596 frv_cache_unlock (FRV_CACHE *cache, SI address)
601 if (non_cache_access (cache, address))
604 found = get_tag (cache, address, &tag);
613 invalidate_return_buffer (FRV_CACHE *cache, SI address)
617 address &= ~(cache->line_size - 1);
618 if (address == cache->pipeline[LS].status.return_buffer.address)
619 cache->pipeline[LS].status.return_buffer.valid = 0;
620 if (address == cache->pipeline[LD].status.return_buffer.address)
621 cache->pipeline[LD].status.return_buffer.valid = 0;
624 /* Invalidate the cache line containing the given address. Flush the
628 frv_cache_invalidate (FRV_CACHE *cache, SI address, int flush)
630 /* See if this data is already in the cache. */
634 /* Check for non-cache access. This operation is still perfromed even if
635 the cache is not currently enabled. */
636 if (non_cache_access (cache, address))
641 found = get_tag (cache, address, &tag);
647 write_line_to_memory (cache, tag);
648 set_least_recently_used (cache, tag);
652 /* If this is the insn cache, then flush the cpu's scache as well. */
653 cpu = cache->cpu;
654 if (cache == CPU_INSN_CACHE (cpu))
658 invalidate_return_buffer (cache, address);
663 /* Invalidate the entire cache. Flush the data if requested. */
665 frv_cache_invalidate_all (FRV_CACHE *cache, int flush)
667 /* See if this data is already in the cache. */
668 int elements = cache->sets * cache->ways;
669 FRV_CACHE_TAG *tag = cache->tag_storage;
677 write_line_to_memory (cache, tag);
683 /* If this is the insn cache, then flush the cpu's scache as well. */
684 cpu = cache->cpu;
685 if (cache == CPU_INSN_CACHE (cpu))
689 cache->pipeline[LS].status.return_buffer.valid = 0;
690 cache->pipeline[LD].status.return_buffer.valid = 0;
696 Functions for operating the cache in cycle accurate mode.
698 /* Convert a VLIW slot to a cache pipeline index. */
715 /* Allocate free chains of cache requests. */
735 /* Return the next free request in the queue for the given cache pipeline. */
751 /* Return the given cache request to the free chain. */
848 /* Return the priority lower than the lowest one in this cache pipeline.
851 next_priority (FRV_CACHE *cache, FRV_CACHE_PIPELINE *pipeline)
882 pipe = pipeline - cache->pipeline;
883 if (cache->BARS.valid && cache->BARS.pipe == pipe
884 && cache->BARS.priority > lowest)
885 lowest = cache->BARS.priority + 1;
886 if (cache->NARS.valid && cache->NARS.pipe == pipe
887 && cache->NARS.priority > lowest)
888 lowest = cache->NARS.priority + 1;
928 advance_pipelines (FRV_CACHE *cache)
932 FRV_CACHE_PIPELINE *pipelines = cache->pipeline;
957 frv_cache_request_load (FRV_CACHE *cache, unsigned reqno, SI address, int slot)
961 /* slot is a UNIT_*. Convert it to a cache pipeline index. */
963 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
969 req->priority = next_priority (cache, pipeline);
976 frv_cache_request_store (FRV_CACHE *cache, SI address,
981 /* slot is a UNIT_*. Convert it to a cache pipeline index. */
983 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
989 req->priority = next_priority (cache, pipeline);
995 invalidate_return_buffer (cache, address);
998 /* Handle a request to invalidate the cache line containing the given address.
1001 frv_cache_request_invalidate (FRV_CACHE *cache, unsigned reqno, SI address,
1006 /* slot is a UNIT_*. Convert it to a cache pipeline index. */
1008 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1014 req->priority = next_priority (cache, pipeline);
1022 /* Handle a request to preload the cache line containing the given address. */
1024 frv_cache_request_preload (FRV_CACHE *cache, SI address,
1029 /* slot is a UNIT_*. Convert it to a cache pipeline index. */
1031 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1037 req->priority = next_priority (cache, pipeline);
1043 invalidate_return_buffer (cache, address);
1046 /* Handle a request to unlock the cache line containing the given address. */
1048 frv_cache_request_unlock (FRV_CACHE *cache, SI address, int slot)
1052 /* slot is a UNIT_*. Convert it to a cache pipeline index. */
1054 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1060 req->priority = next_priority (cache, pipeline);
1069 address_interference (FRV_CACHE *cache, SI address, FRV_CACHE_REQUEST *req,
1073 int line_mask = ~(cache->line_size - 1);
1084 for (other_req = cache->pipeline[pipe].requests;
1096 other_req = cache->pipeline[other_pipe].stages[LAST_STAGE].request;
1109 FRV_CACHE_WAR *war = & cache->pipeline[i].WAR[j];
1123 other_req = cache->pipeline[i].stages[j].request;
1139 if (cache->BARS.valid
1140 && (address == (cache->BARS.address & line_mask)
1142 && priority > cache->BARS.priority)
1144 if (cache->NARS.valid
1145 && (address == (cache->NARS.address & line_mask)
1147 && priority > cache->NARS.priority)
1155 cache, int pipe, FRV_CACHE_REQUEST *req)
1157 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1159 if (! cache->BARS.valid)
1161 cache->BARS.pipe = pipe;
1162 cache->BARS.reqno = req->reqno;
1163 cache->BARS.address = req->address;
1164 cache->BARS.priority = req->priority - 1;
1168 cache->BARS.preload = 0;
1169 cache->BARS.lock = 0;
1172 cache->BARS.preload = 1;
1173 cache->BARS.lock = 0;
1176 cache->BARS.preload = 1;
1177 cache->BARS.lock = req->u.preload.lock;
1180 cache->BARS.valid = 1;
1183 if (! cache->NARS.valid)
1185 cache->NARS.pipe = pipe;
1186 cache->NARS.reqno = req->reqno;
1187 cache->NARS.address = req->address;
1188 cache->NARS.priority = req->priority - 1;
1192 cache->NARS.preload = 0;
1193 cache->NARS.lock = 0;
1196 cache->NARS.preload = 1;
1197 cache->NARS.lock = 0;
1200 cache->NARS.preload = 1;
1201 cache->NARS.lock = req->u.preload.lock;
1204 cache->NARS.valid = 1;
1213 wait_in_WAR (FRV_CACHE* cache, int pipe, FRV_CACHE_REQUEST *req)
1216 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1224 wait_for_WAR (cache, pipe, req);
1231 pipeline->WAR[war].latency = cache->memory_latency + 1;
1251 handle_req_load (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
1257 if (address_interference (cache, address, req, pipe))
1259 pipeline_requeue_request (& cache->pipeline[pipe]);
1263 if (frv_cache_enabled (cache) && ! non_cache_access (cache, address))
1265 int found = get_tag (cache, address, &tag);
1270 set_most_recently_used (cache, tag);
1271 copy_line_to_return_buffer (cache, pipe, tag, address);
1272 set_return_buffer_reqno (cache, pipe, req->reqno);
1277 /* The data is not in the cache or this is a non-cache access. We need to
1280 wait_in_WAR (cache, pipe, req);
1284 handle_req_preload (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
1296 if (! frv_cache_enabled (cache) || non_cache_access (cache, address))
1305 offset = address & (cache->line_size - 1);
1306 lines = 1 + (offset + length - 1) / cache->line_size;
1307 cur_address = address & ~(cache->line_size - 1);
1312 if (address_interference (cache, cur_address, req, pipe))
1314 pipeline_requeue_request (& cache->pipeline[pipe]);
1317 cur_address += cache->line_size;
1320 /* Now process each cache line. */
1323 cur_address = address & ~(cache->line_size - 1);
1327 found = get_tag (cache, cur_address, &tag);
1335 /* The data is not in the cache. We need to wait for the memory
1338 wait_in_WAR (cache, pipe, req);
1340 cur_address += cache->line_size;
1345 handle_req_store (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
1356 if (address_interference (cache, address, req, pipe))
1358 pipeline_requeue_request (& cache->pipeline[pipe]);
1362 /* Non-cache access. Write the data directly to memory. */
1363 if (! frv_cache_enabled (cache) || non_cache_access (cache, address))
1365 write_data_to_memory (cache, address, data, length);
1369 /* See if the data is in the cache. */
1370 found = get_tag (cache, address, &tag);
1372 /* Write the data to the cache line if one was available and if it is
1376 current_cpu = cache->cpu;
1386 wait_in_WAR (cache, pipe, req);
1387 pipeline_requeue_request (& cache->pipeline[pipe]);
1391 --cache->statistics.accesses;
1392 --cache->statistics.hits;
1395 line_offset = address & (cache->line_size - 1);
1397 invalidate_return_buffer (cache, address);
1401 set_most_recently_used (cache, tag);
1408 write_data_to_memory (cache, address, data, length);
1415 handle_req_invalidate (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
1417 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1422 if (address_interference (cache, interfere_address, req, pipe))
1428 /* Invalidate the cache line now. This function already checks for
1429 non-cache access. */
1431 frv_cache_invalidate_all (cache, req->u.invalidate.flush);
1433 frv_cache_invalidate (cache, address, req->u.invalidate.flush);
1443 handle_req_unlock (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
1445 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1449 if (address_interference (cache, address, req, pipe))
1455 /* Unlock the cache line. This function checks for non-cache access. */
1456 frv_cache_unlock (cache, address);
1460 handle_req_WAR (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
1465 if (frv_cache_enabled (cache) && ! non_cache_access (cache, address))
1467 /* Look for the data in the cache. The statistics of cache hit or
1469 and after obtaining the cache line. */
1470 FRV_CACHE_STATISTICS save_stats = cache->statistics;
1471 tag = find_or_retrieve_cache_line (cache, address);
1472 cache->statistics = save_stats;
1477 copy_line_to_return_buffer (cache, pipe, tag, address);
1478 set_return_buffer_reqno (cache, pipe, req->reqno);
1482 invalidate_return_buffer (cache, address);
1490 /* All cache lines in the set were locked, so just copy the data to the
1494 copy_memory_to_return_buffer (cache, pipe, address);
1495 set_return_buffer_reqno (cache, pipe, req->reqno);
1501 arbitrate_requests (FRV_CACHE *cache)
1508 = pipeline_stage_request (& cache->pipeline[pipe], LAST_STAGE);
1517 handle_req_load (cache, pipe, req);
1520 handle_req_store (cache, pipe, req);
1523 handle_req_invalidate (cache, pipe, req);
1526 handle_req_preload (cache, pipe, req);
1529 handle_req_unlock (cache, pipe, req);
1532 handle_req_WAR (cache, pipe, req);
1542 move_ARS_to_WAR (FRV_CACHE *cache, int pipe, FRV_CACHE_WAR *war)
1546 if (cache->BARS.valid && cache->BARS.pipe == pipe)
1548 war->address = cache->BARS.address;
1549 war->reqno = cache->BARS.reqno;
1550 war->priority = cache->BARS.priority;
1551 war->preload = cache->BARS.preload;
1552 war->lock = cache->BARS.lock;
1553 war->latency = cache->memory_latency + 1;
1555 if (cache->NARS.valid)
1557 cache->BARS = cache->NARS;
1558 cache->NARS.valid = 0;
1561 cache->BARS.valid = 0;
1565 if (cache->NARS.valid && cache->NARS.pipe == pipe)
1567 war->address = cache->NARS.address;
1568 war->reqno = cache->NARS.reqno;
1569 war->priority = cache->NARS.priority;
1570 war->preload = cache->NARS.preload;
1571 war->lock = cache->NARS.lock;
1572 war->latency = cache->memory_latency + 1;
1574 cache->NARS.valid = 0;
1578 /* Decrease the latencies of the various states in the cache. */
1580 decrease_latencies (FRV_CACHE *cache)
1586 FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
1599 move_ARS_to_WAR (cache, pipe, war);
1606 /* Run the cache for the given number of cycles. */
1608 frv_cache_run (FRV_CACHE *cache, int cycles)
1613 advance_pipelines (cache);
1614 arbitrate_requests (cache);
1615 decrease_latencies (cache);
1620 frv_cache_read_passive_SI (FRV_CACHE *cache, SI address, SI *value)
1625 if (non_cache_access (cache, address))
1629 FRV_CACHE_STATISTICS save_stats = cache->statistics;
1630 int found = get_tag (cache, address, &tag);
1631 cache->statistics = save_stats;
1634 return 0; /* Indicate non-cache-access. */
1637 /* A cache line was available for the data.
1639 offset = address & (cache->line_size - 1);
1644 /* Check the return buffers of the data cache to see if the requested data is
1647 frv_cache_data_in_buffer (FRV_CACHE* cache, int pipe, SI address,
1650 return cache->pipeline[pipe].status.return_buffer.valid
1651 && cache->pipeline[pipe].status.return_buffer.reqno == reqno
1652 && cache->pipeline[pipe].status.return_buffer.address <= address
1653 && cache->pipeline[pipe].status.return_buffer.address + cache->line_size
1659 frv_cache_data_flushed (FRV_CACHE* cache, int pipe, SI address, unsigned reqno)
1661 return cache->pipeline[pipe].status.flush.valid
1662 && cache->pipeline[pipe].status.flush.reqno == reqno
1663 && cache->pipeline[pipe].status.flush.address <= address
1664 && cache->pipeline[pipe].status.flush.address + cache->line_size