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 2007 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/sysmacros.h> 30 #include <sys/modctl.h> 31 #include <sys/conf.h> 32 #include <sys/devops.h> 33 #include <sys/cmn_err.h> 34 #include <sys/kmem.h> 35 #include <sys/stat.h> 36 #include <sys/open.h> 37 #include <sys/file.h> 38 #include <sys/ddi.h> 39 #include <sys/sunddi.h> 40 #include <sys/cpuvar.h> 41 #include <sys/disp.h> 42 #include <sys/hsvc.h> 43 #include <sys/machsystm.h> 44 #include <sys/param.h> 45 #include <sys/hypervisor_api.h> 46 #include <sys/n2rng.h> 47 48 /* 49 * There are 3 noise cells each with its own oscillator, and each 50 * oscillator can be set to 4 different bias setttings. The bias 51 * setting controls the nominal frequency of the oscillator. The 3 52 * and 4 and hardcoded throughout this file. 53 */ 54 55 #define BITS_IN(type) (8 * sizeof (type)) 56 #define EXTRACTBIT64(val, bit) (((val) >> (bit)) & 1UL) 57 58 /* 59 * Policy settings 60 */ 61 /* Log2 of the number of bits */ 62 #define SETTLECYCLES 1000000 63 #define NORMAL_BYPASS 1 64 #define NUMOSC 3 65 #define LOG2_DATA_WORDS 15 66 #define DATA_WORDS (1 << LOG2_DATA_WORDS) 67 68 #define ENTROPY_PASS_VALUE 150000000ULL 69 70 /* 71 * There is a hardware bug that causes the RNG_DATA register to 72 * occasionally be read one cycle before the specifed time. 73 * LOGIC_TEST_EXPECTED_M1 is the value one cycle before 74 * LOGIC_TEST_CYCLES. And there is a second bug that causes the read 75 * to be delayed. We have seen delays of about 150 cycles, but do not 76 * know that maximum that could possibly occur. 77 * 78 * We collect LOGIC_TEST_WORDS words using a diagnostic read with all 79 * entropy turned off. The first one we skip, becuase we have no 80 * knowledge of the time since the last read. We check that the 81 * remaining values fall in the window of values that should occur 82 * between LOGIC_TEST_CYCLES - 1 and LOGIC_TEST_CYCLES + 83 * LOGIC_TEST_BUG_MAX. As further protecion against false positives, 84 * we report success if the the number of mismatches does not exceed 85 * LOGIC_TEST_ERRORS_ALLOWED. 86 * 87 * When running on maramba systems, delays as high as 20000 were observed 88 * LOGIC_TEST_BUG_MAX was increased to twice this observed value since all 89 * that matters is that the hardware is indeed generating the expected values 90 * in diag mode. The code was also modified to exit as soon as the required 91 * number of matches is detected. 92 */ 93 94 #define LOGIC_TEST_CYCLES 38859 95 #define LOGIC_TEST_EXPECTED_M1 0xb8820c7bd387e32cULL 96 #define LOGIC_TEST_BUG_MAX 40000 97 #define LOGIC_TEST_WORDS 8 /* includes first one, unused */ 98 #define LOGIC_TEST_ERRORS_ALLOWED 1 99 #define LOGIC_TEST_MATCHES_NEEDED (LOGIC_TEST_WORDS - 1 - \ 100 LOGIC_TEST_ERRORS_ALLOWED) 101 102 #define RNG_POLY 0x231dcee91262b8a3ULL 103 #define ENTDIVISOR (((1ULL << LOG_VAL_SCALE) + 500ULL) / 1000ULL) 104 105 #define ENCODEBIAS(osc, bias) (((bias) & 0x3) << (2 * (osc))) 106 #define EXTRACTBIAS(blob, osc) (((blob) >> (2 * (osc))) & 0x3) 107 108 extern int n2rng_herr2kerr(uint64_t hv_errcode); 109 110 111 /* 112 * Each value is a representation of the polynomail bit_i * x^i, where 113 * i=0 corresponds to the least significant bit of the word. The 114 * modulus polynomial is x^64 + the interpretation of poly. Out is 115 * set to in * x^exp mod moduluspolynomial. This corresponds to 116 * running the LFSR exp cycles. This implemenation directly simulates 117 * the lfsr. It's running time is O(exp), but the constant is small. 118 * (This code was taken verbatim from Legion.) 119 */ 120 static void 121 lfsr64_adv_seq(uint64_t poly, uint64_t in, uint64_t exp, uint64_t *out) 122 { 123 int i; 124 uint64_t res = in; 125 126 for (i = 0; i < exp; i++) { 127 if (res & 0x8000000000000000ULL) { 128 res = (res << 1) ^ poly; 129 } else { 130 res <<= 1; 131 } 132 } 133 134 *out = res; 135 } 136 137 int 138 n2rng_logic_test(n2rng_t *n2rng, int rngid) 139 { 140 n2rng_setup_t logictest; 141 uint64_t buffer[LOGIC_TEST_WORDS]; 142 uint64_t reg; 143 int rv; 144 int i, j; 145 int correctcount = 0; 146 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid]; 147 int cycles[LOGIC_TEST_WORDS] = 148 {0, 0, 0, 0, 0, 0, 0, 0}; 149 150 /* 151 * This test runs the RNG with no entropy for 152 * LOGIC_TEST_CYCLES cycles. Ideally the value would be be 153 * LOGIC_TEST_RESULT, but because of the RNG bug, the actual 154 * register read may be delayed by upto LOGIC_TEST_BUG_MAX 155 * cycles. So we simulate over that window, and a match 156 * occurs, we report success. 157 */ 158 159 logictest.ctlwds[0].word = 0; 160 logictest.ctlwds[0].fields.rnc_anlg_sel = N2RNG_NOANALOGOUT; 161 logictest.ctlwds[1] = logictest.ctlwds[0]; 162 logictest.ctlwds[2] = logictest.ctlwds[0]; 163 logictest.ctlwds[3] = logictest.ctlwds[0]; 164 logictest.ctlwds[3].fields.rnc_mode = 1; 165 logictest.ctlwds[3].fields.rnc_cnt = LOGIC_TEST_CYCLES - 2; 166 167 /* read LOGIC_TEST_WORDS 64-bit words */ 168 rv = n2rng_collect_diag_bits(n2rng, rngid, &logictest, buffer, 169 LOGIC_TEST_WORDS * sizeof (uint64_t), 170 &rng->n_preferred_config, rng->n_rng_state); 171 if (rv) { 172 cmn_err(CE_WARN, "n2rng: n2rng_collect_diag_bits failed with " 173 "0x%x on rng(%d)", rv, rngid); 174 return (rv); 175 } 176 177 reg = LOGIC_TEST_EXPECTED_M1; 178 for (i = 0; i <= LOGIC_TEST_BUG_MAX; i++) { 179 for (j = 1; j < LOGIC_TEST_WORDS; ++j) { 180 if (buffer[j] == reg) { 181 ++correctcount; 182 cycles[j] = i; 183 } 184 } 185 /* exit loop if we have already found enough matches */ 186 if (correctcount >= LOGIC_TEST_MATCHES_NEEDED) { 187 break; 188 } 189 /* advance reg by one step */ 190 lfsr64_adv_seq(RNG_POLY, reg, 1, ®); 191 } 192 193 if (correctcount < LOGIC_TEST_MATCHES_NEEDED) { 194 cmn_err(CE_WARN, "n2rng: logic error on rng(%d), only %d " 195 "matches found", rngid, correctcount); 196 for (i = 0; i < LOGIC_TEST_WORDS; i++) { 197 DBG3(n2rng, DHEALTH, "buffer[%d] %016llx, cycles = %d", 198 i, buffer[i], cycles[i]); 199 } 200 return (EIO); 201 } else { 202 DBG3(n2rng, DHEALTH, "n2rng: rng(%d) logic test passed, " 203 "%d matches in %d cycles", rngid, correctcount, i); 204 for (i = 0; i < LOGIC_TEST_WORDS; i++) { 205 DBG3(n2rng, DCHATTY, "buffer[%d] %016llx, cycles = %d", 206 i, buffer[i], cycles[i]); 207 } 208 } 209 210 return (0); 211 } 212 213 214 /* 215 * gets the metric for the specified state. 216 */ 217 int 218 n2rng_collect_metrics(n2rng_t *n2rng, int rngid, n2rng_setup_t *setupp, 219 n2rng_setup_t *exit_setupp, 220 uint64_t exit_state, n2rng_osc_perf_t *metricp) 221 { 222 int rv; 223 int bufsize; 224 uint64_t *buffer = NULL; 225 226 227 bufsize = DATA_WORDS * sizeof (uint64_t); 228 buffer = (uint64_t *)contig_mem_alloc_align(bufsize, 229 CONTIG_ALIGNMENT); 230 if (buffer == NULL) { 231 return (ENOMEM); 232 } 233 234 rv = n2rng_collect_diag_bits(n2rng, rngid, setupp, buffer, bufsize, 235 exit_setupp, exit_state); 236 if (rv) { 237 cmn_err(CE_WARN, 238 "n2rng: n2rng_collect_bits returns 0x%x", rv); 239 } else { 240 n2rng_renyi_entropy(buffer, LOG2_DATA_WORDS, metricp); 241 } 242 243 contig_mem_free(buffer, bufsize); 244 245 return (rv); 246 } 247 248 249 /* 250 * Fills in table with the performance of each oscillator at each 251 * bias setting. A particular datum goes in table[osc][bias]. 252 */ 253 int 254 collect_rng_perf(n2rng_t *n2rng, int rngid, n2rng_osc_perf_table_t ptable) 255 { 256 int bias; 257 int osc; 258 n2rng_setup_t rngstate; 259 int rv; 260 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid]; 261 262 rngstate.ctlwds[0].word = 0; 263 rngstate.ctlwds[0].fields.rnc_anlg_sel = N2RNG_NOANALOGOUT; 264 rngstate.ctlwds[1] = rngstate.ctlwds[0]; 265 rngstate.ctlwds[2] = rngstate.ctlwds[0]; 266 rngstate.ctlwds[3] = rngstate.ctlwds[0]; 267 268 for (osc = 0; osc < N2RNG_NOSC; osc++) { 269 rngstate.ctlwds[3].fields.rnc_selbits = 1 << osc; 270 for (bias = 0; bias < N2RNG_NBIASES; bias++) { 271 rngstate.ctlwds[3].fields.rnc_vcoctl = bias; 272 rv = n2rng_collect_metrics(n2rng, rngid, &rngstate, 273 &rng->n_preferred_config, rng->n_rng_state, 274 &(ptable[osc][bias])); 275 if (rv) { 276 return (rv); 277 } 278 } 279 } 280 281 return (rv); 282 } 283 284 /* 285 * The following 2 functions test the performance of each noise cell 286 * and select the bias settings. They implement the following 287 * policies: 288 * 289 * 1. No two cells may be set to the same bias. (Cells with the same bias, 290 * which controls frequency, may beat together, with long 291 * runs of no entropy as a pair when they are nearly synchronized.) 292 * 2. The entropy of each cell is determined (for now) by the Renyi H2 293 * entropy of a collection of samples of raw bits. 294 * 3. The selected configuration is the one that has the largest total 295 * entropy, computed as stated above. 296 * 4. The delay is hard coded. 297 */ 298 299 300 /* 301 * Finds the preferred configuration from perf data. Sets the 302 * preferred configuration in the n2rng structure. 303 */ 304 int 305 n2rng_noise_gen_preferred(n2rng_t *n2rng, int rngid) 306 { 307 int rv; 308 int rventropy = 0; /* EIO if entropy is too low */ 309 int b0, b1, b2; 310 int osc; 311 int bset; 312 n2rng_osc_perf_t *candidates[N2RNG_NOSC]; 313 uint64_t bestcellentropy[N2RNG_NOSC] = {0}; 314 uint64_t bestentropy = 0; 315 n2rng_ctl_t rng_ctl = {0}; 316 int i; 317 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid]; 318 319 rv = collect_rng_perf(n2rng, rngid, rng->n_perftable); 320 if (rv) { 321 return (rv); 322 } 323 324 /* 325 * bset is the bias setting of all 3 oscillators packed into a 326 * word, 2 bits for each: b2:b1:b0. First we set up an 327 * arbitrary assignment, because in an earlier version of 328 * this code, there were cases where the assignment would 329 * never happen. Also, that way we don't need to prove 330 * assignment to prove we never have uninitalized variables, 331 * and hence it might avoid lint warnings. 332 * 333 * This block of code picks the "best" setting of the biases, 334 * where "best" is defined by the rules in the big comment 335 * block above. 336 * 337 * There are only 24 possible combinations such that no two 338 * oscillators get the same bias. We just do a brute force 339 * exhaustive search of the entire space. 340 */ 341 bset = ENCODEBIAS(2, 2) | ENCODEBIAS(1, 1) | ENCODEBIAS(0, 0); 342 for (b0 = 0; b0 < N2RNG_NBIASES; b0++) { 343 candidates[0] = &rng->n_perftable[0][b0]; 344 for (b1 = 0; b1 < N2RNG_NBIASES; b1++) { 345 if (b0 == b1) continue; 346 candidates[1] = &rng->n_perftable[1][b1]; 347 for (b2 = 0; b2 < N2RNG_NBIASES; b2++) { 348 uint64_t totalentropy = 0; 349 350 if (b0 == b2 || b1 == b2) continue; 351 candidates[2] = &rng->n_perftable[2][b2]; 352 for (i = 0; i < N2RNG_NOSC; i++) { 353 totalentropy += candidates[i]->H2; 354 } 355 if (totalentropy > bestentropy) { 356 bestentropy = totalentropy; 357 bset = ENCODEBIAS(0, b0) | 358 ENCODEBIAS(1, b1) | 359 ENCODEBIAS(2, b2); 360 for (i = 0; i < N2RNG_NOSC; i++) { 361 bestcellentropy[i] = 362 candidates[i]->H2; 363 } 364 365 } 366 367 } 368 } 369 } 370 371 if (bestentropy < ENTROPY_PASS_VALUE) { 372 cmn_err(CE_WARN, 373 "n2rng: RNG hardware producing insufficient " 374 "entropy (producing %ld, need %lld)", 375 bestentropy, ENTROPY_PASS_VALUE); 376 rventropy = EIO; 377 } 378 379 /* 380 * Set up fields of control words that will be the same for all 381 * osciallators and for final value that selects all 382 * oscillators. 383 */ 384 rng_ctl.fields.rnc_cnt = n2rng->n_ctl_data->n_accumulate_cycles; 385 rng_ctl.fields.rnc_mode = 1; /* set normal mode */ 386 rng_ctl.fields.rnc_anlg_sel = N2RNG_NOANALOGOUT; 387 388 389 /* 390 * Now set the oscillator biases. 391 */ 392 for (osc = 0; osc < N2RNG_NOSC; osc++) { 393 rng_ctl.fields.rnc_selbits = 1 << osc; 394 rng_ctl.fields.rnc_vcoctl = EXTRACTBIAS(bset, osc); 395 rng->n_preferred_config.ctlwds[osc] = rng_ctl; 396 } 397 398 rng_ctl.fields.rnc_cnt = n2rng->n_ctl_data->n_accumulate_cycles; 399 rng_ctl.fields.rnc_vcoctl = 0; 400 rng_ctl.fields.rnc_selbits = 0x7; 401 rng->n_preferred_config.ctlwds[3] = rng_ctl; 402 403 if (rventropy == 0) { 404 405 /* Save bias and entropy results for kstats */ 406 for (i = 0; i < N2RNG_NOSC; i++) { 407 rng->n_bias_info[i].bias = 408 (uint64_t)EXTRACTBIAS(bset, i); 409 rng->n_bias_info[i].entropy = 410 (uint64_t)(bestcellentropy[i] / ENTDIVISOR); 411 DBG4(n2rng, DCHATTY, 412 "n2rng_noise_gen_preferred: rng %d cell %d bias " 413 "%ld: %ld", rngid, i, rng->n_bias_info[i].bias, 414 rng->n_bias_info[i].entropy); 415 } 416 } else { 417 418 /* Clear bias and entropy results for kstats */ 419 for (i = 0; i < N2RNG_NOSC; i++) { 420 rng->n_bias_info[i].bias = 0; 421 rng->n_bias_info[i].entropy = 0; 422 } 423 } 424 425 return (rv ? rv : rventropy); 426 } 427 428 /* 429 * Do a logic test, then find and set the best bias confuration 430 * (failing if insufficient entropy is generated, then set state to 431 * configured. This function should only be called when running in 432 * the control domain. 433 */ 434 int 435 n2rng_do_health_check(n2rng_t *n2rng, int rngid) 436 { 437 int rv = EIO; 438 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid]; 439 int attempts; 440 441 for (attempts = 0; 442 (attempts < RNG_MAX_LOGIC_TEST_ATTEMPTS) && rv; attempts++) { 443 rv = n2rng_logic_test(n2rng, rngid); 444 } 445 446 if (rv) { 447 cmn_err(CE_WARN, "n2rng: n2rng_logic_test failed %d attempts", 448 RNG_MAX_LOGIC_TEST_ATTEMPTS); 449 goto errorexit; 450 } else if (attempts > 1) { 451 DBG1(n2rng, DHEALTH, 452 "n2rng: n2rng_logic_test failed %d attempts", 453 attempts - 1); 454 goto errorexit; 455 } 456 457 rv = n2rng_noise_gen_preferred(n2rng, rngid); 458 if (rv) { 459 DBG0(n2rng, DHEALTH, 460 "n2rng: n2rng_noise_gen_preferred failed"); 461 goto errorexit; 462 } 463 464 /* Push the selected config into HW */ 465 rv = n2rng_collect_diag_bits(n2rng, rngid, NULL, NULL, 0, 466 &rng->n_preferred_config, CTL_STATE_CONFIGURED); 467 if (rv) { 468 DBG0(n2rng, DHEALTH, 469 "n2rng: n2rng_collect_diag_bits failed"); 470 goto errorexit; 471 } 472 473 return (rv); 474 475 errorexit: 476 /* Push the selected config into HW with an error state */ 477 (void) n2rng_collect_diag_bits(n2rng, rngid, NULL, NULL, 0, 478 &rng->n_preferred_config, CTL_STATE_ERROR); 479 480 return (rv); 481 } 482