1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2023 Oxide Computer Company 14 */ 15 16 /* 17 * A collection of utility functions for interacting with fabric IDs. 18 */ 19 20 #include <amdzen_client.h> 21 22 /* 23 * Validate whether a fabric ID actually represents a valid ID for a given data 24 * fabric. 25 */ 26 boolean_t 27 zen_fabric_id_valid_fabid(const df_fabric_decomp_t *decomp, 28 const uint32_t fabid) 29 { 30 uint32_t mask = decomp->dfd_node_mask | decomp->dfd_comp_mask; 31 return ((fabid & ~mask) == 0); 32 } 33 34 /* 35 * Validate whether the parts of a fabric ID (e.g. the socket, die, and 36 * component) are in fact valid for a given data fabric. 37 */ 38 boolean_t 39 zen_fabric_id_valid_parts(const df_fabric_decomp_t *decomp, const uint32_t sock, 40 const uint32_t die, const uint32_t comp) 41 { 42 uint32_t node; 43 44 if (((sock << decomp->dfd_sock_shift) & ~decomp->dfd_sock_mask) != 0) { 45 return (B_FALSE); 46 } 47 if (((die << decomp->dfd_die_shift) & ~decomp->dfd_die_mask) != 0) { 48 return (B_FALSE); 49 } 50 if ((comp & ~decomp->dfd_comp_mask) != 0) { 51 return (B_FALSE); 52 } 53 54 node = die << decomp->dfd_die_shift; 55 node |= sock << decomp->dfd_sock_shift; 56 57 if (((node << decomp->dfd_node_shift) & ~decomp->dfd_node_mask) != 0) { 58 return (B_FALSE); 59 } 60 61 return (B_TRUE); 62 } 63 64 /* 65 * Take apart a fabric ID into its constituent parts. The decomposition 66 * information has the die and socket information relative to the node ID. 67 */ 68 void 69 zen_fabric_id_decompose(const df_fabric_decomp_t *decomp, const uint32_t fabid, 70 uint32_t *sockp, uint32_t *diep, uint32_t *compp) 71 { 72 uint32_t node; 73 74 ASSERT(zen_fabric_id_valid_fabid(decomp, fabid)); 75 76 *compp = (fabid & decomp->dfd_comp_mask) >> decomp->dfd_comp_shift; 77 node = (fabid & decomp->dfd_node_mask) >> decomp->dfd_node_shift; 78 *diep = (node & decomp->dfd_die_mask) >> decomp->dfd_die_shift; 79 *sockp = (node & decomp->dfd_sock_mask) >> decomp->dfd_sock_shift; 80 } 81 82 /* 83 * Compose a fabric ID from its constituent parts: the socket, die, and fabric. 84 */ 85 void 86 zen_fabric_id_compose(const df_fabric_decomp_t *decomp, const uint32_t sock, 87 const uint32_t die, const uint32_t comp, uint32_t *fabidp) 88 { 89 uint32_t node; 90 91 ASSERT(zen_fabric_id_valid_parts(decomp, sock, die, comp)); 92 93 node = die << decomp->dfd_die_shift; 94 node |= sock << decomp->dfd_sock_shift; 95 *fabidp = (node << decomp->dfd_node_shift) | 96 (comp << decomp->dfd_comp_shift); 97 } 98 99 #ifdef DEBUG 100 static boolean_t 101 zen_apic_id_valid_parts(const amdzen_apic_decomp_t *decomp, const uint32_t sock, 102 const uint32_t die, const uint32_t ccd, const uint32_t ccx, 103 const uint32_t core, const uint32_t thread) 104 { 105 ASSERT3U(decomp->aad_sock_shift, <, 32); 106 ASSERT3U(decomp->aad_die_shift, <, 32); 107 ASSERT3U(decomp->aad_ccd_shift, <, 32); 108 ASSERT3U(decomp->aad_ccx_shift, <, 32); 109 ASSERT3U(decomp->aad_core_shift, <, 32); 110 ASSERT3U(decomp->aad_thread_shift, <, 32); 111 112 if (((sock << decomp->aad_sock_shift) & ~decomp->aad_sock_mask) != 0) { 113 return (B_FALSE); 114 } 115 116 if (((die << decomp->aad_die_shift) & ~decomp->aad_die_mask) != 0) { 117 return (B_FALSE); 118 } 119 120 if (((ccd << decomp->aad_ccd_shift) & ~decomp->aad_ccd_mask) != 0) { 121 return (B_FALSE); 122 } 123 124 if (((ccx << decomp->aad_ccx_shift) & ~decomp->aad_ccx_mask) != 0) { 125 return (B_FALSE); 126 } 127 128 if (((core << decomp->aad_core_shift) & ~decomp->aad_core_mask) != 0) { 129 return (B_FALSE); 130 } 131 132 if (((thread << decomp->aad_thread_shift) & 133 ~decomp->aad_thread_mask) != 0) { 134 return (B_FALSE); 135 } 136 return (B_TRUE); 137 } 138 #endif /* DEBUG */ 139 140 /* 141 * Compose an APIC ID from its constituent parts. 142 */ 143 void 144 zen_apic_id_compose(const amdzen_apic_decomp_t *decomp, const uint32_t sock, 145 const uint32_t die, const uint32_t ccd, const uint32_t ccx, 146 const uint32_t core, const uint32_t thread, uint32_t *apicid) 147 { 148 uint32_t id; 149 150 ASSERT(zen_apic_id_valid_parts(decomp, sock, die, ccd, ccx, core, 151 thread)); 152 id = thread << decomp->aad_thread_shift; 153 id |= core << decomp->aad_core_shift; 154 id |= ccx << decomp->aad_ccx_shift; 155 id |= ccd << decomp->aad_ccd_shift; 156 id |= die << decomp->aad_die_shift; 157 id |= sock << decomp->aad_sock_shift; 158 159 *apicid = id; 160 } 161