mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2025-01-07 13:03:00 -06:00
Add ACPI Timer as the primary TSC correction source and PIT Timer as fallback
This commit is contained in:
parent
eac4d03462
commit
a5576974cf
10
app/main.c
10
app/main.c
@ -34,6 +34,7 @@
|
||||
#include "smbios.h"
|
||||
#include "smp.h"
|
||||
#include "temperature.h"
|
||||
#include "timers.h"
|
||||
#include "vmem.h"
|
||||
|
||||
#include "unistd.h"
|
||||
@ -221,6 +222,8 @@ static void global_init(void)
|
||||
|
||||
acpi_init();
|
||||
|
||||
timers_init();
|
||||
|
||||
membw_init();
|
||||
|
||||
smbios_init();
|
||||
@ -281,10 +284,9 @@ static void global_init(void)
|
||||
for (int i = 0; i < pm_map_size; i++) {
|
||||
trace(0, "pm %0*x - %0*x", 2*sizeof(uintptr_t), pm_map[i].start, 2*sizeof(uintptr_t), pm_map[i].end);
|
||||
}
|
||||
if (rsdp_addr != 0) {
|
||||
trace(0, "ACPI RSDP found in %s at %0*x", rsdp_source, 2*sizeof(uintptr_t), rsdp_addr);
|
||||
trace(0, "ACPI FADT found at %0*x", 2*sizeof(uintptr_t), fadt_addr);
|
||||
trace(0, "ACPI HPET found at %0*x", 2*sizeof(uintptr_t), hpet_addr);
|
||||
if (acpi_config.rsdp_addr != 0) {
|
||||
trace(0, "ACPI RSDP (v%u.%u) found in %s at %0*x", acpi_config.ver_maj, acpi_config.ver_min, rsdp_source, 2*sizeof(uintptr_t), acpi_config.rsdp_addr);
|
||||
trace(0, "ACPI FADT found at %0*x", 2*sizeof(uintptr_t), acpi_config.fadt_addr);
|
||||
}
|
||||
if (!load_addr_ok) {
|
||||
trace(0, "Cannot relocate program. Press any key to reboot...");
|
||||
|
@ -33,6 +33,7 @@ SYS_OBJS = system/acpi.o \
|
||||
system/smbus.o \
|
||||
system/smp.o \
|
||||
system/temperature.o \
|
||||
system/timers.o \
|
||||
system/uhci.o \
|
||||
system/usbhcd.o \
|
||||
system/vmem.o \
|
||||
|
@ -33,6 +33,7 @@ SYS_OBJS = system/acpi.o \
|
||||
system/smbus.o \
|
||||
system/smp.o \
|
||||
system/temperature.o \
|
||||
system/timers.o \
|
||||
system/uhci.o \
|
||||
system/usbhcd.o \
|
||||
system/vmem.o \
|
||||
|
@ -89,7 +89,7 @@ static const efi_guid_t EFI_ACPI_2_RDSP_GUID = { 0x8868e871, 0xe4f1, 0x11d3, {0x
|
||||
|
||||
const char *rsdp_source = "";
|
||||
|
||||
acpi_t acpi_config = {0, 0, 0, 0, 0, 0, 0, 0, false};
|
||||
acpi_t acpi_config = {0, 0, 0, 0, 0, 0, 0, false};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private Functions
|
||||
|
@ -22,10 +22,9 @@
|
||||
* A struct containing various ACPI-related infos for later uses.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t ver_maj;
|
||||
uint8_t ver_min;
|
||||
uint64_t test;
|
||||
uintptr_t rsdp_addr;
|
||||
uintptr_t madt_addr;
|
||||
uintptr_t fadt_addr;
|
||||
|
@ -33,7 +33,6 @@
|
||||
// Constants
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define PIT_TICKS_50mS 59659 // PIT clock is 1.193182MHz
|
||||
#define BENCH_MIN_START_ADR 0x1000000 // 16MB
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -861,37 +860,6 @@ static void determine_cpu_model(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void measure_cpu_speed(void)
|
||||
{
|
||||
if (cpuid_info.flags.rdtsc == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up timer
|
||||
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
|
||||
outb(0xb0, 0x43);
|
||||
outb(PIT_TICKS_50mS & 0xff, 0x42);
|
||||
outb(PIT_TICKS_50mS >> 8, 0x42);
|
||||
|
||||
uint32_t start_time;
|
||||
rdtscl(start_time);
|
||||
|
||||
int loops = 0;
|
||||
do {
|
||||
loops++;
|
||||
} while ((inb(0x61) & 0x20) == 0);
|
||||
|
||||
uint32_t end_time;
|
||||
rdtscl(end_time);
|
||||
|
||||
uint32_t run_time = end_time - start_time;
|
||||
|
||||
// Make sure we have a credible result
|
||||
if (loops >= 4 && run_time >= 50000) {
|
||||
clks_per_msec = run_time / 50;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t memspeed(uintptr_t src, uint32_t len, int iter)
|
||||
{
|
||||
uintptr_t dst;
|
||||
@ -1084,8 +1052,6 @@ void cpuinfo_init(void)
|
||||
determine_cache_size();
|
||||
|
||||
determine_cpu_model();
|
||||
|
||||
measure_cpu_speed();
|
||||
}
|
||||
|
||||
void membw_init(void)
|
||||
|
94
system/timers.c
Normal file
94
system/timers.c
Normal file
@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
// Copyright (C) 2004-2022 Sam Demeulemeester.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "acpi.h"
|
||||
#include "cpuid.h"
|
||||
#include "cpuinfo.h"
|
||||
#include "io.h"
|
||||
#include "tsc.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constants
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#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
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void correct_tsc(void)
|
||||
{
|
||||
uint32_t start_time, end_time, run_time, counter;
|
||||
int loops = 0;
|
||||
|
||||
if (cpuid_info.flags.rdtsc == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If available, use APIC Timer to find TSC correction factor
|
||||
if (acpi_config.pm_is_io && acpi_config.pm_addr != 0) {
|
||||
rdtscl(start_time);
|
||||
|
||||
counter = inl(acpi_config.pm_addr);
|
||||
|
||||
// Make sure counter is incrementing
|
||||
if (inl(acpi_config.pm_addr) > counter) {
|
||||
|
||||
while (1) {
|
||||
if (inl(acpi_config.pm_addr) > (counter + APIC_TICKS_50mS) || loops > 1000000) {
|
||||
break;
|
||||
}
|
||||
loops++;
|
||||
}
|
||||
|
||||
rdtscl(end_time);
|
||||
|
||||
run_time = end_time - start_time;
|
||||
|
||||
// Make sure we have a credible result
|
||||
if (loops >= 10 && run_time >= 50000) {
|
||||
clks_per_msec = run_time / 50;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use PIT Timer to find TSC correction factor if APIC not available
|
||||
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
|
||||
outb(0xb0, 0x43);
|
||||
outb(PIT_TICKS_50mS & 0xff, 0x42);
|
||||
outb(PIT_TICKS_50mS >> 8, 0x42);
|
||||
|
||||
rdtscl(start_time);
|
||||
|
||||
loops = 0;
|
||||
do {
|
||||
loops++;
|
||||
} while ((inb(0x61) & 0x20) == 0);
|
||||
|
||||
rdtscl(end_time);
|
||||
|
||||
run_time = end_time - start_time;
|
||||
|
||||
// Make sure we have a credible result
|
||||
if (loops >= 4 && run_time >= 50000) {
|
||||
clks_per_msec = run_time / 50;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void timers_init(void)
|
||||
{
|
||||
correct_tsc();
|
||||
}
|
20
system/timers.h
Normal file
20
system/timers.h
Normal file
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifndef _TIMERS_H_
|
||||
#define _TIMERS_H_
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Provides support for various timers sources
|
||||
*
|
||||
*//*
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
* Copyright (C) 2004-2022 Sam Demeulemeester
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize timers (to correct TSC frequency)
|
||||
*/
|
||||
void timers_init(void);
|
||||
|
||||
#endif /* _TIMERS_H_ */
|
Loading…
Reference in New Issue
Block a user