Compare commits

..

No commits in common. "main" and "v6.10" have entirely different histories.
main ... v6.10

21 changed files with 160 additions and 472 deletions

View file

@ -20,7 +20,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
compiler: [gcc, clang] compiler: [gcc, clang]
os: [ubuntu-20.04, ubuntu-22.04] os: [ubuntu-18.04, ubuntu-20.04, ubuntu-22.04]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View file

@ -6,7 +6,7 @@ jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v8 - uses: actions/stale@v7
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
exempt-issue-milestones: 'future,alpha,beta,release' exempt-issue-milestones: 'future,alpha,beta,release'

View file

@ -157,7 +157,7 @@ recognised:
* 9600 * 9600
* 19200 * 19200
* 38400 * 38400
* 57600 * 54600
* 115200 (default if not specified or invalid) * 115200 (default if not specified or invalid)
* 230400 * 230400

View file

@ -409,7 +409,6 @@ void check_input(void)
return; return;
} else if (big_status_displayed) { } else if (big_status_displayed) {
restore_big_status(); restore_big_status();
enable_big_status = false;
} }
switch (input_key) { switch (input_key) {

View file

@ -251,8 +251,6 @@ static void global_init(void)
error_init(); error_init();
temperature_init();
initial_config(); initial_config();
clear_message_area(); clear_message_area();
@ -671,8 +669,7 @@ void main(void)
if (error_count == 0) { if (error_count == 0) {
display_status("Pass "); display_status("Pass ");
display_big_status(true); display_big_status(true);
} else { //display_notice("** Pass completed, no errors **");
display_big_status(false);
} }
} }
} }

View file

@ -1,2 +1,2 @@
#define MT_VERSION "6.20" #define MT_VERSION "6.10"
#define GIT_HASH "unknown" #define GIT_HASH "unknown"

View file

@ -502,10 +502,6 @@ static efi_status_t set_screen_info(boot_params_t *boot_params)
status = EFI_SUCCESS; status = EFI_SUCCESS;
} }
efi_call_bs(free_pool, handles); efi_call_bs(free_pool, handles);
} else if (status == EFI_NOT_FOUND) {
// This may be a headless system. We can still output to a serial console.
boot_params->screen_info.orig_video_isVGA = VIDEO_TYPE_NONE;
status = EFI_SUCCESS;
} }
return status; return status;

View file

@ -78,11 +78,11 @@ boot/header.o : | ../boot/sbat.csv
boot/startup.o: ../boot/startup64.S ../boot/boot.h boot/startup.o: ../boot/startup64.S ../boot/boot.h
@mkdir -p boot @mkdir -p boot
$(CC) -m64 -x assembler-with-cpp -c -I../boot -o $@ $< $(CC) -x assembler-with-cpp -c -I../boot -o $@ $<
boot/%.o: ../boot/%.S ../boot/boot.h app/build_version.h boot/%.o: ../boot/%.S ../boot/boot.h app/build_version.h
@mkdir -p boot @mkdir -p boot
$(CC) -m64 -x assembler-with-cpp -c -I../boot -Iapp -o $@ $< $(CC) -x assembler-with-cpp -c -I../boot -Iapp -o $@ $<
boot/efisetup.o: ../boot/efisetup.c boot/efisetup.o: ../boot/efisetup.c
@mkdir -p boot @mkdir -p boot

View file

@ -4,7 +4,7 @@
// //
// Derived from memtest86+ cpuid.h // Derived from memtest86+ cpuid.h
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "cpuid.h" #include "cpuid.h"
@ -36,7 +36,7 @@ void cpuid_init(void)
// Get the processor family information & feature flags. // Get the processor family information & feature flags.
if (cpuid_info.max_cpuid >= 1) { if (cpuid_info.max_cpuid >= 1) {
cpuid(0x1, 0, cpuid(0x1, 0,
&cpuid_info.version.raw[0], &cpuid_info.version.raw,
&cpuid_info.proc_info.raw, &cpuid_info.proc_info.raw,
&cpuid_info.flags.raw[1], &cpuid_info.flags.raw[1],
&cpuid_info.flags.raw[0] &cpuid_info.flags.raw[0]
@ -65,8 +65,8 @@ void cpuid_init(void)
if (cpuid_info.max_xcpuid >= 0x80000001) { if (cpuid_info.max_xcpuid >= 0x80000001) {
cpuid(0x80000001, 0, cpuid(0x80000001, 0,
&reg[0], &reg[0],
&cpuid_info.version.raw[1],
&reg[1], &reg[1],
&reg[2],
&cpuid_info.flags.raw[2] &cpuid_info.flags.raw[2]
); );
} }
@ -108,6 +108,9 @@ void cpuid_init(void)
} }
// Get cache information. // Get cache information.
switch (cpuid_info.vendor_id.str[0]) {
case 'A':
// AMD Processors
if (cpuid_info.max_xcpuid >= 0x80000005) { if (cpuid_info.max_xcpuid >= 0x80000005) {
cpuid(0x80000005, 0, cpuid(0x80000005, 0,
&reg[0], &reg[0],
@ -124,6 +127,12 @@ void cpuid_init(void)
&cpuid_info.cache_info.raw[3] &cpuid_info.cache_info.raw[3]
); );
} }
break;
case 'G':
// Intel Processors
// No cpuid info to read.
break;
}
// Detect CPU Topology (Core/Thread) infos // Detect CPU Topology (Core/Thread) infos
cpuid_info.topology.core_count = -1; cpuid_info.topology.core_count = -1;
@ -167,8 +176,7 @@ void cpuid_init(void)
} }
break; break;
case 'C': case 'C':
// Cyrix / VIA / CentaurHauls / Zhaoxin // VIA / CentaurHauls
cpuid_info.flags.htt = false;
break; break;
case 'G': case 'G':
if (cpuid_info.vendor_id.str[7] == 'T') break; // Transmeta if (cpuid_info.vendor_id.str[7] == 'T') break; // Transmeta

