From da11bd9d6028b811732e98bc8cbf3e00b7a1f2b3 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 3 Mar 2017 13:34:03 +0100 Subject: efi: move x86 clocksource to device/driver so we can dynamicly register the device As we may need to use HW IP for clocksource. As on EFI we could use Timestamp GUID if present (Not often the case as it's not even enabled by default on any Target on EDK II not even OVMF) Or if we choose we could use a Simulated Timestamp driver that work on Event (Add Later) Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Sascha Hauer --- arch/x86/Kconfig | 2 +- arch/x86/mach-efi/Makefile | 1 + arch/x86/mach-efi/clocksource.c | 11 ++++++ drivers/clocksource/Kconfig | 6 ++-- drivers/clocksource/Makefile | 2 +- drivers/clocksource/efi.c | 61 ------------------------------- drivers/clocksource/efi_x86.c | 79 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 96 insertions(+), 66 deletions(-) create mode 100644 arch/x86/mach-efi/clocksource.c delete mode 100644 drivers/clocksource/efi.c create mode 100644 drivers/clocksource/efi_x86.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9803f3f95f..52ccf4894f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -77,7 +77,7 @@ choice select EFI_GUID select EFI_DEVICEPATH select PRINTF_UUID - select CLOCKSOURCE_EFI + select CLOCKSOURCE_EFI_X86 config X86_BIOS_BRINGUP bool "16 bit BIOS" diff --git a/arch/x86/mach-efi/Makefile b/arch/x86/mach-efi/Makefile index c8a97bae07..f633e7c7ed 100644 --- a/arch/x86/mach-efi/Makefile +++ b/arch/x86/mach-efi/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_X86_64) += reloc_x86_64.o crt0-efi-x86_64.o obj-$(CONFIG_X86_32) += reloc_ia32.o crt0-efi-ia32.o +obj-y += clocksource.o extra-$(CONFIG_X86_32) += elf_ia32_efi.lds extra-$(CONFIG_X86_64) += elf_x86_64_efi.lds diff --git a/arch/x86/mach-efi/clocksource.c b/arch/x86/mach-efi/clocksource.c new file mode 100644 index 0000000000..2023fa19ac --- /dev/null +++ b/arch/x86/mach-efi/clocksource.c @@ -0,0 +1,11 @@ +#include +#include +#include + +static int efi_x86_pure_init(void) +{ + struct device_d *dev = device_alloc("efi-cs-x86", DEVICE_ID_SINGLE); + + return platform_device_register(dev); +} +core_initcall(efi_x86_pure_init); diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 54b05bbf3b..9b7f0a9d7f 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -34,9 +34,9 @@ config CLOCKSOURCE_DUMMY_RATE The option CONFIG_CLOCKSOURCE_DUMMY_RATE is used to adjust this clocksource. The bigger rate valuest makes clocksource "faster". -config CLOCKSOURCE_EFI - bool - depends on EFI_BOOTUP +config CLOCKSOURCE_EFI_X86 + bool "EFI X86 HW driver" + depends on EFI_BOOTUP && X86 config CLOCKSOURCE_MVEBU bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index e83fdeeec2..1fd18296ea 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o obj-$(CONFIG_CLOCKSOURCE_BCM283X) += bcm2835.o obj-$(CONFIG_CLOCKSOURCE_CLPS711X) += clps711x.o obj-$(CONFIG_CLOCKSOURCE_DIGIC) += digic.o -obj-$(CONFIG_CLOCKSOURCE_EFI) += efi.o +obj-$(CONFIG_CLOCKSOURCE_EFI_X86) += efi_x86.o obj-$(CONFIG_CLOCKSOURCE_MVEBU) += mvebu.o obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o diff --git a/drivers/clocksource/efi.c b/drivers/clocksource/efi.c deleted file mode 100644 index 6d2fee8eba..0000000000 --- a/drivers/clocksource/efi.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include -#include - -#ifdef __x86_64__ -uint64_t ticks_read(void) -{ - uint64_t a, d; - - __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); - - return (d << 32) | a; -} -#else -uint64_t ticks_read(void) -{ - uint64_t val; - - __asm__ volatile ("rdtsc" : "=A" (val)); - - return val; -} -#endif - -static uint64_t freq; - -/* count TSC ticks during a millisecond delay */ -static uint64_t ticks_freq(void) -{ - uint64_t ticks_start, ticks_end; - - ticks_start = ticks_read(); - BS->stall(1000); - ticks_end = ticks_read(); - - return (ticks_end - ticks_start) * 1000; -} - -static uint64_t efi_clocksource_read(void) -{ - return 1000 * 1000 * ticks_read() / freq; -} - -static struct clocksource cs = { - .read = efi_clocksource_read, - .mask = CLOCKSOURCE_MASK(64), - .shift = 0, -}; - -static int efi_clocksource_init(void) -{ - cs.mult = clocksource_hz2mult(1000 * 1000, cs.shift); - - freq = ticks_freq(); - - return init_clock(&cs); -} -/* for efi the time must be init at core initcall level */ -core_initcall(efi_clocksource_init); diff --git a/drivers/clocksource/efi_x86.c b/drivers/clocksource/efi_x86.c new file mode 100644 index 0000000000..4d2657ea1d --- /dev/null +++ b/drivers/clocksource/efi_x86.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include + +#ifdef __x86_64__ +uint64_t ticks_read(void) +{ + uint64_t a, d; + + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + + return (d << 32) | a; +} +#else +uint64_t ticks_read(void) +{ + uint64_t val; + + __asm__ volatile ("rdtsc" : "=A" (val)); + + return val; +} +#endif + +static uint64_t freq; + +/* count TSC ticks during a millisecond delay */ +static uint64_t ticks_freq(void) +{ + uint64_t ticks_start, ticks_end; + + ticks_start = ticks_read(); + BS->stall(1000); + ticks_end = ticks_read(); + + return (ticks_end - ticks_start) * 1000; +} + +static uint64_t efi_x86_cs_read(void) +{ + return 1000 * 1000 * ticks_read() / freq; +} + +static int efi_x86_cs_init(struct clocksource *cs) +{ + cs->mult = clocksource_hz2mult(1000 * 1000, cs->shift); + + freq = ticks_freq(); + + return 0; +} + +static struct clocksource efi_x86_cs = { + .read = efi_x86_cs_read, + .mask = CLOCKSOURCE_MASK(64), + .shift = 0, + .priority = 100, + .init = efi_x86_cs_init, +}; + +static int efi_x86_cs_probe(struct device_d *dev) +{ + return init_clock(&efi_x86_cs); +} + +static struct driver_d efi_x86_cs_driver = { + .name = "efi-cs-x86", + .probe = efi_x86_cs_probe, +}; + +static int efi_x86_cs_initcall(void) +{ + return platform_driver_register(&efi_x86_cs_driver); +} +/* for efi the time must be init at core initcall level */ +core_initcall(efi_x86_cs_initcall); -- cgit v1.2.3