1*2449e17fSsherrym /* 2*2449e17fSsherrym * CDDL HEADER START 3*2449e17fSsherrym * 4*2449e17fSsherrym * The contents of this file are subject to the terms of the 5*2449e17fSsherrym * Common Development and Distribution License (the "License"). 6*2449e17fSsherrym * You may not use this file except in compliance with the License. 7*2449e17fSsherrym * 8*2449e17fSsherrym * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2449e17fSsherrym * or http://www.opensolaris.org/os/licensing. 10*2449e17fSsherrym * See the License for the specific language governing permissions 11*2449e17fSsherrym * and limitations under the License. 12*2449e17fSsherrym * 13*2449e17fSsherrym * When distributing Covered Code, include this CDDL HEADER in each 14*2449e17fSsherrym * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2449e17fSsherrym * If applicable, add the following below this CDDL HEADER, with the 16*2449e17fSsherrym * fields enclosed by brackets "[]" replaced with your own identifying 17*2449e17fSsherrym * information: Portions Copyright [yyyy] [name of copyright owner] 18*2449e17fSsherrym * 19*2449e17fSsherrym * CDDL HEADER END 20*2449e17fSsherrym */ 21*2449e17fSsherrym /* 22*2449e17fSsherrym * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*2449e17fSsherrym * Use is subject to license terms. 24*2449e17fSsherrym */ 25*2449e17fSsherrym 26*2449e17fSsherrym #ifndef _SYS_UCODE_H 27*2449e17fSsherrym #define _SYS_UCODE_H 28*2449e17fSsherrym 29*2449e17fSsherrym #pragma ident "%Z%%M% %I% %E% SMI" 30*2449e17fSsherrym 31*2449e17fSsherrym #include <sys/types.h> 32*2449e17fSsherrym #include <sys/priv.h> 33*2449e17fSsherrym #include <sys/processor.h> 34*2449e17fSsherrym #ifndef _KERNEL 35*2449e17fSsherrym #include <limits.h> 36*2449e17fSsherrym #endif 37*2449e17fSsherrym #include <ucode/ucode_errno.h> 38*2449e17fSsherrym 39*2449e17fSsherrym #ifdef __cplusplus 40*2449e17fSsherrym extern "C" { 41*2449e17fSsherrym #endif 42*2449e17fSsherrym 43*2449e17fSsherrym /* 44*2449e17fSsherrym * /dev/ucode 45*2449e17fSsherrym */ 46*2449e17fSsherrym #define UCODE_DRIVER_NAME "ucode" 47*2449e17fSsherrym #define UCODE_NODE_NAME "ucode" 48*2449e17fSsherrym #define UCODE_MINOR ((minor_t)0x3fffful) 49*2449e17fSsherrym 50*2449e17fSsherrym /* 51*2449e17fSsherrym * Where to install the microcode 52*2449e17fSsherrym */ 53*2449e17fSsherrym #define UCODE_INSTALL_PATH "platform/i86pc/ucode" 54*2449e17fSsherrym #define UCODE_INSTALL_COMMON_PATH ".f" 55*2449e17fSsherrym 56*2449e17fSsherrym /* 57*2449e17fSsherrym * ioctl numbers 58*2449e17fSsherrym */ 59*2449e17fSsherrym #define UCODE_IOC (('u'<<24)|('c'<<16)|('o'<<8)) 60*2449e17fSsherrym 61*2449e17fSsherrym #define UCODE_GET_VERSION (UCODE_IOC|0) 62*2449e17fSsherrym #define UCODE_UPDATE (UCODE_IOC|1) 63*2449e17fSsherrym 64*2449e17fSsherrym struct ucode_get_rev_struct { 65*2449e17fSsherrym uint32_t *ugv_rev; /* microcode revision array */ 66*2449e17fSsherrym int ugv_size; /* size of the array */ 67*2449e17fSsherrym ucode_errno_t ugv_errno; /* EUC error code */ 68*2449e17fSsherrym }; 69*2449e17fSsherrym 70*2449e17fSsherrym struct ucode_write_struct { 71*2449e17fSsherrym uint32_t uw_size; /* size of the uw_code buffer */ 72*2449e17fSsherrym uint8_t *uw_ucode; /* pointer to the undigested microcode */ 73*2449e17fSsherrym ucode_errno_t uw_errno; /* EUC error code */ 74*2449e17fSsherrym }; 75*2449e17fSsherrym 76*2449e17fSsherrym #if defined(_SYSCALL32_IMPL) 77*2449e17fSsherrym 78*2449e17fSsherrym #include <sys/types32.h> 79*2449e17fSsherrym 80*2449e17fSsherrym struct ucode_get_rev_struct32 { 81*2449e17fSsherrym caddr32_t ugv_rev; /* microcode revision array */ 82*2449e17fSsherrym int ugv_size; /* size of the array */ 83*2449e17fSsherrym ucode_errno_t ugv_errno; /* EUC error code */ 84*2449e17fSsherrym }; 85*2449e17fSsherrym 86*2449e17fSsherrym struct ucode_write_struct32 { 87*2449e17fSsherrym uint32_t uw_size; /* size of the uw_code buffer */ 88*2449e17fSsherrym caddr32_t uw_ucode; /* pointer to the undigested microcode */ 89*2449e17fSsherrym ucode_errno_t uw_errno; /* EUC error code */ 90*2449e17fSsherrym }; 91*2449e17fSsherrym 92*2449e17fSsherrym #endif /* _SYSCALL32_IMPL */ 93*2449e17fSsherrym 94*2449e17fSsherrym /* 95*2449e17fSsherrym * Microcode file information 96*2449e17fSsherrym */ 97*2449e17fSsherrym typedef struct ucode_header { 98*2449e17fSsherrym uint32_t uh_header_ver; 99*2449e17fSsherrym uint32_t uh_rev; 100*2449e17fSsherrym uint32_t uh_date; 101*2449e17fSsherrym uint32_t uh_signature; 102*2449e17fSsherrym uint32_t uh_checksum; 103*2449e17fSsherrym uint32_t uh_loader_ver; 104*2449e17fSsherrym uint32_t uh_proc_flags; 105*2449e17fSsherrym uint32_t uh_body_size; 106*2449e17fSsherrym uint32_t uh_total_size; 107*2449e17fSsherrym uint32_t uh_reserved[3]; 108*2449e17fSsherrym } ucode_header_t; 109*2449e17fSsherrym 110*2449e17fSsherrym typedef struct ucode_ext_sig { 111*2449e17fSsherrym uint32_t ues_signature; 112*2449e17fSsherrym uint32_t ues_proc_flags; 113*2449e17fSsherrym uint32_t ues_checksum; 114*2449e17fSsherrym } ucode_ext_sig_t; 115*2449e17fSsherrym 116*2449e17fSsherrym typedef struct ucode_ext_table { 117*2449e17fSsherrym uint32_t uet_count; 118*2449e17fSsherrym uint32_t uet_checksum; 119*2449e17fSsherrym uint32_t uet_reserved[3]; 120*2449e17fSsherrym ucode_ext_sig_t uet_ext_sig[1]; 121*2449e17fSsherrym } ucode_ext_table_t; 122*2449e17fSsherrym 123*2449e17fSsherrym typedef struct ucode_file { 124*2449e17fSsherrym ucode_header_t uf_header; 125*2449e17fSsherrym uint8_t *uf_body; 126*2449e17fSsherrym ucode_ext_table_t *uf_ext_table; 127*2449e17fSsherrym } ucode_file_t; 128*2449e17fSsherrym 129*2449e17fSsherrym 130*2449e17fSsherrym #define UCODE_SHORT_NAME_LEN 12 /* "32-bit-sig"-"8-bit-platid"\0 */ 131*2449e17fSsherrym /* 132*2449e17fSsherrym * Length of UCODE_INSTALL_COMMON_PATH/short-name 133*2449e17fSsherrym * strlen(UCODE_INSTALL_COMMON_PATH) + 1 + UCODE_SHORT_NAME_LEN 134*2449e17fSsherrym * Use sizeof which will give us the additional byte for the '/' in between 135*2449e17fSsherrym * the common path and the file name. 136*2449e17fSsherrym */ 137*2449e17fSsherrym #define UCODE_COMMON_NAME_LEN \ 138*2449e17fSsherrym (sizeof (UCODE_INSTALL_COMMON_PATH) + (UCODE_SHORT_NAME_LEN)) 139*2449e17fSsherrym #define UCODE_MAX_PATH_LEN (PATH_MAX - UCODE_COMMON_NAME_LEN) 140*2449e17fSsherrym 141*2449e17fSsherrym 142*2449e17fSsherrym #define UCODE_HEADER_SIZE (sizeof (struct ucode_header)) 143*2449e17fSsherrym #define UCODE_EXT_TABLE_SIZE (20) /* 20-bytes */ 144*2449e17fSsherrym #define UCODE_EXT_SIG_SIZE (sizeof (struct ucode_ext_sig)) 145*2449e17fSsherrym 146*2449e17fSsherrym #define UCODE_KB(a) ((a) << 10) /* KB */ 147*2449e17fSsherrym #define UCODE_MB(a) ((a) << 20) /* MB */ 148*2449e17fSsherrym #define UCODE_DEFAULT_TOTAL_SIZE UCODE_KB(2) 149*2449e17fSsherrym #define UCODE_DEFAULT_BODY_SIZE (UCODE_KB(2) - UCODE_HEADER_SIZE) 150*2449e17fSsherrym 151*2449e17fSsherrym /* 152*2449e17fSsherrym * For a single microcode file, the minimum size is 1K, maximum size is 16K. 153*2449e17fSsherrym * Such limitations, while somewhat artificial, are not only to provide better 154*2449e17fSsherrym * sanity checks, but also avoid wasting precious memory at startup time as the 155*2449e17fSsherrym * microcode buffer for the first processor has to be statically allocated. 156*2449e17fSsherrym * 157*2449e17fSsherrym * For the concatenation of all the microcode binary files, the maximum size 158*2449e17fSsherrym * is 16M. 159*2449e17fSsherrym */ 160*2449e17fSsherrym #define UCODE_MIN_SIZE UCODE_KB(1) 161*2449e17fSsherrym #define UCODE_MAX_SIZE UCODE_KB(16) 162*2449e17fSsherrym #define UCODE_MAX_COMBINED_SIZE UCODE_MB(16) 163*2449e17fSsherrym 164*2449e17fSsherrym #define UCODE_SIZE_CONVERT(size, default_size) \ 165*2449e17fSsherrym ((size) == 0 ? (default_size) : (size)) 166*2449e17fSsherrym 167*2449e17fSsherrym #define UCODE_BODY_SIZE(size) \ 168*2449e17fSsherrym UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_BODY_SIZE) 169*2449e17fSsherrym 170*2449e17fSsherrym #define UCODE_TOTAL_SIZE(size) \ 171*2449e17fSsherrym UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_TOTAL_SIZE) 172*2449e17fSsherrym 173*2449e17fSsherrym #define UCODE_MATCH(sig1, sig2, pf1, pf2) \ 174*2449e17fSsherrym (((sig1) == (sig2)) && \ 175*2449e17fSsherrym (((pf1) & (pf2)) || (((pf1) == 0) && ((pf2) == 0)))) 176*2449e17fSsherrym 177*2449e17fSsherrym extern ucode_errno_t ucode_header_validate(ucode_header_t *); 178*2449e17fSsherrym extern uint32_t ucode_checksum(uint32_t, uint32_t, uint8_t *); 179*2449e17fSsherrym extern ucode_errno_t ucode_validate(uint8_t *, int); 180*2449e17fSsherrym extern ucode_errno_t ucode_get_rev(uint32_t *); 181*2449e17fSsherrym extern ucode_errno_t ucode_update(uint8_t *, int); 182*2449e17fSsherrym 183*2449e17fSsherrym #define UCODE_MAX_VENDORS_NAME_LEN 20 184*2449e17fSsherrym 185*2449e17fSsherrym #define UCODE_VENDORS \ 186*2449e17fSsherrym static struct { \ 187*2449e17fSsherrym char *filestr; \ 188*2449e17fSsherrym char *vendorstr; \ 189*2449e17fSsherrym int supported; \ 190*2449e17fSsherrym } ucode_vendors[] = { \ 191*2449e17fSsherrym { "intel", "GenuineIntel", 1 }, \ 192*2449e17fSsherrym { "amd", "AuthenticAMD", 0 }, \ 193*2449e17fSsherrym { NULL, NULL, 0 } \ 194*2449e17fSsherrym } 195*2449e17fSsherrym 196*2449e17fSsherrym #ifdef __cplusplus 197*2449e17fSsherrym } 198*2449e17fSsherrym #endif 199*2449e17fSsherrym 200*2449e17fSsherrym #endif /* _SYS_UCODE_H */ 201