From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7953 invoked by alias); 8 Apr 2009 15:36:07 -0000 Received: (qmail 7940 invoked by uid 22791); 8 Apr 2009 15:35:59 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 08 Apr 2009 15:35:51 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n38FZnKs019024 for ; Wed, 8 Apr 2009 11:35:49 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n38FZoCU018439; Wed, 8 Apr 2009 11:35:50 -0400 Received: from dhcp-10-15-16-104.yyz.redhat.com (dhcp-10-15-16-111.yyz.redhat.com [10.15.16.111]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n38FZmYd024566; Wed, 8 Apr 2009 11:35:48 -0400 Message-ID: <49DCC453.5010009@redhat.com> Date: Wed, 08 Apr 2009 15:36:00 -0000 From: Dave Brolley User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: DJ Delorie CC: sid@sourceware.org Subject: Re: mep C5 support References: <200904080253.n382rhTc006961@greed.delorie.com> In-Reply-To: <200904080253.n382rhTc006961@greed.delorie.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact sid-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: sid-owner@sourceware.org X-SW-Source: 2009-q2/txt/msg00002.txt.bz2 Looks like it was implemented along the lines we discussed. The patch looks ok to me. Dave DJ Delorie wrote: > This patch adds a couple of things that are needed by the new MeP C5 > core: > > * a write-hint pin for the cache. What this does is mark a cache line > "read" without actually reading it, in preparation for the cpu > filling the cache line with new data and writing it out. That > prevents reading N-1 bytes when you write the first byte of an > N-byte cache line. > > * A variety of new semantics needed by new C5 opcodes. > > * Support for the C5 core flags. > > * Regenerated semantics et al (pending > http://sourceware.org/ml/cgen/2009-q2/msg00002.html) > > Ok? > > * component/cache/cache.cxx (cache_component::cache_component): > Add write_hint_pin(). Attach it to write-hint. > (cache_component::write_hint): New. > * component/cache/cache.h (write_hint_pin): New. > (write_hint): New. > > * component/cgen-cpu/mep/Makefile.am: Regenerate. > * component/cgen-cpu/mep/Makefile.in: Regenerate. > * component/cgen-cpu/mep/mep-core1-decode.cxx: Regenerate. > * component/cgen-cpu/mep/mep-core1-decode.h: Regenerate. > * component/cgen-cpu/mep/mep-core1-defs.h: Regenerate. > * component/cgen-cpu/mep/mep-core1-model.cxx: Regenerate. > * component/cgen-cpu/mep/mep-core1-model.h: Regenerate. > * component/cgen-cpu/mep/mep-core1-sem.cxx: Regenerate. > * component/cgen-cpu/mep/mep-decode.cxx: Regenerate. > * component/cgen-cpu/mep/mep-decode.h: Regenerate. > * component/cgen-cpu/mep/mep-defs.h: Regenerate. > * component/cgen-cpu/mep/mep-desc.h: Regenerate. > * component/cgen-cpu/mep/mep-model.cxx: Regenerate. > * component/cgen-cpu/mep/mep-model.h: Regenerate. > * component/cgen-cpu/mep/mep-sem.cxx: Regenerate. > * component/cgen-cpu/mep/mep.cxx (mep_cpu): Connect > write-hint pin. > (do_cache): Add C5 support. > (do_cache_prefetch): Likewise. > (do_casb3, do_cash3, do_casw3): New. > * component/cgen-cpu/mep/mep.h: Add C5 support and write-hint pin. > (do_casb3, do_cash3, do_casw3): New. > > * component/families/mep/Makefile.in: Regenerate. > * component/families/mep/dsu.in: Add C5 support. > * main/dynamic/mainDynamic.cxx: Add C5 support. > * main/dynamic/mepCfg.cxx: Connect write-hint pin. > * main/dynamic/mepCfg.h: Add C5 support. > > Index: component/cache/cache.cxx > =================================================================== > RCS file: /cvs/src/src/sid/component/cache/cache.cxx,v > retrieving revision 1.23 > diff -p -U3 -r1.23 component/cache/cache.cxx > --- component/cache/cache.cxx 5 Feb 2007 20:28:39 -0000 1.23 > +++ component/cache/cache.cxx 8 Apr 2009 02:47:11 -0000 > @@ -68,6 +68,7 @@ cache_component::cache_component (unsign > invalidate_set_pin (this, &cache_component::invalidate_set), > flush_and_invalidate_pin (this, &cache_component::flush_and_invalidate_line), > prefetch_pin (this, &cache_component::prefetch_line), > + write_hint_pin (this, &cache_component::write_hint), > lock_pin (this, &cache_component::lock_line), > unlock_pin (this, &cache_component::unlock_line), > write_allocate_p (false), > @@ -101,6 +102,7 @@ cache_component::cache_component (unsign > add_pin ("invalidate", &invalidate_pin); > add_pin ("flush-and-invalidate", &flush_and_invalidate_pin); > add_pin ("prefetch", &prefetch_pin); > + add_pin ("write-hint", &write_hint_pin); > add_pin ("lock", &lock_pin); > add_pin ("unlock", &unlock_pin); > add_pin ("operation-status", &operation_status_pin); > @@ -355,6 +357,64 @@ cache_component::read_any (host_int_4 ad > return st; > } > > +// Prepare a line for writing. This means we are expecting to write > +// to all the bytes in the line, so we set it up to *not* read the > +// line from the cache on the first write to it, by making the line > +// valid if needed. As a side effect, if you don't write to all the > +// bytes in the line, unwritten bytes are undefined when written to > +// memory. > +void > +cache_component::write_hint (host_int_4 addr) > +{ > + bus::status st, read_status; > + > + if (UNLIKELY (downstream == 0)) > + return; > + > + if (LIKELY (collect_p)) > + stats.reads++; > + > + cache_tag tag = acache.addr_to_tag (addr); > + cache_line* line = acache.find (tag); > + if (LIKELY (line)) > + { > + // Line already exists in cache, nothing to do. > + } > + else > + { > + // miss! > + if (acache.vacancy_p (addr)) > + { > + if (LIKELY (collect_p)) > + stats.replacements++; > + > + cache_line *expelled_line = acache.expell_line (tag); > + assert (expelled_line); > + if (expelled_line->valid_p () && expelled_line->dirty_p ()) > + { > + // flush a dirty line being replaced > + if ((st = write_line (*expelled_line)) != bus::ok) > + return; > + } > + expelled_line->set_tag (tag); > + // We don't actually read the line, though. > + expelled_line->validate (); > + } > + else > + { > + // No room in the cache, so our hint must go uneeded. > + } > + } > + > + st = bus::ok; > + if (line) > + st.latency += hit_latency; > + else > + st.latency = miss_latency; > + report_status (st); > + return; > +} > + > bus::status > cache_component::read_line (cache_line& line) > { > Index: component/cache/cache.h > =================================================================== > RCS file: /cvs/src/src/sid/component/cache/cache.h,v > retrieving revision 1.11 > diff -p -U3 -r1.11 component/cache/cache.h > --- component/cache/cache.h 10 May 2005 15:41:05 -0000 1.11 > +++ component/cache/cache.h 8 Apr 2009 02:47:11 -0000 > @@ -168,6 +168,9 @@ protected: > callback_pin prefetch_pin; > virtual void prefetch_line (host_int_4 addr); > > + callback_pin write_hint_pin; > + virtual void write_hint (host_int_4 addr); > + > callback_pin lock_pin; > virtual void lock_line (host_int_4 addr); > > Index: component/cgen-cpu/mep/mep.cxx > =================================================================== > RCS file: /cvs/src/src/sid/component/cgen-cpu/mep/mep.cxx,v > retrieving revision 1.1 > diff -p -U3 -r1.1 component/cgen-cpu/mep/mep.cxx > --- component/cgen-cpu/mep/mep.cxx 5 Feb 2007 20:28:40 -0000 1.1 > +++ component/cgen-cpu/mep/mep.cxx 8 Apr 2009 02:47:13 -0000 > @@ -133,6 +133,7 @@ mep_cpu::mep_cpu () > add_watchable_pin ("cache-index-invalidate", &cache_index_invalidate_pin); > add_watchable_pin ("cache-index-flush-and-invalidate", &cache_index_flush_and_invalidate_pin); > add_watchable_pin ("cache-prefetch", &cache_prefetch_pin); > + add_watchable_pin ("cache-write-hint", &cache_write_hint_pin); > add_watchable_pin ("data-cache-invalidate-all", &data_cache_invalidate_all_pin); > add_watchable_pin ("insn-cache-invalidate-all", &insn_cache_invalidate_all_pin); > add_watchable_pin ("cache-operation-status", &cache_operation_status_pin); > @@ -922,8 +923,16 @@ mep_cpu::do_cache (USI& op, int& rma, PC > check_option_dcache (pc); > cache_index_flush_and_invalidate_pin.drive (value); > break; > + case 5: > + if (core_type () == CORE_C5) > + { > + check_option_dcache (pc); > + cache_write_hint_pin.drive (value); > + } > + break; > case 6: // address > - if (core_type () == CORE_H1) > + if (core_type () == CORE_H1 > + || core_type () == CORE_C5) > { > check_option_dcache (pc); > cache_invalidate_pin.drive (value); > @@ -962,10 +971,11 @@ mep_cpu::do_cache (USI& op, int& rma, PC > } > > VOID > -mep_cpu::do_cache_prefetch (USI& op, int& rma, PCADDR& pc) > +mep_cpu::do_cache_prefetch (USI& op, int rma, PCADDR& pc) > { > - // Only implemented on the H1 core. > - if (core_type () != CORE_H1) > + // Only implemented on the H1 and C5 cores. > + if (core_type () != CORE_H1 > + && core_type () != CORE_C5) > { > invalid_insn (pc); > return; > @@ -1190,6 +1200,58 @@ mep_cpu::do_sleep () > sleeping_p = true; > } > > +// C5 Instructions > + > +VOID > +mep_cpu::do_casb3 (SI rl, SI rn, UINT word_addr, UINT pc) > +{ > + SI temp; > + > + // Compare and swap byte: > + // temp <- Rl > + // Rl <- ZeroExt (MemByte (Rm)) > + // if (temp == Rl) > + // MemByte (Rm) <- Rn [0..7] > + // else > + // MemByte (Rm) <- Rl [0..7] > + > + temp = h_gpr_get (rl); > + h_gpr_set (rl, ZEXTQISI (GETMEMQI (pc, word_addr))); > + > + if (temp == h_gpr_get (rl)) > + SETMEMQI (pc, word_addr, rn); > + else > + SETMEMQI (pc, word_addr, rl); > +} > + > +VOID > +mep_cpu::do_cash3 (SI rl, SI rn, UINT word_addr, UINT pc) > +{ > + SI temp; > + > + temp = h_gpr_get (rl); > + h_gpr_set (rl, ZEXTHISI (GETMEMHI (pc, word_addr))); > + > + if (temp == h_gpr_get (rl)) > + SETMEMHI (pc, word_addr, rn); > + else > + SETMEMHI (pc, word_addr, rl); > +} > + > +VOID > +mep_cpu::do_casw3 (SI rl, SI rn, UINT word_addr, UINT pc) > +{ > + SI temp; > + > + temp = h_gpr_get (rl); > + h_gpr_set (rl, GETMEMSI (pc, word_addr)); > + > + if (temp == h_gpr_get (rl)) > + SETMEMSI (pc, word_addr, rn); > + else > + SETMEMSI (pc, word_addr, rl); > +} > + > // UCI/DSP pin protocols > > SI > Index: component/cgen-cpu/mep/mep.h > =================================================================== > RCS file: /cvs/src/src/sid/component/cgen-cpu/mep/mep.h,v > retrieving revision 1.2 > diff -p -U3 -r1.2 component/cgen-cpu/mep/mep.h > --- component/cgen-cpu/mep/mep.h 3 Feb 2009 21:29:28 -0000 1.2 > +++ component/cgen-cpu/mep/mep.h 8 Apr 2009 02:47:13 -0000 > @@ -166,7 +166,7 @@ namespace mep > SI do_ldcb (UINT word_addr); > VOID do_stcb (SI rn, UINT word_addr); > VOID do_cache (USI& op, int& addr, PCADDR& pc); > - VOID do_cache_prefetch (USI& op, int& addr, PCADDR& pc); > + VOID do_cache_prefetch (USI& op, int addr, PCADDR& pc); > > VOID do_smcp (USI rma, DI crn, PCADDR &pc); > VOID do_smcpa (UINT rma_ix, SI cdisp8a8, DI crn, PCADDR &pc); > @@ -179,6 +179,11 @@ namespace mep > VOID do_sleep (); > VOID check_write_to_text (UINT address); > > + // C5 instructions > + VOID do_casb3 (SI rl, SI rn, UINT word_addr, UINT pc); > + VOID do_cash3 (SI rl, SI rn, UINT word_addr, UINT pc); > + VOID do_casw3 (SI rl, SI rn, UINT word_addr, UINT pc); > + > // Methods for checking if an instruction class is activated. > VOID check_option_abs (PCADDR &pc) { check_option (ABS, pc); } > VOID check_option_ave (PCADDR &pc) { check_option (AVE, pc); } > @@ -247,10 +252,17 @@ namespace mep > static const int CORE_C2 = 0x02; > static const int CORE_C3 = 0x03; > static const int CORE_C4 = 0x04; > + static const int CORE_C5 = 0x50; > static const int CORE_H1 = 0x10; > int core_type () const { return (h_csr_get (17) >> 8) & 0xff; } > - int machine () const { return core_type () == CORE_H1 ? bfd_mach_mep_h1 : bfd_mach_mep; } > - const char *machine_name () const { return core_type () == CORE_H1 ? "h1" : "mep"; } > + int machine () const { switch (core_type ()) { > + case CORE_H1 : return bfd_mach_mep_h1; > + case CORE_C5 : return bfd_mach_mep_c5; > + default: return bfd_mach_mep; } } > + const char *machine_name () const { switch (core_type ()) { > + case CORE_H1 : return "h1"; > + case CORE_C5 : return "c5"; > + default: return "mep"; } } > > private: > bool hw_debugger_p; > @@ -343,6 +355,7 @@ namespace mep > output_pin cache_flush_and_invalidate_pin; > output_pin cache_index_flush_and_invalidate_pin; > output_pin cache_prefetch_pin; > + output_pin cache_write_hint_pin; > output_pin data_cache_invalidate_all_pin; > output_pin insn_cache_invalidate_all_pin; > > Index: component/families/mep/dsu.h > =================================================================== > RCS file: /cvs/src/src/sid/component/families/mep/dsu.h,v > retrieving revision 1.1 > diff -p -U3 -r1.1 component/families/mep/dsu.h > --- component/families/mep/dsu.h 5 Feb 2007 20:28:40 -0000 1.1 > +++ component/families/mep/dsu.h 8 Apr 2009 02:47:13 -0000 > @@ -24,6 +24,7 @@ using namespace sid; > #define MEP_CORE_C2 0x02 > #define MEP_CORE_C3 0x03 > #define MEP_CORE_C4 0x04 > +#define MEP_CORE_C5 0x08 > #define MEP_CORE_H1 0x10 > > class mep_dsu; > @@ -133,7 +134,8 @@ private: > big_int_4 get_ibc0_te () { return ibc0_te; } > void set_ibc0_te (big_int_4 value, big_int_4 mask) > { > - if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1) > + if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1 > + || core_type == MEP_CORE_C5) > ibc0_te = value & mask; > } > > @@ -141,7 +143,8 @@ private: > big_int_4 get_dbc0_te () { return dbc0_te; } > void set_dbc0_te (big_int_4 value, big_int_4 mask) > { > - if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1) > + if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1 > + || core_type == MEP_CORE_C5) > dbc0_te = value & mask; > } > > Index: main/dynamic/mainDynamic.cxx > =================================================================== > RCS file: /cvs/src/src/sid/main/dynamic/mainDynamic.cxx,v > retrieving revision 1.13 > diff -p -U3 -r1.13 main/dynamic/mainDynamic.cxx > --- main/dynamic/mainDynamic.cxx 3 Feb 2009 21:29:29 -0000 1.13 > +++ main/dynamic/mainDynamic.cxx 8 Apr 2009 02:47:13 -0000 > @@ -51,7 +51,7 @@ static BoardCfg * > mk_default (const string name, SessionCfg *sess) > { > MepBoardCfg *b = new MepBoardCfg (name, "default", sess); > - b->set_core_type (MEP_CORE_C4); > + b->set_core_type (MEP_CORE_C5); > b->set_cpu ("mep-ext1"); > b->add_irq_board (); > b->set_imem_size (32); > Index: main/dynamic/mepCfg.cxx > =================================================================== > RCS file: /cvs/src/src/sid/main/dynamic/mepCfg.cxx,v > retrieving revision 1.4 > diff -p -U3 -r1.4 main/dynamic/mepCfg.cxx > --- main/dynamic/mepCfg.cxx 3 Feb 2009 21:29:29 -0000 1.4 > +++ main/dynamic/mepCfg.cxx 8 Apr 2009 02:47:14 -0000 > @@ -910,6 +910,7 @@ public: > conn_pin (my_cpu, "cache-flush-and-invalidate", my_cache, "flush-and-invalidate"); > conn_pin (my_cpu, "cache-index-flush-and-invalidate", my_cache, "flush-and-invalidate-set"); > conn_pin (my_cpu, "cache-prefetch", my_cache, "prefetch"); > + conn_pin (my_cpu, "cache-write-hint", my_cache, "write-hint"); > conn_pin (my_cpu, "data-cache-invalidate-all", my_cache, "invalidate-all"); > > if (bit_insn_probe) > Index: main/dynamic/mepCfg.h > =================================================================== > RCS file: /cvs/src/src/sid/main/dynamic/mepCfg.h,v > retrieving revision 1.1 > diff -p -U3 -r1.1 main/dynamic/mepCfg.h > --- main/dynamic/mepCfg.h 5 Feb 2007 20:28:42 -0000 1.1 > +++ main/dynamic/mepCfg.h 8 Apr 2009 02:47:14 -0000 > @@ -27,6 +27,7 @@ class MepBusArbitratorCfg; > #define MEP_CORE_C2 0x02 > #define MEP_CORE_C3 0x03 > #define MEP_CORE_C4 0x04 > +#define MEP_CORE_C5 0x08 > #define MEP_CORE_H1 0x10 > > class MepBoardCfg : >