mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2026-08-26 13:17:12 -05:00
loongarch: Supports 2K2000/3B6000M (#512)
* loongarch: adjust 2K/3B6000M DDR rate factor * loongarch: Supports fewer cache layers than L3 For example: 2K2000 chip does not have L3, but has L2. If L2Cache is not flushed to memory, it will cause read and write data errors after cache_off.
This commit is contained in:
+26
-6
@@ -94,12 +94,22 @@ static inline void cache_flush(void)
|
||||
: "memory"
|
||||
);
|
||||
#elif defined (__loongarch_lp64)
|
||||
if (!(__cpucfg(0x10) & (1 << 10))) {
|
||||
return; // No L3
|
||||
uint64_t cache_present, cache_info_reg;
|
||||
/*detect_max_cache_level*/
|
||||
if (__cpucfg(0x10) & (1 << 10)) {
|
||||
cache_present = 3; //L3 unified cache
|
||||
} else if (__cpucfg(0x10) & (1 << 3)) {
|
||||
cache_present = 2; //L2 unified cache
|
||||
} else if (__cpucfg(0x10) & (1 << 0)) {
|
||||
cache_present = 1; //L1 data cache
|
||||
} else {
|
||||
return; //No Cache present
|
||||
}
|
||||
uint64_t ways = (__cpucfg(0x14) & 0xFFFF) + 1;
|
||||
uint64_t sets = 1 << ((__cpucfg(0x14) >> 16) & 0xFF);
|
||||
uint64_t line_size = 1 << ((__cpucfg(0x14) >> 24) & 0x7F);
|
||||
cache_info_reg = 0x11 + cache_present; //cache last leaf
|
||||
|
||||
uint64_t ways = (__cpucfg(cache_info_reg) & 0xFFFF) + 1;
|
||||
uint64_t sets = 1 << ((__cpucfg(cache_info_reg) >> 16) & 0xFF);
|
||||
uint64_t line_size = 1 << ((__cpucfg(cache_info_reg) >> 24) & 0x7F);
|
||||
uint64_t va, i, j;
|
||||
uint64_t cpu_module[1];
|
||||
va = 0;
|
||||
@@ -119,7 +129,17 @@ static inline void cache_flush(void)
|
||||
} else {
|
||||
for (i = 0; i < sets; i++) {
|
||||
for (j = 0; j < ways; j++) {
|
||||
cache_op(0xB, va);
|
||||
switch (cache_present) {
|
||||
case 1:
|
||||
cache_op(0x9,va); //Flush L1
|
||||
break;
|
||||
case 2:
|
||||
cache_op(0xA,va); //Flush L2
|
||||
break;
|
||||
case 3:
|
||||
cache_op(0xB,va); //Flush L3
|
||||
break;
|
||||
}
|
||||
va++;
|
||||
}
|
||||
va -= ways;
|
||||
|
||||
@@ -123,11 +123,12 @@ void get_imc_config_loongson_ddr4(void)
|
||||
{
|
||||
uint32_t val;
|
||||
uint16_t refc, loopc, div, div_mode, ref_clk;
|
||||
uint8_t max_mc, node_num;
|
||||
uint8_t max_mc, node_num, ddr_rate_factor;
|
||||
bool route_flag;
|
||||
|
||||
imc.type = "DDR4";
|
||||
node_num = 1;
|
||||
ddr_rate_factor = 4;
|
||||
|
||||
if (strstr(cpuid_info.brand_id.str, "3C") ||
|
||||
(strstr(cpuid_info.brand_id.str, "3B6000") &&
|
||||
@@ -150,6 +151,7 @@ void get_imc_config_loongson_ddr4(void)
|
||||
strstr(cpuid_info.brand_id.str, "3B6000M")) {
|
||||
route_flag = false;
|
||||
max_mc = 1;
|
||||
ddr_rate_factor = 2;
|
||||
} else {
|
||||
route_flag = false;
|
||||
max_mc = 0;
|
||||
@@ -164,7 +166,7 @@ void get_imc_config_loongson_ddr4(void)
|
||||
div_mode = 0x1 << ((val >> 4) & 0x3);
|
||||
refc = (val >> 8) & 0x1f;
|
||||
ref_clk = (uint16_t)(((__cpucfg(0x4) * (__cpucfg(0x5) & 0xFFFF)) / ((__cpucfg(0x5) >> 16) & 0xFFFF)) / 1000000);
|
||||
imc.freq = (ref_clk * loopc / refc / div / div_mode) * 4;
|
||||
imc.freq = (ref_clk * loopc / refc / div / div_mode) * ddr_rate_factor;
|
||||
} else {
|
||||
imc.freq = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user