cpu_ucode.c revision 1.1 1 /* $NetBSD: cpu_ucode.c,v 1.1 2012/01/13 16:05:15 cegger Exp $ */
2 /*
3 * Copyright (c) 2012 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Christoph Egger.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: cpu_ucode.c,v 1.1 2012/01/13 16:05:15 cegger Exp $");
33
34 #include "opt_cpu_ucode.h"
35
36 #include <sys/param.h>
37 #include <sys/cpuio.h>
38 #include <sys/cpu.h>
39
40 #include <dev/firmload.h>
41
42 #include <machine/cpuvar.h>
43 #include <machine/cputypes.h>
44
45 #include <x86/cpu_ucode.h>
46
47 static struct cpu_ucode_softc ucode_softc;
48
49 int
50 cpu_ucode_get_version(void *data)
51 {
52 struct cpu_ucode *ucode = data;
53
54 switch (cpu_vendor) {
55 case CPUVENDOR_AMD:
56 return cpu_ucode_amd_get_version(ucode);
57 default:
58 ucode->version = (uint64_t)-1;
59 return EOPNOTSUPP;
60 }
61
62 return 0;
63 }
64
65 int
66 cpu_ucode_md_open(firmware_handle_t *fwh, const char *fwname)
67 {
68 switch (cpu_vendor) {
69 case CPUVENDOR_AMD:
70 return cpu_ucode_amd_firmware_open(fwh, fwname);
71 case CPUVENDOR_INTEL:
72 return EOPNOTSUPP; /* not yet supported */
73 default:
74 return EOPNOTSUPP;
75 }
76 }
77
78 int
79 cpu_ucode_apply(void *data)
80 {
81 struct cpu_ucode *ucode = data;
82 struct cpu_ucode_softc *sc = &ucode_softc;
83 int error;
84
85 error = cpu_ucode_load(sc, ucode->fwname);
86 if (error)
87 return error;
88
89 switch (cpu_vendor) {
90 case CPUVENDOR_AMD:
91 error = cpu_ucode_amd_apply(sc);
92 break;
93 default:
94 return EOPNOTSUPP;
95 }
96
97 if (sc->sc_blob != NULL)
98 firmware_free(sc->sc_blob, 0);
99 sc->sc_blob = NULL;
100 sc->sc_blobsize = 0;
101 return error;
102 }
103