From 50720a4b0b251eb1d97d4682a4db9c2c589d6019 Mon Sep 17 00:00:00 2001 From: Thomas Heijligen Date: Tue, 14 Dec 2021 17:25:49 +0100 Subject: hwaccess physmap: move x86 msr related code into own files Allow x86 msr related code to be compiled independent from memory mapping functionality. This enables for a better selection of needed hardware access types. Change-Id: Idc9ce9df3ea1e291ad469de59467646b294119c4 Signed-off-by: Thomas Heijligen Reviewed-on: https://review.coreboot.org/c/flashrom/+/60111 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- physmap.c | 324 -------------------------------------------------------------- 1 file changed, 324 deletions(-) (limited to 'physmap.c') diff --git a/physmap.c b/physmap.c index 796860ce..6f2896ff 100644 --- a/physmap.c +++ b/physmap.c @@ -362,327 +362,3 @@ void *physmap_ro_unaligned(const char *descr, uintptr_t phys_addr, size_t len) { return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_EXACT); } - -#if CONFIG_INTERNAL == 1 -/* MSR abstraction implementations for Linux, OpenBSD, FreeBSD/Dragonfly, OSX, libpayload - * and a non-working default implementation on the bottom. See also hwaccess.h for some (re)declarations. */ -#if defined(__i386__) || defined(__x86_64__) - -#ifdef __linux__ -/* - * Reading and writing to MSRs, however requires instructions rdmsr/wrmsr, - * which are ring0 privileged instructions so only the kernel can do the - * read/write. This function, therefore, requires that the msr kernel module - * be loaded to access these instructions from user space using device - * /dev/cpu/0/msr. - */ - -static int fd_msr = -1; - -msr_t rdmsr(int addr) -{ - uint32_t buf[2]; - msr_t msr = { 0xffffffff, 0xffffffff }; - - if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) { - msg_perr("Could not lseek() MSR: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - if (read(fd_msr, buf, 8) == 8) { - msr.lo = buf[0]; - msr.hi = buf[1]; - return msr; - } - - if (errno != EIO) { - // A severe error. - msg_perr("Could not read() MSR: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - return msr; -} - -int wrmsr(int addr, msr_t msr) -{ - uint32_t buf[2]; - buf[0] = msr.lo; - buf[1] = msr.hi; - - if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) { - msg_perr("Could not lseek() MSR: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - if (write(fd_msr, buf, 8) != 8 && errno != EIO) { - msg_perr("Could not write() MSR: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - /* Some MSRs must not be written. */ - if (errno == EIO) - return -1; - - return 0; -} - -int setup_cpu_msr(int cpu) -{ - char msrfilename[64] = { 0 }; - snprintf(msrfilename, sizeof(msrfilename), "/dev/cpu/%d/msr", cpu); - - if (fd_msr != -1) { - msg_pinfo("MSR was already initialized\n"); - return -1; - } - - fd_msr = open(msrfilename, O_RDWR); - - if (fd_msr < 0) { - msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno)); - msg_pinfo("Did you run 'modprobe msr'?\n"); - return -1; - } - - return 0; -} - -void cleanup_cpu_msr(void) -{ - if (fd_msr == -1) { - msg_pinfo("No MSR initialized.\n"); - return; - } - - close(fd_msr); - - /* Clear MSR file descriptor. */ - fd_msr = -1; -} -#elif defined(__OpenBSD__) && defined (__i386__) /* This does only work for certain AMD Geode LX systems see amdmsr(4). */ -#include -#include - -static int fd_msr = -1; - -msr_t rdmsr(int addr) -{ - struct amdmsr_req args; - - msr_t msr = { 0xffffffff, 0xffffffff }; - - args.addr = (uint32_t)addr; - - if (ioctl(fd_msr, RDMSR, &args) < 0) { - msg_perr("Error while executing RDMSR ioctl: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - msr.lo = args.val & 0xffffffff; - msr.hi = args.val >> 32; - - return msr; -} - -int wrmsr(int addr, msr_t msr) -{ - struct amdmsr_req args; - - args.addr = addr; - args.val = (((uint64_t)msr.hi) << 32) | msr.lo; - - if (ioctl(fd_msr, WRMSR, &args) < 0) { - msg_perr("Error while executing WRMSR ioctl: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - return 0; -} - -int setup_cpu_msr(int cpu) -{ - char msrfilename[64] = { 0 }; - snprintf(msrfilename, sizeof(msrfilename), "/dev/amdmsr"); - - if (fd_msr != -1) { - msg_pinfo("MSR was already initialized\n"); - return -1; - } - - fd_msr = open(msrfilename, O_RDWR); - - if (fd_msr < 0) { - msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno)); - return -1; - } - - return 0; -} - -void cleanup_cpu_msr(void) -{ - if (fd_msr == -1) { - msg_pinfo("No MSR initialized.\n"); - return; - } - - close(fd_msr); - - /* Clear MSR file descriptor. */ - fd_msr = -1; -} - -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#include - -typedef struct { - int msr; - uint64_t data; -} cpu_msr_args_t; -#define CPU_RDMSR _IOWR('c', 1, cpu_msr_args_t) -#define CPU_WRMSR _IOWR('c', 2, cpu_msr_args_t) - -static int fd_msr = -1; - -msr_t rdmsr(int addr) -{ - cpu_msr_args_t args; - - msr_t msr = { 0xffffffff, 0xffffffff }; - - args.msr = addr; - - if (ioctl(fd_msr, CPU_RDMSR, &args) < 0) { - msg_perr("Error while executing CPU_RDMSR ioctl: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - msr.lo = args.data & 0xffffffff; - msr.hi = args.data >> 32; - - return msr; -} - -int wrmsr(int addr, msr_t msr) -{ - cpu_msr_args_t args; - - args.msr = addr; - args.data = (((uint64_t)msr.hi) << 32) | msr.lo; - - if (ioctl(fd_msr, CPU_WRMSR, &args) < 0) { - msg_perr("Error while executing CPU_WRMSR ioctl: %s\n", strerror(errno)); - close(fd_msr); - exit(1); - } - - return 0; -} - -int setup_cpu_msr(int cpu) -{ - char msrfilename[64] = { 0 }; - snprintf(msrfilename, sizeof(msrfilename), "/dev/cpu%d", cpu); - - if (fd_msr != -1) { - msg_pinfo("MSR was already initialized\n"); - return -1; - } - - fd_msr = open(msrfilename, O_RDWR); - - if (fd_msr < 0) { - msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno)); - msg_pinfo("Did you install ports/sysutils/devcpu?\n"); - return -1; - } - - return 0; -} - -void cleanup_cpu_msr(void) -{ - if (fd_msr == -1) { - msg_pinfo("No MSR initialized.\n"); - return; - } - - close(fd_msr); - - /* Clear MSR file descriptor. */ - fd_msr = -1; -} - -#elif defined(__MACH__) && defined(__APPLE__) -/* rdmsr() and wrmsr() are provided by DirectHW which needs neither setup nor cleanup. */ -int setup_cpu_msr(int cpu) -{ - // Always succeed for now - return 0; -} - -void cleanup_cpu_msr(void) -{ - // Nothing, yet. -} -#elif defined(__LIBPAYLOAD__) -msr_t libpayload_rdmsr(int addr) -{ - msr_t msr; - unsigned long long val = _rdmsr(addr); - msr.lo = val & 0xffffffff; - msr.hi = val >> 32; - return msr; -} - -int libpayload_wrmsr(int addr, msr_t msr) -{ - _wrmsr(addr, msr.lo | ((unsigned long long)msr.hi << 32)); - return 0; -} - -int setup_cpu_msr(int cpu) -{ - return 0; -} - -void cleanup_cpu_msr(void) -{ -} -#else -/* default MSR implementation */ -msr_t rdmsr(int addr) -{ - msr_t ret = { 0xffffffff, 0xffffffff }; - - return ret; -} - -int wrmsr(int addr, msr_t msr) -{ - return -1; -} - -int setup_cpu_msr(int cpu) -{ - msg_pinfo("No MSR support for your OS yet.\n"); - return -1; -} - -void cleanup_cpu_msr(void) -{ - // Nothing, yet. -} -#endif // OS switches for MSR code -#else // x86 -/* Does MSR exist on non-x86 architectures? */ -#endif // arch switches for MSR code -#endif // CONFIG_INTERNAL == 1 -- cgit v1.2.3