cpuctl.c (195189) | cpuctl.c (228436) |
---|---|
1/*- 2 * Copyright (c) 2006-2008 Stanislav Sedov <stas@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006-2008 Stanislav Sedov <stas@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/dev/cpuctl/cpuctl.c 195189 2009-06-30 12:35:47Z stas $"); | 29__FBSDID("$FreeBSD: head/sys/dev/cpuctl/cpuctl.c 228436 2011-12-12 12:30:44Z fabient $"); |
30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/conf.h> 34#include <sys/fcntl.h> 35#include <sys/ioccom.h> 36#include <sys/malloc.h> 37#include <sys/module.h> --- 31 unchanged lines hidden (view full) --- 69 struct thread *td); 70static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, 71 struct thread *td); 72static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data, 73 struct thread *td); 74static int update_intel(int cpu, cpuctl_update_args_t *args, 75 struct thread *td); 76static int update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td); | 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/conf.h> 34#include <sys/fcntl.h> 35#include <sys/ioccom.h> 36#include <sys/malloc.h> 37#include <sys/module.h> --- 31 unchanged lines hidden (view full) --- 69 struct thread *td); 70static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, 71 struct thread *td); 72static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data, 73 struct thread *td); 74static int update_intel(int cpu, cpuctl_update_args_t *args, 75 struct thread *td); 76static int update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td); |
77static int update_via(int cpu, cpuctl_update_args_t *args, 78 struct thread *td); |
|
77 78static struct cdev **cpuctl_devs; 79static MALLOC_DEFINE(M_CPUCTL, "cpuctl", "CPUCTL buffer"); 80 81static struct cdevsw cpuctl_cdevsw = { 82 .d_version = D_VERSION, 83 .d_open = cpuctl_open, 84 .d_ioctl = cpuctl_ioctl, --- 191 unchanged lines hidden (view full) --- 276 return (ENXIO); 277 } 278 ((uint32_t *)vendor)[0] = args.data[1]; 279 ((uint32_t *)vendor)[1] = args.data[3]; 280 ((uint32_t *)vendor)[2] = args.data[2]; 281 vendor[12] = '\0'; 282 if (strncmp(vendor, INTEL_VENDOR_ID, sizeof(INTEL_VENDOR_ID)) == 0) 283 ret = update_intel(cpu, data, td); | 79 80static struct cdev **cpuctl_devs; 81static MALLOC_DEFINE(M_CPUCTL, "cpuctl", "CPUCTL buffer"); 82 83static struct cdevsw cpuctl_cdevsw = { 84 .d_version = D_VERSION, 85 .d_open = cpuctl_open, 86 .d_ioctl = cpuctl_ioctl, --- 191 unchanged lines hidden (view full) --- 278 return (ENXIO); 279 } 280 ((uint32_t *)vendor)[0] = args.data[1]; 281 ((uint32_t *)vendor)[1] = args.data[3]; 282 ((uint32_t *)vendor)[2] = args.data[2]; 283 vendor[12] = '\0'; 284 if (strncmp(vendor, INTEL_VENDOR_ID, sizeof(INTEL_VENDOR_ID)) == 0) 285 ret = update_intel(cpu, data, td); |
284 else if(strncmp(vendor, INTEL_VENDOR_ID, sizeof(AMD_VENDOR_ID)) == 0) | 286 else if(strncmp(vendor, AMD_VENDOR_ID, sizeof(AMD_VENDOR_ID)) == 0) |
285 ret = update_amd(cpu, data, td); | 287 ret = update_amd(cpu, data, td); |
288 else if(strncmp(vendor, CENTAUR_VENDOR_ID, sizeof(CENTAUR_VENDOR_ID)) == 0) 289 ret = update_via(cpu, data, td); |
|
286 else 287 ret = ENXIO; 288 return (ret); 289} 290 291static int 292update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td) 293{ --- 103 unchanged lines hidden (view full) --- 397 restore_cpu(oldcpu, is_bound, td); 398 ret = 0; 399fail: 400 if (ptr != NULL) 401 contigfree(ptr, args->size, M_CPUCTL); 402 return (ret); 403} 404 | 290 else 291 ret = ENXIO; 292 return (ret); 293} 294 295static int 296update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td) 297{ --- 103 unchanged lines hidden (view full) --- 401 restore_cpu(oldcpu, is_bound, td); 402 ret = 0; 403fail: 404 if (ptr != NULL) 405 contigfree(ptr, args->size, M_CPUCTL); 406 return (ret); 407} 408 |
409static int 410update_via(int cpu, cpuctl_update_args_t *args, struct thread *td) 411{ 412 void *ptr = NULL; 413 uint64_t rev0, rev1, res; 414 uint32_t tmp[4]; 415 int is_bound = 0; 416 int oldcpu; 417 int ret; 418 419 if (args->size == 0 || args->data == NULL) { 420 DPRINTF("[cpuctl,%d]: zero-sized firmware image", __LINE__); 421 return (EINVAL); 422 } 423 if (args->size > UCODE_SIZE_MAX) { 424 DPRINTF("[cpuctl,%d]: firmware image too large", __LINE__); 425 return (EINVAL); 426 } 427 428 /* 429 * 4 byte alignment required. 430 */ 431 ptr = malloc(args->size + 16, M_CPUCTL, M_WAITOK); 432 ptr = (void *)(16 + ((intptr_t)ptr & ~0xf)); 433 if (copyin(args->data, ptr, args->size) != 0) { 434 DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed", 435 __LINE__, args->data, ptr, args->size); 436 ret = EFAULT; 437 goto fail; 438 } 439 oldcpu = td->td_oncpu; 440 is_bound = cpu_sched_is_bound(td); 441 set_cpu(cpu, td); 442 critical_enter(); 443 rdmsr_safe(MSR_BIOS_SIGN, &rev0); /* Get current micorcode revision. */ 444 445 /* 446 * Perform update. 447 */ 448 wrmsr_safe(MSR_BIOS_UPDT_TRIG, (uintptr_t)(ptr)); 449 do_cpuid(1, tmp); 450 451 /* 452 * Result are in low byte of MSR FCR5: 453 * 0x00: No update has been attempted since RESET. 454 * 0x01: The last attempted update was successful. 455 * 0x02: The last attempted update was unsuccessful due to a bad 456 * environment. No update was loaded and any preexisting 457 * patches are still active. 458 * 0x03: The last attempted update was not applicable to this processor. 459 * No update was loaded and any preexisting patches are still 460 * active. 461 * 0x04: The last attempted update was not successful due to an invalid 462 * update data block. No update was loaded and any preexisting 463 * patches are still active 464 */ 465 rdmsr_safe(0x1205, &res); 466 res &= 0xff; 467 critical_exit(); 468 rdmsr_safe(MSR_BIOS_SIGN, &rev1); /* Get new microcode revision. */ 469 restore_cpu(oldcpu, is_bound, td); 470 471 DPRINTF("[cpu,%d]: rev0=%x rev1=%x res=%x\n", __LINE__, 472 (unsigned)(rev0 >> 32), (unsigned)(rev1 >> 32), (unsigned)res); 473 474 if (res != 0x01) 475 ret = EINVAL; 476 else 477 ret = 0; 478fail: 479 if (ptr != NULL) 480 contigfree(ptr, args->size, M_CPUCTL); 481 return (ret); 482} 483 |
|
405int 406cpuctl_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) 407{ 408 int ret = 0; 409 int cpu; 410 411 cpu = dev2unit(dev); 412 if (cpu >= mp_ncpus || !cpu_enabled(cpu)) { --- 52 unchanged lines hidden --- | 484int 485cpuctl_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) 486{ 487 int ret = 0; 488 int cpu; 489 490 cpu = dev2unit(dev); 491 if (cpu >= mp_ncpus || !cpu_enabled(cpu)) { --- 52 unchanged lines hidden --- |