1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/machsystm.h> 30 #include <sys/x_call.h> 31 #include <sys/cmp.h> 32 #include <sys/debug.h> 33 #include <sys/chip.h> 34 #include <sys/cheetahregs.h> 35 36 /* 37 * Note: We assume that chipid == portid. This is not necessarily true. 38 * We buried it down here in the implementation, and not in the 39 * interfaces, so that we can change it later. 40 */ 41 42 /* 43 * pre-alloc'ed because this is used early in boot (before the memory 44 * allocator is available). 45 */ 46 static cpuset_t chips[MAX_CPU_CHIPID]; 47 48 /* 49 * Returns 1 if cpuid is CMP-capable, 0 otherwise. 50 */ 51 int 52 cmp_cpu_is_cmp(processorid_t cpuid) 53 { 54 chipid_t chipid; 55 56 /* N.B. We're assuming that the cpunode[].portid is still intact */ 57 chipid = cpunodes[cpuid].portid; 58 return (!CPUSET_ISNULL(chips[chipid])); 59 } 60 61 /* 62 * Indicate that this core (cpuid) resides on the chip indicated by chipid. 63 * Called during boot and DR add. 64 */ 65 void 66 cmp_add_cpu(chipid_t chipid, processorid_t cpuid) 67 { 68 CPUSET_ADD(chips[chipid], cpuid); 69 } 70 71 /* 72 * Indicate that this core (cpuid) is being DR removed. 73 */ 74 void 75 cmp_delete_cpu(processorid_t cpuid) 76 { 77 chipid_t chipid; 78 79 /* N.B. We're assuming that the cpunode[].portid is still intact */ 80 chipid = cpunodes[cpuid].portid; 81 CPUSET_DEL(chips[chipid], cpuid); 82 } 83 84 /* 85 * Called when cpuid is being onlined or offlined. If the offlined 86 * processor is CMP-capable then current target of the CMP Error Steering 87 * Register is set to either the lowest numbered on-line sibling core, if 88 * one exists, or else to this core. 89 */ 90 /* ARGSUSED */ 91 void 92 cmp_error_resteer(processorid_t cpuid) 93 { 94 #ifndef _CMP_NO_ERROR_STEERING 95 cpuset_t mycores; 96 cpu_t *cpu; 97 chipid_t chipid; 98 int i; 99 100 if (!cmp_cpu_is_cmp(cpuid)) 101 return; 102 103 ASSERT(MUTEX_HELD(&cpu_lock)); 104 chipid = cpunodes[cpuid].portid; 105 mycores = chips[chipid]; 106 107 /* Look for an online sibling core */ 108 for (i = 0; i < NCPU; i++) { 109 if (i == cpuid) 110 continue; 111 112 if (CPU_IN_SET(mycores, i) && 113 (cpu = cpu_get(i)) != NULL && cpu_is_active(cpu)) { 114 /* Found one, reset error steering */ 115 xc_one(i, (xcfunc_t *)set_cmp_error_steering, 0, 0); 116 break; 117 } 118 } 119 120 /* No online sibling cores, point to this core. */ 121 if (i == NCPU) { 122 xc_one(cpuid, (xcfunc_t *)set_cmp_error_steering, 0, 0); 123 } 124 #else 125 /* Not all CMP's support (e.g. Olympus-C by Fujitsu) error steering */ 126 return; 127 #endif /* _CMP_NO_ERROR_STEERING */ 128 } 129 130 chipid_t 131 cmp_cpu_to_chip(processorid_t cpuid) 132 { 133 if (!cmp_cpu_is_cmp(cpuid)) { 134 /* This CPU is not a CMP, so by definition chipid==cpuid */ 135 ASSERT(cpuid < MAX_CPU_CHIPID && CPUSET_ISNULL(chips[cpuid])); 136 return (cpuid); 137 } 138 139 /* N.B. We're assuming that the cpunode[].portid is still intact */ 140 return (cpunodes[cpuid].portid); 141 } 142 143 /* 144 * Return a chip "id" for the given cpu_t 145 * cpu_t's residing on the same physical processor 146 * should map to the same "id" 147 */ 148 chipid_t 149 chip_plat_get_chipid(cpu_t *cp) 150 { 151 return (cmp_cpu_to_chip(cp->cpu_id)); 152 } 153 154 /* 155 * Return the "core id" for the given cpu_t 156 * The "core id" space spans uniquely across all 157 * cpu chips. 158 */ 159 id_t 160 chip_plat_get_coreid(cpu_t *cp) 161 { 162 int impl; 163 164 impl = cpunodes[cp->cpu_id].implementation; 165 166 if (IS_OLYMPUS_C(impl)) { 167 /* 168 * Currently only Fujitsu Olympus-c processor supports 169 * multi-stranded cores. Return the cpu_id with 170 * the strand bit masked out. 171 */ 172 return ((id_t)((uint_t)cp->cpu_id & ~(0x1))); 173 } else { 174 return (cp->cpu_id); 175 } 176 } 177 178 void 179 chip_plat_define_chip(cpu_t *cp, chip_def_t *cd) 180 { 181 int impl; 182 183 /* 184 * Define the chip's type 185 */ 186 impl = cpunodes[cp->cpu_id].implementation; 187 188 if (IS_JAGUAR(impl)) { 189 cd->chipd_type = CHIP_CMP_SPLIT_CACHE; 190 } else if (IS_PANTHER(impl) || IS_OLYMPUS_C(impl)) { 191 cd->chipd_type = CHIP_CMP_SHARED_CACHE; 192 } else { 193 cd->chipd_type = CHIP_DEFAULT; 194 } 195 196 /* 197 * Define any needed adjustment of rechoose_interval 198 * For now, all chips use the default. This 199 * will change with future processors. 200 */ 201 cd->chipd_rechoose_adj = 0; 202 } 203