<p>Nico Huber has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/21916">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP] cpu/x86/mtrr: Always allow holes<br><br>Now that calc_var_mtrrs_with_hole() always chooses the optimal<br>allocation, there is no need for calc_var_mtrrs_without_hole()<br>any more. Drop it and all the logic to decide which one to call.<br><br>Change-Id: Iedf7dfad61d6baac91973062e2688ad866f05afd<br>Signed-off-by: Nico Huber <nico.h@gmx.de><br>---<br>M src/cpu/x86/mtrr/mtrr.c<br>1 file changed, 12 insertions(+), 92 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/21916/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c<br>index 82666fc..d8df4d0 100644<br>--- a/src/cpu/x86/mtrr/mtrr.c<br>+++ b/src/cpu/x86/mtrr/mtrr.c<br>@@ -109,20 +109,8 @@<br> #define RANGE_1MB PHYS_TO_RANGE_ADDR(1 << 20)<br> #define RANGE_4GB (1 << (ADDR_SHIFT_TO_RANGE_SHIFT(32)))<br> <br>-/*<br>- * The default MTRR type selection uses 3 approaches for selecting the<br>- * optimal number of variable MTRRs. For each range do 3 calculations:<br>- * 1. UC as default type with no holes at top of range.<br>- * 2. UC as default using holes at top of range.<br>- * 3. WB as default.<br>- * If using holes is optimal for a range when UC is the default type the<br>- * tag is updated to direct the commit routine to use a hole at the top<br>- * of a range.<br>- */<br> #define MTRR_ALGO_SHIFT (8)<br> #define MTRR_TAG_MASK ((1 << MTRR_ALGO_SHIFT) - 1)<br>-/* If the default type is UC use the hole carving algorithm for a range. */<br>-#define MTRR_RANGE_UC_USE_HOLE (1 << MTRR_ALGO_SHIFT)<br> <br> static inline uint32_t range_entry_base_mtrr_addr(struct range_entry *r)<br> {<br>@@ -608,37 +596,6 @@<br> calc_var_mtrr_range(var_state, b1, b2 - b1, var_state->def_mtrr_type);<br> }<br> <br>-static void calc_var_mtrrs_without_hole(struct var_mtrr_state *var_state,<br>- struct range_entry *r)<br>-{<br>- const int mtrr_type = range_entry_mtrr_type(r);<br>-<br>- uint32_t base = range_entry_base_mtrr_addr(r);<br>- uint32_t end = range_entry_end_mtrr_addr(r);<br>-<br>- /* The end address is within the first 1MiB. The fixed MTRRs take<br>- * precedence over the variable ones. Therefore this range<br>- * can be ignored. */<br>- if (end <= RANGE_1MB)<br>- return;<br>-<br>- /* Again, the fixed MTRRs take precedence so the beginning<br>- * of the range can be set to 0 if it starts at or below 1MiB. */<br>- if (base <= RANGE_1MB)<br>- base = 0;<br>-<br>- /* If the range starts above 4GiB the processing is done. */<br>- if (!var_state->above4gb && base >= RANGE_4GB)<br>- return;<br>-<br>- /* Clip the upper address to 4GiB if addresses above 4GiB<br>- * are not being processed. */<br>- if (!var_state->above4gb && end > RANGE_4GB)<br>- end = RANGE_4GB;<br>-<br>- calc_var_mtrr_range(var_state, base, end - base, mtrr_type);<br>-}<br>-<br> static void __calc_var_mtrrs(struct memranges *addr_space,<br> int above4gb, int address_bits,<br> int *num_def_wb_mtrrs, int *num_def_uc_mtrrs)<br>@@ -660,16 +617,14 @@<br> uc_deftype_count = 0;<br> <br> /*<br>- * For each range do 3 calculations:<br>- * 1. UC as default type with no holes at top of range.<br>- * 2. UC as default using holes at top of range.<br>- * 3. WB as default.<br>+ * For each range do 2 calculations:<br>+ * 1. UC as default type with possible holes at top of range.<br>+ * 2. WB as default.<br> * The lowest count is then used as default after totaling all<br>- * MTRRs. Note that the optimal algorithm for UC default is marked in<br>- * the tag of each range regardless of final decision. UC takes<br>- * precedence in the MTRR architecture. Therefore, only holes can be<br>- * used when the type of the region is MTRR_TYPE_WRBACK with<br>- * MTRR_TYPE_UNCACHEABLE as the default type.<br>+ * MTRRs. UC takes precedence in the MTRR architecture. There-<br>+ * fore, only holes can be used when the type of the region is<br>+ * MTRR_TYPE_WRBACK with MTRR_TYPE_UNCACHEABLE as the default<br>+ * type.<br> */<br> memranges_each_entry(r, var_state.addr_space) {<br> int mtrr_type;<br>@@ -677,43 +632,16 @@<br> mtrr_type = range_entry_mtrr_type(r);<br> <br> if (mtrr_type != MTRR_TYPE_UNCACHEABLE) {<br>- int uc_hole_count;<br>- int uc_no_hole_count;<br>-<br>- var_state.def_mtrr_type = MTRR_TYPE_UNCACHEABLE;<br> var_state.mtrr_index = 0;<br>-<br>- /* No hole calculation. */<br>- calc_var_mtrrs_without_hole(&var_state, r);<br>- uc_no_hole_count = var_state.mtrr_index;<br>-<br>- /* Hole calculation only if type is WB. The 64 number<br>- * is a count that is unachievable, thus making it<br>- * a default large number in the case of not doing<br>- * the hole calculation. */<br>- uc_hole_count = 64;<br>- if (mtrr_type == MTRR_TYPE_WRBACK) {<br>- var_state.mtrr_index = 0;<br>- calc_var_mtrrs_with_hole(&var_state, r);<br>- uc_hole_count = var_state.mtrr_index;<br>- }<br>-<br>- /* Mark the entry with the optimal algorithm. */<br>- if (uc_no_hole_count < uc_hole_count) {<br>- uc_deftype_count += uc_no_hole_count;<br>- } else {<br>- unsigned long new_tag;<br>-<br>- new_tag = mtrr_type | MTRR_RANGE_UC_USE_HOLE;<br>- range_entry_update_tag(r, new_tag);<br>- uc_deftype_count += uc_hole_count;<br>- }<br>+ var_state.def_mtrr_type = MTRR_TYPE_UNCACHEABLE;<br>+ calc_var_mtrrs_with_hole(&var_state, r);<br>+ uc_deftype_count += var_state.mtrr_index;<br> }<br> <br> if (mtrr_type != MTRR_TYPE_WRBACK) {<br> var_state.mtrr_index = 0;<br> var_state.def_mtrr_type = MTRR_TYPE_WRBACK;<br>- calc_var_mtrrs_without_hole(&var_state, r);<br>+ calc_var_mtrrs_with_hole(&var_state, r);<br> wb_deftype_count += var_state.mtrr_index;<br> }<br> }<br>@@ -770,12 +698,7 @@<br> memranges_each_entry(r, var_state.addr_space) {<br> if (range_entry_mtrr_type(r) == def_type)<br> continue;<br>-<br>- if (def_type == MTRR_TYPE_UNCACHEABLE &&<br>- (range_entry_tag(r) & MTRR_RANGE_UC_USE_HOLE))<br>- calc_var_mtrrs_with_hole(&var_state, r);<br>- else<br>- calc_var_mtrrs_without_hole(&var_state, r);<br>+ calc_var_mtrrs_with_hole(&var_state, r);<br> }<br> <br> /* Update the solution. */<br>@@ -885,9 +808,6 @@<br> orig = get_physical_address_space();<br> memranges_each_entry(r, orig) {<br> unsigned long tag = range_entry_tag(r);<br>-<br>- /* Remove any special tags from original solution. */<br>- tag &= ~MTRR_RANGE_UC_USE_HOLE;<br> <br> /* Remove any write combining MTRRs from the temporary<br> * solution as it just fragments the address space. */<br></pre><p>To view, visit <a href="https://review.coreboot.org/21916">change 21916</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/21916"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iedf7dfad61d6baac91973062e2688ad866f05afd </div>
<div style="display:none"> Gerrit-Change-Number: 21916 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Nico Huber <nico.h@gmx.de> </div>