123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- From 9fba0468e75877cbda62f5eaeef1946d6489a8f9 Mon Sep 17 00:00:00 2001
- From: Angel Pons <th3fanbus@gmail.com>
- Date: Sun, 8 May 2022 00:56:00 +0200
- Subject: [PATCH 19/26] haswell NRI: Add range tracking library
- Implement a small library used to keep track of passing ranges. This
- will be used by 1D training algorithms when margining some parameter.
- Change-Id: I8718e85165160afd7c0c8e730b5ce6c9c00f8a60
- Signed-off-by: Angel Pons <th3fanbus@gmail.com>
- ---
- .../intel/haswell/native_raminit/Makefile.inc | 1 +
- .../intel/haswell/native_raminit/ranges.c | 109 ++++++++++++++++++
- .../intel/haswell/native_raminit/ranges.h | 68 +++++++++++
- 3 files changed, 178 insertions(+)
- create mode 100644 src/northbridge/intel/haswell/native_raminit/ranges.c
- create mode 100644 src/northbridge/intel/haswell/native_raminit/ranges.h
- diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc
- index 6e1b365602..2da950771d 100644
- --- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc
- +++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc
- @@ -9,6 +9,7 @@ romstage-y += io_comp_control.c
- romstage-y += memory_map.c
- romstage-y += raminit_main.c
- romstage-y += raminit_native.c
- +romstage-y += ranges.c
- romstage-y += reut.c
- romstage-y += setup_wdb.c
- romstage-y += spd_bitmunching.c
- diff --git a/src/northbridge/intel/haswell/native_raminit/ranges.c b/src/northbridge/intel/haswell/native_raminit/ranges.c
- new file mode 100644
- index 0000000000..cdebc1fa66
- --- /dev/null
- +++ b/src/northbridge/intel/haswell/native_raminit/ranges.c
- @@ -0,0 +1,109 @@
- +/* SPDX-License-Identifier: GPL-2.0-or-later */
- +
- +#include <types.h>
- +
- +#include "ranges.h"
- +
- +void linear_record_pass(
- + struct linear_train_data *const data,
- + const bool pass,
- + const int32_t value,
- + const int32_t start,
- + const int32_t step)
- +{
- + /* If this is the first time, initialize all values */
- + if (value == start) {
- + /*
- + * If value passed, create a zero-length region for the current value,
- + * which may be extended as long as the successive values are passing.
- + *
- + * Otherwise, create a zero-length range for the preceding value. This
- + * range cannot be extended by other passing values, which is desired.
- + */
- + data->current.start = start - (pass ? 0 : step);
- + data->current.end = data->current.start;
- + data->largest = data->current;
- + } else if (pass) {
- + /* If this pass is not contiguous, it belongs to a new region */
- + if (data->current.end != (value - step))
- + data->current.start = value;
- +
- + /* Update end of current region */
- + data->current.end = value;
- +
- + /* Update largest region */
- + if (range_width(data->current) > range_width(data->largest))
- + data->largest = data->current;
- + }
- +}
- +
- +void phase_record_pass(
- + struct phase_train_data *const data,
- + const bool pass,
- + const int32_t value,
- + const int32_t start,
- + const int32_t step)
- +{
- + /* If this is the first time, initialize all values */
- + if (value == start) {
- + /*
- + * If value passed, create a zero-length region for the current value,
- + * which may be extended as long as the successive values are passing.
- + *
- + * Otherwise, create a zero-length range for the preceding value. This
- + * range cannot be extended by other passing values, which is desired.
- + */
- + data->current.start = start - (pass ? 0 : step);
- + data->current.end = data->current.start;
- + data->largest = data->current;
- + data->initial = data->current;
- + return;
- + }
- + if (!pass)
- + return;
- +
- + /* Update initial region */
- + if (data->initial.end == (value - step))
- + data->initial.end = value;
- +
- + /* If this pass is not contiguous, it belongs to a new region */
- + if (data->current.end != (value - step))
- + data->current.start = value;
- +
- + /* Update end of current region */
- + data->current.end = value;
- +
- + /* Update largest region */
- + if (range_width(data->current) > range_width(data->largest))
- + data->largest = data->current;
- +}
- +
- +void phase_append_initial_to_current(
- + struct phase_train_data *const data,
- + const int32_t start,
- + const int32_t step)
- +{
- + /* If initial region is valid and does not overlap, append it */
- + if (data->initial.start == start && data->initial.end != data->current.end)
- + data->current.end += step + range_width(data->initial);
- +
- + /* Update largest region */
- + if (range_width(data->current) > range_width(data->largest))
- + data->largest = data->current;
- +}
- +
- +void phase_append_current_to_initial(
- + struct phase_train_data *const data,
- + const int32_t start,
- + const int32_t step)
- +{
- + /* If initial region is valid and does not overlap, append it */
- + if (data->initial.start == start && data->initial.end != data->current.end) {
- + data->initial.start -= (step + range_width(data->current));
- + data->current = data->initial;
- + }
- +
- + /* Update largest region */
- + if (range_width(data->current) > range_width(data->largest))
- + data->largest = data->current;
- +}
- diff --git a/src/northbridge/intel/haswell/native_raminit/ranges.h b/src/northbridge/intel/haswell/native_raminit/ranges.h
- new file mode 100644
- index 0000000000..235392df96
- --- /dev/null
- +++ b/src/northbridge/intel/haswell/native_raminit/ranges.h
- @@ -0,0 +1,68 @@
- +/* SPDX-License-Identifier: GPL-2.0-or-later */
- +
- +#ifndef HASWELL_RAMINIT_RANGES_H
- +#define HASWELL_RAMINIT_RANGES_H
- +
- +#include <types.h>
- +
- +/*
- + * Many algorithms shmoo some parameter to determine the largest passing
- + * range. Provide a common implementation to avoid redundant boilerplate.
- + */
- +struct passing_range {
- + int32_t start;
- + int32_t end;
- +};
- +
- +/* Structure for linear parameters, such as roundtrip delays */
- +struct linear_train_data {
- + struct passing_range current;
- + struct passing_range largest;
- +};
- +
- +/*
- + * Phase ranges are "circular": the first and last indices are contiguous.
- + * To correctly determine the largest passing range, one has to combine
- + * the initial range and the current range when processing the last index.
- + */
- +struct phase_train_data {
- + struct passing_range initial;
- + struct passing_range current;
- + struct passing_range largest;
- +};
- +
- +static inline int32_t range_width(const struct passing_range range)
- +{
- + return range.end - range.start;
- +}
- +
- +static inline int32_t range_center(const struct passing_range range)
- +{
- + return range.start + range_width(range) / 2;
- +}
- +
- +void linear_record_pass(
- + struct linear_train_data *data,
- + bool pass,
- + int32_t value,
- + int32_t start,
- + int32_t step);
- +
- +void phase_record_pass(
- + struct phase_train_data *data,
- + bool pass,
- + int32_t value,
- + int32_t start,
- + int32_t step);
- +
- +void phase_append_initial_to_current(
- + struct phase_train_data *data,
- + int32_t start,
- + int32_t step);
- +
- +void phase_append_current_to_initial(
- + struct phase_train_data *data,
- + int32_t start,
- + int32_t step);
- +
- +#endif
- --
- 2.39.2
|