? sid/include/sidblockingutil.h Index: sid/component/Makefile.am =================================================================== RCS file: /cvs/src/src/sid/component/Makefile.am,v retrieving revision 1.3 diff -c -p -r1.3 Makefile.am *** sid/component/Makefile.am 17 Jul 2001 01:42:34 -0000 1.3 --- sid/component/Makefile.am 3 May 2005 20:42:14 -0000 *************** SUBDIRS = @subdirs@ @make_subdirs@ *** 7,12 **** --- 7,17 ---- bin_SCRIPTS=siddoc + CXXFLAGS= + TOP_CXXFLAGS=$(CXXFLAGS) @comp_defs@ + AM_CXXFLAGS=$(TOP_CXXFLAGS) + AM_MAKEFLAGS= "TOP_CXXFLAGS=$(TOP_CXXFLAGS)" + all-local: chmod a+x siddoc Index: sid/component/configure.in =================================================================== RCS file: /cvs/src/src/sid/component/configure.in,v retrieving revision 1.12 diff -c -p -r1.12 configure.in *** sid/component/configure.in 24 Oct 2003 19:03:01 -0000 1.12 --- sid/component/configure.in 3 May 2005 20:42:14 -0000 *************** if test x$ac_cv_decl_socklen_t = xyes; t *** 89,94 **** --- 89,107 ---- AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define if socklen_t is declared via sys/socket.h]) fi + dnl Need extra defines for Solaris threads + case "$host" in + sparc-sun-solaris*) + # Note: If _REENTRANT isn't defined, then Solaris + # won't define thread-safe library routines. + comp_defs="-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS" + ;; + *) + comp_defs= + ;; + esac + AC_SUBST(comp_defs) + AC_SUBST(CYGWIN) dnl building docs Index: sid/component/cache/Makefile.am =================================================================== RCS file: /cvs/src/src/sid/component/cache/Makefile.am,v retrieving revision 1.4 diff -c -p -r1.4 Makefile.am *** sid/component/cache/Makefile.am 17 May 2002 21:28:14 -0000 1.4 --- sid/component/cache/Makefile.am 3 May 2005 20:42:14 -0000 *************** AUTOMAKE_OPTIONS = foreign *** 4,11 **** pkglib_LTLIBRARIES = libcache.la INCLUDES = -I. -I../../include -I$(srcdir)/../../include ! libcache_la_SOURCES = cache.cxx cache.h cacheutil.cxx cacheutil.h log2.h libcache_la_LDFLAGS = -module -no-undefined pkgdata_DATA = hw-cache.txt --- 4,17 ---- pkglib_LTLIBRARIES = libcache.la + AM_CXXFLAGS=$(TOP_CXXFLAGS) + AM_MAKEFLAGS= "TOP_CXXFLAGS=$(TOP_CXXFLAGS)" + INCLUDES = -I. -I../../include -I$(srcdir)/../../include ! EXTRA_SOURCES= ! libcache_la_SOURCES = cache.cxx cache.h \ ! $(EXTRA_SOURCES) \ ! cacheutil.cxx cacheutil.h log2.h libcache_la_LDFLAGS = -module -no-undefined pkgdata_DATA = hw-cache.txt Index: sid/component/cache/cache.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cache/cache.cxx,v retrieving revision 1.19 diff -c -p -r1.19 cache.cxx *** sid/component/cache/cache.cxx 20 Jul 2004 17:10:48 -0000 1.19 --- sid/component/cache/cache.cxx 3 May 2005 20:42:14 -0000 *************** *** 1,6 **** // cache.cxx -- A universal memory cache. -*- C++ -*- ! // Copyright (C) 2001, 2002, 2004 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,6 ---- // cache.cxx -- A universal memory cache. -*- C++ -*- ! // Copyright (C) 2001, 2002, 2004, 2005 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** cache_component::cache_component (unsign *** 73,82 **** line_size (line_sz), cache_size (cache_sz), assoc (assocy), hit_latency (0), miss_latency (0), refill_latency (0), ! refill_latency_specified (false) { acache.init (); memset (&stats, 0, sizeof (stats)); --- 73,84 ---- line_size (line_sz), cache_size (cache_sz), assoc (assocy), + data_width (4), hit_latency (0), miss_latency (0), refill_latency (0), ! refill_latency_specified (false), ! total_latency_p (false) { acache.init (); memset (&stats, 0, sizeof (stats)); *************** cache_component::cache_component (unsign *** 96,101 **** --- 98,104 ---- add_pin ("prefetch", &prefetch_pin); add_pin ("lock", &lock_pin); add_pin ("unlock", &unlock_pin); + add_pin ("operation-status", &operation_status_pin); add_attribute_ro ("cache-size", &cache_size, "setting"); add_attribute_ro ("line-size", &line_size, "setting"); *************** cache_component::cache_component (unsign *** 103,108 **** --- 106,112 ---- &cache_component::associativity, &cache_component::set_nothing, "setting"); + add_attribute ("data-width", &data_width, "setting"); add_attribute ("write-through?", &write_through_p, "setting"); add_attribute ("write-allocate?", &write_allocate_p, "setting"); *************** cache_component::cache_component (unsign *** 144,149 **** --- 148,154 ---- add_attribute ("hit-latency", &hit_latency, "setting"); add_attribute ("miss-latency", &miss_latency, "setting"); + add_attribute ("total-latency?", &total_latency_p, "setting"); add_attribute_virtual ("refill-latency", this, &cache_component::get_refill_latency, *************** cache_component::write_any (host_int_4 a *** 199,205 **** line->insert (line_offset (*line, addr), data); if (write_through_p) { ! if ((st = downstream->write (addr, data)) != bus::ok) return st; } } --- 204,217 ---- line->insert (line_offset (*line, addr), data); if (write_through_p) { ! do ! { ! st = downstream->write (addr, data); ! if (st == bus::ok) ! break; ! } ! while (handle_write_error (st, addr)); ! if (st != bus::ok) return st; } } *************** cache_component::write_any (host_int_4 a *** 224,230 **** } else { ! if ((st = downstream->write (addr, data)) != bus::ok) return st; } --- 236,249 ---- } else { ! do ! { ! st = downstream->write (addr, data); ! if (st == bus::ok) ! break; ! } ! while (handle_write_error (st, addr)); ! if (st != bus::ok) return st; } *************** cache_component::write_any (host_int_4 a *** 237,243 **** else { // write through to memory to preserve the write ! if ((st = downstream->write (addr, data)) != bus::ok) return st; } } --- 256,269 ---- else { // write through to memory to preserve the write ! do ! { ! st = downstream->write (addr, data); ! if (st == bus::ok) ! break; ! } ! while (handle_write_error (st, addr)); ! if (st != bus::ok) return st; } } *************** cache_component::read_any (host_int_4 ad *** 304,310 **** } else { ! st = downstream->read (addr, data); st.latency += miss_latency; return st; } --- 330,342 ---- } else { ! do ! { ! st = downstream->read (addr, data); ! if (st == bus::ok) ! break; ! } ! while (handle_read_error (st, addr)); st.latency += miss_latency; return st; } *************** bus::status *** 322,348 **** cache_component::read_line (cache_line& line) { bus::status st; - int overall_latency = 0; host_int_4 base = acache.tag_to_addr (line.tag ()); ! for (host_int_4 offset = 0; offset < line_size; offset += 4) ! { ! sid::big_int_4 data; ! st = downstream->read (base + offset, data); ! // Record the latency of the first read. ! if (offset == 0) ! overall_latency = st.latency; if (st != bus::ok) ! return st; ! line.insert (offset, data); } line.unlock (); line.clean (); line.validate (); ! if (refill_latency_specified) st.latency = refill_latency; else ! st.latency = overall_latency; return st; } --- 354,400 ---- cache_component::read_line (cache_line& line) { bus::status st; host_int_4 base = acache.tag_to_addr (line.tag ()); ! lock_downstream (); ! host_int_2 actual_fill_latency = 0; ! for (host_int_4 offset = 0; offset < line_size; offset += data_width) ! { ! // Unlock the downstream interface for the last read ! if (offset + data_width >= line_size) ! unlock_downstream (); ! ! sid::big_int_8 data8; ! sid::big_int_4 data4; ! host_int_4 address = base + offset; ! if (data_width == 8) ! st = read_downstream (address, data8); ! else ! st = read_downstream (address, data4); ! if (st != bus::ok) ! { ! unlock_downstream (); ! return st; ! } ! ! if (total_latency_p) ! actual_fill_latency += st.latency; ! else if (st.latency > actual_fill_latency) ! actual_fill_latency = st.latency; ! ! if (data_width == 8) ! line.insert (offset, data8); ! else ! line.insert (offset, data4); } line.unlock (); line.clean (); line.validate (); ! if (refill_latency_specified && ! total_latency_p) st.latency = refill_latency; else ! st.latency = actual_fill_latency; return st; } *************** cache_component::write_line (cache_line& *** 352,427 **** { bus::status st; host_int_4 base = acache.tag_to_addr (line.tag ()); ! for (host_int_4 offset = 0; offset < line_size; offset += 4) ! { ! sid::big_int_4 data; ! line.extract (offset, data); ! st = downstream->write (base + offset, data); if (st != bus::ok) ! return st; } line.clean (); if (LIKELY (collect_p)) stats.flushes++; return st; } void cache_component::flush_all_lines (host_int_4) { while (true) { cache_line* line = acache.find_any_dirty (); if (line == 0) break; ! (void) write_line (*line); } } void cache_component::flush_line (host_int_4 addr) { cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line && line->dirty_p ()) ! (void) write_line (*line); } void ! cache_component::flush_set (host_int_4 index) { ! if (index >= acache.num_sets ()) ! return; // bad value cache_set& set = acache [index]; for (unsigned i = 0; i < set.num_lines(); i++) { cache_line& line = set [i]; if (line.valid_p () && line.dirty_p ()) ! (void) write_line (line); } } void ! cache_component::flush_and_invalidate_set (host_int_4 index) { ! if (index >= acache.num_sets ()) ! return; // bad value cache_set& set = acache [index]; for (unsigned i = 0; i < set.num_lines(); i++) { cache_line& line = set [i]; if (line.valid_p () && line.dirty_p ()) { ! (void) write_line (line); line.invalidate (); } } } void cache_component::invalidate_all_lines (host_int_4 ignore) { acache.invalidate (); } void --- 404,561 ---- { bus::status st; host_int_4 base = acache.tag_to_addr (line.tag ()); ! lock_downstream (); ! host_int_2 actual_latency = 0; ! for (host_int_4 offset = 0; offset < line_size; offset += data_width) ! { ! // Unlock the downstream interface for the last write ! if (offset + data_width >= line_size) ! unlock_downstream (); ! ! sid::big_int_4 data4; ! sid::big_int_8 data8; ! host_int_4 address = base + offset; ! if (data_width == 8) ! { ! line.extract (offset, data8); ! st = write_downstream (address, data8); ! } ! else ! { ! line.extract (offset, data4); ! st = write_downstream (address, data4); ! } ! if (st != bus::ok) ! { ! unlock_downstream (); ! return st; ! } ! ! if (total_latency_p) ! actual_latency += st.latency; ! else if (st.latency > actual_latency) ! actual_latency = st.latency; } line.clean (); if (LIKELY (collect_p)) stats.flushes++; + st.latency = actual_latency; + return st; + } + + template + bus::status + cache_component::read_downstream (host_int_4 address, DataType &data) + { + bus::status st; + do + { + st = downstream->read (address, data); + if (st == bus::ok) + break; + } + while (handle_read_error (st, address)); + return st; + } + + template + bus::status + cache_component::write_downstream (host_int_4 address, DataType data) + { + bus::status st; + do + { + st = downstream->write (address, data); + if (st == bus::ok) + break; + } + while (handle_write_error (st, address)); return st; } void cache_component::flush_all_lines (host_int_4) { + host_int_2 total_latency = 0; + bus::status st; while (true) { cache_line* line = acache.find_any_dirty (); if (line == 0) break; ! st = write_line (*line); ! if (st != bus::ok) ! break; ! total_latency += st.latency; } + st.latency = total_latency; + report_status (st); } void cache_component::flush_line (host_int_4 addr) { + bus::status st; cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line && line->dirty_p ()) ! st = write_line (*line); ! report_status (st); } void ! cache_component::flush_set (host_int_4 addr) { ! host_int_4 index = acache.addr_to_index (addr); ! assert (index < acache.num_sets ()); + host_int_2 total_latency = 0; + bus::status st; cache_set& set = acache [index]; for (unsigned i = 0; i < set.num_lines(); i++) { cache_line& line = set [i]; if (line.valid_p () && line.dirty_p ()) ! { ! st = write_line (line); ! if (st != bus::ok) ! break; ! total_latency += st.latency; ! } } + st.latency = total_latency; + report_status (st); } void ! cache_component::flush_and_invalidate_set (host_int_4 addr) { ! host_int_4 index = acache.addr_to_index (addr); ! assert (index < acache.num_sets ()); + host_int_2 total_latency = 0; + bus::status st; cache_set& set = acache [index]; for (unsigned i = 0; i < set.num_lines(); i++) { cache_line& line = set [i]; if (line.valid_p () && line.dirty_p ()) { ! st = write_line (line); ! if (st != bus::ok) ! break; ! total_latency += st.latency; line.invalidate (); } } + st.latency = total_latency; + report_status (st); } void cache_component::invalidate_all_lines (host_int_4 ignore) { acache.invalidate (); + report_status (bus::ok); } void *************** cache_component::invalidate_line (host_i *** 430,435 **** --- 564,570 ---- cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line) line->invalidate (); + report_status (bus::ok); } void *************** cache_component::flush_and_invalidate_li *** 438,459 **** cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line && line->dirty_p ()) { ! (void) write_line (*line); line->invalidate (); } } void ! cache_component::invalidate_set (host_int_4 set) { acache.invalidate (set); } void cache_component::prefetch_line (host_int_4 addr) { sid::big_int_1 dummy; ! (void) read_any (addr, dummy); } void --- 573,600 ---- cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line && line->dirty_p ()) { ! bus::status st = write_line (*line); line->invalidate (); + report_status (st); + return; } + report_status (bus::ok); } void ! cache_component::invalidate_set (host_int_4 addr) { + host_int_4 set = acache.addr_to_index (addr); acache.invalidate (set); + report_status (bus::ok); } void cache_component::prefetch_line (host_int_4 addr) { sid::big_int_1 dummy; ! bus::status st = read_any (addr, dummy); ! report_status (st); } void *************** cache_component::lock_line (host_int_4 a *** 462,467 **** --- 603,609 ---- cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line) line->lock (); + report_status (bus::ok); } void *************** cache_component::unlock_line (host_int_4 *** 470,475 **** --- 612,618 ---- cache_line* line = acache.find (acache.addr_to_tag (addr)); if (line) line->unlock (); + report_status (bus::ok); } void *************** cache_component::write_hit_rate () *** 586,591 **** --- 729,931 ---- } } + // ------------------------------------------------------------------------ + // The blocking cache component. + + // This function is the root of the blockable child thread. It gets passed + // to pthread_create. + // + extern "C" void * + blocking_cache_child_thread_root (void *comp) + { + // Set up this thread to receive and handle signals from the parent thread. + // this need only be done once. + // + blocking_cache_component *cache = static_cast(comp); + cache->child_init (); + + for (;;) + { + // Signal completion and wait for the signal to resume + cache->child_completed (); + + // Now perform the transaction + cache->perform_transaction (); + } + + // We should never reach here. + return NULL; + } + + blocking_cache_component::blocking_cache_component (unsigned assocy, + unsigned cache_sz, + unsigned line_sz, + cache_replacement_algorithm& replacer, + cache_line_factory& factory) + :cache_component (assocy, cache_sz, line_sz, replacer, factory), + blocking_component (this, blocking_cache_child_thread_root) + { + add_pin ("downstream-lock", & downstream_lock_pin); + downstream_lock_pin.set_active_high (); + } + + blocking_cache_component::blocking_cache_component (void *child_self, + unsigned assocy, + unsigned cache_sz, + unsigned line_sz, + cache_replacement_algorithm& replacer, + cache_line_factory& factory) + :cache_component (assocy, cache_sz, line_sz, replacer, factory), + blocking_component (child_self, blocking_cache_child_thread_root) + { + add_pin ("downstream-lock", & downstream_lock_pin); + downstream_lock_pin.set_active_high (); + } + + // Handles bus errors from reads and writes from/to insn and data memory. + // Specifically, bus::busy is handled in blockable mode. + // + bool + blocking_cache_component::handle_bus_error (bus::status s) + { + if (s != bus::busy) + return false; // not handled + + // Signal that we're blocked and wait for the signal to try again + transaction_status = s; + child_blocked (); + return true; + } + + #define DEFN_METHOD(DataType) \ + bus::status \ + blocking_cache_component::write(host_int_4 addr, DataType data) \ + { \ + if (blockable) \ + { \ + /* Signal the child thread to resume */ \ + need_child_thread (); \ + setup_write_transaction (addr, data); \ + continue_child_thread_and_wait (); \ + \ + return transaction_status; \ + } \ + return this->write_any(addr, data); \ + } \ + bus::status \ + blocking_cache_component::read(host_int_4 addr, DataType& data) \ + { \ + if (blockable) \ + { \ + /* Signal the child thread to resume */ \ + need_child_thread (); \ + setup_read_transaction (addr, data); \ + continue_child_thread_and_wait (); \ + \ + get_transaction_data (data); \ + return transaction_status; \ + } \ + return this->read_any(addr, data); \ + } + DEFN_METHOD (big_int_1) + DEFN_METHOD (big_int_2) + DEFN_METHOD (big_int_4) + DEFN_METHOD (big_int_8) + DEFN_METHOD (little_int_1) + DEFN_METHOD (little_int_2) + DEFN_METHOD (little_int_4) + DEFN_METHOD (little_int_8) + #undef DEFN_METHOD + + void + blocking_cache_component::flush_all_lines (host_int_4 v) + { + if (blockable) + { + // Signal the child thread to resume + need_child_thread (); + setup_flush_all_transaction (); + int signal = continue_child_thread_and_wait (); + if (signal == ctl_child_blocked) + report_status (transaction_status); + return; + } + cache_component::flush_all_lines (v); + } + + void + blocking_cache_component::flush_line (host_int_4 addr) + { + if (blockable) + { + // Signal the child thread to resume + need_child_thread (); + setup_flush_line_transaction (addr); + int signal = continue_child_thread_and_wait (); + if (signal == ctl_child_blocked) + report_status (transaction_status); + return; + } + cache_component::flush_line (addr); + } + + void + blocking_cache_component::flush_set (host_int_4 addr) + { + if (blockable) + { + // Signal the child thread to resume + need_child_thread (); + setup_flush_set_transaction (addr); + int signal = continue_child_thread_and_wait (); + if (signal == ctl_child_blocked) + report_status (transaction_status); + return; + } + cache_component::flush_set (addr); + } + + void + blocking_cache_component::flush_and_invalidate_set (host_int_4 addr) + { + if (blockable) + { + // Signal the child thread to resume + need_child_thread (); + setup_flush_and_invalidate_set_transaction (addr); + int signal = continue_child_thread_and_wait (); + if (signal == ctl_child_blocked) + report_status (transaction_status); + return; + } + cache_component::flush_and_invalidate_set (addr); + } + + void + blocking_cache_component::flush_and_invalidate_line (host_int_4 addr) + { + if (blockable) + { + // Signal the child thread to resume + need_child_thread (); + setup_flush_and_invalidate_line_transaction (addr); + int signal = continue_child_thread_and_wait (); + if (signal == ctl_child_blocked) + report_status (transaction_status); + return; + } + cache_component::flush_and_invalidate_line (addr); + } + + void + blocking_cache_component::prefetch_line (host_int_4 addr) + { + sid::big_int_1 dummy; + bus::status st = read (addr, dummy); + report_status (st); + } + + cache_line * cache_replacement_fifo::expell (cache_set& cset) { *************** CacheListTypes () *** 715,721 **** --- 1055,1063 ---- vector types; types.push_back ("hw-cache-basic"); + types.push_back ("hw-blocking-cache-basic"); types.push_back ("hw-cache-buffer-8"); + types.push_back ("hw-blocking-cache-buffer-8"); for (unsigned i = 0; i < (sizeof (assocs) / sizeof (string)); i++) for (unsigned j = 0; j < (sizeof (cache_sizes) / sizeof (string)); j++) *************** CacheListTypes () *** 723,743 **** { if (assocs[i] == "direct") { ! type = string ("hw-cache-direct/"); ! type += cache_sizes[j] + "kb/"; type += line_sizes[k]; ! types.push_back (type); } else for (unsigned m = 0; m < (sizeof (replacement_algorithms) / sizeof (string)); m++) { ! type = string ("hw-cache-"); ! type += assocs[i] + "/"; type += cache_sizes[j] + "kb/"; type += line_sizes[k] + "/"; type += replacement_algorithms[m]; ! types.push_back (type); } } return types; --- 1065,1085 ---- { if (assocs[i] == "direct") { ! type = cache_sizes[j] + "kb/"; type += line_sizes[k]; ! types.push_back ("hw-cache-direct/" + type); ! types.push_back ("hw-blocking-cache-direct/" + type); } else for (unsigned m = 0; m < (sizeof (replacement_algorithms) / sizeof (string)); m++) { ! type = assocs[i] + "/"; type += cache_sizes[j] + "kb/"; type += line_sizes[k] + "/"; type += replacement_algorithms[m]; ! types.push_back ("hw-cache-" + type); ! types.push_back ("hw-blocking-cache-" + type); } } return types; *************** CacheCreate (const string& typeName) *** 752,766 **** if (typeName == "hw-cache-basic") return new cache_component (1, 16384, 32, null_replacement, internal_line_factory); if (typeName == "hw-cache-buffer-8") return new cache_component (0, 8, 8, null_replacement, internal_line_factory); vector parts = sidutil::tokenize (typeName, "-/"); ! if (parts.size () < 5 || parts[0] != "hw" || parts[1] != "cache") return 0; ! string assoc_string = parts[2]; for (match = false, i = 0; i < sizeof (assocs) / sizeof (string); i++) if (assoc_string == assocs[i]) match = true; --- 1094,1119 ---- if (typeName == "hw-cache-basic") return new cache_component (1, 16384, 32, null_replacement, internal_line_factory); + if (typeName == "hw-blocking-cache-basic") + return new blocking_cache_component (1, 16384, 32, null_replacement, internal_line_factory); + if (typeName == "hw-cache-buffer-8") return new cache_component (0, 8, 8, null_replacement, internal_line_factory); + if (typeName == "hw-blocking-cache-buffer-8") + return new blocking_cache_component (0, 8, 8, null_replacement, internal_line_factory); + vector parts = sidutil::tokenize (typeName, "-/"); ! unsigned extra_ix; ! if (parts.size () >= 5 && parts[0] == "hw" && parts[1] == "cache") ! extra_ix = 0; ! else if (parts.size () >= 6 && parts[0] == "hw" && parts[1] == "blocking" && parts[2] == "cache") ! extra_ix = 1; ! else return 0; ! string assoc_string = parts[2 + extra_ix]; for (match = false, i = 0; i < sizeof (assocs) / sizeof (string); i++) if (assoc_string == assocs[i]) match = true; *************** CacheCreate (const string& typeName) *** 770,776 **** // Parse "kb", where is a positive integer. int cache_sz; ! string cache_size_string = parts[3].substr (0, parts[3].length() - 2); for (match = false, i = 0; i < sizeof (cache_sizes) / sizeof (string); i++) if (cache_size_string == cache_sizes[i]) { --- 1123,1129 ---- // Parse "kb", where is a positive integer. int cache_sz; ! string cache_size_string = parts[3 + extra_ix].substr (0, parts[3 + extra_ix].length() - 2); for (match = false, i = 0; i < sizeof (cache_sizes) / sizeof (string); i++) if (cache_size_string == cache_sizes[i]) { *************** CacheCreate (const string& typeName) *** 782,788 **** return 0; int line_sz; ! string line_size_string = parts[4]; for (match = false, i = 0; i < sizeof (line_sizes) / sizeof (string); i++) if (line_size_string == line_sizes[i]) { --- 1135,1141 ---- return 0; int line_sz; ! string line_size_string = parts[4 + extra_ix]; for (match = false, i = 0; i < sizeof (line_sizes) / sizeof (string); i++) if (line_size_string == line_sizes[i]) { *************** CacheCreate (const string& typeName) *** 795,805 **** string replace_alg_string; if (assoc_string != "direct") ! if (parts.size () < 6) return 0; else { ! replace_alg_string = parts[5]; for (match = false, i = 0; i < sizeof (replacement_algorithms) / sizeof (string); i++) if (replace_alg_string == replacement_algorithms[i]) match = true; --- 1148,1158 ---- string replace_alg_string; if (assoc_string != "direct") ! if (parts.size () + extra_ix < 6) return 0; else { ! replace_alg_string = parts[5 + extra_ix]; for (match = false, i = 0; i < sizeof (replacement_algorithms) / sizeof (string); i++) if (replace_alg_string == replacement_algorithms[i]) match = true; *************** CacheCreate (const string& typeName) *** 823,837 **** return 0; } ! if (assoc == 1) ! return new cache_component (assoc, cache_sz, line_sz, null_replacement, internal_line_factory); ! if (replace_alg_string == "lru") ! return new cache_component (assoc, cache_sz, line_sz, lru_replacement, internal_line_factory); ! else if (replace_alg_string == "fifo") ! return new cache_component (assoc, cache_sz, line_sz, fifo_replacement, internal_line_factory); ! else if (replace_alg_string == "random") ! return new cache_component (assoc, cache_sz, line_sz, random_replacement, internal_line_factory); return 0; } --- 1176,1205 ---- return 0; } ! if (extra_ix == 0) ! { ! if (assoc == 1) ! return new cache_component (assoc, cache_sz, line_sz, null_replacement, internal_line_factory); ! ! if (replace_alg_string == "lru") ! return new cache_component (assoc, cache_sz, line_sz, lru_replacement, internal_line_factory); ! else if (replace_alg_string == "fifo") ! return new cache_component (assoc, cache_sz, line_sz, fifo_replacement, internal_line_factory); ! else if (replace_alg_string == "random") ! return new cache_component (assoc, cache_sz, line_sz, random_replacement, internal_line_factory); ! } ! else ! { ! if (assoc == 1) ! return new blocking_cache_component (assoc, cache_sz, line_sz, null_replacement, internal_line_factory); ! if (replace_alg_string == "lru") ! return new blocking_cache_component (assoc, cache_sz, line_sz, lru_replacement, internal_line_factory); ! else if (replace_alg_string == "fifo") ! return new blocking_cache_component (assoc, cache_sz, line_sz, fifo_replacement, internal_line_factory); ! else if (replace_alg_string == "random") ! return new blocking_cache_component (assoc, cache_sz, line_sz, random_replacement, internal_line_factory); ! } return 0; } Index: sid/component/cache/cache.h =================================================================== RCS file: /cvs/src/src/sid/component/cache/cache.h,v retrieving revision 1.10 diff -c -p -r1.10 cache.h *** sid/component/cache/cache.h 29 Apr 2004 20:26:08 -0000 1.10 --- sid/component/cache/cache.h 3 May 2005 20:42:14 -0000 *************** *** 7,30 **** #ifndef CACHE_H #define CACHE_H #include "cacheutil.h" using std::string; using std::vector; ! using sid::bus; ! using sid::component; ! using sid::host_int_2; ! using sid::host_int_4; using sidutil::fixed_attribute_map_component; using sidutil::fixed_bus_map_component; using sidutil::fixed_pin_map_component; using sidutil::fixed_accessor_map_component; using sidutil::no_relation_component; using sidutil::callback_pin; using sidutil::make_attribute; using sidutil::parse_attribute; class cache_component; class cache_bus: public bus --- 7,31 ---- #ifndef CACHE_H #define CACHE_H + #include "sidblockingutil.h" #include "cacheutil.h" using std::string; using std::vector; ! using namespace sid; using sidutil::fixed_attribute_map_component; using sidutil::fixed_bus_map_component; using sidutil::fixed_pin_map_component; using sidutil::fixed_accessor_map_component; using sidutil::no_relation_component; + using sidutil::blocking_component; using sidutil::callback_pin; using sidutil::make_attribute; using sidutil::parse_attribute; + using sidutil::binary_output_pin; + using sidutil::output_pin; class cache_component; class cache_bus: public bus *************** private: *** 46,59 **** bus::status write(host_int_4 addr, DataType data) throw (); \ bus::status read(host_int_4 addr, DataType& data) throw (); ! DEFN_METHOD (sid::big_int_1) ! DEFN_METHOD (sid::big_int_2) ! DEFN_METHOD (sid::big_int_4) ! DEFN_METHOD (sid::big_int_8) ! DEFN_METHOD (sid::little_int_1) ! DEFN_METHOD (sid::little_int_2) ! DEFN_METHOD (sid::little_int_4) ! DEFN_METHOD (sid::little_int_8) #undef DEFN_METHOD }; --- 47,60 ---- bus::status write(host_int_4 addr, DataType data) throw (); \ bus::status read(host_int_4 addr, DataType& data) throw (); ! DEFN_METHOD (big_int_1) ! DEFN_METHOD (big_int_2) ! DEFN_METHOD (big_int_4) ! DEFN_METHOD (big_int_8) ! DEFN_METHOD (little_int_1) ! DEFN_METHOD (little_int_2) ! DEFN_METHOD (little_int_4) ! DEFN_METHOD (little_int_8) #undef DEFN_METHOD }; *************** public: *** 98,106 **** class cache_component: public virtual component, ! protected fixed_attribute_map_component, protected fixed_bus_map_component, ! protected fixed_pin_map_component, protected fixed_accessor_map_component, protected no_relation_component { --- 99,107 ---- class cache_component: public virtual component, ! protected virtual fixed_attribute_map_component, protected fixed_bus_map_component, ! protected virtual fixed_pin_map_component, protected fixed_accessor_map_component, protected no_relation_component { *************** public: *** 111,116 **** --- 112,131 ---- virtual ~cache_component () throw(); + #define DEFN_METHOD(DataType) \ + virtual bus::status write(host_int_4 addr, DataType data) { return this->write_any(addr, data); } \ + virtual bus::status read(host_int_4 addr, DataType& data) { return this->read_any(addr, data); } + DEFN_METHOD (big_int_1) + DEFN_METHOD (big_int_2) + DEFN_METHOD (big_int_4) + DEFN_METHOD (big_int_8) + DEFN_METHOD (little_int_1) + DEFN_METHOD (little_int_2) + DEFN_METHOD (little_int_4) + DEFN_METHOD (little_int_8) + #undef DEFN_METHOD + + protected: template bus::status write_any (host_int_4 addr, DataType data); *************** protected: *** 127,168 **** void emit_report (host_int_4 ignore); callback_pin flush_all_pin; ! void flush_all_lines (host_int_4 ignore); callback_pin flush_pin; ! void flush_line (host_int_4 addr); callback_pin flush_set_pin; ! void flush_set (host_int_4 set); callback_pin flush_and_invalidate_set_pin; ! void flush_and_invalidate_set (host_int_4 set); callback_pin invalidate_all_pin; ! void invalidate_all_lines (host_int_4 ignore); callback_pin invalidate_pin; ! void invalidate_line (host_int_4 addr); callback_pin flush_and_invalidate_pin; ! void flush_and_invalidate_line (host_int_4 addr); callback_pin invalidate_set_pin; ! void invalidate_set (host_int_4 set); callback_pin prefetch_pin; ! void prefetch_line (host_int_4 addr); callback_pin lock_pin; ! void lock_line (host_int_4 addr); callback_pin unlock_pin; ! void unlock_line (host_int_4 addr); string read_hit_rate (); string write_hit_rate (); string get_nothing () { return ""; } ! status set_nothing (const string& ignore) { return sid::component::ok; } string associativity (); status dump (const string& ignore); string get_hash_mask (); --- 142,191 ---- void emit_report (host_int_4 ignore); callback_pin flush_all_pin; ! virtual void flush_all_lines (host_int_4 ignore); callback_pin flush_pin; ! virtual void flush_line (host_int_4 addr); callback_pin flush_set_pin; ! virtual void flush_set (host_int_4 set); callback_pin flush_and_invalidate_set_pin; ! virtual void flush_and_invalidate_set (host_int_4 set); callback_pin invalidate_all_pin; ! virtual void invalidate_all_lines (host_int_4 ignore); callback_pin invalidate_pin; ! virtual void invalidate_line (host_int_4 addr); callback_pin flush_and_invalidate_pin; ! virtual void flush_and_invalidate_line (host_int_4 addr); callback_pin invalidate_set_pin; ! virtual void invalidate_set (host_int_4 set); callback_pin prefetch_pin; ! virtual void prefetch_line (host_int_4 addr); callback_pin lock_pin; ! virtual void lock_line (host_int_4 addr); callback_pin unlock_pin; ! virtual void unlock_line (host_int_4 addr); ! ! // Completion status for the above operations ! output_pin operation_status_pin; ! void report_status (bus::status st) ! { ! host_int_4 v = (st.latency << 16) | st.code; ! operation_status_pin.drive (v); ! } string read_hit_rate (); string write_hit_rate (); string get_nothing () { return ""; } ! status set_nothing (const string& ignore) { return component::ok; } string associativity (); status dump (const string& ignore); string get_hash_mask (); *************** protected: *** 177,182 **** --- 200,215 ---- bus::status read_line (cache_line& line); bus::status write_line (cache_line& line); + template bus::status read_downstream (host_int_4 address, DataType &data); + template bus::status write_downstream (host_int_4 address, DataType data); + + // Handle read/write errors. The default is not to handle them. + virtual bool handle_read_error (bus::status s, host_int_4 &addr) { return false; } + virtual bool handle_write_error (bus::status s, host_int_4 &addr) { return false; } + + virtual void lock_downstream () { } + virtual void unlock_downstream () { } + bool write_allocate_p; bool write_through_p; bool collect_p; *************** protected: *** 198,236 **** unsigned line_size; unsigned cache_size; unsigned assoc; host_int_2 hit_latency; host_int_2 miss_latency; host_int_2 refill_latency; bool refill_latency_specified; }; template bus::status cache_bus::write_any (host_int_4 addr, DataType data) { ! return cache.write_any (addr, data); } template bus::status cache_bus::read_any (host_int_4 addr, DataType& data) { ! return cache.read_any (addr, data); } #define DEFN_METHOD(DataType) \ inline bus::status cache_bus::write(host_int_4 addr, DataType data) throw () { return this->write_any(addr, data); } \ inline bus::status cache_bus::read(host_int_4 addr, DataType& data) throw () { return this->read_any(addr, data); } ! DEFN_METHOD (sid::big_int_1) ! DEFN_METHOD (sid::big_int_2) ! DEFN_METHOD (sid::big_int_4) ! DEFN_METHOD (sid::big_int_8) ! DEFN_METHOD (sid::little_int_1) ! DEFN_METHOD (sid::little_int_2) ! DEFN_METHOD (sid::little_int_4) ! DEFN_METHOD (sid::little_int_8) #undef DEFN_METHOD #endif // CACHE_H --- 231,407 ---- unsigned line_size; unsigned cache_size; unsigned assoc; + unsigned data_width; host_int_2 hit_latency; host_int_2 miss_latency; host_int_2 refill_latency; bool refill_latency_specified; + bool total_latency_p; }; template bus::status cache_bus::write_any (host_int_4 addr, DataType data) { ! return cache.write (addr, data); } template bus::status cache_bus::read_any (host_int_4 addr, DataType& data) { ! return cache.read (addr, data); } #define DEFN_METHOD(DataType) \ inline bus::status cache_bus::write(host_int_4 addr, DataType data) throw () { return this->write_any(addr, data); } \ inline bus::status cache_bus::read(host_int_4 addr, DataType& data) throw () { return this->read_any(addr, data); } ! DEFN_METHOD (big_int_1) ! DEFN_METHOD (big_int_2) ! DEFN_METHOD (big_int_4) ! DEFN_METHOD (big_int_8) ! DEFN_METHOD (little_int_1) ! DEFN_METHOD (little_int_2) ! DEFN_METHOD (little_int_4) ! DEFN_METHOD (little_int_8) ! #undef DEFN_METHOD ! ! // This cache component handles bus::busy from downstream by blocking on ! // and waiting to retry. ! // ! class blocking_cache_component : ! public cache_component, public blocking_component ! { ! public: ! // For use when constructing directly ! blocking_cache_component (unsigned asoctvty, unsigned cache_sz, ! unsigned line_sz, ! cache_replacement_algorithm& replacer, ! cache_line_factory &line_factory); ! // For use by constructor of derived class ! blocking_cache_component (void *child_self, ! unsigned asoctvty, unsigned cache_sz, ! unsigned line_sz, ! cache_replacement_algorithm& replacer, ! cache_line_factory &line_factory); ! ! virtual ~blocking_cache_component () throw() {} ! ! #define DEFN_METHOD(DataType) \ ! virtual bus::status write(host_int_4 addr, DataType data); \ ! virtual bus::status read(host_int_4 addr, DataType& data); ! DEFN_METHOD (big_int_1) ! DEFN_METHOD (big_int_2) ! DEFN_METHOD (big_int_4) ! DEFN_METHOD (big_int_8) ! DEFN_METHOD (little_int_1) ! DEFN_METHOD (little_int_2) ! DEFN_METHOD (little_int_4) ! DEFN_METHOD (little_int_8) ! #undef DEFN_METHOD ! ! protected: ! // Virtual overrides ! virtual void flush_all_lines (host_int_4 ignore); ! virtual void flush_line (host_int_4 addr); ! virtual void flush_set (host_int_4 set); ! virtual void flush_and_invalidate_set (host_int_4 set); ! virtual void flush_and_invalidate_line (host_int_4 addr); ! virtual void prefetch_line (host_int_4 addr); ! ! protected: ! // Handle read/write errors. ! virtual bool handle_read_error (bus::status s, host_int_4 &addr) ! { return handle_bus_error (s); } ! virtual bool handle_write_error (bus::status s, host_int_4 &addr) ! { return handle_bus_error (s); } ! ! // Common function handles both read and write errors ! bool handle_bus_error (bus::status s); ! ! // Performing transactions on the child thread ! public: ! void perform_transaction () { (this->*transaction_func) (); } ! protected: ! host_int_4 transaction_addr; ! bus::status transaction_status; ! void (blocking_cache_component::*transaction_func)(); ! ! #define DEFN_METHOD(DataType) \ ! DataType transaction_data##DataType; \ ! void setup_read_transaction (host_int_4 addr, const DataType &data) \ ! { transaction_addr = addr; \ ! transaction_func = & blocking_cache_component::perform_read_transaction##DataType; \ ! } \ ! void setup_write_transaction (host_int_4 addr, const DataType &data) \ ! { transaction_addr = addr; \ ! transaction_data##DataType = data; \ ! transaction_func = & blocking_cache_component::perform_write_transaction##DataType; \ ! } \ ! void perform_read_transaction##DataType () \ ! { transaction_status = cache_component::read (transaction_addr, transaction_data##DataType); } \ ! void perform_write_transaction##DataType () \ ! { transaction_status = cache_component::write (transaction_addr, transaction_data##DataType); } \ ! void get_transaction_data (DataType &data) { data = transaction_data##DataType; } ! ! DEFN_METHOD (big_int_1) ! DEFN_METHOD (big_int_2) ! DEFN_METHOD (big_int_4) ! DEFN_METHOD (big_int_8) ! DEFN_METHOD (little_int_1) ! DEFN_METHOD (little_int_2) ! DEFN_METHOD (little_int_4) ! DEFN_METHOD (little_int_8) #undef DEFN_METHOD + protected: + // Setup methods for blockable transactions + // + void setup_flush_all_transaction () + { + transaction_func = & blocking_cache_component::perform_flush_all_transaction; + } + void setup_flush_line_transaction (host_int_4 addr) + { + transaction_addr = addr; + transaction_func = & blocking_cache_component::perform_flush_line_transaction; + } + void setup_flush_set_transaction (host_int_4 index) + { + transaction_addr = index; + transaction_func = & blocking_cache_component::perform_flush_set_transaction; + } + void setup_flush_and_invalidate_set_transaction (host_int_4 index) + { + transaction_addr = index; + transaction_func = & blocking_cache_component::perform_flush_and_invalidate_set_transaction; + } + void setup_flush_and_invalidate_line_transaction (host_int_4 addr) + { + transaction_addr = addr; + transaction_func = & blocking_cache_component::perform_flush_and_invalidate_line_transaction; + } + + protected: + // Work methods for blockable transactions + // + void perform_flush_all_transaction () + { cache_component::flush_all_lines (transaction_addr); } + void perform_flush_line_transaction () + { cache_component::flush_line (transaction_addr); } + void perform_flush_set_transaction () + { cache_component::flush_set (transaction_addr); } + void perform_flush_and_invalidate_set_transaction () + { cache_component::flush_and_invalidate_set (transaction_addr); } + void perform_flush_and_invalidate_line_transaction () + { cache_component::flush_and_invalidate_line (transaction_addr); } + + protected: + binary_output_pin downstream_lock_pin; + virtual void lock_downstream () { downstream_lock_pin.on (); } + virtual void unlock_downstream () { downstream_lock_pin.off (); } + }; + #endif // CACHE_H Index: sid/component/cache/cacheutil.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cache/cacheutil.cxx,v retrieving revision 1.10 diff -c -p -r1.10 cacheutil.cxx *** sid/component/cache/cacheutil.cxx 20 Jul 2004 17:10:48 -0000 1.10 --- sid/component/cache/cacheutil.cxx 3 May 2005 20:42:14 -0000 *************** *** 1,6 **** // cacheutil.cxx -- Helper classes for a generic memory cache. -*- C++ -*- ! // Copyright (C) 2001, 2002, 2004 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,6 ---- // cacheutil.cxx -- Helper classes for a generic memory cache. -*- C++ -*- ! // Copyright (C) 2001, 2002, 2004, 2005 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** cache::addr_to_tag (const sid::host_int_ *** 289,294 **** --- 289,300 ---- return addr >> num_non_tag_bits; } + unsigned + cache::addr_to_index (const sid::host_int_4& addr) const + { + return hash_fn (addr_to_tag (addr)); + } + sid::host_int_4 cache::tag_to_addr (const cache_tag& tag) const { Index: sid/component/cache/cacheutil.h =================================================================== RCS file: /cvs/src/src/sid/component/cache/cacheutil.h,v retrieving revision 1.7 diff -c -p -r1.7 cacheutil.h *** sid/component/cache/cacheutil.h 29 Apr 2004 20:26:08 -0000 1.7 --- sid/component/cache/cacheutil.h 3 May 2005 20:42:15 -0000 *************** *** 1,6 **** // cacheutil.h -- Helper classes for a generic memory cache. -*- C++ -*- ! // Copyright (C) 2001, 2002, 2004 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,6 ---- // cacheutil.h -- Helper classes for a generic memory cache. -*- C++ -*- ! // Copyright (C) 2001, 2002, 2004, 2005 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** public: *** 270,275 **** --- 270,278 ---- // Calculate a tag. cache_tag addr_to_tag (const sid::host_int_4& addr) const; + // Calculate a set index. + unsigned addr_to_index (const sid::host_int_4& addr) const; + // Perform the inverse operation. sid::host_int_4 tag_to_addr (const cache_tag& tag) const; Index: sid/component/cache/hw-cache.xml =================================================================== RCS file: /cvs/src/src/sid/component/cache/hw-cache.xml,v retrieving revision 1.9 diff -c -p -r1.9 hw-cache.xml *** sid/component/cache/hw-cache.xml 16 Jul 2002 19:25:45 -0000 1.9 --- sid/component/cache/hw-cache.xml 3 May 2005 20:42:15 -0000 *************** *** 14,25 **** ! ! ! --- 14,25 ---- ! ! ! Index: sid/component/cgen-cpu/cgen-cpu.h =================================================================== RCS file: /cvs/src/src/sid/component/cgen-cpu/cgen-cpu.h,v retrieving revision 1.11 diff -c -p -r1.11 cgen-cpu.h *** sid/component/cgen-cpu/cgen-cpu.h 12 Feb 2005 16:25:45 -0000 1.11 --- sid/component/cgen-cpu/cgen-cpu.h 3 May 2005 20:42:15 -0000 *************** *** 25,30 **** --- 25,31 ---- #include "bfd.h" #include "dis-asm.h" + #include "opcode/cgen-bitset.h" // ansidecl.h interferes with this perfectly ordinary word #undef AND *************** public: *** 68,74 **** // Disassembly tracing support void disassemble (PCADDR pc, disassembler_ftype printfn, enum bfd_flavour flavour, enum bfd_architecture arch, ! enum bfd_endian endian, const char *name, unsigned long isa_mask = 0, int machine = 0); struct disassemble_info info; protected: static int cgen_read_memory (bfd_vma memaddr, bfd_byte *myaddr, --- 69,75 ---- // Disassembly tracing support void disassemble (PCADDR pc, disassembler_ftype printfn, enum bfd_flavour flavour, enum bfd_architecture arch, ! enum bfd_endian endian, const char *name, CGEN_BITSET *isas = NULL, int machine = 0); struct disassemble_info info; protected: static int cgen_read_memory (bfd_vma memaddr, bfd_byte *myaddr, *************** public: *** 88,192 **** public: // rtl memory access methods inline QI ! GETMEMQI(PCADDR pc, ADDR addr) const { return this->read_data_memory_1 (pc, addr); } inline UQI ! GETMEMUQI(PCADDR pc, ADDR addr) const { return this->read_data_memory_1 (pc, addr); } inline void ! SETMEMBI(PCADDR pc, ADDR addr, BI value) const { return this->write_insn_memory_1 (pc, addr, value); } inline void ! SETMEMQI(PCADDR pc, ADDR addr, QI value) const { return this->write_data_memory_1 (pc, addr, value); } inline void ! SETMEMUQI(PCADDR pc, ADDR addr, UQI value) const { return this->write_data_memory_1 (pc, addr, value); } inline HI ! GETMEMHI(PCADDR pc, ADDR addr) const { return this->read_data_memory_2 (pc, addr); } inline UHI ! GETMEMUHI(PCADDR pc, ADDR addr) const { return this->read_data_memory_2 (pc, addr); } inline void ! SETMEMHI(PCADDR pc, ADDR addr, HI value) const { return this->write_data_memory_2 (pc, addr, value); } inline void ! SETMEMUHI(PCADDR pc, ADDR addr, UHI value) const { return this->write_data_memory_2 (pc, addr, value); } inline SI ! GETMEMSI(PCADDR pc, ADDR addr) const { return this->read_data_memory_4 (pc, addr); } inline void ! SETMEMSI(PCADDR pc, ADDR addr, SI value) const { return this->write_data_memory_4 (pc, addr, value); } inline USI ! GETMEMUSI(PCADDR pc, ADDR addr) const { return this->read_data_memory_4 (pc, addr); } inline void ! SETMEMUSI(PCADDR pc, ADDR addr, USI value) const { return this->write_data_memory_4 (pc, addr, value); } inline DI ! GETMEMDI(PCADDR pc, ADDR addr) const { return this->read_data_memory_8 (pc, addr); } inline void ! SETMEMDI(PCADDR pc, ADDR addr, DI value) const { return this->write_data_memory_8 (pc, addr, value); } inline void ! SETMEMUDI(PCADDR pc, ADDR addr, UDI value) const { return this->write_data_memory_8 (pc, addr, value); } // floats (can you think of a better way to do this?) inline SF ! GETMEMSF(PCADDR pc, IADDR addr) const { return reinterpret_cast(this->read_insn_memory_4 (pc, addr)); } inline void ! SETMEMSF(PCADDR pc, ADDR addr, SF value) const { return this->write_insn_memory_4 (pc, addr, reinterpret_cast(value)); } inline DF ! GETMEMDF(PCADDR pc, IADDR addr) const { return reinterpret_cast(this->read_insn_memory_8 (pc, addr)); } inline void ! SETMEMDF(PCADDR pc, ADDR addr, DF value) const { return this->write_insn_memory_8 (pc, addr, reinterpret_cast(value)); } --- 89,193 ---- public: // rtl memory access methods inline QI ! GETMEMQI(PCADDR pc, ADDR addr) { return this->read_data_memory_1 (pc, addr); } inline UQI ! GETMEMUQI(PCADDR pc, ADDR addr) { return this->read_data_memory_1 (pc, addr); } inline void ! SETMEMBI(PCADDR pc, ADDR addr, BI value) { return this->write_insn_memory_1 (pc, addr, value); } inline void ! SETMEMQI(PCADDR pc, ADDR addr, QI value) { return this->write_data_memory_1 (pc, addr, value); } inline void ! SETMEMUQI(PCADDR pc, ADDR addr, UQI value) { return this->write_data_memory_1 (pc, addr, value); } inline HI ! GETMEMHI(PCADDR pc, ADDR addr) { return this->read_data_memory_2 (pc, addr); } inline UHI ! GETMEMUHI(PCADDR pc, ADDR addr) { return this->read_data_memory_2 (pc, addr); } inline void ! SETMEMHI(PCADDR pc, ADDR addr, HI value) { return this->write_data_memory_2 (pc, addr, value); } inline void ! SETMEMUHI(PCADDR pc, ADDR addr, UHI value) { return this->write_data_memory_2 (pc, addr, value); } inline SI ! GETMEMSI(PCADDR pc, ADDR addr) { return this->read_data_memory_4 (pc, addr); } inline void ! SETMEMSI(PCADDR pc, ADDR addr, SI value) { return this->write_data_memory_4 (pc, addr, value); } inline USI ! GETMEMUSI(PCADDR pc, ADDR addr) { return this->read_data_memory_4 (pc, addr); } inline void ! SETMEMUSI(PCADDR pc, ADDR addr, USI value) { return this->write_data_memory_4 (pc, addr, value); } inline DI ! GETMEMDI(PCADDR pc, ADDR addr) { return this->read_data_memory_8 (pc, addr); } inline void ! SETMEMDI(PCADDR pc, ADDR addr, DI value) { return this->write_data_memory_8 (pc, addr, value); } inline void ! SETMEMUDI(PCADDR pc, ADDR addr, UDI value) { return this->write_data_memory_8 (pc, addr, value); } // floats (can you think of a better way to do this?) inline SF ! GETMEMSF(PCADDR pc, IADDR addr) { return reinterpret_cast(this->read_insn_memory_4 (pc, addr)); } inline void ! SETMEMSF(PCADDR pc, ADDR addr, SF value) { return this->write_insn_memory_4 (pc, addr, reinterpret_cast(value)); } inline DF ! GETMEMDF(PCADDR pc, IADDR addr) { return reinterpret_cast(this->read_insn_memory_8 (pc, addr)); } inline void ! SETMEMDF(PCADDR pc, ADDR addr, DF value) { return this->write_insn_memory_8 (pc, addr, reinterpret_cast(value)); } *************** public: *** 194,275 **** // IMEM: instruction memory calls inline QI ! GETIMEMQI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_1 (pc, addr); } inline void ! SETIMEMQI(PCADDR pc, ADDR addr, QI value) const { return this->write_insn_memory_1 (pc, addr, value); } inline UQI ! GETIMEMUQI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_1 (pc, addr); } inline void ! SETIMEMUQI(PCADDR pc, ADDR addr, UQI value) const { return this->write_insn_memory_1 (pc, addr, value); } inline HI ! GETIMEMHI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_2 (pc, addr); } inline void ! SETIMEMHI(PCADDR pc, ADDR addr, HI value) const { return this->write_insn_memory_2 (pc, addr, value); } inline UHI ! GETIMEMUHI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_2 (pc, addr); } inline void ! SETIMEMUHI(PCADDR pc, ADDR addr, UHI value) const { return this->write_insn_memory_2 (pc, addr, value); } inline SI ! GETIMEMSI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_4 (pc, addr); } inline void ! SETIMEMSI(PCADDR pc, ADDR addr, SI value) const { return this->write_insn_memory_4 (pc, addr, value); } inline USI ! GETIMEMUSI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_4 (pc, addr); } inline void ! SETIMEMUSI(PCADDR pc, ADDR addr, USI value) const { return this->write_insn_memory_4 (pc, addr, value); } inline DI ! GETIMEMDI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_8 (pc, addr); } inline void ! SETIMEMDI(PCADDR pc, ADDR addr, DI value) const { return this->write_insn_memory_8 (pc, addr, value); } inline UDI ! GETIMEMUDI(PCADDR pc, IADDR addr) const { return this->read_insn_memory_8 (pc, addr); } inline void ! SETIMEMUDI(PCADDR pc, ADDR addr, UDI value) const { return this->write_insn_memory_8 (pc, addr, value); } --- 195,276 ---- // IMEM: instruction memory calls inline QI ! GETIMEMQI(PCADDR pc, IADDR addr) { return this->read_insn_memory_1 (pc, addr); } inline void ! SETIMEMQI(PCADDR pc, ADDR addr, QI value) { return this->write_insn_memory_1 (pc, addr, value); } inline UQI ! GETIMEMUQI(PCADDR pc, IADDR addr) { return this->read_insn_memory_1 (pc, addr); } inline void ! SETIMEMUQI(PCADDR pc, ADDR addr, UQI value) { return this->write_insn_memory_1 (pc, addr, value); } inline HI ! GETIMEMHI(PCADDR pc, IADDR addr) { return this->read_insn_memory_2 (pc, addr); } inline void ! SETIMEMHI(PCADDR pc, ADDR addr, HI value) { return this->write_insn_memory_2 (pc, addr, value); } inline UHI ! GETIMEMUHI(PCADDR pc, IADDR addr) { return this->read_insn_memory_2 (pc, addr); } inline void ! SETIMEMUHI(PCADDR pc, ADDR addr, UHI value) { return this->write_insn_memory_2 (pc, addr, value); } inline SI ! GETIMEMSI(PCADDR pc, IADDR addr) { return this->read_insn_memory_4 (pc, addr); } inline void ! SETIMEMSI(PCADDR pc, ADDR addr, SI value) { return this->write_insn_memory_4 (pc, addr, value); } inline USI ! GETIMEMUSI(PCADDR pc, IADDR addr) { return this->read_insn_memory_4 (pc, addr); } inline void ! SETIMEMUSI(PCADDR pc, ADDR addr, USI value) { return this->write_insn_memory_4 (pc, addr, value); } inline DI ! GETIMEMDI(PCADDR pc, IADDR addr) { return this->read_insn_memory_8 (pc, addr); } inline void ! SETIMEMDI(PCADDR pc, ADDR addr, DI value) { return this->write_insn_memory_8 (pc, addr, value); } inline UDI ! GETIMEMUDI(PCADDR pc, IADDR addr) { return this->read_insn_memory_8 (pc, addr); } inline void ! SETIMEMUDI(PCADDR pc, ADDR addr, UDI value) { return this->write_insn_memory_8 (pc, addr, value); } Index: sid/include/sidattrutil.h =================================================================== RCS file: /cvs/src/src/sid/include/sidattrutil.h,v retrieving revision 1.6 diff -c -p -r1.6 sidattrutil.h *** sid/include/sidattrutil.h 21 Oct 2003 21:38:24 -0000 1.6 --- sid/include/sidattrutil.h 3 May 2005 20:42:16 -0000 *************** make_attribute (const sid::any_intoutput_saved_messages (); - #if SID_LOG_PERSISTENT_BUFFER - delete [] buffer; - #endif } void log (sid::host_int_4 level, const char *fmt, ...) --- 1022,1045 ---- : public virtual fixed_attribute_map_component, public virtual fixed_pin_map_component { protected: fixed_attribute_map_with_logging_component () : ulog_level (0), ulog_mode ("less"), ulog_out_pin (), ! buffer_output (true) { add_attribute ("buffer-output", &buffer_output, "setting"); add_attribute ("ulog-level", &ulog_level, "setting"); add_attribute ("ulog-mode", &ulog_mode, "setting"); add_pin ("ulog-out", & ulog_out_pin); ulog_logger = new logger (& ulog_out_pin, buffer_output, ulog_level, ulog_mode); } ~fixed_attribute_map_with_logging_component () throw() { // Output any saved messages. // output_saved_messages (); ulog_logger->output_saved_messages (); } void log (sid::host_int_4 level, const char *fmt, ...) *************** make_attribute (const sid::any_intcheck_level (level); ! } ! ! void output_saved_messages () { ! while (saved_messages.size () > 0) ! { ! if (check_level (saved_levels[0])) ! { ! std::string s = saved_messages[0]; ! for (int i = 0; i < s.size (); ++i) ! ulog_out_pin.drive (s[i]); ! } ! saved_messages.erase (saved_messages.begin ()); ! saved_levels.erase (saved_levels.begin ()); ! } } - sid::host_int_4 ulog_level; std::string ulog_mode; sidutil::output_pin ulog_out_pin; bool buffer_output; sidutil::logger *ulog_logger; - char *buffer; - long buffer_size; - std::vector saved_messages; - std::vector saved_levels; - #undef SID_LOG_PERSISTENT_BUFFER - #undef SID_LOG_TRANSIENT_MALLOC_BUFFER }; } --- 1052,1067 ---- va_end (ap); } ! protected: ! bool check_level (sid::host_int_4 level) const { ! return ulog_logger->check_level (level); } sid::host_int_4 ulog_level; std::string ulog_mode; sidutil::output_pin ulog_out_pin; bool buffer_output; sidutil::logger *ulog_logger; }; } Index: sid/include/sidbusutil.h =================================================================== RCS file: /cvs/src/src/sid/include/sidbusutil.h,v retrieving revision 1.14 diff -c -p -r1.14 sidbusutil.h *** sid/include/sidbusutil.h 21 Oct 2003 21:38:24 -0000 1.14 --- sid/include/sidbusutil.h 3 May 2005 20:42:16 -0000 *************** *** 1,6 **** // sidbusutil.h -*- C++ -*- Different types and sizes of buses. ! // Copyright (C) 1999, 2000, 2001, 2002 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,6 ---- // sidbusutil.h -*- C++ -*- Different types and sizes of buses. ! // Copyright (C) 1999, 2000, 2001, 2002, 2004 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** *** 9,14 **** --- 9,18 ---- #include #include + #include + #include + #include + #include #include #include *************** namespace sidutil *** 52,59 **** --- 56,65 ---- sid::host_int_4 a = address; unsigned bytesWritten = 0; + sid::host_int_2 max_latency = 0; DataType d = 0; DataType mask = 0; + sid::bus::status s; while(bytesWritten < accWidth) { sid::host_int_1 byte = data.read_byte(bytesWritten); *************** namespace sidutil *** 63,69 **** if(((bytesWritten + a) % busWidth == (busWidth - 1)) || // last byte in target (bytesWritten == (accWidth - 1))) // last byte in source { - sid::bus::status s; s = this->word_write(sid::host_int_4(a / busWidth), mask, d); if (s != sid::bus::ok) --- 69,74 ---- *************** namespace sidutil *** 71,76 **** --- 76,83 ---- this->post_access_hook(); return s; } + if (s.latency > max_latency) + max_latency = s.latency; a = a + busWidth; // advance address // Clear data. *************** namespace sidutil *** 82,88 **** } this->post_access_hook(); ! return sid::bus::ok; } --- 89,96 ---- } this->post_access_hook(); ! s.latency = max_latency; ! return s; } *************** namespace sidutil *** 101,107 **** --- 109,117 ---- unsigned bytesRead = 0; unsigned bytesAddressed = 0; + sid::host_int_2 max_latency = 0; DataType mask = 0; + sid::bus::status s; while(bytesAddressed < accWidth) { mask.write_byte((bytesAddressed + a) % busWidth, 0xff); *************** namespace sidutil *** 109,116 **** if(((bytesAddressed + a) % busWidth == (busWidth - 1)) || // last byte in target (bytesAddressed == (accWidth - 1))) // last byte in source { - sid::bus::status s; - DataType d = 0; s = this->word_read(sid::host_int_4(a / busWidth), mask, d); if (s != sid::bus::ok) --- 119,124 ---- *************** namespace sidutil *** 118,123 **** --- 126,133 ---- this->post_access_hook(); return s; } + if (s.latency > max_latency) + max_latency = s.latency; // Copy over newly read bytes while (bytesRead <= bytesAddressed) *************** namespace sidutil *** 138,144 **** assert (bytesAddressed == bytesRead); this->post_access_hook(); ! return sid::bus::ok; } --- 148,155 ---- assert (bytesAddressed == bytesRead); this->post_access_hook(); ! s.latency = max_latency; ! return s; } *************** namespace sidutil *** 1180,1185 **** --- 1191,1464 ---- typedef std::map bus_map_t; mutable bus_map_t bus_map; }; + + // Following class is a virtual base class used for implementing bus + // arbitrators. + class bus_arbitrator: public virtual sid::component, + protected fixed_bus_map_component, + protected virtual fixed_pin_map_component, + protected fixed_accessor_map_component, + protected no_relation_component, + public fixed_attribute_map_with_logging_component + { + public: + bus_arbitrator () : + sched ("step", this, & bus_arbitrator::step_cycle) + { + // Attributes + add_attribute ("name", &name); + // Control pins + // + add_pin ("running", & running_pin); + running_pin.set_active_high (); + add_pin ("active", & active_pin); + active_pin.set_active_high (); + add_pin ("passthrough", & passthrough_pin); + passthrough_pin.set_active_high (); + } + ~bus_arbitrator () throw () { } + + protected: + // A bus for requests from the input interfaces. + // + class input_interface : public sid::bus + { + public: + input_interface (bus_arbitrator *h, int us) : host (h), upstream (us) { } + + #define SID_GB_WRITE(dtype) \ + sid::bus::status write(sid::host_int_4 addr, dtype data) throw ()\ + { return host->write(upstream, addr, data); } + + #define SID_GB_READ(dtype) \ + sid::bus::status read(sid::host_int_4 addr, dtype& data) throw ()\ + { return host->read(upstream, addr, data); } + + SID_GB_WRITE(sid::little_int_1) + SID_GB_WRITE(sid::big_int_1) + SID_GB_WRITE(sid::little_int_2) + SID_GB_WRITE(sid::big_int_2) + SID_GB_WRITE(sid::little_int_4) + SID_GB_WRITE(sid::big_int_4) + SID_GB_WRITE(sid::little_int_8) + SID_GB_WRITE(sid::big_int_8) + + SID_GB_READ(sid::little_int_1) + SID_GB_READ(sid::big_int_1) + SID_GB_READ(sid::little_int_2) + SID_GB_READ(sid::big_int_2) + SID_GB_READ(sid::little_int_4) + SID_GB_READ(sid::big_int_4) + SID_GB_READ(sid::little_int_8) + SID_GB_READ(sid::big_int_8) + + #undef SID_GB_WRITE + #undef SID_GB_READ + private: + bus_arbitrator *host; + int upstream; + }; + friend class input_interface; + + // A struct representing a bus request + struct bus_request + { + bus_request () {} + bus_request (bool r, int us, int ds, sid::host_int_4 a, unsigned s) + : is_read(r), upstream(us), downstream(ds), addr(a), size(s) + { } + bool operator== (const bus_request &r) + { + return is_read == r.is_read + && upstream == r.upstream + && downstream == r.downstream + && addr == r.addr + && size == r.size; + } + bool is_read; + int upstream; + int downstream; + sid::host_int_4 addr; + unsigned size; + }; + + protected: + // Handlers for input interfaces + // + template + sid::bus::status + write(int upstream, sid::host_int_4 addr, DataType data) + { + if (ulog_level >= 8 || ! check_passthrough ()) + log (5, "%s: received write request from %s interface at 0x%x\n", + name.c_str (), up2str(upstream), addr); + return arbitrate_write (upstream, downstream_for_address (addr), addr, data); + } + + template + sid::bus::status + read(int upstream, sid::host_int_4 addr, DataType& data) + { + if (ulog_level >= 8 || ! check_passthrough ()) + log (5, "%s: received read request from %s interface at 0x%x\n", + name.c_str (), up2str(upstream), addr); + return arbitrate_read (upstream, downstream_for_address (addr), addr, data); + } + + virtual const char *up2str (int upstream) = 0; + virtual int downstream_for_address (sid::host_int_4 address) = 0; + + protected: + // Advance time + // + virtual void step_cycle () + { + log (5, "%s: Stepping\n", name.c_str()); + update_busy_routes (); + } + + virtual void reschedule (sid::host_int_2 latency) + { + if (latency) + { + log (5, "%s: rescheduling (%d)\n", name.c_str (), latency); + sched.schedule_irregular (1); + } + } + + // Methods for arbitration + // + template + sid::bus::status arbitrate_read (int upstream, + int downstream, + sid::host_int_4 addr, + DataType& data) + { + // Check for direct passthrough + if (check_passthrough ()) + return downstream_bus (downstream)->read (addr, data); + + // Prioritize the request + // Execute it if it's ready + bus_request r (true, upstream, downstream, addr, sizeof (data)); + if (prioritize_request (r)) + return perform_read (r, data); + + return busy_status (); + } + + template + sid::bus::status arbitrate_write (int upstream, + int downstream, + sid::host_int_4 addr, + DataType data) + { + // Check for direct passthrough + if (check_passthrough ()) + return downstream_bus (downstream)->write(addr, data); + + // Prioritize the request + // Execute it if it's ready + bus_request r (false, upstream, downstream, addr, sizeof (data)); + if (prioritize_request (r)) + return perform_write (r, data); + + return busy_status (); + } + + // Provide a default implementation which does no prioritization and + // handles the requests right away as they arrive. + virtual bool prioritize_request (bus_request &r) { return true; } + + // Methods for downstream accessors + // + template + sid::bus::status perform_read (bus_request &r, DataType &data) + { + // See if the route is available + if (check_route_busy (r.upstream, r.downstream)) + return busy_status (); + + // Propagate any locked pin from upstream + lock_downstream (r.upstream, r.downstream); + + // Perform the read + sid::bus::status s = downstream_bus (r.downstream)->read (r.addr, data); + + // Update status + if (s == sid::bus::ok) + s = set_route_busy (r, s); + return s; + } + + template + sid::bus::status perform_write (bus_request &r, DataType data) + { + // See if the route is available + if (check_route_busy (r.upstream, r.downstream)) + return busy_status (); + + // Propogate any locked pin from upstream + lock_downstream (r.upstream, r.downstream); + + // Perform the write + sid::bus::status s = downstream_bus (r.downstream)->write (r.addr, data); + + // Update status + if (s == sid::bus::ok) + s = set_route_busy (r, s); + return s; + } + + bool check_passthrough () + { + if (passthrough_pin.state () == binary_pin_active) + { + log (8, "%s: passthrough enabled\n", name.c_str ()); + return true; + } + + if (running_pin.state () != binary_pin_active + || active_pin.state () != binary_pin_active) + { + log (8, "%s: system is idle -- passthrough\n", name.c_str ()); + return true; + } + return false; + } + + protected: + // Route locking + // + virtual void lock_downstream (int upstream, int downstream) { } + + virtual bool check_route_busy (int upstream, int downstream) { return false; } + + virtual sid::bus::status set_route_busy (bus_request &r, sid::bus::status s) { return s; } + virtual void update_busy_routes () {} + virtual sid::bus::status busy_status () + { + // Default - busy for 1 cycle + sid::bus::status s (sid::bus::busy, 1); + return s; + } + + virtual sid::bus *downstream_bus (int downstream) = 0; + + protected: + scheduler_event_subscription sched; + // This class must be a friend of scheduler_event_subscription. + friend class scheduler_event_subscription; + + // Attributes + string name; + + // Control pins + // + binary_input_pin running_pin; + binary_input_pin active_pin; + binary_input_pin passthrough_pin; + }; } Index: sid/include/sidcomp.h =================================================================== RCS file: /cvs/src/src/sid/include/sidcomp.h,v retrieving revision 1.5 diff -c -p -r1.5 sidcomp.h *** sid/include/sidcomp.h 25 Jun 2001 01:45:28 -0000 1.5 --- sid/include/sidcomp.h 3 May 2005 20:42:16 -0000 *************** *** 1,7 **** // sidcomp.h - Define the external interface of a SID component, that // is, the SID component API expressed in -*- C++ -*-. ! // Copyright (C) 1999, 2000, 2001 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,7 ---- // sidcomp.h - Define the external interface of a SID component, that // is, the SID component API expressed in -*- C++ -*-. ! // Copyright (C) 1999, 2000, 2001, 2004 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** namespace sid *** 45,50 **** --- 45,51 ---- misaligned = 0x01, // address misaligned unmapped = 0x02, // address not in mapped range unpermitted = 0x04, // may not read or may not write at address + busy = 0x05 // target component is busy }; struct status Index: sid/include/sidcpuutil.h =================================================================== RCS file: /cvs/src/src/sid/include/sidcpuutil.h,v retrieving revision 1.29 diff -c -p -r1.29 sidcpuutil.h *** sid/include/sidcpuutil.h 29 Jun 2004 19:10:41 -0000 1.29 --- sid/include/sidcpuutil.h 3 May 2005 20:42:17 -0000 *************** namespace sidutil *** 101,111 **** class basic_cpu: public virtual sid::component, ! protected fixed_pin_map_component, ! protected fixed_accessor_map_component, ! protected fixed_attribute_map_component, ! protected fixed_relation_map_component, ! protected fixed_bus_map_component { // custom memory allocators for poisioning freshly-allocated memory public: --- 101,111 ---- class basic_cpu: public virtual sid::component, ! protected virtual fixed_pin_map_component, ! protected virtual fixed_accessor_map_component, ! protected virtual fixed_attribute_map_component, ! protected virtual fixed_relation_map_component, ! protected virtual fixed_bus_map_component { // custom memory allocators for poisioning freshly-allocated memory public: *************** namespace sidutil *** 260,266 **** bool enable_step_trap_p; cpu_trace_stream trace_stream; ! void step_pin_handler (sid::host_int_4) { recursion_record limit (& this->step_limit); if (UNLIKELY(! limit.ok())) return; --- 260,266 ---- bool enable_step_trap_p; cpu_trace_stream trace_stream; ! virtual void step_pin_handler (sid::host_int_4) { recursion_record limit (& this->step_limit); if (UNLIKELY(! limit.ok())) return; *************** namespace sidutil *** 530,542 **** protected: template ! BigOrLittleInt read_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const; template ! BigOrLittleInt write_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const; template ! BigOrLittleInt read_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const; template ! BigOrLittleInt write_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const; // ------------------------------------------------------------------------ --- 530,552 ---- protected: template ! BigOrLittleInt read_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt); template ! BigOrLittleInt write_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value); template ! BigOrLittleInt read_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt); template ! BigOrLittleInt write_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value); ! ! virtual bool handle_insn_memory_read_error (sid::bus::status s, sid::host_int_4 & address) { return false; } ! virtual bool handle_insn_memory_write_error (sid::bus::status s, sid::host_int_4 & address) { return false; } ! virtual bool handle_data_memory_read_error (sid::bus::status s, sid::host_int_4 & address) { return false; } ! virtual bool handle_data_memory_write_error (sid::bus::status s, sid::host_int_4 & address) { return false; } ! ! virtual void record_insn_memory_read_latency (sid::bus::status s) { total_latency += s.latency; } ! virtual void record_insn_memory_write_latency (sid::bus::status s) { total_latency += s.latency; } ! virtual void record_data_memory_read_latency (sid::bus::status s) { total_latency += s.latency; } ! virtual void record_data_memory_write_latency (sid::bus::status s) { total_latency += s.latency; } // ------------------------------------------------------------------------ *************** public: *** 642,704 **** } template ! BigOrLittleInt basic_cpu::read_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const { - BigOrLittleInt value; sid::bus::status s; ! if (LIKELY(this->insn_bus)) ! s = this->insn_bus->read (address, value); ! else ! s = sid::bus::unmapped; ! total_latency += s.latency; ! if (LIKELY(s == sid::bus::ok)) ! return value; throw cpu_memory_fault (pc, address, s, "insn read"); } template ! BigOrLittleInt basic_cpu::write_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const { sid::bus::status s; ! if (LIKELY(this->insn_bus)) ! s = this->insn_bus->write (address, value); ! else ! s = sid::bus::unmapped; ! total_latency += s.latency; ! if (LIKELY(s == sid::bus::ok)) ! return value; throw cpu_memory_fault (pc, address, s, "insn write"); } template ! BigOrLittleInt basic_cpu::read_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const { - BigOrLittleInt value; sid::bus::status s; ! if (LIKELY(this->data_bus)) ! s = this->data_bus->read (address, value); ! else ! s = sid::bus::unmapped; ! total_latency += s.latency; ! if (LIKELY(s == sid::bus::ok)) ! return value; throw cpu_memory_fault (pc, address, s, "data read"); } template ! BigOrLittleInt basic_cpu::write_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const { sid::bus::status s; ! if (LIKELY(this->data_bus)) ! s = this->data_bus->write (address, value); ! else ! s = sid::bus::unmapped; ! total_latency += s.latency; ! if (LIKELY(s == sid::bus::ok)) ! return value; throw cpu_memory_fault (pc, address, s, "data write"); } --- 652,750 ---- } template ! BigOrLittleInt basic_cpu::read_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) { sid::bus::status s; ! do ! { ! BigOrLittleInt value; ! if (LIKELY(this->insn_bus)) ! { ! s = this->insn_bus->read (address, value); ! if (LIKELY(s == sid::bus::ok)) ! { ! if (UNLIKELY ((trace_counter_p || final_insn_count_p) && s.latency)) ! record_insn_memory_read_latency (s); ! return value; ! } ! } ! else ! s = sid::bus::unmapped; ! } ! while (UNLIKELY (handle_insn_memory_read_error (s, address))); throw cpu_memory_fault (pc, address, s, "insn read"); } template ! BigOrLittleInt basic_cpu::write_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) { sid::bus::status s; ! do ! { ! if (LIKELY(this->insn_bus)) ! { ! s = this->insn_bus->write (address, value); ! if (LIKELY(s == sid::bus::ok)) ! { ! if (UNLIKELY ((trace_counter_p || final_insn_count_p) && s.latency)) ! record_insn_memory_write_latency (s); ! return value; ! } ! } ! else ! s = sid::bus::unmapped; ! } ! while (UNLIKELY (handle_insn_memory_read_error (s, address))); throw cpu_memory_fault (pc, address, s, "insn write"); } template ! BigOrLittleInt basic_cpu::read_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) { sid::bus::status s; ! do ! { ! BigOrLittleInt value; ! if (LIKELY(this->data_bus)) ! { ! s = this->data_bus->read (address, value); ! if (LIKELY(s == sid::bus::ok)) ! { ! if (UNLIKELY ((trace_counter_p || final_insn_count_p) && s.latency)) ! record_data_memory_read_latency (s); ! return value; ! } ! } ! else ! s = sid::bus::unmapped; ! } ! while (UNLIKELY (handle_insn_memory_read_error (s, address))); throw cpu_memory_fault (pc, address, s, "data read"); } template ! BigOrLittleInt basic_cpu::write_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) { sid::bus::status s; ! do ! { ! if (LIKELY(this->data_bus)) ! { ! s = this->data_bus->write (address, value); ! if (LIKELY(s == sid::bus::ok)) ! { ! if (UNLIKELY ((trace_counter_p || final_insn_count_p) && s.latency)) ! record_data_memory_write_latency (s); ! return value; ! } ! } ! else ! s = sid::bus::unmapped; ! } ! while (UNLIKELY (handle_insn_memory_read_error (s, address))); throw cpu_memory_fault (pc, address, s, "data write"); } *************** public: *** 721,802 **** } ~basic_big_endian_cpu () throw() {} ! sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::big_int_8()); } ! void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const { this->write_insn_memory (pc, address, sid::big_int_1(value)); } ! void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const { this->write_insn_memory (pc, address, sid::big_int_2(value)); } ! void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const { this->write_insn_memory (pc, address, sid::big_int_4(value)); } ! void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const { this->write_insn_memory (pc, address, sid::big_int_8(value)); } ! sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::big_int_8()); } ! void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const { this->write_data_memory (pc, address, sid::big_int_1(value)); } ! void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const { this->write_data_memory (pc, address, sid::big_int_2(value)); } ! void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const { this->write_data_memory (pc, address, sid::big_int_4(value)); } ! void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const { this->write_data_memory (pc, address, sid::big_int_8(value)); } --- 767,848 ---- } ~basic_big_endian_cpu () throw() {} ! sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::big_int_8()); } ! void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) { this->write_insn_memory (pc, address, sid::big_int_1(value)); } ! void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) { this->write_insn_memory (pc, address, sid::big_int_2(value)); } ! void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) { this->write_insn_memory (pc, address, sid::big_int_4(value)); } ! void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) { this->write_insn_memory (pc, address, sid::big_int_8(value)); } ! sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::big_int_8()); } ! void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) { this->write_data_memory (pc, address, sid::big_int_1(value)); } ! void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) { this->write_data_memory (pc, address, sid::big_int_2(value)); } ! void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) { this->write_data_memory (pc, address, sid::big_int_4(value)); } ! void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) { this->write_data_memory (pc, address, sid::big_int_8(value)); } *************** public: *** 817,898 **** } ~basic_little_endian_cpu () throw() {} ! sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::little_int_1()); } ! sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::little_int_2()); } ! sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::little_int_4()); } ! sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_insn_memory (pc, address, sid::little_int_8()); } ! void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const { this->write_insn_memory (pc, address, sid::little_int_1(value)); } ! void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const { this->write_insn_memory (pc, address, sid::little_int_2(value)); } ! void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const { this->write_insn_memory (pc, address, sid::little_int_4(value)); } ! void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const { this->write_insn_memory (pc, address, sid::little_int_8(value)); } ! sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::little_int_1()); } ! sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::little_int_2()); } ! sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::little_int_4()); } ! sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const { return this->read_data_memory (pc, address, sid::little_int_8()); } ! void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const { this->write_data_memory (pc, address, sid::little_int_1(value)); } ! void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const { this->write_data_memory (pc, address, sid::little_int_2(value)); } ! void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const { this->write_data_memory (pc, address, sid::little_int_4(value)); } ! void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const { this->write_data_memory (pc, address, sid::little_int_8(value)); } --- 863,944 ---- } ~basic_little_endian_cpu () throw() {} ! sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::little_int_1()); } ! sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::little_int_2()); } ! sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::little_int_4()); } ! sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_insn_memory (pc, address, sid::little_int_8()); } ! void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) { this->write_insn_memory (pc, address, sid::little_int_1(value)); } ! void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) { this->write_insn_memory (pc, address, sid::little_int_2(value)); } ! void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) { this->write_insn_memory (pc, address, sid::little_int_4(value)); } ! void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) { this->write_insn_memory (pc, address, sid::little_int_8(value)); } ! sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::little_int_1()); } ! sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::little_int_2()); } ! sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::little_int_4()); } ! sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) { return this->read_data_memory (pc, address, sid::little_int_8()); } ! void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) { this->write_data_memory (pc, address, sid::little_int_1(value)); } ! void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) { this->write_data_memory (pc, address, sid::little_int_2(value)); } ! void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) { this->write_data_memory (pc, address, sid::little_int_4(value)); } ! void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) { this->write_data_memory (pc, address, sid::little_int_8(value)); } *************** public: *** 945,951 **** } ! sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_1()); --- 991,997 ---- } ! sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_1()); *************** public: *** 953,959 **** return this->read_insn_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_2()); --- 999,1005 ---- return this->read_insn_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_2()); *************** public: *** 961,967 **** return this->read_insn_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_4()); --- 1007,1013 ---- return this->read_insn_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_4()); *************** public: *** 969,975 **** return this->read_insn_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_8()); --- 1015,1021 ---- return this->read_insn_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_insn_memory (pc, address, sid::little_int_8()); *************** public: *** 977,983 **** return this->read_insn_memory (pc, address, sid::big_int_8()); } ! void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_1(value)); --- 1023,1029 ---- return this->read_insn_memory (pc, address, sid::big_int_8()); } ! void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_1(value)); *************** public: *** 985,991 **** this->write_insn_memory (pc, address, sid::big_int_1(value)); } ! void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_2(value)); --- 1031,1037 ---- this->write_insn_memory (pc, address, sid::big_int_1(value)); } ! void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_2(value)); *************** public: *** 993,999 **** this->write_insn_memory (pc, address, sid::big_int_2(value)); } ! void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_4(value)); --- 1039,1045 ---- this->write_insn_memory (pc, address, sid::big_int_2(value)); } ! void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_4(value)); *************** public: *** 1001,1007 **** this->write_insn_memory (pc, address, sid::big_int_4(value)); } ! void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_8(value)); --- 1047,1053 ---- this->write_insn_memory (pc, address, sid::big_int_4(value)); } ! void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) { if (this->_current_endianness == endian_little) this->write_insn_memory (pc, address, sid::little_int_8(value)); *************** public: *** 1009,1015 **** this->write_insn_memory (pc, address, sid::big_int_8(value)); } ! sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_1()); --- 1055,1061 ---- this->write_insn_memory (pc, address, sid::big_int_8(value)); } ! sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_1()); *************** public: *** 1017,1023 **** return this->read_data_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_2()); --- 1063,1069 ---- return this->read_data_memory (pc, address, sid::big_int_1()); } ! sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_2()); *************** public: *** 1025,1031 **** return this->read_data_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_4()); --- 1071,1077 ---- return this->read_data_memory (pc, address, sid::big_int_2()); } ! sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_4()); *************** public: *** 1033,1039 **** return this->read_data_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_8()); --- 1079,1085 ---- return this->read_data_memory (pc, address, sid::big_int_4()); } ! sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) { if (this->_current_endianness == endian_little) return this->read_data_memory (pc, address, sid::little_int_8()); *************** public: *** 1041,1047 **** return this->read_data_memory (pc, address, sid::big_int_8()); } ! void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_1(value)); --- 1087,1093 ---- return this->read_data_memory (pc, address, sid::big_int_8()); } ! void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_1(value)); *************** public: *** 1049,1055 **** this->write_data_memory (pc, address, sid::big_int_1(value)); } ! void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_2(value)); --- 1095,1101 ---- this->write_data_memory (pc, address, sid::big_int_1(value)); } ! void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_2(value)); *************** public: *** 1057,1063 **** this->write_data_memory (pc, address, sid::big_int_2(value)); } ! void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_4(value)); --- 1103,1109 ---- this->write_data_memory (pc, address, sid::big_int_2(value)); } ! void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_4(value)); *************** public: *** 1065,1071 **** this->write_data_memory (pc, address, sid::big_int_4(value)); } ! void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_8(value)); --- 1111,1117 ---- this->write_data_memory (pc, address, sid::big_int_4(value)); } ! void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) { if (this->_current_endianness == endian_little) this->write_data_memory (pc, address, sid::little_int_8(value)); Index: sid/main/dynamic/commonCfg.cxx =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/commonCfg.cxx,v retrieving revision 1.8 diff -c -p -r1.8 commonCfg.cxx *** sid/main/dynamic/commonCfg.cxx 29 Jun 2004 19:10:41 -0000 1.8 --- sid/main/dynamic/commonCfg.cxx 3 May 2005 20:42:17 -0000 *************** void CacheCfg::set_refill_latency (sid:: *** 254,259 **** --- 254,301 ---- set (this, "refill-latency", sidutil::make_attribute (i)); } + // BlockingCacheCfg + BlockingCacheCfg::~BlockingCacheCfg () {} + BlockingCacheCfg::BlockingCacheCfg (const string name) : + CacheCfg (name), + ComponentCfg (name), + AtomicCfg (name, + "libcache.la", + "cache_component_library", + "hw-blocking-cache-buffer-8") + {} + + // direct caches + BlockingCacheCfg::BlockingCacheCfg (const string name, + const sid::host_int_4 size, + const sid::host_int_4 linesize) : + CacheCfg (name, size, linesize), + ComponentCfg (name), + AtomicCfg (name, + "libcache.la", + "cache_component_library", + "hw-blocking-cache-direct/" + + sidutil::make_attribute(size) + "kb/" + + sidutil::make_attribute(linesize)) + {} + + // complex associative caches + BlockingCacheCfg::BlockingCacheCfg (const string name, + const string assoc, + const sid::host_int_4 size, + const sid::host_int_4 linesize, + const string replace) : + CacheCfg (name, assoc, size, linesize, replace), + ComponentCfg (name), + AtomicCfg (name, + "libcache.la", + "cache_component_library", + "hw-blocking-cache-" + assoc + "/" + + sidutil::make_attribute(size) + "kb/" + + sidutil::make_attribute(linesize) + "/" + + replace) + {} + // CpuCfg Index: sid/main/dynamic/commonCfg.h =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/commonCfg.h,v retrieving revision 1.6 diff -c -p -r1.6 commonCfg.h *** sid/main/dynamic/commonCfg.h 29 Apr 2004 20:28:01 -0000 1.6 --- sid/main/dynamic/commonCfg.h 3 May 2005 20:42:17 -0000 *************** public: *** 70,75 **** --- 70,94 ---- string my_replace; }; + class BlockingCacheCfg : + public CacheCfg + { + public: + // 8-byte buffers + BlockingCacheCfg (const string name); + // direct caches + BlockingCacheCfg (const string name, + const sid::host_int_4 size, + const sid::host_int_4 linesize); + // complex associative caches + BlockingCacheCfg (const string name, + const string assoc, + const sid::host_int_4 size, + const sid::host_int_4 linesize, + const string replace); + virtual ~BlockingCacheCfg(); + }; + class SchedCfg : virtual public AtomicCfg