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