Skip to content

Commit 1143ae0

Browse files
SapthagiriPchetan-rathore
authored andcommitted
fix: Keep the MAIR register intact and update free slots
- modify the logic to dynamically read MAIR and update with additional attributes but keeping the old attributes at same index Signed-off-by: sapthagiri padmanabhan <sapthagiri.padmanabhan@arm.com> Change-Id: I7309afa22482be0e518e7ee4ee6856118bd9dcdb
1 parent 56b77ce commit 1143ae0

File tree

1 file changed

+43
-16
lines changed

1 file changed

+43
-16
lines changed

val/src/acs_mmu.c

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ uint32_t val_mmu_update_entry(uint64_t address, uint32_t size, uint64_t attr)
228228
/**
229229
@brief This is local function is used to get log base 2 of input value.
230230
231-
@param value - input value
231+
@param value - input value.
232232
233233
@return result
234234
**/
@@ -258,27 +258,54 @@ void val_setup_mair_register(void)
258258
MAIR_DEVICE_nGnRnE, MAIR_NORMAL_NC, MAIR_NORMAL_WT_AGR,
259259
MAIR_NORMAL_WB, MAIR_DEVICE_nGnRE, MAIR_DEVICE_nGRE, MAIR_DEVICE_GRE,
260260
MAIR_NORMAL_WT};
261-
uint64_t mair_val = 0;
261+
uint64_t mair_val;
262+
uint64_t current_mair;
263+
uint8_t attr_seen[256];
264+
uint8_t free_slots[8];
265+
uint32_t free_cnt = 0;
262266

263267
currentEL = (val_read_current_el() & 0xc) >> 2;
264-
/*
265-
* Setup Memory Attribute Indirection Register
266-
* Attr0 = MAIR_DEVICE_nGnRnE
267-
* Attr1 = MAIR_NORMAL_NC
268-
* Attr2 = MAIR_NORMAL_WT_AGR
269-
* Attr3 = MAIR_NORMAL_WB
270-
* Attr4 = MAIR_DEVICE_nGnRE
271-
* Attr5 = MAIR_DEVICE_nGRE
272-
* Attr6 = MAIR_DEVICE_GRE
273-
* Attr7 = MAIR_NORMAL_WT
274-
*/
275-
for (uint64_t attr = 0; attr < (sizeof(mair_attr) / sizeof(mair_attr[0])); attr++)
268+
269+
current_mair = val_pe_reg_read(MAIR_ELx);
270+
mair_val = current_mair;
271+
272+
val_memory_set(attr_seen, sizeof(attr_seen), 0);
273+
/* Identify unique existing attributes so we leave them untouched,
274+
and treat any duplicate slots as available for new attributes. */
275+
for (uint32_t idx = 0; idx < 8; idx++) {
276+
uint8_t entry = (current_mair >> (idx * 8)) & 0xFF;
277+
278+
if (!attr_seen[entry]) {
279+
attr_seen[entry] = 1;
280+
} else {
281+
free_slots[free_cnt++] = idx;
282+
}
283+
}
284+
285+
for (uint32_t attr = 0; attr < (sizeof(mair_attr) / sizeof(mair_attr[0])); attr++)
276286
{
277-
mair_val = mair_val | ((uint64_t)(mair_attr[attr]) << (attr * 8));
287+
uint8_t new_attr = mair_attr[attr];
288+
289+
if (attr_seen[new_attr])
290+
continue;
291+
292+
if (free_cnt == 0) {
293+
val_print(ACS_PRINT_WARN,
294+
"\n MAIR register full, could not add attribute 0x%02x", new_attr);
295+
break;
296+
}
297+
298+
uint32_t slot = free_slots[--free_cnt];
299+
mair_val &= ~((uint64_t)0xFF << (slot * 8));
300+
mair_val |= ((uint64_t)new_attr << (slot * 8));
301+
attr_seen[new_attr] = 1;
278302
}
279303

280-
val_mair_write(mair_val, currentEL);
304+
if (mair_val != current_mair)
305+
val_mair_write(mair_val, currentEL);
281306

307+
val_print(ACS_PRINT_DEBUG, "\n Previous MAIR register value 0x%lx", current_mair);
308+
val_print(ACS_PRINT_DEBUG, "\n Current MAIR register value 0x%lx\n", mair_val);
282309
return;
283310
}
284311

0 commit comments

Comments
 (0)