View file

@ -29,7 +29,7 @@ typedef enum {
*/ */
typedef union { typedef union {
uint32_t raw[2]; uint32_t raw;
struct { struct {
uint32_t stepping : 4; uint32_t stepping : 4;
uint32_t model : 4; uint32_t model : 4;
@ -39,7 +39,6 @@ typedef union {
uint32_t extendedModel : 4; uint32_t extendedModel : 4;
uint32_t extendedFamily : 8; uint32_t extendedFamily : 8;
uint32_t : 4; uint32_t : 4;
uint32_t extendedBrandID : 32; // AMD Only
}; };
} cpuid_version_t; } cpuid_version_t;
@ -123,7 +122,7 @@ typedef union {
} cpuid_brand_string_t; } cpuid_brand_string_t;
typedef union { typedef union {
uint32_t raw[4]; uint32_t raw[12];
struct { struct {
uint32_t : 24; uint32_t : 24;
uint32_t l1_i_size : 8; uint32_t l1_i_size : 8;

View file

@ -71,45 +71,12 @@ static void determine_cache_size()
l3_cache *= 512; l3_cache *= 512;
break; break;
case 'C': case 'C':
if (cpuid_info.vendor_id.str[5] == 'I') {
// Cyrix
if (cpuid_info.version.family == 5 && cpuid_info.version.model == 4) {
// Media GXm, Geode GXm/GXLV/GX1
// Cache info in CPUID has a Cyrix-specific encoding so hardcode it
l1_cache = 16;
}
break;
}
// WinChip 2/3, VIA C3/C7/Nano
if (cpuid_info.version.family == 5 || cpuid_info.version.family == 6) {
l1_cache = cpuid_info.cache_info.l1_d_size;
l2_cache = cpuid_info.cache_info.l2_size;
break;
} else if (cpuid_info.version.family != 7) {
break;
}
// Zhaoxin CPU only // Zhaoxin CPU only
if (cpuid_info.version.family != 7) {
break;
}
/* fall through */ /* fall through */
case 'G': case 'G':
if (cpuid_info.vendor_id.str[9] == 'N') {
// National Semiconductor
if (cpuid_info.version.family == 5) {
switch (cpuid_info.version.model) {
case 4:
// Geode GXm/GXLV/GX1
// Cache info in CPUID has a Cyrix-specific encoding so hardcode it
l1_cache = 16;
break;
case 5:
// Geode GX2
l1_cache = cpuid_info.cache_info.l1_d_size;
break;
default:
break;
}
}
break;
}
// Intel Processors // Intel Processors
l1_cache = 0; l1_cache = 0;
l2_cache = 0; l2_cache = 0;
@ -493,9 +460,6 @@ static void determine_imc(void)
case 0x9: case 0x9:
imc_type = IMC_KBL; // Core 7/8/9th Gen (Kaby/Coffee/Comet Lake) imc_type = IMC_KBL; // Core 7/8/9th Gen (Kaby/Coffee/Comet Lake)
break; break;
case 0xB:
imc_type = IMC_ADL_N; // Core 12th Gen (Alder Lake-N - Gracemont E-Cores only)
break;
default: default:
break; break;
} }
@ -635,9 +599,9 @@ static void determine_cpu_model(void)
// Transmeta Processors - vendor_id starts with "GenuineTMx86" // Transmeta Processors - vendor_id starts with "GenuineTMx86"
if (cpuid_info.vendor_id.str[7] == 'T' ) { if (cpuid_info.vendor_id.str[7] == 'T' ) {
if (cpuid_info.version.family == 5) { if (cpuid_info.version.family == 5) {
cpu_model = "Transmeta TM 5x00"; cpu_model = "TM 5x00";
} else if (cpuid_info.version.family == 15) { } else if (cpuid_info.version.family == 15) {
cpu_model = "Transmeta TM 8x00"; cpu_model = "TM 8x00";
} }
l1_cache = cpuid_info.cache_info.l1_i_size + cpuid_info.cache_info.l1_d_size; l1_cache = cpuid_info.cache_info.l1_i_size + cpuid_info.cache_info.l1_d_size;
l2_cache = cpuid_info.cache_info.l2_size; l2_cache = cpuid_info.cache_info.l2_size;
@ -683,14 +647,14 @@ static void determine_cpu_model(void)
case 2: case 2:
case 3: case 3:
case 7: case 7:
cpu_model = "Intel Pentium"; cpu_model = "Pentium";
if (l1_cache == 0) { if (l1_cache == 0) {
l1_cache = 8; l1_cache = 8;
} }
break; break;
case 4: case 4:
case 8: case 8:
cpu_model = "Intel Pentium MMX"; cpu_model = "Pentium-MMX";
if (l1_cache == 0) { if (l1_cache == 0) {
l1_cache = 16; l1_cache = 16;
} }
@ -703,54 +667,54 @@ static void determine_cpu_model(void)
switch (cpuid_info.version.model) { switch (cpuid_info.version.model) {
case 0: case 0:
case 1: case 1:
cpu_model = "Intel Pentium Pro"; cpu_model = "Pentium Pro";
break; break;
case 3: case 3:
case 4: case 4:
cpu_model = "Intel Pentium II"; cpu_model = "Pentium II";
break; break;
case 5: case 5:
if (l2_cache == 0) { if (l2_cache == 0) {
cpu_model = "Intel Celeron"; cpu_model = "Celeron";
} else { } else {
cpu_model = "Intel Pentium II"; cpu_model = "Pentium II";
} }
break; break;
case 6: case 6:
if (l2_cache == 128) { if (l2_cache == 128) {
cpu_model = "Intel Celeron"; cpu_model = "Celeron";
} else { } else {
cpu_model = "Intel Pentium II"; cpu_model = "Pentium II";
} }
break; break;
case 7: case 7:
case 8: case 8:
case 11: case 11:
if (l2_cache == 128) { if (l2_cache == 128) {
cpu_model = "Intel Celeron"; cpu_model = "Celeron";
} else { } else {
cpu_model = "Intel Pentium III"; cpu_model = "Pentium III";
} }
break; break;
case 9: case 9:
if (l2_cache == 512) { if (l2_cache == 512) {
cpu_model = "Intel Celeron M (0.13)"; cpu_model = "Celeron M (0.13)";
} else { } else {
cpu_model = "Intel Pentium M (0.13)"; cpu_model = "Pentium M (0.13)";
} }
break; break;
case 10: case 10:
cpu_model = "Intel Pentium III Xeon"; cpu_model = "Pentium III Xeon";
break; break;
case 12: case 12:
l1_cache = 24; l1_cache = 24;
cpu_model = "Intel Atom (0.045)"; cpu_model = "Atom (0.045)";
break; break;
case 13: case 13:
if (l2_cache == 1024) { if (l2_cache == 1024) {
cpu_model = "Intel Celeron M (0.09)"; cpu_model = "Celeron M (0.09)";
} else { } else {
cpu_model = "Intel Pentium M (0.09)"; cpu_model = "Pentium M (0.09)";
} }
break; break;
case 14: case 14:
@ -758,7 +722,7 @@ static void determine_cpu_model(void)
break; break;
case 15: case 15:
if (l2_cache == 1024) { if (l2_cache == 1024) {
cpu_model = "Intel Pentium E"; cpu_model = "Pentium E";
} else { } else {
cpu_model = "Intel Core 2"; cpu_model = "Intel Core 2";
} }
@ -773,17 +737,17 @@ static void determine_cpu_model(void)
case 1: case 1:
case 2: case 2:
if (l2_cache == 128) { if (l2_cache == 128) {
cpu_model = "Intel Celeron"; cpu_model = "Celeron";
} else { } else {
cpu_model = "Intel Pentium 4"; cpu_model = "Pentium 4";
} }
break; break;
case 3: case 3:
case 4: case 4:
if (l2_cache == 256) { if (l2_cache == 256) {
cpu_model = "Intel Celeron (0.09)"; cpu_model = "Celeron (0.09)";
} else { } else {
cpu_model = "Intel Pentium 4 (0.09)"; cpu_model = "Pentium 4 (0.09)";
} }
break; break;
case 6: case 6:
@ -803,40 +767,78 @@ static void determine_cpu_model(void)
// VIA/Cyrix/Centaur Processors with CPUID // VIA/Cyrix/Centaur Processors with CPUID
if (cpuid_info.vendor_id.str[1] == 'e' ) { if (cpuid_info.vendor_id.str[1] == 'e' ) {
// CentaurHauls // CentaurHauls
l1_cache = cpuid_info.cache_info.l1_i_size + cpuid_info.cache_info.l1_d_size;
l2_cache = cpuid_info.cache_info.l2_size >> 8;
switch (cpuid_info.version.family) { switch (cpuid_info.version.family) {
case 5: case 5:
cpu_model = "IDT WinChip C6"; cpu_model = "Centaur 5x86";
l1_cache = 32; break;
// WinChip 2/3 (models 8/9) have brand string case 6: // VIA C3
switch (cpuid_info.version.model) {
case 10:
cpu_model = "VIA C7 (C5J)";
l1_cache = 64;
l2_cache = 128;
break;
case 13:
cpu_model = "VIA C7 (C5R)";
l1_cache = 64;
l2_cache = 128;
break;
case 15:
cpu_model = "VIA Isaiah (CN)";
l1_cache = 64;
l2_cache = 128;
break; break;
default: default:
// All VIA/Centaur family values >= 6 have brand string if (cpuid_info.version.stepping < 8) {
cpu_model = "VIA C3 Samuel2";
} else {
cpu_model = "VIA C3 Eden";
}
break;
}
default:
break; break;
} }
} else { /* CyrixInstead */ } else { /* CyrixInstead */
switch (cpuid_info.version.family) { switch (cpuid_info.version.family) {
case 4: case 5:
switch (cpuid_info.version.model) { switch (cpuid_info.version.model) {
case 2: case 0:
cpu_model = "Cyrix 5x86"; cpu_model = "Cyrix 6x86MX/MII";
l1_cache = 16;
break; break;
case 4: case 4:
cpu_model = "Cyrix MediaGX/GXi"; cpu_model = "Cyrix GXm";
l1_cache = 16;
break; break;
default: default:
break; break;
} }
break; break;
case 5: case 6: // VIA C3
cpu_model = "Cyrix 6x86/6x86L"; switch (cpuid_info.version.model) {
l1_cache = 16;
// Media GXm (model 4) has brand string
break;
case 6: case 6:
cpu_model = "Cyrix 6x86MX/MII"; cpu_model = "Cyrix III";
break;
case 7:
if (cpuid_info.version.stepping < 8) {
cpu_model = "VIA C3 Samuel2";
} else {
cpu_model = "VIA C3 Ezra-T";
}
break;
case 8:
cpu_model = "VIA C3 Ezra-T";
break;
case 9:
cpu_model = "VIA C3 Nehemiah";
break;
default:
break;
}
// L1 = L2 = 64 KB from Cyrix III to Nehemiah
l1_cache = 64; l1_cache = 64;
l2_cache = 64;
break; break;
default: default:
break; break;
@ -847,10 +849,10 @@ static void determine_cpu_model(void)
// Unknown processor - make a guess at the family. // Unknown processor - make a guess at the family.
switch (cpuid_info.version.family) { switch (cpuid_info.version.family) {
case 5: case 5:
cpu_model = "586-class CPU (unknown)"; cpu_model = "586";
break; break;
case 6: case 6:
cpu_model = "686-class CPU (unknown)"; cpu_model = "686";
break; break;
default: default:
cpu_model = "Unidentified Processor"; cpu_model = "Unidentified Processor";

View file

@ -8,7 +8,7 @@
* *
*//* *//*
* Copyright (C) 2020-2022 Martin Whitaker. * Copyright (C) 2020-2022 Martin Whitaker.
* Copyright (C) 2004-2023 Sam Demeulemeester. * Copyright (C) 2004-2022 Sam Demeulemeester.
*/ */
#include <stdbool.h> #include <stdbool.h>
@ -47,7 +47,6 @@
#define IMC_KBL_UY 0x3030 // Core 7/8/9th Gen (Kaby/Coffee/Comet/Amber Lake-U/Y) #define IMC_KBL_UY 0x3030 // Core 7/8/9th Gen (Kaby/Coffee/Comet/Amber Lake-U/Y)
#define IMC_ICL 0x3040 // Core 10th Gen (IceLake-Y) #define IMC_ICL 0x3040 // Core 10th Gen (IceLake-Y)
#define IMC_TGL 0x3050 // Core 11th Gen (Tiger Lake-U) #define IMC_TGL 0x3050 // Core 11th Gen (Tiger Lake-U)
#define IMC_ADL_N 0x3061 // Core 12th Gen (Alder Lake-N - Gracemont E-Cores only)
#define IMC_BYT 0x4010 // Atom Bay Trail #define IMC_BYT 0x4010 // Atom Bay Trail
#define IMC_CDT 0x4020 // Atom Cedar Trail #define IMC_CDT 0x4020 // Atom Cedar Trail

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2004-2023 Sam Demeulemeester // Copyright (C) 2004-2022 Samuel Demeulemeester
// //
// ------------------------ // ------------------------
// This file is used to detect quirks on specific hardware // This file is used to detect quirks on specific hardware
@ -13,9 +13,6 @@
#include "pci.h" #include "pci.h"
#include "unistd.h" #include "unistd.h"
#include "cpuinfo.h" #include "cpuinfo.h"
#include "cpuid.h"
#include "config.h"
#include "temperature.h"
quirk_t quirk; quirk_t quirk;
@ -67,38 +64,6 @@ static void get_m1541_l2_cache_size(void)
if (reg == 0b10) { l2_cache = 1024; } if (reg == 0b10) { l2_cache = 1024; }
} }
static void disable_temp_reporting(void)
{
enable_temperature = false;
}
static void amd_k8_revfg_temp(void)
{
uint32_t rtcr = pci_config_read32(0, 24, 3, AMD_TEMP_REG_K8);
// For Rev F & G, switch sensor if no temperature is reported
if (!((rtcr >> 16) & 0xFF)) {
pci_config_write8(0, 24, 3, AMD_TEMP_REG_K8, rtcr | 0x04);
}
// K8 Rev G Desktop requires an additional offset.
if (cpuid_info.version.extendedModel < 6 && cpuid_info.version.extendedModel > 7) // Not Rev G
return;
if (cpuid_info.version.extendedModel == 6 && cpuid_info.version.extendedModel < 9) // Not Desktop
return;
uint16_t brandID = (cpuid_info.version.extendedBrandID >> 9) & 0x1f;
if (cpuid_info.version.model == 0xF && (brandID == 0x7 || brandID == 0x9 || brandID == 0xC)) // Mobile (Single Core)
return;
if (cpuid_info.version.model == 0xB && brandID > 0xB) // Mobile (Dual Core)
return;
cpu_temp_offset = 21.0f;
}
// --------------------- // ---------------------
// -- Public function -- // -- Public function --
// --------------------- // ---------------------
@ -150,53 +115,4 @@ void quirks_init(void)
quirk.process = NULL; quirk.process = NULL;
} }
} }
// ------------------------------------------------------
// -- Early AMD K8 doesn't support temperature reading --
// ------------------------------------------------------
// The on-die temperature diode on SH-B0/B3 stepping does not work.
if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF
&& cpuid_info.version.extendedFamily == 0 && cpuid_info.version.extendedModel == 0) { // Early K8
if ((cpuid_info.version.model == 4 && cpuid_info.version.stepping == 0) || // SH-B0 ClawHammer (Athlon 64)
(cpuid_info.version.model == 5 && cpuid_info.version.stepping <= 1)) { // SH-B0/B3 SledgeHammer (Opteron)
quirk.id = QUIRK_K8_BSTEP_NOTEMP;
quirk.type |= QUIRK_TYPE_TEMP;
quirk.process = disable_temp_reporting;
}
}
// ---------------------------------------------------
// -- Late AMD K8 (rev F/G) temp sensor workaround --
// ---------------------------------------------------
if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF
&& cpuid_info.version.extendedFamily == 0 && cpuid_info.version.extendedModel >= 4) { // Later K8
quirk.id = QUIRK_K8_REVFG_TEMP;
quirk.type |= QUIRK_TYPE_TEMP;
quirk.process = amd_k8_revfg_temp;
}
// ------------------------------------------------
// -- AMD K10 CPUs Temp workaround (Errata #319) --
// ------------------------------------------------
// Some AMD K10 CPUs on Socket AM2+/F have buggued thermal diode leading
// to inaccurate temperature measurements. Affected steppings: DR-BA/B2/B3, RB-C2 & HY-D0.
if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF
&& cpuid_info.version.extendedFamily == 1 && cpuid_info.version.extendedModel == 0) { // AMD K10
uint8_t pkg_type = (cpuid_info.version.extendedBrandID >> 28) & 0x0F;
uint32_t dct0_high = pci_config_read32(0, 24, 2, 0x94); // 0x94[8] = 1 for DDR3
if (pkg_type == 0b0000 || (pkg_type == 0b0001 && (((dct0_high >> 8) & 1) == 0))) { // Socket F or AM2+ (exclude AM3)
if (cpuid_info.version.model < 4 || // DR-BA, DR-B2 & DR-B3
(cpuid_info.version.model == 4 && cpuid_info.version.stepping <= 2) || // RB-C2
cpuid_info.version.model == 8) { // HY-D0
quirk.id = QUIRK_AMD_ERRATA_319;
quirk.type |= QUIRK_TYPE_TEMP;
quirk.process = disable_temp_reporting;
}
}
}
} }

View file

@ -19,16 +19,12 @@
#define QUIRK_TYPE_SMBUS (1 << 4) #define QUIRK_TYPE_SMBUS (1 << 4)
#define QUIRK_TYPE_TIMER (1 << 5) #define QUIRK_TYPE_TIMER (1 << 5)
#define QUIRK_TYPE_MEM_SIZE (1 << 6) #define QUIRK_TYPE_MEM_SIZE (1 << 6)
#define QUIRK_TYPE_TEMP (1 << 7)
typedef enum { typedef enum {
QUIRK_NONE, QUIRK_NONE,
QUIRK_TUSL2, QUIRK_TUSL2,
QUIRK_ALI_ALADDIN_V, QUIRK_ALI_ALADDIN_V,
QUIRK_X10SDV_NOSMP, QUIRK_X10SDV_NOSMP
QUIRK_K8_BSTEP_NOTEMP,
QUIRK_K8_REVFG_TEMP,
QUIRK_AMD_ERRATA_319
} quirk_id_t; } quirk_id_t;
typedef struct { typedef struct {

View file

@ -478,7 +478,7 @@ static const struct spd_jedec_manufacturer jep106[] = {
// { 0x0353, "Primarion" }, // { 0x0353, "Primarion" },
// { 0x0354, "Picochip Designs Ltd" }, // { 0x0354, "Picochip Designs Ltd" },
// { 0x0355, "Silverback Systems" }, // { 0x0355, "Silverback Systems" },
{ 0x0356, "Jade Star" }, // { 0x0356, "Jade Star Technologies" },
// { 0x0357, "Pijnenburg Securealink" }, // { 0x0357, "Pijnenburg Securealink" },
{ 0x0358, "takeMS" }, // Ultron AG { 0x0358, "takeMS" }, // Ultron AG
// { 0x0359, "Cambridge Silicon Radio" }, // { 0x0359, "Cambridge Silicon Radio" },
@ -882,7 +882,7 @@ static const struct spd_jedec_manufacturer jep106[] = {
// { 0x066E, "Certicom Corporation" }, // { 0x066E, "Certicom Corporation" },
// { 0x066F, "JSC ICC Milandr" }, // { 0x066F, "JSC ICC Milandr" },
// { 0x0670, "PhotoFast Global Inc" }, // { 0x0670, "PhotoFast Global Inc" },
{ 0x0671, "InnoDisk" }, // { 0x0671, "InnoDisk Corporation" },
// { 0x0672, "Muscle Power" }, // { 0x0672, "Muscle Power" },
// { 0x0673, "Energy Micro" }, // { 0x0673, "Energy Micro" },
// { 0x0674, "Innofidei" }, // { 0x0674, "Innofidei" },

View file

@ -30,9 +30,6 @@
#define MSR_AMD64_NB_CFG 0xc001001f #define MSR_AMD64_NB_CFG 0xc001001f
#define MSR_AMD64_COFVID_STATUS 0xc0010071 #define MSR_AMD64_COFVID_STATUS 0xc0010071
#define MSR_VIA_TEMP_C7 0x1169
#define MSR_VIA_TEMP_NANO 0x1423
#define rdmsr(msr, value1, value2) \ #define rdmsr(msr, value1, value2) \
__asm__ __volatile__("rdmsr" \ __asm__ __volatile__("rdmsr" \
: "=a" (value1), \ : "=a" (value1), \

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2004-2023 Sam Demeulemeester // Copyright (C) 2004-2022 Samuel Demeulemeester
#include "display.h" #include "display.h"
@ -50,12 +50,9 @@ static bool amd_sb_get_smb(void);
static bool fch_zen_get_smb(void); static bool fch_zen_get_smb(void);
static bool piix4_get_smb(uint8_t address); static bool piix4_get_smb(uint8_t address);
static bool ich5_get_smb(void); static bool ich5_get_smb(void);
static bool ali_get_smb(uint8_t address);
static uint8_t ich5_process(void); static uint8_t ich5_process(void);
static uint8_t ich5_read_spd_byte(uint8_t adr, uint16_t cmd); static uint8_t ich5_read_spd_byte(uint8_t adr, uint16_t cmd);
static uint8_t nf_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr); static uint8_t nf_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr);
static uint8_t ali_m1563_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr);
static uint8_t ali_m1543_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr);
static inline uint8_t bcd_to_ui8(uint8_t bcd) static inline uint8_t bcd_to_ui8(uint8_t bcd)
{ {
@ -1207,7 +1204,7 @@ static bool find_smb_controller(uint16_t vid, uint16_t did)
// case 0x01B4: // nForce // case 0x01B4: // nForce
case 0x0064: // nForce 2 case 0x0064: // nForce 2
// case 0x0084: // nForce 2 Mobile // case 0x0084: // nForce 2 Mobile
case 0x00E4: // nForce 3 // case 0x00E4: // nForce 3
// case 0x0034: // MCP04 // case 0x0034: // MCP04
// case 0x0052: // nForce 4 // case 0x0052: // nForce 4
case 0x0264: // nForce 410/430 MCP case 0x0264: // nForce 410/430 MCP
@ -1254,10 +1251,10 @@ static bool find_smb_controller(uint16_t vid, uint16_t did)
// SMB base address = 0x90 // SMB base address = 0x90
// viapro SMBus controller, i.e. PIIX4. // viapro SMBus controller, i.e. PIIX4.
return piix4_get_smb(PIIX4_SMB_BASE_ADR_DEFAULT); return piix4_get_smb(PIIX4_SMB_BASE_ADR_DEFAULT);
case 0x3074: // 8233 // case 0x3074: // 8233_0
case 0x3147: // 8233A // case 0x3147: // 8233A
case 0x3177: // 8235 case 0x3177: // 8235
case 0x3227: // 8237 // case 0x3227: // 8237
// case 0x3337: // 8237A // case 0x3337: // 8237A
// case 0x3372: // 8237S // case 0x3372: // 8237S
// case 0x3287: // 8251 // case 0x3287: // 8251
@ -1285,10 +1282,8 @@ static bool find_smb_controller(uint16_t vid, uint16_t did)
case PCI_VID_ALI: case PCI_VID_ALI:
switch(did) switch(did)
{ {
case 0x7101: // ALi M1533/1535/1543C // case 0x1563: // ali1563 (M1563) SMBus controller, nearly compatible with PIIX4 according to Linux i2c-ali1563 driver.
return ali_get_smb(PIIX4_SMB_BASE_ADR_ALI1543); // case 0x7101: // ali1535 (M1535) or ali15x3 (M1533/M1543) SMBus controllers
case 0x1563: // ALi M1563
return piix4_get_smb(PIIX4_SMB_BASE_ADR_ALI1563);
default: default:
return false; return false;
} }
@ -1340,18 +1335,10 @@ static bool ich5_get_smb(void)
{ {
uint16_t x; uint16_t x;
// Enable SMBus IO Space if disabled
x = pci_config_read16(0, smbdev, smbfun, 0x4);
if (!(x & 1)) {
pci_config_write16(0, smbdev, smbfun, 0x4, x | 1);
}
// Read Base Address
x = pci_config_read16(0, smbdev, smbfun, 0x20); x = pci_config_read16(0, smbdev, smbfun, 0x20);
smbusbase = x & 0xFFF0; smbusbase = x & 0xFFF0;
// Enable I2C Host Controller Interface if disabled // Enable I2C Bus
uint8_t temp = pci_config_read8(0, smbdev, smbfun, 0x40); uint8_t temp = pci_config_read8(0, smbdev, smbfun, 0x40);
if ((temp & 4) == 0) { if ((temp & 4) == 0) {
pci_config_write8(0, smbdev, smbfun, 0x40, temp | 0x04); pci_config_write8(0, smbdev, smbfun, 0x40, temp | 0x04);
@ -1450,35 +1437,6 @@ static bool nv_mcp_get_smb(void)
return false; return false;
} }
// ---------------------------------------
// ALi SMBUS Controller (M1533/1535/1543C)
// ---------------------------------------
static bool ali_get_smb(uint8_t address)
{
// Enable SMB I/O Base Address Register Control (Reg0x5B[2] = 0)
uint16_t temp = pci_config_read8(0, smbdev, smbfun, 0x5B);
pci_config_write8(0, smbdev, smbfun, 0x5B, temp & ~0x06);
// Enable Response to I/O Access. (Reg0x04[0] = 1)
temp = pci_config_read8(0, smbdev, smbfun, 0x04);
pci_config_write8(0, smbdev, smbfun, 0x04, temp | 0x01);
// SMB Host Controller Interface Enable (Reg0xE0[0] = 1)
temp = pci_config_read8(0, smbdev, smbfun, 0xE0);
pci_config_write8(0, smbdev, smbfun, 0xE0, temp | 0x01);
// Read SMBase Register (usually 0xE800)
uint16_t x = pci_config_read16(0, smbdev, smbfun, address) & 0xFFF0;
if (x != 0) {
smbusbase = x;
return true;
}
return false;
}
// ------------------ // ------------------
// get_spd() function // get_spd() function
// ------------------ // ------------------
@ -1486,11 +1444,6 @@ static bool ali_get_smb(uint8_t address)
static uint8_t get_spd(uint8_t slot_idx, uint16_t spd_adr) static uint8_t get_spd(uint8_t slot_idx, uint16_t spd_adr)
{ {
switch ((smbus_id >> 16) & 0xFFFF) { switch ((smbus_id >> 16) & 0xFFFF) {
case PCI_VID_ALI:
if ((smbus_id & 0xFFFF) == 0x7101)
return ali_m1543_read_spd_byte(slot_idx, (uint8_t)spd_adr);
else
return ali_m1563_read_spd_byte(slot_idx, (uint8_t)spd_adr);
case PCI_VID_NVIDIA: case PCI_VID_NVIDIA:
return nf_read_spd_byte(slot_idx, (uint8_t)spd_adr); return nf_read_spd_byte(slot_idx, (uint8_t)spd_adr);
default: default:
@ -1633,73 +1586,3 @@ static uint8_t nf_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr)
return __inb(NVSMBDAT(0)); return __inb(NVSMBDAT(0));
} }
static uint8_t ali_m1563_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr)
{
int i;
smbus_adr += 0x50;
// Reset Status Register
__outb(0xFF, SMBHSTSTS);
// Set Slave ADR
__outb((smbus_adr << 1 | I2C_READ), SMBHSTADD);
__outb((__inb(SMBHSTCNT) & ~ALI_SMBHSTCNT_SIZEMASK) | (ALI_SMBHSTCNT_BYTE_DATA << 3), SMBHSTCNT);
// Set Command (SPD Byte to Read)
__outb(spd_adr, SMBHSTCMD);
// Start transaction
__outb(__inb(SMBHSTCNT) | SMBHSTCNT_START, SMBHSTCNT);
// Wait until transaction complete
for (i = 500; i > 0; i--) {
usleep(50);
if (!(__inb(SMBHSTSTS) & SMBHSTSTS_HOST_BUSY)) {
break;
}
}
// If timeout or Error Status, exit
if (i == 0 || __inb(SMBHSTSTS) & ALI_SMBHSTSTS_BAD) {
return 0xFF;
}
return __inb(SMBHSTDAT0);
}
static uint8_t ali_m1543_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr)
{
int i;
smbus_adr += 0x50;
// Reset Status Register
__outb(0xFF, SMBHSTSTS);
// Set Slave ADR
__outb((smbus_adr << 1 | I2C_READ), ALI_OLD_SMBHSTADD);
// Set Command (SPD Byte to Read)
__outb(spd_adr, ALI_OLD_SMBHSTCMD);
// Start transaction
__outb(ALI_OLD_SMBHSTCNT_BYTE_DATA, ALI_OLD_SMBHSTCNT);
__outb(0xFF, ALI_OLD_SMBHSTSTART);
// Wait until transaction complete
for (i = 500; i > 0; i--) {
usleep(50);
if (!(__inb(SMBHSTSTS) & ALI_OLD_SMBHSTSTS_BUSY)) {
break;
}
}
// If timeout or Error Status, exit
if (i == 0 || __inb(SMBHSTSTS) & ALI_OLD_SMBHSTSTS_BAD) {
return 0xFF;
}
return __inb(ALI_OLD_SMBHSTDAT0);
}

View file

@ -7,7 +7,7 @@
* *
* Provides functions for reading SPD via SMBUS * Provides functions for reading SPD via SMBUS
* *
* Copyright (C) 2004-2023 Sam Demeulemeester. * Copyright (C) 2004-2022 Samuel Demeulemeester.
*/ */
#define I2C_WRITE 0 #define I2C_WRITE 0
@ -74,28 +74,6 @@
#define NVSMBSTS_RES 0x20 #define NVSMBSTS_RES 0x20
#define NVSMBSTS_STATUS 0x1f #define NVSMBSTS_STATUS 0x1f
/* ALi-Specific constants (M1563 & newer) */
#define ALI_SMBHSTCNT_SIZEMASK 0x03
#define ALI_SMBHSTSTS_BAD 0x1C
#define ALI_SMBHSTCNT_QUICK 0x00
#define ALI_SMBHSTCNT_BYTE 0x01
#define ALI_SMBHSTCNT_BYTE_DATA 0x02
#define ALI_SMBHSTCNT_WORD_DATA 0x03
#define ALI_SMBHSTCNT_KILL 0x04
#define ALI_SMBHSTCNT_BLOCK 0x05
/* ALi-Specific constants (M1543 & older) */
#define ALI_OLD_SMBHSTSTS_BAD 0xE0
#define ALI_OLD_SMBHSTSTS_BUSY 0x08
#define ALI_OLD_SMBHSTCNT_BYTE_DATA 0x20
#define ALI_OLD_SMBHSTCNT smbusbase + 1
#define ALI_OLD_SMBHSTSTART smbusbase + 2
#define ALI_OLD_SMBHSTADD smbusbase + 3
#define ALI_OLD_SMBHSTDAT0 smbusbase + 4
#define ALI_OLD_SMBHSTCMD smbusbase + 7
/** Rounding factors for timing computation /** Rounding factors for timing computation
* *
* These factors are used as a configurable CEIL() function * These factors are used as a configurable CEIL() function
@ -109,8 +87,6 @@
#define PIIX4_SMB_BASE_ADR_DEFAULT 0x90 #define PIIX4_SMB_BASE_ADR_DEFAULT 0x90
#define PIIX4_SMB_BASE_ADR_VIAPRO 0xD0 #define PIIX4_SMB_BASE_ADR_VIAPRO 0xD0
#define PIIX4_SMB_BASE_ADR_ALI1563 0x80
#define PIIX4_SMB_BASE_ADR_ALI1543 0x14
struct pci_smbus_controller { struct pci_smbus_controller {
unsigned vendor; unsigned vendor;

View file

@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020-2022 Martin Whitaker. // Copyright (C) 2020-2022 Martin Whitaker.
// Copyright (C) 2004-2023 Sam Demeulemeester.
// //
// Derived from an extract of memtest86+ init.c: // Derived from an extract of memtest86+ init.c:
// //
@ -17,120 +16,57 @@
#include "cpuid.h" #include "cpuid.h"
#include "cpuinfo.h" #include "cpuinfo.h"
#include "hwquirks.h"
#include "msr.h" #include "msr.h"
#include "pci.h" #include "pci.h"
#include "temperature.h" #include "temperature.h"
//------------------------------------------------------------------------------
// Public Variables
//------------------------------------------------------------------------------
float cpu_temp_offset = 0;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Public Functions // Public Functions
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int TjMax = 0;
void get_specific_TjMax(void)
{
// The TjMax value for some Mobile/Embedded CPUs must be read from a fixed
// table according to their CPUID, PCI Root DID/VID or PNS.
// Trying to read the MSR 0x1A2 on some of them trigger a reboot.
// Yonah C0 Step (Pentium/Core Duo T2000 & Celeron M 200/400)
if (cpuid_info.version.raw[0] == 0x6E8) {
TjMax = 100;
}
}
void temperature_init(void)
{
uint32_t regl, regh;
// Process temperature-related quirks
if (quirk.type & QUIRK_TYPE_TEMP) {
quirk.process();
}
// Get TjMax for Intel CPU
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6 && (cpuid_info.dts_pmp & 1)) {
get_specific_TjMax();
if (TjMax == 0) {
// Generic Method using MSR 0x1A2
rdmsr(MSR_IA32_TEMPERATURE_TARGET, regl, regh);
TjMax = (regl >> 16) & 0x7F;
if (TjMax < 50 || TjMax > 125) {
TjMax = 100;
}
}
}
}
int get_cpu_temperature(void) int get_cpu_temperature(void)
{ {
uint32_t regl, regh;
// Intel CPU // Intel CPU
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6 && (cpuid_info.dts_pmp & 1)) { if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6) {
if (cpuid_info.dts_pmp & 1) {
uint32_t msrl, msrh;
rdmsr(MSR_IA32_THERM_STATUS, regl, regh); rdmsr(MSR_IA32_THERM_STATUS, msrl, msrh);
int Tabs = (regl >> 16) & 0x7F; int Tabs = (msrl >> 16) & 0x7F;
return TjMax - Tabs; rdmsr(MSR_IA32_TEMPERATURE_TARGET, msrl, msrh);
int Tjunc = (msrl >> 16) & 0x7F;
if (Tjunc < 50 || Tjunc > 125) {
Tjunc = 90;
}
return Tjunc - Tabs;
}
} }
// AMD CPU // AMD CPU
else if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF) { // Target only K8 & newer if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.extendedFamily > 0 && cpuid_info.version.extendedFamily < 8) {
if (cpuid_info.version.extendedFamily >= 8) { // Target Zen µarch and newer. Use SMN to get temperature. // Untested yet
uint32_t rtcr = pci_config_read32(0, 24, 3, 0xA4);
int raw_temp = (rtcr >> 21) & 0x7FF;
regl = amd_smn_read(SMN_THM_TCON_CUR_TMP); return raw_temp / 8;
if ((regl >> 19) & 0x01) { } else if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.extendedFamily >= 8) {
cpu_temp_offset = -49.0f;
// Grab CPU Temp. for ZEN CPUs using SNM
uint32_t tval = amd_smn_read(SMN_THM_TCON_CUR_TMP);
float offset = 0;
if((tval >> 19) & 0x01) {
offset = -49.0f;
} }
return cpu_temp_offset + 0.125f * (float)((regl >> 21) & 0x7FF); return offset + 0.125f * (float)((tval >> 21) & 0x7FF);
} else if (cpuid_info.version.extendedFamily > 0) { // Target K10 to K15 (Bulldozer)
regl = pci_config_read32(0, 24, 3, AMD_TEMP_REG_K10);
int raw_temp = ((regl >> 21) & 0x7FF) / 8;
return (raw_temp > 0) ? raw_temp : 0;
} else { // Target K8 (CPUID ExtFamily = 0)
regl = pci_config_read32(0, 24, 3, AMD_TEMP_REG_K8);
int raw_temp = ((regl >> 16) & 0xFF) - 49 + cpu_temp_offset;
return (raw_temp > 0) ? raw_temp : 0;
}
}
// VIA/Centaur/Zhaoxin CPU
else if (cpuid_info.vendor_id.str[0] == 'C' && cpuid_info.vendor_id.str[1] == 'e'
&& (cpuid_info.version.family == 6 || cpuid_info.version.family == 7)) {
uint32_t msr_temp;
if (cpuid_info.version.family == 7 || cpuid_info.version.model == 0xF) {
msr_temp = MSR_VIA_TEMP_NANO; // Zhaoxin, Nano
} else if (cpuid_info.version.model == 0xA || cpuid_info.version.model == 0xD) {
msr_temp = MSR_VIA_TEMP_C7; // C7 A/D
} else {
return 0;
}
rdmsr(msr_temp, regl, regh);
return (int)(regl & 0xffffff);
} }
return 0; return 0;

View file

@ -8,22 +8,8 @@
* *
*//* *//*
* Copyright (C) 2020-2022 Martin Whitaker. * Copyright (C) 2020-2022 Martin Whitaker.
* Copyright (C) 2003-2023 Sam Demeulemeester.
*/ */
#define AMD_TEMP_REG_K8 0xE4
#define AMD_TEMP_REG_K10 0xA4
/**
* Global CPU Temperature offset
*/
extern float cpu_temp_offset;
/**
* Init temperature sensor and compute offsets if needed
*/
void temperature_init(void);
/** /**
* Returns the current temperature of the CPU. Returns 0 if * Returns the current temperature of the CPU. Returns 0 if
* the temperature cannot be read. * the temperature cannot be read.

View file

@ -18,6 +18,7 @@
#define PIT_TICKS_50mS 59659 // PIT clock is 1.193182MHz #define PIT_TICKS_50mS 59659 // PIT clock is 1.193182MHz
#define APIC_TICKS_50mS 178977 // APIC clock is 3.579545MHz #define APIC_TICKS_50mS 178977 // APIC clock is 3.579545MHz
#define BENCH_MIN_START_ADR 0x1000000 // 16MB
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Private Functions // Private Functions
@ -38,9 +39,6 @@ static void correct_tsc(void)
counter = inl(acpi_config.pm_addr); counter = inl(acpi_config.pm_addr);
// Generate a dirty delay
for(volatile uint8_t i=0; i<100u; i++);
// Make sure counter is incrementing // Make sure counter is incrementing
if (inl(acpi_config.pm_addr) > counter) { if (inl(acpi_config.pm_addr) > counter) {