Kyösti Mälkki has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36549 )
Change subject: cpu/amd/family10h-15h: Extend monotonic timer to romstage ......................................................................
cpu/amd/family10h-15h: Extend monotonic timer to romstage
Use the TSC based counters for udelay() and timestamps.
Change-Id: I9a63bacfcc2285b4058be184a1db7559e85b22d0 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- M src/cpu/amd/family_10h-family_15h/Kconfig M src/cpu/amd/family_10h-family_15h/Makefile.inc M src/cpu/amd/family_10h-family_15h/monotonic_timer.c 3 files changed, 30 insertions(+), 15 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/49/36549/1
diff --git a/src/cpu/amd/family_10h-family_15h/Kconfig b/src/cpu/amd/family_10h-family_15h/Kconfig index 40a5576..ef702fb 100644 --- a/src/cpu/amd/family_10h-family_15h/Kconfig +++ b/src/cpu/amd/family_10h-family_15h/Kconfig @@ -6,8 +6,7 @@ select ARCH_RAMSTAGE_X86_32 select SSE2 select TSC_SYNC_LFENCE - select UDELAY_LAPIC - select COLLECT_TIMESTAMPS_TSC if COLLECT_TIMESTAMPS + select GENERIC_UDELAY select SUPPORT_CPU_UCODE_IN_CBFS select CPU_MICROCODE_MULTIPLE_FILES select CAR_GLOBAL_MIGRATION diff --git a/src/cpu/amd/family_10h-family_15h/Makefile.inc b/src/cpu/amd/family_10h-family_15h/Makefile.inc index 7035323..535002d 100644 --- a/src/cpu/amd/family_10h-family_15h/Makefile.inc +++ b/src/cpu/amd/family_10h-family_15h/Makefile.inc @@ -11,7 +11,10 @@ ramstage-y += tsc_freq.c romstage-y += ram_calc.c ramstage-y += ram_calc.c + +romstage-y += monotonic_timer.c ramstage-y += monotonic_timer.c + ramstage-$(CONFIG_HAVE_ACPI_TABLES) += powernow_acpi.c
# Microcode for Family 10h, 11h, 12h, and 14h diff --git a/src/cpu/amd/family_10h-family_15h/monotonic_timer.c b/src/cpu/amd/family_10h-family_15h/monotonic_timer.c index 51244b8..62e5b17 100644 --- a/src/cpu/amd/family_10h-family_15h/monotonic_timer.c +++ b/src/cpu/amd/family_10h-family_15h/monotonic_timer.c @@ -10,10 +10,13 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include <stdint.h> #include <arch/cpu.h> +#include <arch/early_variables.h> #include <cpu/x86/msr.h> #include <cpu/amd/msr.h> +#include <delay.h> #include <timer.h> #include <device/pci.h> #include <device/pci_ops.h> @@ -24,7 +27,12 @@ uint32_t core_frequency; struct mono_time time; uint64_t last_value; -} mono_counter; +} mono_counter_g CAR_GLOBAL; + +static inline struct monotonic_counter *get_monotonic_context(void) +{ + return car_get_var_ptr(&mono_counter_g); +}
static inline uint64_t read_counter_msr(void) { @@ -35,13 +43,15 @@ return ((uint64_t)counter_msr.hi << 32) | (uint64_t)counter_msr.lo; }
-static void init_timer(void) +void init_timer(void) { + struct monotonic_counter *mono_counter; uint8_t model; uint32_t cpuid_fms; uint8_t cpufid; uint8_t cpudid; uint8_t boost_capable = 0; + pci_devfn_t BOOSTCAP = PCI_DEV(0, 0x18, 4);
/* Get CPU model */ cpuid_fms = cpuid_eax(0x80000001); @@ -49,8 +59,7 @@
/* Get boost capability */ if ((model == 0x8) || (model == 0x9)) { /* revision D */ - boost_capable = (pci_read_config32(pcidev_on_root(0x18, 4), - 0x15c) & 0x4) >> 2; + boost_capable = (pci_s_read_config32(BOOSTCAP, 0x15c) & 0x4) >> 2; }
/* Set up TSC (BKDG v3.62 section 2.9.4)*/ @@ -62,30 +71,34 @@ msr = rdmsr(PSTATE_0_MSR + boost_capable); cpufid = (msr.lo & 0x3f); cpudid = (msr.lo & 0x1c0) >> 6; - mono_counter.core_frequency = (100 * (cpufid + 0x10)) / (0x01 << cpudid);
- mono_counter.last_value = read_counter_msr(); - mono_counter.initialized = 1; + mono_counter = get_monotonic_context(); + mono_counter->core_frequency = (100 * (cpufid + 0x10)) / (0x01 << cpudid); }
void timer_monotonic_get(struct mono_time *mt) { uint64_t current_tick; uint32_t usecs_elapsed = 0; + struct monotonic_counter *mono_counter;
- if (!mono_counter.initialized) + mono_counter = get_monotonic_context(); + if (!mono_counter->initialized) { init_timer(); + mono_counter->last_value = read_counter_msr(); + mono_counter->initialized = 1; + }
current_tick = read_counter_msr(); - if (mono_counter.core_frequency != 0) - usecs_elapsed = (current_tick - mono_counter.last_value) / mono_counter.core_frequency; + if (mono_counter->core_frequency != 0) + usecs_elapsed = (current_tick - mono_counter->last_value) / mono_counter->core_frequency;
/* Update current time and tick values only if a full tick occurred. */ if (usecs_elapsed) { - mono_time_add_usecs(&mono_counter.time, usecs_elapsed); - mono_counter.last_value = current_tick; + mono_time_add_usecs(&mono_counter->time, usecs_elapsed); + mono_counter->last_value = current_tick; }
/* Save result. */ - *mt = mono_counter.time; + *mt = mono_counter->time; }