From b884fcf412f43ae8e1d365f23846f0f8e912ef1a Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Tue, 25 Mar 2014 13:15:04 -0500 Subject: [PATCH] cpu: o3: lsq: Fix TSO implementation This patch fixes violation of TSO in the O3CPU, as all loads must be ordered with all other loads. In the LQ, if a snoop is observed, all subsequent loads need to be squashed if the system is TSO. Prior to this patch, the following case could be violated: P0 | P1 ; MOV [x],mail=/usr/spool/mail/nilay | MOV EAX,[y] ; MOV [y],mail=/usr/spool/mail/nilay | MOV EBX,[x] ; exists (1:EAX=1 /\ 1:EBX=0) [is a violation] The problem was found using litmus [http://diy.inria.fr]. Committed by: Nilay Vaish ::checkSnoop(PacketPtr pkt) incrLdIdx(load_idx); + bool force_squash = false; + while (load_idx != loadTail) { DynInstPtr ld_inst = loadQueue[load_idx]; @@ -476,8 +478,14 @@ LSQUnit::checkSnoop(PacketPtr pkt) DPRINTF(LSQUnit, "-- inst [sn:%lli] load_addr: %#x to pktAddr:%#x\n", ld_inst->seqNum, load_addr, invalidate_addr); - if (load_addr == invalidate_addr) { - if (ld_inst->possibleLoadViolation()) { + if (load_addr == invalidate_addr || force_squash) { + if (needsTSO) { + // If we have a TSO system, as all loads must be ordered with + // all other loads, this load as well as *all* subsequent loads + // need to be squashed to prevent possible load reordering. + force_squash = true; + } + if (ld_inst->possibleLoadViolation() || force_squash) { DPRINTF(LSQUnit, "Conflicting load at addr %#x [sn:%lli]\n", pkt->getAddr(), ld_inst->seqNum);