* 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. */
| 470 | * process. |
| 471 | */ |
| 472 | static void |
| 473 | npxinitstate(void *arg __unused) |
| 474 | { |
| 475 | uint64_t *xstate_bv; |
| 476 | register_t saveintr; |
| 477 | int cp[4], i, max_ext_n; |
| 478 | |
| 479 | if (!hw_float) |
| 480 | return; |
| 481 | |
| 482 | /* Do potentially blocking operations before disabling interrupts. */ |
| 483 | fpu_save_area_zone = uma_zcreate("FPU_save_area", |
| 484 | cpu_max_ext_state_size, NULL, NULL, NULL, NULL, |
| 485 | XSAVE_AREA_ALIGN - 1, 0); |
| 486 | npx_initialstate = uma_zalloc(fpu_save_area_zone, M_WAITOK | M_ZERO); |
| 487 | if (use_xsave) { |
| 488 | if (xsave_mask >> 32 != 0) |
| 489 | max_ext_n = fls(xsave_mask >> 32) + 32; |
| 490 | else |
| 491 | max_ext_n = fls(xsave_mask); |
| 492 | xsave_area_desc = malloc(max_ext_n * sizeof(struct |
| 493 | xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO); |
| 494 | } |
| 495 | |
| 496 | saveintr = intr_disable(); |
| 497 | stop_emulating(); |
| 498 | |
| 499 | if (cpu_fxsr) |
| 500 | fpusave_fxsave(npx_initialstate); |
| 501 | else |
| 502 | fpusave_fnsave(npx_initialstate); |
| 503 | if (cpu_fxsr) { |
| 504 | if (npx_initialstate->sv_xmm.sv_env.en_mxcsr_mask) |
| 505 | cpu_mxcsr_mask = |
| 506 | npx_initialstate->sv_xmm.sv_env.en_mxcsr_mask; |
| 507 | else |
| 508 | cpu_mxcsr_mask = 0xFFBF; |
| 509 | |
| 510 | /* |
| 511 | * The fninit instruction does not modify XMM |
| 512 | * registers or x87 registers (MM/ST). The fpusave |
| 513 | * call dumped the garbage contained in the registers |
| 514 | * after reset to the initial state saved. Clear XMM |
| 515 | * and x87 registers file image to make the startup |
| 516 | * program state and signal handler XMM/x87 register |
| 517 | * content predictable. |
| 518 | */ |
| 519 | bzero(npx_initialstate->sv_xmm.sv_fp, |
| 520 | sizeof(npx_initialstate->sv_xmm.sv_fp)); |
| 521 | bzero(npx_initialstate->sv_xmm.sv_xmm, |
| 522 | sizeof(npx_initialstate->sv_xmm.sv_xmm)); |
| 523 | |
| 524 | } else |
| 525 | bzero(npx_initialstate->sv_87.sv_ac, |
| 526 | sizeof(npx_initialstate->sv_87.sv_ac)); |
| 527 | |
| 528 | /* |
| 529 | * Create a table describing the layout of the CPU Extended |
nothing calls this directly
no test coverage detected