* On the boot CPU we generate a clean state that is used to * initialize the floating point unit when it is first used by a * process. */
| 431 | * process. |
| 432 | */ |
| 433 | static void |
| 434 | fpuinitstate(void *arg __unused) |
| 435 | { |
| 436 | uint64_t *xstate_bv; |
| 437 | register_t saveintr; |
| 438 | int cp[4], i, max_ext_n; |
| 439 | |
| 440 | /* Do potentially blocking operations before disabling interrupts. */ |
| 441 | fpu_save_area_zone = uma_zcreate("FPU_save_area", |
| 442 | cpu_max_ext_state_size, NULL, NULL, NULL, NULL, |
| 443 | XSAVE_AREA_ALIGN - 1, 0); |
| 444 | fpu_initialstate = uma_zalloc(fpu_save_area_zone, M_WAITOK | M_ZERO); |
| 445 | if (use_xsave) { |
| 446 | max_ext_n = flsl(xsave_mask); |
| 447 | xsave_area_desc = malloc(max_ext_n * sizeof(struct |
| 448 | xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO); |
| 449 | } |
| 450 | |
| 451 | saveintr = intr_disable(); |
| 452 | stop_emulating(); |
| 453 | |
| 454 | fpusave_fxsave(fpu_initialstate); |
| 455 | if (fpu_initialstate->sv_env.en_mxcsr_mask) |
| 456 | cpu_mxcsr_mask = fpu_initialstate->sv_env.en_mxcsr_mask; |
| 457 | else |
| 458 | cpu_mxcsr_mask = 0xFFBF; |
| 459 | |
| 460 | /* |
| 461 | * The fninit instruction does not modify XMM registers or x87 |
| 462 | * registers (MM/ST). The fpusave call dumped the garbage |
| 463 | * contained in the registers after reset to the initial state |
| 464 | * saved. Clear XMM and x87 registers file image to make the |
| 465 | * startup program state and signal handler XMM/x87 register |
| 466 | * content predictable. |
| 467 | */ |
| 468 | bzero(fpu_initialstate->sv_fp, sizeof(fpu_initialstate->sv_fp)); |
| 469 | bzero(fpu_initialstate->sv_xmm, sizeof(fpu_initialstate->sv_xmm)); |
| 470 | |
| 471 | /* |
| 472 | * Create a table describing the layout of the CPU Extended |
| 473 | * Save Area. |
| 474 | */ |
| 475 | if (use_xsave) { |
| 476 | xstate_bv = (uint64_t *)((char *)(fpu_initialstate + 1) + |
| 477 | offsetof(struct xstate_hdr, xstate_bv)); |
| 478 | *xstate_bv = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; |
| 479 | |
| 480 | /* x87 state */ |
| 481 | xsave_area_desc[0].offset = 0; |
| 482 | xsave_area_desc[0].size = 160; |
| 483 | /* XMM */ |
| 484 | xsave_area_desc[1].offset = 160; |
| 485 | xsave_area_desc[1].size = 288 - 160; |
| 486 | |
| 487 | for (i = 2; i < max_ext_n; i++) { |
| 488 | cpuid_count(0xd, i, cp); |
| 489 | xsave_area_desc[i].offset = cp[1]; |
| 490 | xsave_area_desc[i].size = cp[0]; |
nothing calls this directly
no test coverage detected