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