Deleted Added
full compact
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 ---