Compare commits

...

23 commits
v6.10 ... main

Author SHA1 Message Date
Sam Demeulemeester
5dcd424ea7 Bump version to v6.20 2023-05-07 16:55:03 +02:00
Sam Demeulemeester
1f1fe5bfe8 Generalize the SMBus IO Enable quirk on all Intel ICHs
This has been tested safe on every ICH since the very first one by CPU-Z.
It also solves various SMBus access issues on Mobile PCHs (like #157)
2023-04-26 00:42:58 +02:00
Sam Demeulemeester
0fd2e4c37a Add support for Intel AlderLake-N CPUs 2023-04-24 00:29:37 +02:00
Sam Demeulemeester
fa4e903509 Fix APIC Timer detection fail on some modern mobile/embedded PCH
On some modern ULV cores (eg: Gracemont), the 2 following I/O reads to check APIC Timer working status are fused in the frontend, leading to the same value being reported twice and the code falling back to the (unusually disabled on these platforms) PIT timer.

Whether this behavior is intentional or not is unknown.

As usleep/sleep is not available at this point, a dirty delay is added between the two reads.
2023-04-23 22:45:27 +02:00
dependabot[bot]
bfbb167a72
Bump actions/stale from 7 to 8 (#287)
Bumps [actions/stale](https://github.com/actions/stale) from 7 to 8.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-29 18:34:20 +02:00
Sam Demeulemeester
79bb781431 Better handling of big FAIL banned in case of errors 2023-03-29 18:29:59 +02:00
Sam Demeulemeester
c6b04e5414 Display big banner only once 2023-03-29 17:58:12 +02:00
Sam Demeulemeester
5cbcd2046b Add 'Jade Star' & 'InnoDisk' JEDEC Manufacturers 2023-03-09 23:08:01 +01:00
Sam Demeulemeester
bf0dae04bc Remove deprecated ubuntu-18.04 job 2023-03-07 00:34:31 +01:00
Jonathan Teh
dcca756e48
[cpuinfo] Fix old CPUs (P5/P6-class) name and cache info (#267)
* cpuinfo: Fix WinChip and Cyrix/NSC CPU name and cache info

Always populate the cache info from extended CPUID, it is not used for
Intel CPUs, even though it is present, and is useful for non-Intel CPUs.

Fix the CPU name and cache sizes for Centaur and Cyrix/NSC CPUs without
brand string, which are the WinChip C6 and all Cyrix CPUs except the
Media GXm.

For the Media GXm and Geode GXm/GXLV/GX1, which are available with both
Cyrix and NSC vendor strings, hardcode the L1 cache size. The Geode GX2
uses standard cache info.

* Add 'Intel' in CPU names for older CPUs

* Add 'Transmeta' and 'IDT' in CPU names for older CPUs
-------

Co-authored-by: Sam Demeulemeester <github@x86-secret.com>
2023-03-03 13:21:27 +01:00
Sam Demeulemeester
262aac4f85
[SMBUS] Add support for ALi M1533/1535/1543C (#273)
Closes #126
2023-02-20 18:31:33 +01:00
Sam Demeulemeester
66bd82f12a
[SMBus] Add support for ALi M1563 Southbridge (#272) 2023-02-19 17:29:56 +01:00
Sam Demeulemeester
ee0c400821 [SMBUS] Add support for VIA VT8233 Southbridge 2023-02-18 19:01:59 +01:00
Sam Demeulemeester
e1fc02bfe0 [SMBUS] Add support for VIA VT8233A Southbridge 2023-02-18 18:58:34 +01:00
Sam Demeulemeester
a1d046fc3a Fix a typo in README.md (serial console baud rate) 2023-02-18 18:51:02 +01:00
Sam Demeulemeester
1a38f513de
[Temperature] Add support for CPUs with specific TjMax (#269)
Solve an issue where reading MSR_IA32_TEMPERATURE_TARGET makes the system crash (e.g. Early Mobile Yonah)
2023-02-18 18:43:38 +01:00
Sam Demeulemeester
22663f89bb
Add support for AMD K8 temperature reporting. (#268)
Add various quirks to handle AMD temp sensors erratas
2023-02-13 22:29:17 +01:00
Sam Demeulemeester
c38b0cbc5f [SMBUS] Add support for nVidia nForce 3 2023-02-13 19:43:09 +01:00
Sam Demeulemeester
dfc41f7196 Solve incorrect core/thread count on some VIA CPUs
No Cyrix / VIA / CentaurHauls / Zhaoxin CPUs support HT, so disable it.
2023-02-11 19:00:36 +01:00
Martin Whitaker
f62bbfde32 Additional fix to support use on headless EFI systems (issue #240) 2023-02-11 09:14:56 +00:00
Jonathan Teh
8305d47675
Support cache and temperature info for VIA/Centaur/Zhaoxin CPUs (#259)
* Support cache and temperature info for VIA/Centaur/Zhaoxin CPUs

Use extended CPUID for VIA C3/C7/Nano cache information.

Use MSR reads for Nano/Zhaoxin and VIA C7 processor temperature.

Tested on VIA C7-D 1.5GHz.

* Small code conventions fixes

* Fix overallocation of cpuid_cache_info_t union (From PR #263)

---------

Co-authored-by: Sam Demeulemeester <github@x86-secret.com>
2023-02-10 22:32:31 +01:00
Jonathan Teh
a47f681151 smbus: Add support for VIA VT8237
Tested on Jetway J7F2 with VT8237R+.

Signed-off-by: Jonathan Teh <jonathan.teh@outlook.com>
2023-02-05 08:22:13 +01:00
Martin Whitaker
68e9542c1e Restore ability to build 64-bit binaries when building on 32-bit system. 2023-02-04 10:10:05 +00:00
21 changed files with 471 additions and 159 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -502,6 +502,10 @@ static efi_status_t set_screen_info(boot_params_t *boot_params)
status = EFI_SUCCESS;
}
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;

View file

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

View file

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

View file

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

View file

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

View file

@ -8,7 +8,7 @@
*
*//*
* Copyright (C) 2020-2022 Martin Whitaker.
* Copyright (C) 2004-2022 Sam Demeulemeester.
* Copyright (C) 2004-2023 Sam Demeulemeester.
*/
#include <stdbool.h>
@ -47,6 +47,7 @@
#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_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_CDT 0x4020 // Atom Cedar Trail

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2004-2022 Samuel Demeulemeester
// Copyright (C) 2004-2023 Sam Demeulemeester
//
// ------------------------
// This file is used to detect quirks on specific hardware
@ -13,6 +13,9 @@
#include "pci.h"
#include "unistd.h"
#include "cpuinfo.h"
#include "cpuid.h"
#include "config.h"
#include "temperature.h"
quirk_t quirk;
@ -64,6 +67,38 @@ static void get_m1541_l2_cache_size(void)
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 --
// ---------------------
@ -115,4 +150,53 @@ void quirks_init(void)
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,12 +19,16 @@
#define QUIRK_TYPE_SMBUS (1 << 4)
#define QUIRK_TYPE_TIMER (1 << 5)
#define QUIRK_TYPE_MEM_SIZE (1 << 6)
#define QUIRK_TYPE_TEMP (1 << 7)
typedef enum {
QUIRK_NONE,
QUIRK_TUSL2,
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;
typedef struct {

View file

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

View file

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

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2004-2022 Samuel Demeulemeester
// Copyright (C) 2004-2023 Sam Demeulemeester
#include "display.h"
@ -50,9 +50,12 @@ static bool amd_sb_get_smb(void);
static bool fch_zen_get_smb(void);
static bool piix4_get_smb(uint8_t address);
static bool ich5_get_smb(void);
static bool ali_get_smb(uint8_t address);
static uint8_t ich5_process(void);
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 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)
{
@ -1204,7 +1207,7 @@ static bool find_smb_controller(uint16_t vid, uint16_t did)
// case 0x01B4: // nForce
case 0x0064: // nForce 2
// case 0x0084: // nForce 2 Mobile
// case 0x00E4: // nForce 3
case 0x00E4: // nForce 3
// case 0x0034: // MCP04
// case 0x0052: // nForce 4
case 0x0264: // nForce 410/430 MCP
@ -1251,10 +1254,10 @@ static bool find_smb_controller(uint16_t vid, uint16_t did)
// SMB base address = 0x90
// viapro SMBus controller, i.e. PIIX4.
return piix4_get_smb(PIIX4_SMB_BASE_ADR_DEFAULT);
// case 0x3074: // 8233_0
// case 0x3147: // 8233A
case 0x3074: // 8233
case 0x3147: // 8233A
case 0x3177: // 8235
// case 0x3227: // 8237
case 0x3227: // 8237
// case 0x3337: // 8237A
// case 0x3372: // 8237S
// case 0x3287: // 8251
@ -1282,8 +1285,10 @@ static bool find_smb_controller(uint16_t vid, uint16_t did)
case PCI_VID_ALI:
switch(did)
{
// case 0x1563: // ali1563 (M1563) SMBus controller, nearly compatible with PIIX4 according to Linux i2c-ali1563 driver.
// case 0x7101: // ali1535 (M1535) or ali15x3 (M1533/M1543) SMBus controllers
case 0x7101: // ALi M1533/1535/1543C
return ali_get_smb(PIIX4_SMB_BASE_ADR_ALI1543);
case 0x1563: // ALi M1563
return piix4_get_smb(PIIX4_SMB_BASE_ADR_ALI1563);
default:
return false;
}
@ -1335,10 +1340,18 @@ static bool ich5_get_smb(void)
{
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);
smbusbase = x & 0xFFF0;
// Enable I2C Bus
// Enable I2C Host Controller Interface if disabled
uint8_t temp = pci_config_read8(0, smbdev, smbfun, 0x40);
if ((temp & 4) == 0) {
pci_config_write8(0, smbdev, smbfun, 0x40, temp | 0x04);
@ -1437,6 +1450,35 @@ static bool nv_mcp_get_smb(void)
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
// ------------------
@ -1444,6 +1486,11 @@ static bool nv_mcp_get_smb(void)
static uint8_t get_spd(uint8_t slot_idx, uint16_t spd_adr)
{
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:
return nf_read_spd_byte(slot_idx, (uint8_t)spd_adr);
default:
@ -1586,3 +1633,73 @@ static uint8_t nf_read_spd_byte(uint8_t smbus_adr, uint8_t spd_adr)
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
*
* Copyright (C) 2004-2022 Samuel Demeulemeester.
* Copyright (C) 2004-2023 Sam Demeulemeester.
*/
#define I2C_WRITE 0
@ -74,6 +74,28 @@
#define NVSMBSTS_RES 0x20
#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
*
* These factors are used as a configurable CEIL() function
@ -87,6 +109,8 @@
#define PIIX4_SMB_BASE_ADR_DEFAULT 0x90
#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 {
unsigned vendor;

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020-2022 Martin Whitaker.
// Copyright (C) 2004-2023 Sam Demeulemeester.
//
// Derived from an extract of memtest86+ init.c:
//
@ -16,57 +17,120 @@
#include "cpuid.h"
#include "cpuinfo.h"
#include "hwquirks.h"
#include "msr.h"
#include "pci.h"
#include "temperature.h"
//------------------------------------------------------------------------------
// Public Variables
//------------------------------------------------------------------------------
float cpu_temp_offset = 0;
//------------------------------------------------------------------------------
// 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)
{
uint32_t regl, regh;
// Intel CPU
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6) {
if (cpuid_info.dts_pmp & 1) {
uint32_t msrl, msrh;
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6 && (cpuid_info.dts_pmp & 1)) {
rdmsr(MSR_IA32_THERM_STATUS, msrl, msrh);
int Tabs = (msrl >> 16) & 0x7F;
rdmsr(MSR_IA32_THERM_STATUS, regl, regh);
int Tabs = (regl >> 16) & 0x7F;
rdmsr(MSR_IA32_TEMPERATURE_TARGET, msrl, msrh);
int Tjunc = (msrl >> 16) & 0x7F;
if (Tjunc < 50 || Tjunc > 125) {
Tjunc = 90;
}
return Tjunc - Tabs;
}
return TjMax - Tabs;
}
// AMD CPU
if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.extendedFamily > 0 && cpuid_info.version.extendedFamily < 8) {
else if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF) { // Target only K8 & newer
// Untested yet
uint32_t rtcr = pci_config_read32(0, 24, 3, 0xA4);
int raw_temp = (rtcr >> 21) & 0x7FF;
if (cpuid_info.version.extendedFamily >= 8) { // Target Zen µarch and newer. Use SMN to get temperature.
return raw_temp / 8;
regl = amd_smn_read(SMN_THM_TCON_CUR_TMP);
} else if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.extendedFamily >= 8) {
// 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;
if ((regl >> 19) & 0x01) {
cpu_temp_offset = -49.0f;
}
return offset + 0.125f * (float)((tval >> 21) & 0x7FF);
return cpu_temp_offset + 0.125f * (float)((regl >> 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;

View file

@ -8,8 +8,22 @@
*
*//*
* 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
* the temperature cannot be read.

View file

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