1*d32f26eeSAndy Fiddaman /* 2*d32f26eeSAndy Fiddaman * CDDL HEADER START 3*d32f26eeSAndy Fiddaman * 4*d32f26eeSAndy Fiddaman * The contents of this file are subject to the terms of the 5*d32f26eeSAndy Fiddaman * Common Development and Distribution License (the "License"). 6*d32f26eeSAndy Fiddaman * You may not use this file except in compliance with the License. 7*d32f26eeSAndy Fiddaman * 8*d32f26eeSAndy Fiddaman * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*d32f26eeSAndy Fiddaman * or http://www.opensolaris.org/os/licensing. 10*d32f26eeSAndy Fiddaman * See the License for the specific language governing permissions 11*d32f26eeSAndy Fiddaman * and limitations under the License. 12*d32f26eeSAndy Fiddaman * 13*d32f26eeSAndy Fiddaman * When distributing Covered Code, include this CDDL HEADER in each 14*d32f26eeSAndy Fiddaman * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*d32f26eeSAndy Fiddaman * If applicable, add the following below this CDDL HEADER, with the 16*d32f26eeSAndy Fiddaman * fields enclosed by brackets "[]" replaced with your own identifying 17*d32f26eeSAndy Fiddaman * information: Portions Copyright [yyyy] [name of copyright owner] 18*d32f26eeSAndy Fiddaman * 19*d32f26eeSAndy Fiddaman * CDDL HEADER END 20*d32f26eeSAndy Fiddaman */ 21*d32f26eeSAndy Fiddaman /* 22*d32f26eeSAndy Fiddaman * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*d32f26eeSAndy Fiddaman * Use is subject to license terms. 24*d32f26eeSAndy Fiddaman * 25*d32f26eeSAndy Fiddaman * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. 26*d32f26eeSAndy Fiddaman * Copyright 2022 Joyent, Inc. 27*d32f26eeSAndy Fiddaman * Copyright 2023 Oxide Computer Company 28*d32f26eeSAndy Fiddaman */ 29*d32f26eeSAndy Fiddaman 30*d32f26eeSAndy Fiddaman #ifndef _SYS_UCODE_H 31*d32f26eeSAndy Fiddaman #define _SYS_UCODE_H 32*d32f26eeSAndy Fiddaman 33*d32f26eeSAndy Fiddaman #ifdef _KERNEL 34*d32f26eeSAndy Fiddaman #include <sys/cpuvar.h> 35*d32f26eeSAndy Fiddaman #include <sys/linker_set.h> 36*d32f26eeSAndy Fiddaman #endif 37*d32f26eeSAndy Fiddaman #include <sys/stdbool.h> 38*d32f26eeSAndy Fiddaman #include <sys/types.h> 39*d32f26eeSAndy Fiddaman #include <sys/priv.h> 40*d32f26eeSAndy Fiddaman #include <sys/processor.h> 41*d32f26eeSAndy Fiddaman #include <ucode/ucode_errno.h> 42*d32f26eeSAndy Fiddaman 43*d32f26eeSAndy Fiddaman #ifdef __cplusplus 44*d32f26eeSAndy Fiddaman extern "C" { 45*d32f26eeSAndy Fiddaman #endif 46*d32f26eeSAndy Fiddaman 47*d32f26eeSAndy Fiddaman /* 48*d32f26eeSAndy Fiddaman * /dev/ucode 49*d32f26eeSAndy Fiddaman */ 50*d32f26eeSAndy Fiddaman #define UCODE_DRIVER_NAME "ucode" 51*d32f26eeSAndy Fiddaman #define UCODE_NODE_NAME "ucode" 52*d32f26eeSAndy Fiddaman #define UCODE_MINOR ((minor_t)0x3fffful) 53*d32f26eeSAndy Fiddaman 54*d32f26eeSAndy Fiddaman /* 55*d32f26eeSAndy Fiddaman * ioctl numbers 56*d32f26eeSAndy Fiddaman */ 57*d32f26eeSAndy Fiddaman #define UCODE_IOC (('u'<<24)|('c'<<16)|('o'<<8)) 58*d32f26eeSAndy Fiddaman 59*d32f26eeSAndy Fiddaman #define UCODE_GET_VERSION (UCODE_IOC|0) 60*d32f26eeSAndy Fiddaman #define UCODE_UPDATE (UCODE_IOC|1) 61*d32f26eeSAndy Fiddaman 62*d32f26eeSAndy Fiddaman struct ucode_get_rev_struct { 63*d32f26eeSAndy Fiddaman uint32_t *ugv_rev; /* microcode revision array */ 64*d32f26eeSAndy Fiddaman int ugv_size; /* size of the array */ 65*d32f26eeSAndy Fiddaman ucode_errno_t ugv_errno; /* EUC error code */ 66*d32f26eeSAndy Fiddaman }; 67*d32f26eeSAndy Fiddaman 68*d32f26eeSAndy Fiddaman struct ucode_write_struct { 69*d32f26eeSAndy Fiddaman uint32_t uw_size; /* size of the uw_code buffer */ 70*d32f26eeSAndy Fiddaman uint8_t *uw_ucode; /* pointer to the undigested microcode */ 71*d32f26eeSAndy Fiddaman ucode_errno_t uw_errno; /* EUC error code */ 72*d32f26eeSAndy Fiddaman }; 73*d32f26eeSAndy Fiddaman 74*d32f26eeSAndy Fiddaman #if defined(_SYSCALL32_IMPL) 75*d32f26eeSAndy Fiddaman 76*d32f26eeSAndy Fiddaman #include <sys/types32.h> 77*d32f26eeSAndy Fiddaman 78*d32f26eeSAndy Fiddaman struct ucode_get_rev_struct32 { 79*d32f26eeSAndy Fiddaman caddr32_t ugv_rev; /* microcode revision array */ 80*d32f26eeSAndy Fiddaman int ugv_size; /* size of the array */ 81*d32f26eeSAndy Fiddaman ucode_errno_t ugv_errno; /* EUC error code */ 82*d32f26eeSAndy Fiddaman }; 83*d32f26eeSAndy Fiddaman 84*d32f26eeSAndy Fiddaman struct ucode_write_struct32 { 85*d32f26eeSAndy Fiddaman uint32_t uw_size; /* size of the uw_code buffer */ 86*d32f26eeSAndy Fiddaman caddr32_t uw_ucode; /* pointer to the undigested microcode */ 87*d32f26eeSAndy Fiddaman ucode_errno_t uw_errno; /* EUC error code */ 88*d32f26eeSAndy Fiddaman }; 89*d32f26eeSAndy Fiddaman 90*d32f26eeSAndy Fiddaman #endif /* _SYSCALL32_IMPL */ 91*d32f26eeSAndy Fiddaman 92*d32f26eeSAndy Fiddaman #define UCODE_KB(a) ((a) << 10) /* KiB */ 93*d32f26eeSAndy Fiddaman #define UCODE_MB(a) ((a) << 20) /* MiB */ 94*d32f26eeSAndy Fiddaman 95*d32f26eeSAndy Fiddaman /* 96*d32f26eeSAndy Fiddaman * For a single microcode file, the following minimum and maximum sizes are 97*d32f26eeSAndy Fiddaman * defined. Such limitations, while somewhat artificial, are not only to 98*d32f26eeSAndy Fiddaman * provide better sanity checks, but also avoid wasting precious memory at 99*d32f26eeSAndy Fiddaman * startup time as the microcode buffer for the first processor has to be 100*d32f26eeSAndy Fiddaman * statically allocated. 101*d32f26eeSAndy Fiddaman * 102*d32f26eeSAndy Fiddaman * The last limit is for the concatenation of all the microcode binary files. 103*d32f26eeSAndy Fiddaman */ 104*d32f26eeSAndy Fiddaman #define UCODE_MIN_SIZE UCODE_KB(1) 105*d32f26eeSAndy Fiddaman #define UCODE_MAX_SIZE UCODE_MB(2) 106*d32f26eeSAndy Fiddaman #define UCODE_MAX_COMBINED_SIZE UCODE_MB(16) 107*d32f26eeSAndy Fiddaman 108*d32f26eeSAndy Fiddaman #ifdef _KERNEL 109*d32f26eeSAndy Fiddaman 110*d32f26eeSAndy Fiddaman extern ucode_errno_t ucode_get_rev(uint32_t *); 111*d32f26eeSAndy Fiddaman extern ucode_errno_t ucode_validate(uint8_t *, int); 112*d32f26eeSAndy Fiddaman extern ucode_errno_t ucode_update(uint8_t *, int); 113*d32f26eeSAndy Fiddaman 114*d32f26eeSAndy Fiddaman /* 115*d32f26eeSAndy Fiddaman * Microcode specific information per core 116*d32f26eeSAndy Fiddaman */ 117*d32f26eeSAndy Fiddaman typedef struct cpu_ucode_info { 118*d32f26eeSAndy Fiddaman uint32_t cui_platid; /* platform id */ 119*d32f26eeSAndy Fiddaman uint32_t cui_rev; /* microcode revision */ 120*d32f26eeSAndy Fiddaman } cpu_ucode_info_t; 121*d32f26eeSAndy Fiddaman 122*d32f26eeSAndy Fiddaman /* 123*d32f26eeSAndy Fiddaman * Data structure used for xcall 124*d32f26eeSAndy Fiddaman */ 125*d32f26eeSAndy Fiddaman typedef struct ucode_update { 126*d32f26eeSAndy Fiddaman uint32_t sig; /* signature */ 127*d32f26eeSAndy Fiddaman cpu_ucode_info_t info; /* ucode info */ 128*d32f26eeSAndy Fiddaman uint32_t expected_rev; 129*d32f26eeSAndy Fiddaman uint32_t new_rev; 130*d32f26eeSAndy Fiddaman uint8_t *ucodep; /* pointer to ucode */ 131*d32f26eeSAndy Fiddaman uint32_t usize; 132*d32f26eeSAndy Fiddaman } ucode_update_t; 133*d32f26eeSAndy Fiddaman 134*d32f26eeSAndy Fiddaman /* 135*d32f26eeSAndy Fiddaman * To register a microcode update method, a ucode_source_t instance should be 136*d32f26eeSAndy Fiddaman * created and passed to UCODE_SOURCE() to include it in the list of sources 137*d32f26eeSAndy Fiddaman * that are tried. 138*d32f26eeSAndy Fiddaman */ 139*d32f26eeSAndy Fiddaman typedef struct ucode_source { 140*d32f26eeSAndy Fiddaman const char *us_name; 141*d32f26eeSAndy Fiddaman uint32_t us_write_msr; 142*d32f26eeSAndy Fiddaman bool us_invalidate; 143*d32f26eeSAndy Fiddaman bool (*us_select)(cpu_t *); 144*d32f26eeSAndy Fiddaman bool (*us_capable)(cpu_t *); 145*d32f26eeSAndy Fiddaman void (*us_file_reset)(processorid_t); 146*d32f26eeSAndy Fiddaman void (*us_read_rev)(cpu_ucode_info_t *); 147*d32f26eeSAndy Fiddaman uint32_t (*us_load)(cpu_ucode_info_t *); 148*d32f26eeSAndy Fiddaman ucode_errno_t (*us_validate)(uint8_t *, int); 149*d32f26eeSAndy Fiddaman ucode_errno_t (*us_extract)(ucode_update_t *, uint8_t *, int); 150*d32f26eeSAndy Fiddaman ucode_errno_t (*us_locate)(cpu_t *, cpu_ucode_info_t *); 151*d32f26eeSAndy Fiddaman } ucode_source_t; 152*d32f26eeSAndy Fiddaman #define UCODE_SOURCE(x) DATA_SET(ucode_source_set, x) 153*d32f26eeSAndy Fiddaman 154*d32f26eeSAndy Fiddaman #endif /* _KERNEL */ 155*d32f26eeSAndy Fiddaman 156*d32f26eeSAndy Fiddaman #ifdef __cplusplus 157*d32f26eeSAndy Fiddaman } 158*d32f26eeSAndy Fiddaman #endif 159*d32f26eeSAndy Fiddaman 160*d32f26eeSAndy Fiddaman #endif /* _SYS_UCODE_H */ 161