Patrick Rudolph (siro@das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13682
-gerrit
commit 7240ff990cfe56fcedbf3c66263e0cca17af2246 Author: Patrick Rudolph siro@das-labor.org Date: Wed Feb 10 19:16:34 2016 +0100
nb/intel/sandybridge/raminit: Make tests circular
Add support for circular buffers in edge write discovery and timC write discovery. It's unlikely, but possible, that rn.start > rn.end and as both tests aren't able to handle circular buffers they'll fail. Add circular buffer support, keep the margin and shrink the region in the tests if neccessary. It should decrease the number of raminit failures for both tests.
Experimental. Don't commit yet! Needs test on real hardware !
Change-Id: Id8c60217093a48bf322f406ea258c10a02c936e8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- src/northbridge/intel/sandybridge/raminit.c | 76 ++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 18 deletions(-)
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index aae963e..2749834 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -3159,6 +3159,7 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel, int lower[NUM_LANES]; int upper[NUM_LANES]; int pat; + int start_offset, end_offset;
FOR_ALL_LANES { lower[lane] = 0; @@ -3252,18 +3253,35 @@ static void discover_edges_write_real(ramctr_timing * ctrl, int channel, ! !(raw_statistics[edge] & (1 << lane)); rn = get_longest_zero_run(statistics, MAX_EDGE_TIMING + 1); + + start_offset = rn.start + ctrl->edge_offset[i]; + if (start_offset > MAX_EDGE_TIMING) + start_offset -= MAX_EDGE_TIMING; + + end_offset = rn.end - ctrl->edge_offset[i]; + if (end_offset < 0) + end_offset += MAX_EDGE_TIMING; + printram("edges: %d, %d, %d: 0x%x-0x%x-0x%x, 0x%x-0x%x\n", channel, slotrank, i, rn.start, rn.middle, - rn.end, rn.start + ctrl->edge_offset[i], - rn.end - ctrl->edge_offset[i]); + rn.end, start_offset, + end_offset); + if (rn.all) + die("edge write discovery failed (1)"); + if (rn.length < ctrl->edge_offset[i] * 2) + die("edge write discovery failed (2)"); + + if (start_offset > end_offset) + start_offset -= MAX_EDGE_TIMING; + lower[lane] = - max(rn.start + ctrl->edge_offset[i], lower[lane]); + max(start_offset, lower[lane]); upper[lane] = - min(rn.end - ctrl->edge_offset[i], upper[lane]); - edges[lane] = (lower[lane] + upper[lane]) / 2; - if (rn.all || (lower[lane] > upper[lane])) - die("edge write discovery failed"); + min(end_offset, upper[lane]);
+ edges[lane] = (lower[lane] + upper[lane]) / 2; + if (edges[lane] < 0) + edges[lane] += MAX_EDGE_TIMING; } } } @@ -3365,6 +3383,7 @@ static void discover_timC_write(ramctr_timing * ctrl) { const u8 rege3c_b24[3] = { 0, 0xf, 0x2f }; int i, pat; + int start_offset, end_offset;
int lower[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; int upper[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; @@ -3410,18 +3429,35 @@ static void discover_timC_write(ramctr_timing * ctrl) (1 << lane)); rn = get_longest_zero_run(statistics, MAX_TIMC + 1); - if (rn.all) - die("timC write discovery failed"); + + start_offset = rn.start + ctrl->timC_offset[i]; + if (start_offset > MAX_TIMC) + start_offset -= MAX_TIMC; + + end_offset = rn.end - ctrl->timC_offset[i]; + if (end_offset < 0) + end_offset += MAX_TIMC; + printram("timC: %d, %d, %d: 0x%x-0x%x-0x%x, 0x%x-0x%x\n", channel, slotrank, i, rn.start, rn.middle, rn.end, - rn.start + ctrl->timC_offset[i], - rn.end - ctrl->timC_offset[i]); + start_offset, + end_offset); + + if (rn.all) + die("timC write discovery failed (1)"); + + if (rn.length < ctrl->timC_offset[i] * 2) + die("timC write discovery failed (2)"); + + if (start_offset > end_offset) + start_offset -= MAX_TIMC; + lower[channel][slotrank][lane] = - max(rn.start + ctrl->timC_offset[i], + max(start_offset, lower[channel][slotrank][lane]); upper[channel][slotrank][lane] = - min(rn.end - ctrl->timC_offset[i], + min(end_offset, upper[channel][slotrank][lane]);
} @@ -3441,13 +3477,17 @@ static void discover_timC_write(ramctr_timing * ctrl) printram("CPB\n");
FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES { + int timC; + + timC = (lower[channel][slotrank][lane] + + upper[channel][slotrank][lane]) / 2; + if (timC < 0) + timC += MAX_TIMC; + ctrl->timings[channel][slotrank].lanes[lane].timC = + timC; printram("timC [%d, %d, %d] = 0x%x\n", channel, slotrank, lane, - (lower[channel][slotrank][lane] + - upper[channel][slotrank][lane]) / 2); - ctrl->timings[channel][slotrank].lanes[lane].timC = - (lower[channel][slotrank][lane] + - upper[channel][slotrank][lane]) / 2; + timC); } FOR_ALL_POPULATED_CHANNELS { program_timings(ctrl, channel);