dsh-remote 0.8.46 → 0.8.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.en.md +361 -361
- package/README.md +368 -368
- package/cordis.patch.yml +9 -9
- package/lib/binding.js +172 -172
- package/lib/client.js +3637 -3637
- package/lib/credential.js +177 -177
- package/lib/deploy-tasks.js +142 -142
- package/lib/errors.js +87 -87
- package/lib/file-reference.js +457 -457
- package/lib/forwards.js +258 -258
- package/lib/hostkey.js +108 -108
- package/lib/http-transport.js +196 -196
- package/lib/ignore.js +156 -156
- package/lib/index.js +3771 -3747
- package/lib/openssh.js +838 -838
- package/lib/paths.js +225 -225
- package/lib/pool.js +757 -757
- package/lib/registry.js +95 -95
- package/lib/remote-fs.js +148 -143
- package/lib/routes-fs.js +233 -233
- package/lib/search.js +230 -230
- package/lib/sftp-surface.js +76 -76
- package/lib/sshconfig.js +454 -454
- package/lib/sync.js +275 -275
- package/lib/tasks.js +95 -95
- package/lib/telemetry.js +213 -213
- package/lib/update.js +472 -472
- package/lib/web-attach.js +850 -850
- package/lib/web-deploy-skill.js +205 -205
- package/lib/web-deploy.js +694 -694
- package/node_modules/asn1/Jenkinsfile +65 -0
- package/node_modules/asn1/LICENSE +19 -0
- package/node_modules/asn1/README.md +50 -0
- package/node_modules/asn1/lib/ber/errors.js +13 -0
- package/node_modules/asn1/lib/ber/index.js +27 -0
- package/node_modules/asn1/lib/ber/reader.js +262 -0
- package/node_modules/asn1/lib/ber/types.js +36 -0
- package/node_modules/asn1/lib/ber/writer.js +317 -0
- package/node_modules/asn1/lib/index.js +20 -0
- package/node_modules/asn1/package.json +31 -0
- package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
- package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
- package/node_modules/bcrypt-pbkdf/README.md +45 -0
- package/node_modules/bcrypt-pbkdf/index.js +556 -0
- package/node_modules/bcrypt-pbkdf/package.json +15 -0
- package/node_modules/buildcheck/.eslintrc.js +5 -0
- package/node_modules/buildcheck/.github/workflows/ci.yml +88 -0
- package/node_modules/buildcheck/.github/workflows/lint.yml +27 -0
- package/node_modules/buildcheck/.npmignore +3 -0
- package/node_modules/buildcheck/LICENSE +19 -0
- package/node_modules/buildcheck/README.md +106 -0
- package/node_modules/buildcheck/deps/Find-VisualStudio.cs +250 -0
- package/node_modules/buildcheck/lib/findvs.js +361 -0
- package/node_modules/buildcheck/lib/index.js +738 -0
- package/node_modules/buildcheck/package.json +36 -0
- package/node_modules/buildcheck/test/test.js +8 -0
- package/node_modules/cpu-features/.eslintrc.js +5 -0
- package/node_modules/cpu-features/.github/workflows/ci.yml +74 -0
- package/node_modules/cpu-features/.github/workflows/lint.yml +27 -0
- package/node_modules/cpu-features/LICENSE +19 -0
- package/node_modules/cpu-features/README.md +59 -0
- package/node_modules/cpu-features/binding.gyp +16 -0
- package/node_modules/cpu-features/buildcheck.js +32 -0
- package/node_modules/cpu-features/deps/cpu_features/.clang-format +4 -0
- package/node_modules/cpu-features/deps/cpu_features/.dockerignore +31 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/Dockerfile +5 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/aarch64_linux_cmake.yml +30 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_freebsd_cmake.yml +22 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_bazel.yml +26 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_cmake.yml +31 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_macos_cmake.yml +43 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_windows_cmake.yml +25 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/arm_linux_cmake.yml +31 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/clang_format.yml +24 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/mips_linux_cmake.yml +30 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/power_linux_cmake.yml +29 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/riscv_linux_cmake.yml +28 -0
- package/node_modules/cpu-features/deps/cpu_features/.github/workflows/s390x_linux_cmake.yml +27 -0
- package/node_modules/cpu-features/deps/cpu_features/.grenrc.yml +21 -0
- package/node_modules/cpu-features/deps/cpu_features/BUILD.bazel +329 -0
- package/node_modules/cpu-features/deps/cpu_features/CMakeLists.txt +261 -0
- package/node_modules/cpu-features/deps/cpu_features/CONTRIBUTING.md +23 -0
- package/node_modules/cpu-features/deps/cpu_features/LICENSE +230 -0
- package/node_modules/cpu-features/deps/cpu_features/README.md +272 -0
- package/node_modules/cpu-features/deps/cpu_features/WORKSPACE +19 -0
- package/node_modules/cpu-features/deps/cpu_features/bazel/ci/README.md +5 -0
- package/node_modules/cpu-features/deps/cpu_features/bazel/platforms.bzl +11 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesConfig.cmake.in +3 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in +3 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/README.md +30 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/Makefile +252 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/README.md +40 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.dot +64 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.svg +312 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/generate_image.sh +7 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/amd64/Dockerfile +48 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/toolchain/Dockerfile +34 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/CMakeLists.txt +22 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/main.cpp +11 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/ci/vagrant/freebsd/Vagrantfile +107 -0
- package/node_modules/cpu-features/deps/cpu_features/cmake/googletest.CMakeLists.txt.in +15 -0
- package/node_modules/cpu-features/deps/cpu_features/cpu_features.gyp +105 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_cache_info.h +54 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_macros.h +384 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_aarch64.h +259 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_arm.h +121 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_mips.h +74 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_ppc.h +149 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_riscv.h +72 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_s390x.h +108 -0
- package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_x86.h +288 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/bit_utils.h +40 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/cpuid_x86.h +37 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/filesystem.h +39 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/hwcaps.h +240 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/stack_line_reader.h +49 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/string_view.h +110 -0
- package/node_modules/cpu-features/deps/cpu_features/include/internal/windows_utils.h +70 -0
- package/node_modules/cpu-features/deps/cpu_features/ndk_compat/CMakeLists.txt +60 -0
- package/node_modules/cpu-features/deps/cpu_features/ndk_compat/README.md +4 -0
- package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.c +205 -0
- package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.h +320 -0
- package/node_modules/cpu-features/deps/cpu_features/ndk_compat/ndk-compat-test.c +12 -0
- package/node_modules/cpu-features/deps/cpu_features/patches/0001-Add-Apple-Silicon-Support.patch +456 -0
- package/node_modules/cpu-features/deps/cpu_features/scripts/generate_badges.d +165 -0
- package/node_modules/cpu-features/deps/cpu_features/scripts/make_release.sh +75 -0
- package/node_modules/cpu-features/deps/cpu_features/scripts/run_integration.sh +490 -0
- package/node_modules/cpu-features/deps/cpu_features/scripts/test_integration.sh +79 -0
- package/node_modules/cpu-features/deps/cpu_features/src/copy.inl +19 -0
- package/node_modules/cpu-features/deps/cpu_features/src/define_introspection.inl +86 -0
- package/node_modules/cpu-features/deps/cpu_features/src/define_introspection_and_hwcaps.inl +26 -0
- package/node_modules/cpu-features/deps/cpu_features/src/equals.inl +22 -0
- package/node_modules/cpu-features/deps/cpu_features/src/filesystem.c +62 -0
- package/node_modules/cpu-features/deps/cpu_features/src/hwcaps.c +169 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64__base_implementation.inl +88 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_linux_or_android.c +79 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c +82 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_windows.c +138 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_arm_linux_or_android.c +212 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_mips_linux_or_android.c +93 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_ppc_linux.c +163 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_riscv_linux.c +111 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_s390x_linux.c +120 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_x86__base_implementation.inl +2055 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_freebsd.c +68 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_linux_or_android.c +58 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_macos.c +57 -0
- package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_windows.c +58 -0
- package/node_modules/cpu-features/deps/cpu_features/src/stack_line_reader.c +132 -0
- package/node_modules/cpu-features/deps/cpu_features/src/string_view.c +192 -0
- package/node_modules/cpu-features/deps/cpu_features/src/utils/list_cpu_features.c +461 -0
- package/node_modules/cpu-features/deps/cpu_features/test/CMakeLists.txt +114 -0
- package/node_modules/cpu-features/deps/cpu_features/test/bit_utils_test.cc +53 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_aarch64_test.cc +396 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_arm_test.cc +384 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_mips_test.cc +176 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_ppc_test.cc +131 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_riscv_test.cc +180 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_s390x_test.cc +82 -0
- package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_x86_test.cc +1729 -0
- package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.cc +103 -0
- package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.h +61 -0
- package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.cc +52 -0
- package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.h +31 -0
- package/node_modules/cpu-features/deps/cpu_features/test/stack_line_reader_test.cc +132 -0
- package/node_modules/cpu-features/deps/cpu_features/test/string_view_test.cc +202 -0
- package/node_modules/cpu-features/lib/index.js +5 -0
- package/node_modules/cpu-features/package.json +40 -0
- package/node_modules/cpu-features/src/binding.cc +151 -0
- package/node_modules/cpu-features/test/test.js +12 -0
- package/node_modules/nan/.github/workflows/ci.yml +46 -0
- package/node_modules/nan/.pre-commit-config.yaml +8 -0
- package/node_modules/nan/CHANGELOG.md +605 -0
- package/node_modules/nan/CMakeLists.txt +138 -0
- package/node_modules/nan/LICENSE.md +9 -0
- package/node_modules/nan/README.md +457 -0
- package/node_modules/nan/doc/asyncworker.md +146 -0
- package/node_modules/nan/doc/buffers.md +54 -0
- package/node_modules/nan/doc/callback.md +76 -0
- package/node_modules/nan/doc/converters.md +41 -0
- package/node_modules/nan/doc/errors.md +226 -0
- package/node_modules/nan/doc/json.md +62 -0
- package/node_modules/nan/doc/maybe_types.md +583 -0
- package/node_modules/nan/doc/methods.md +689 -0
- package/node_modules/nan/doc/new.md +147 -0
- package/node_modules/nan/doc/node_misc.md +123 -0
- package/node_modules/nan/doc/object_wrappers.md +263 -0
- package/node_modules/nan/doc/persistent.md +296 -0
- package/node_modules/nan/doc/scopes.md +73 -0
- package/node_modules/nan/doc/script.md +58 -0
- package/node_modules/nan/doc/string_bytes.md +81 -0
- package/node_modules/nan/doc/v8_internals.md +211 -0
- package/node_modules/nan/doc/v8_misc.md +85 -0
- package/node_modules/nan/include_dirs.js +1 -0
- package/node_modules/nan/nan.h +3202 -0
- package/node_modules/nan/nan_callbacks.h +141 -0
- package/node_modules/nan/nan_callbacks_12_inl.h +730 -0
- package/node_modules/nan/nan_callbacks_pre_12_inl.h +528 -0
- package/node_modules/nan/nan_converters.h +72 -0
- package/node_modules/nan/nan_converters_43_inl.h +68 -0
- package/node_modules/nan/nan_converters_pre_43_inl.h +42 -0
- package/node_modules/nan/nan_define_own_property_helper.h +29 -0
- package/node_modules/nan/nan_implementation_12_inl.h +446 -0
- package/node_modules/nan/nan_implementation_pre_12_inl.h +263 -0
- package/node_modules/nan/nan_json.h +166 -0
- package/node_modules/nan/nan_maybe_43_inl.h +360 -0
- package/node_modules/nan/nan_maybe_pre_43_inl.h +268 -0
- package/node_modules/nan/nan_new.h +340 -0
- package/node_modules/nan/nan_object_wrap.h +156 -0
- package/node_modules/nan/nan_persistent_12_inl.h +132 -0
- package/node_modules/nan/nan_persistent_pre_12_inl.h +242 -0
- package/node_modules/nan/nan_private.h +73 -0
- package/node_modules/nan/nan_scriptorigin.h +97 -0
- package/node_modules/nan/nan_string_bytes.h +305 -0
- package/node_modules/nan/nan_typedarray_contents.h +96 -0
- package/node_modules/nan/nan_weak.h +453 -0
- package/node_modules/nan/package.json +38 -0
- package/node_modules/nan/tools/1to2.js +412 -0
- package/node_modules/nan/tools/README.md +14 -0
- package/node_modules/nan/tools/package.json +19 -0
- package/node_modules/safer-buffer/LICENSE +21 -0
- package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
- package/node_modules/safer-buffer/Readme.md +156 -0
- package/node_modules/safer-buffer/dangerous.js +58 -0
- package/node_modules/safer-buffer/package.json +34 -0
- package/node_modules/safer-buffer/safer.js +77 -0
- package/node_modules/safer-buffer/tests.js +406 -0
- package/node_modules/ssh2/.eslintignore +4 -0
- package/node_modules/ssh2/.eslintrc.js +5 -0
- package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
- package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
- package/node_modules/ssh2/LICENSE +19 -0
- package/node_modules/ssh2/README.md +1529 -0
- package/node_modules/ssh2/SFTP.md +413 -0
- package/node_modules/ssh2/examples/server-chat.js +238 -0
- package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
- package/node_modules/ssh2/install.js +27 -0
- package/node_modules/ssh2/lib/Channel.js +295 -0
- package/node_modules/ssh2/lib/agent.js +1123 -0
- package/node_modules/ssh2/lib/client.js +2176 -0
- package/node_modules/ssh2/lib/http-agents.js +84 -0
- package/node_modules/ssh2/lib/index.js +44 -0
- package/node_modules/ssh2/lib/keygen.js +582 -0
- package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
- package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
- package/node_modules/ssh2/lib/protocol/constants.js +356 -0
- package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
- package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
- package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
- package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
- package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
- package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
- package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
- package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
- package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
- package/node_modules/ssh2/lib/protocol/utils.js +356 -0
- package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
- package/node_modules/ssh2/lib/server.js +1380 -0
- package/node_modules/ssh2/lib/utils.js +336 -0
- package/node_modules/ssh2/package.json +49 -0
- package/node_modules/ssh2/test/common.js +316 -0
- package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
- package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
- package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
- package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
- package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
- package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
- package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
- package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
- package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
- package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
- package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
- package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
- package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
- package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
- package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
- package/node_modules/ssh2/test/test-exec.js +578 -0
- package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
- package/node_modules/ssh2/test/test-keygen.js +60 -0
- package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
- package/node_modules/ssh2/test/test-openssh.js +261 -0
- package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
- package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
- package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
- package/node_modules/ssh2/test/test-sftp.js +842 -0
- package/node_modules/ssh2/test/test-shell.js +109 -0
- package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
- package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
- package/node_modules/ssh2/test/test-userauth.js +611 -0
- package/node_modules/ssh2/test/test-worker-imports.js +25 -0
- package/node_modules/ssh2/test/test.js +20 -0
- package/node_modules/ssh2/util/build_pagent.bat +2 -0
- package/node_modules/ssh2/util/pagent.c +88 -0
- package/node_modules/ssh2/util/pagent.exe +0 -0
- package/node_modules/tweetnacl/.npmignore +4 -0
- package/node_modules/tweetnacl/AUTHORS.md +28 -0
- package/node_modules/tweetnacl/CHANGELOG.md +221 -0
- package/node_modules/tweetnacl/LICENSE +24 -0
- package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
- package/node_modules/tweetnacl/README.md +459 -0
- package/node_modules/tweetnacl/nacl-fast.js +2388 -0
- package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
- package/node_modules/tweetnacl/nacl.d.ts +98 -0
- package/node_modules/tweetnacl/nacl.js +1175 -0
- package/node_modules/tweetnacl/nacl.min.js +1 -0
- package/node_modules/tweetnacl/package.json +58 -0
- package/package.json +95 -89
|
@@ -0,0 +1,2055 @@
|
|
|
1
|
+
// Copyright 2017 Google LLC
|
|
2
|
+
// Copyright 2020 Intel Corporation
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
|
|
16
|
+
// A note on x86 SIMD instructions availability
|
|
17
|
+
// -----------------------------------------------------------------------------
|
|
18
|
+
// A number of conditions need to be met for an application to use SIMD
|
|
19
|
+
// instructions:
|
|
20
|
+
// 1. The CPU itself must support the instruction.
|
|
21
|
+
// - we use `CPUID` to check whether the feature is supported.
|
|
22
|
+
// 2. The OS must save and restore the associated SIMD register across context
|
|
23
|
+
// switches, we check that:
|
|
24
|
+
// - the CPU reports supporting hardware context switching instructions via
|
|
25
|
+
// CPUID.1:ECX.XSAVE[bit 26]
|
|
26
|
+
// - the OS reports supporting hardware context switching instructions via
|
|
27
|
+
// CPUID.1:ECX.OSXSAVE[bit 27]
|
|
28
|
+
// - the CPU extended control register 0 (XCR0) is set to save and restore the
|
|
29
|
+
// needed SIMD registers
|
|
30
|
+
//
|
|
31
|
+
// Note that if `XSAVE`/`OSXSAVE` are missing, we delegate the detection to the
|
|
32
|
+
// OS via the `DetectFeaturesFromOs` function or via microarchitecture
|
|
33
|
+
// heuristics.
|
|
34
|
+
//
|
|
35
|
+
// Encoding
|
|
36
|
+
// -----------------------------------------------------------------------------
|
|
37
|
+
// X86Info contains fields such as vendor and brand_string that are ASCII
|
|
38
|
+
// encoded strings. `vendor` length of characters is 13 and `brand_string` is 49
|
|
39
|
+
// (with null terminated string). We use CPUID.1:E[D,C,B]X to get `vendor` and
|
|
40
|
+
// CPUID.8000_000[4:2]:E[D,C,B,A]X to get `brand_string`
|
|
41
|
+
//
|
|
42
|
+
// Microarchitecture
|
|
43
|
+
// -----------------------------------------------------------------------------
|
|
44
|
+
// `GetX86Microarchitecture` function consists of check on vendor via
|
|
45
|
+
// `IsVendorByX86Info`. We use `CPUID(family, model)` to define the vendor's
|
|
46
|
+
// microarchitecture. In cases where the `family` and `model` is the same for
|
|
47
|
+
// several microarchitectures we do a stepping check or in the worst case we
|
|
48
|
+
// rely on parsing brand_string (see HasSecondFMA for an example). Details of
|
|
49
|
+
// identification by `brand_string` can be found by reference:
|
|
50
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/cascade_lake
|
|
51
|
+
// https://www.intel.com/content/www/us/en/processors/processor-numbers.html
|
|
52
|
+
|
|
53
|
+
// CacheInfo X86
|
|
54
|
+
// -----------------------------------------------------------------------------
|
|
55
|
+
// We use the CacheInfo struct to store information about cache levels. The
|
|
56
|
+
// maximum number of levels is hardcoded but can be increased if needed. We have
|
|
57
|
+
// full support of cache identification for the following processors:
|
|
58
|
+
// • Intel:
|
|
59
|
+
// ◦ modern processors:
|
|
60
|
+
// we use `ParseCacheInfo` function with `leaf_id` 0x00000004.
|
|
61
|
+
// ◦ old processors:
|
|
62
|
+
// we parse descriptors via `GetCacheLevelInfo`, see Application Note
|
|
63
|
+
// 485: Intel Processor Identification and CPUID Instruction.
|
|
64
|
+
// • AMD:
|
|
65
|
+
// ◦ modern processors:
|
|
66
|
+
// we use `ParseCacheInfo` function with `leaf_id` 0x8000001D.
|
|
67
|
+
// ◦ old processors:
|
|
68
|
+
// we parse cache info using Fn8000_0005_E[A,B,C,D]X and
|
|
69
|
+
// Fn8000_0006_E[A,B,C,D]X. See AMD CPUID Specification:
|
|
70
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf.
|
|
71
|
+
// • Hygon:
|
|
72
|
+
// we reuse AMD cache detection implementation.
|
|
73
|
+
// • Zhaoxin:
|
|
74
|
+
// we reuse Intel cache detection implementation.
|
|
75
|
+
//
|
|
76
|
+
// Internal structures
|
|
77
|
+
// -----------------------------------------------------------------------------
|
|
78
|
+
// We use internal structures such as `Leaves` and `OsPreserves` to cache the
|
|
79
|
+
// result of cpuid info and support of registers, since latency of CPUID
|
|
80
|
+
// instruction is around ~100 cycles, see
|
|
81
|
+
// https://www.agner.org/optimize/instruction_tables.pdf. Hence, we use
|
|
82
|
+
// `ReadLeaves` function for `GetX86Info`, `GetCacheInfo` and
|
|
83
|
+
// `FillX86BrandString` to read leaves and hold these values to avoid redundant
|
|
84
|
+
// call on the same leaf.
|
|
85
|
+
|
|
86
|
+
#include <stdbool.h>
|
|
87
|
+
#include <string.h>
|
|
88
|
+
|
|
89
|
+
#include "copy.inl"
|
|
90
|
+
#include "cpuinfo_x86.h"
|
|
91
|
+
#include "equals.inl"
|
|
92
|
+
#include "internal/bit_utils.h"
|
|
93
|
+
#include "internal/cpuid_x86.h"
|
|
94
|
+
|
|
95
|
+
#if !defined(CPU_FEATURES_ARCH_X86)
|
|
96
|
+
#error "Cannot compile cpuinfo_x86 on a non x86 platform."
|
|
97
|
+
#endif
|
|
98
|
+
|
|
99
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
100
|
+
// Definitions for CpuId and GetXCR0Eax.
|
|
101
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
102
|
+
|
|
103
|
+
#if defined(CPU_FEATURES_MOCK_CPUID_X86)
|
|
104
|
+
// Implementation will be provided by test/cpuinfo_x86_test.cc.
|
|
105
|
+
#elif defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
|
|
106
|
+
|
|
107
|
+
#include <cpuid.h>
|
|
108
|
+
|
|
109
|
+
Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) {
|
|
110
|
+
Leaf leaf;
|
|
111
|
+
__cpuid_count(leaf_id, ecx, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx);
|
|
112
|
+
return leaf;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
uint32_t GetXCR0Eax(void) {
|
|
116
|
+
uint32_t eax, edx;
|
|
117
|
+
/* named form of xgetbv not supported on OSX, so must use byte form, see:
|
|
118
|
+
https://github.com/asmjit/asmjit/issues/78
|
|
119
|
+
*/
|
|
120
|
+
__asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
|
|
121
|
+
return eax;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#elif defined(CPU_FEATURES_COMPILER_MSC)
|
|
125
|
+
|
|
126
|
+
#include <immintrin.h>
|
|
127
|
+
#include <intrin.h> // For __cpuidex()
|
|
128
|
+
|
|
129
|
+
Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) {
|
|
130
|
+
Leaf leaf;
|
|
131
|
+
int data[4];
|
|
132
|
+
__cpuidex(data, leaf_id, ecx);
|
|
133
|
+
leaf.eax = data[0];
|
|
134
|
+
leaf.ebx = data[1];
|
|
135
|
+
leaf.ecx = data[2];
|
|
136
|
+
leaf.edx = data[3];
|
|
137
|
+
return leaf;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
uint32_t GetXCR0Eax(void) { return (uint32_t)_xgetbv(0); }
|
|
141
|
+
|
|
142
|
+
#else
|
|
143
|
+
#error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC."
|
|
144
|
+
#endif
|
|
145
|
+
|
|
146
|
+
static const Leaf kEmptyLeaf;
|
|
147
|
+
|
|
148
|
+
static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx) {
|
|
149
|
+
if (leaf_id <= max_cpuid_leaf) {
|
|
150
|
+
return GetCpuidLeaf(leaf_id, ecx);
|
|
151
|
+
} else {
|
|
152
|
+
return kEmptyLeaf;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
typedef struct {
|
|
157
|
+
uint32_t max_cpuid_leaf;
|
|
158
|
+
Leaf leaf_0; // Root
|
|
159
|
+
Leaf leaf_1; // Family, Model, Stepping
|
|
160
|
+
Leaf leaf_2; // Intel cache info + features
|
|
161
|
+
Leaf leaf_7; // Features
|
|
162
|
+
Leaf leaf_7_1; // Features
|
|
163
|
+
uint32_t max_cpuid_leaf_ext;
|
|
164
|
+
Leaf leaf_80000000; // Root for extended leaves
|
|
165
|
+
Leaf leaf_80000001; // AMD features features and cache
|
|
166
|
+
Leaf leaf_80000002; // brand string
|
|
167
|
+
Leaf leaf_80000003; // brand string
|
|
168
|
+
Leaf leaf_80000004; // brand string
|
|
169
|
+
} Leaves;
|
|
170
|
+
|
|
171
|
+
static Leaves ReadLeaves(void) {
|
|
172
|
+
const Leaf leaf_0 = GetCpuidLeaf(0, 0);
|
|
173
|
+
const uint32_t max_cpuid_leaf = leaf_0.eax;
|
|
174
|
+
const Leaf leaf_80000000 = GetCpuidLeaf(0x80000000, 0);
|
|
175
|
+
const uint32_t max_cpuid_leaf_ext = leaf_80000000.eax;
|
|
176
|
+
return (Leaves){
|
|
177
|
+
.max_cpuid_leaf = max_cpuid_leaf,
|
|
178
|
+
.leaf_0 = leaf_0,
|
|
179
|
+
.leaf_1 = SafeCpuIdEx(max_cpuid_leaf, 0x00000001, 0),
|
|
180
|
+
.leaf_2 = SafeCpuIdEx(max_cpuid_leaf, 0x00000002, 0),
|
|
181
|
+
.leaf_7 = SafeCpuIdEx(max_cpuid_leaf, 0x00000007, 0),
|
|
182
|
+
.leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 0x00000007, 1),
|
|
183
|
+
.max_cpuid_leaf_ext = max_cpuid_leaf_ext,
|
|
184
|
+
.leaf_80000000 = leaf_80000000,
|
|
185
|
+
.leaf_80000001 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000001, 0),
|
|
186
|
+
.leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0),
|
|
187
|
+
.leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0),
|
|
188
|
+
.leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
193
|
+
// OS support
|
|
194
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
195
|
+
|
|
196
|
+
#define MASK_XMM 0x2
|
|
197
|
+
#define MASK_YMM 0x4
|
|
198
|
+
#define MASK_MASKREG 0x20
|
|
199
|
+
#define MASK_ZMM0_15 0x40
|
|
200
|
+
#define MASK_ZMM16_31 0x80
|
|
201
|
+
#define MASK_XTILECFG 0x20000
|
|
202
|
+
#define MASK_XTILEDATA 0x40000
|
|
203
|
+
|
|
204
|
+
static bool HasMask(uint32_t value, uint32_t mask) {
|
|
205
|
+
return (value & mask) == mask;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Checks that operating system saves and restores xmm registers during context
|
|
209
|
+
// switches.
|
|
210
|
+
static bool HasXmmOsXSave(uint32_t xcr0_eax) {
|
|
211
|
+
return HasMask(xcr0_eax, MASK_XMM);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Checks that operating system saves and restores ymm registers during context
|
|
215
|
+
// switches.
|
|
216
|
+
static bool HasYmmOsXSave(uint32_t xcr0_eax) {
|
|
217
|
+
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Checks that operating system saves and restores zmm registers during context
|
|
221
|
+
// switches.
|
|
222
|
+
static bool HasZmmOsXSave(uint32_t xcr0_eax) {
|
|
223
|
+
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 |
|
|
224
|
+
MASK_ZMM16_31);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Checks that operating system saves and restores AMX/TMUL state during context
|
|
228
|
+
// switches.
|
|
229
|
+
static bool HasTmmOsXSave(uint32_t xcr0_eax) {
|
|
230
|
+
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 |
|
|
231
|
+
MASK_ZMM16_31 | MASK_XTILECFG | MASK_XTILEDATA);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
235
|
+
// Vendor
|
|
236
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
237
|
+
|
|
238
|
+
static void SetVendor(const Leaf leaf, char* const vendor) {
|
|
239
|
+
*(uint32_t*)(vendor) = leaf.ebx;
|
|
240
|
+
*(uint32_t*)(vendor + 4) = leaf.edx;
|
|
241
|
+
*(uint32_t*)(vendor + 8) = leaf.ecx;
|
|
242
|
+
vendor[12] = '\0';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
static int IsVendor(const Leaf leaf, const char* const name) {
|
|
246
|
+
const uint32_t ebx = *(const uint32_t*)(name);
|
|
247
|
+
const uint32_t edx = *(const uint32_t*)(name + 4);
|
|
248
|
+
const uint32_t ecx = *(const uint32_t*)(name + 8);
|
|
249
|
+
return leaf.ebx == ebx && leaf.ecx == ecx && leaf.edx == edx;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static int IsVendorByX86Info(const X86Info* info, const char* const name) {
|
|
253
|
+
return equals(info->vendor, name, sizeof(info->vendor));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// TODO: Remove when deprecation period is over,
|
|
257
|
+
void FillX86BrandString(char brand_string[49]) {
|
|
258
|
+
const Leaves leaves = ReadLeaves();
|
|
259
|
+
const Leaf packed[3] = {
|
|
260
|
+
leaves.leaf_80000002,
|
|
261
|
+
leaves.leaf_80000003,
|
|
262
|
+
leaves.leaf_80000004,
|
|
263
|
+
};
|
|
264
|
+
#if __STDC_VERSION__ >= 201112L
|
|
265
|
+
_Static_assert(sizeof(packed) == 48, "Leaves must be packed");
|
|
266
|
+
#endif
|
|
267
|
+
copy(brand_string, (const char*)(packed), 48);
|
|
268
|
+
brand_string[48] = '\0';
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
272
|
+
// CpuId
|
|
273
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
274
|
+
|
|
275
|
+
static bool HasSecondFMA(const X86Info* info) {
|
|
276
|
+
// Skylake server
|
|
277
|
+
if (info->model == 0x55) {
|
|
278
|
+
// detect Xeon
|
|
279
|
+
if (info->brand_string[9] == 'X') {
|
|
280
|
+
// detect Silver or Bronze
|
|
281
|
+
if (info->brand_string[17] == 'S' || info->brand_string[17] == 'B')
|
|
282
|
+
return false;
|
|
283
|
+
// detect Gold 5_20 and below, except for Gold 53__
|
|
284
|
+
if (info->brand_string[17] == 'G' && info->brand_string[22] == '5')
|
|
285
|
+
return (
|
|
286
|
+
(info->brand_string[23] == '3') ||
|
|
287
|
+
(info->brand_string[24] == '2' && info->brand_string[25] == '2'));
|
|
288
|
+
// detect Xeon W 210x
|
|
289
|
+
if (info->brand_string[17] == 'W' && info->brand_string[21] == '0')
|
|
290
|
+
return false;
|
|
291
|
+
// detect Xeon D 2xxx
|
|
292
|
+
if (info->brand_string[17] == 'D' && info->brand_string[19] == '2' &&
|
|
293
|
+
info->brand_string[20] == '1')
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
// Cannon Lake client
|
|
299
|
+
if (info->model == 0x66) return false;
|
|
300
|
+
// Ice Lake client
|
|
301
|
+
if (info->model == 0x7d || info->model == 0x7e) return false;
|
|
302
|
+
// This is the right default...
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Internal structure to hold the OS support for vector operations.
|
|
307
|
+
// Avoid to recompute them since each call to cpuid is ~100 cycles.
|
|
308
|
+
typedef struct {
|
|
309
|
+
bool sse_registers;
|
|
310
|
+
bool avx_registers;
|
|
311
|
+
bool avx512_registers;
|
|
312
|
+
bool amx_registers;
|
|
313
|
+
} OsPreserves;
|
|
314
|
+
|
|
315
|
+
// These two functions have to be implemented by the OS, that is the file
|
|
316
|
+
// including this file.
|
|
317
|
+
static void OverrideOsPreserves(OsPreserves* os_preserves);
|
|
318
|
+
static void DetectFeaturesFromOs(X86Info* info, X86Features* features);
|
|
319
|
+
|
|
320
|
+
// Reference https://en.wikipedia.org/wiki/CPUID.
|
|
321
|
+
static void ParseCpuId(const Leaves* leaves, X86Info* info,
|
|
322
|
+
OsPreserves* os_preserves) {
|
|
323
|
+
const Leaf leaf_1 = leaves->leaf_1;
|
|
324
|
+
const Leaf leaf_7 = leaves->leaf_7;
|
|
325
|
+
const Leaf leaf_7_1 = leaves->leaf_7_1;
|
|
326
|
+
const Leaf leaf_80000001 = leaves->leaf_80000001;
|
|
327
|
+
|
|
328
|
+
const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
|
|
329
|
+
const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
|
|
330
|
+
const bool have_xcr0 = have_xsave && have_osxsave;
|
|
331
|
+
|
|
332
|
+
const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8);
|
|
333
|
+
const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20);
|
|
334
|
+
const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4);
|
|
335
|
+
const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16);
|
|
336
|
+
|
|
337
|
+
X86Features* const features = &info->features;
|
|
338
|
+
|
|
339
|
+
// Fill Family, Model and Stepping.
|
|
340
|
+
info->family = extended_family + family;
|
|
341
|
+
info->model = (extended_model << 4) + model;
|
|
342
|
+
info->stepping = ExtractBitRange(leaf_1.eax, 3, 0);
|
|
343
|
+
|
|
344
|
+
// Fill Brand String.
|
|
345
|
+
const Leaf packed[3] = {
|
|
346
|
+
leaves->leaf_80000002,
|
|
347
|
+
leaves->leaf_80000003,
|
|
348
|
+
leaves->leaf_80000004,
|
|
349
|
+
};
|
|
350
|
+
#if __STDC_VERSION__ >= 201112L
|
|
351
|
+
_Static_assert(sizeof(packed) == 48, "Leaves must be packed");
|
|
352
|
+
#endif
|
|
353
|
+
copy(info->brand_string, (const char*)(packed), 48);
|
|
354
|
+
info->brand_string[48] = '\0';
|
|
355
|
+
|
|
356
|
+
// Fill cpu features.
|
|
357
|
+
features->fpu = IsBitSet(leaf_1.edx, 0);
|
|
358
|
+
features->tsc = IsBitSet(leaf_1.edx, 4);
|
|
359
|
+
features->cx8 = IsBitSet(leaf_1.edx, 8);
|
|
360
|
+
features->clfsh = IsBitSet(leaf_1.edx, 19);
|
|
361
|
+
features->mmx = IsBitSet(leaf_1.edx, 23);
|
|
362
|
+
features->ss = IsBitSet(leaf_1.edx, 27);
|
|
363
|
+
features->pclmulqdq = IsBitSet(leaf_1.ecx, 1);
|
|
364
|
+
features->smx = IsBitSet(leaf_1.ecx, 6);
|
|
365
|
+
features->cx16 = IsBitSet(leaf_1.ecx, 13);
|
|
366
|
+
features->dca = IsBitSet(leaf_1.ecx, 18);
|
|
367
|
+
features->movbe = IsBitSet(leaf_1.ecx, 22);
|
|
368
|
+
features->popcnt = IsBitSet(leaf_1.ecx, 23);
|
|
369
|
+
features->aes = IsBitSet(leaf_1.ecx, 25);
|
|
370
|
+
features->f16c = IsBitSet(leaf_1.ecx, 29);
|
|
371
|
+
features->rdrnd = IsBitSet(leaf_1.ecx, 30);
|
|
372
|
+
features->sgx = IsBitSet(leaf_7.ebx, 2);
|
|
373
|
+
features->bmi1 = IsBitSet(leaf_7.ebx, 3);
|
|
374
|
+
features->hle = IsBitSet(leaf_7.ebx, 4);
|
|
375
|
+
features->bmi2 = IsBitSet(leaf_7.ebx, 8);
|
|
376
|
+
features->erms = IsBitSet(leaf_7.ebx, 9);
|
|
377
|
+
features->rtm = IsBitSet(leaf_7.ebx, 11);
|
|
378
|
+
features->rdseed = IsBitSet(leaf_7.ebx, 18);
|
|
379
|
+
features->clflushopt = IsBitSet(leaf_7.ebx, 23);
|
|
380
|
+
features->clwb = IsBitSet(leaf_7.ebx, 24);
|
|
381
|
+
features->sha = IsBitSet(leaf_7.ebx, 29);
|
|
382
|
+
features->gfni = IsBitSet(leaf_7.ecx, 8);
|
|
383
|
+
features->vaes = IsBitSet(leaf_7.ecx, 9);
|
|
384
|
+
features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10);
|
|
385
|
+
features->movdiri = IsBitSet(leaf_7.ecx, 27);
|
|
386
|
+
features->movdir64b = IsBitSet(leaf_7.ecx, 28);
|
|
387
|
+
features->fs_rep_mov = IsBitSet(leaf_7.edx, 4);
|
|
388
|
+
features->fz_rep_movsb = IsBitSet(leaf_7_1.eax, 10);
|
|
389
|
+
features->fs_rep_stosb = IsBitSet(leaf_7_1.eax, 11);
|
|
390
|
+
features->fs_rep_cmpsb_scasb = IsBitSet(leaf_7_1.eax, 12);
|
|
391
|
+
features->adx = IsBitSet(leaf_7.ebx, 19);
|
|
392
|
+
features->lzcnt = IsBitSet(leaf_80000001.ecx, 5);
|
|
393
|
+
|
|
394
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
395
|
+
// The following section is devoted to Vector Extensions.
|
|
396
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
397
|
+
|
|
398
|
+
// CPU with AVX expose XCR0 which enables checking vector extensions OS
|
|
399
|
+
// support through cpuid.
|
|
400
|
+
if (have_xcr0) {
|
|
401
|
+
// Here we rely exclusively on cpuid for both CPU and OS support of vector
|
|
402
|
+
// extensions.
|
|
403
|
+
const uint32_t xcr0_eax = GetXCR0Eax();
|
|
404
|
+
os_preserves->sse_registers = HasXmmOsXSave(xcr0_eax);
|
|
405
|
+
os_preserves->avx_registers = HasYmmOsXSave(xcr0_eax);
|
|
406
|
+
os_preserves->avx512_registers = HasZmmOsXSave(xcr0_eax);
|
|
407
|
+
os_preserves->amx_registers = HasTmmOsXSave(xcr0_eax);
|
|
408
|
+
OverrideOsPreserves(os_preserves);
|
|
409
|
+
|
|
410
|
+
if (os_preserves->sse_registers) {
|
|
411
|
+
features->sse = IsBitSet(leaf_1.edx, 25);
|
|
412
|
+
features->sse2 = IsBitSet(leaf_1.edx, 26);
|
|
413
|
+
features->sse3 = IsBitSet(leaf_1.ecx, 0);
|
|
414
|
+
features->ssse3 = IsBitSet(leaf_1.ecx, 9);
|
|
415
|
+
features->sse4_1 = IsBitSet(leaf_1.ecx, 19);
|
|
416
|
+
features->sse4_2 = IsBitSet(leaf_1.ecx, 20);
|
|
417
|
+
}
|
|
418
|
+
if (os_preserves->avx_registers) {
|
|
419
|
+
features->fma3 = IsBitSet(leaf_1.ecx, 12);
|
|
420
|
+
features->avx = IsBitSet(leaf_1.ecx, 28);
|
|
421
|
+
features->avx_vnni = IsBitSet(leaf_7_1.eax, 4);
|
|
422
|
+
features->avx2 = IsBitSet(leaf_7.ebx, 5);
|
|
423
|
+
}
|
|
424
|
+
if (os_preserves->avx512_registers) {
|
|
425
|
+
features->avx512f = IsBitSet(leaf_7.ebx, 16);
|
|
426
|
+
features->avx512cd = IsBitSet(leaf_7.ebx, 28);
|
|
427
|
+
features->avx512er = IsBitSet(leaf_7.ebx, 27);
|
|
428
|
+
features->avx512pf = IsBitSet(leaf_7.ebx, 26);
|
|
429
|
+
features->avx512bw = IsBitSet(leaf_7.ebx, 30);
|
|
430
|
+
features->avx512dq = IsBitSet(leaf_7.ebx, 17);
|
|
431
|
+
features->avx512vl = IsBitSet(leaf_7.ebx, 31);
|
|
432
|
+
features->avx512ifma = IsBitSet(leaf_7.ebx, 21);
|
|
433
|
+
features->avx512vbmi = IsBitSet(leaf_7.ecx, 1);
|
|
434
|
+
features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6);
|
|
435
|
+
features->avx512vnni = IsBitSet(leaf_7.ecx, 11);
|
|
436
|
+
features->avx512bitalg = IsBitSet(leaf_7.ecx, 12);
|
|
437
|
+
features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14);
|
|
438
|
+
features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2);
|
|
439
|
+
features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3);
|
|
440
|
+
features->avx512_second_fma = HasSecondFMA(info);
|
|
441
|
+
features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3);
|
|
442
|
+
features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5);
|
|
443
|
+
features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8);
|
|
444
|
+
features->avx512_fp16 = IsBitSet(leaf_7.edx, 23);
|
|
445
|
+
}
|
|
446
|
+
if (os_preserves->amx_registers) {
|
|
447
|
+
features->amx_bf16 = IsBitSet(leaf_7.edx, 22);
|
|
448
|
+
features->amx_tile = IsBitSet(leaf_7.edx, 24);
|
|
449
|
+
features->amx_int8 = IsBitSet(leaf_7.edx, 25);
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
// When XCR0 is not available (Atom based or older cpus) we need to defer to
|
|
453
|
+
// the OS via custom code.
|
|
454
|
+
DetectFeaturesFromOs(info, features);
|
|
455
|
+
// Now that we have queried the OS for SSE support, we report this back to
|
|
456
|
+
// os_preserves. This is needed in case of AMD CPU's to enable testing of
|
|
457
|
+
// sse4a (See ParseExtraAMDCpuId below).
|
|
458
|
+
if (features->sse) os_preserves->sse_registers = true;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
|
|
463
|
+
OsPreserves os_preserves) {
|
|
464
|
+
const Leaf leaf_80000001 = leaves->leaf_80000001;
|
|
465
|
+
|
|
466
|
+
X86Features* const features = &info->features;
|
|
467
|
+
|
|
468
|
+
if (os_preserves.sse_registers) {
|
|
469
|
+
features->sse4a = IsBitSet(leaf_80000001.ecx, 6);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (os_preserves.avx_registers) {
|
|
473
|
+
features->fma4 = IsBitSet(leaf_80000001.ecx, 16);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
static const X86Info kEmptyX86Info;
|
|
478
|
+
static const OsPreserves kEmptyOsPreserves;
|
|
479
|
+
|
|
480
|
+
X86Info GetX86Info(void) {
|
|
481
|
+
X86Info info = kEmptyX86Info;
|
|
482
|
+
const Leaves leaves = ReadLeaves();
|
|
483
|
+
const bool is_intel =
|
|
484
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL);
|
|
485
|
+
const bool is_amd =
|
|
486
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
|
|
487
|
+
const bool is_hygon =
|
|
488
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE);
|
|
489
|
+
const bool is_zhaoxin =
|
|
490
|
+
(IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) ||
|
|
491
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI));
|
|
492
|
+
SetVendor(leaves.leaf_0, info.vendor);
|
|
493
|
+
if (is_intel || is_amd || is_hygon || is_zhaoxin) {
|
|
494
|
+
OsPreserves os_preserves = kEmptyOsPreserves;
|
|
495
|
+
ParseCpuId(&leaves, &info, &os_preserves);
|
|
496
|
+
if (is_amd || is_hygon) {
|
|
497
|
+
ParseExtraAMDCpuId(&leaves, &info, os_preserves);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return info;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
504
|
+
// Microarchitecture
|
|
505
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
506
|
+
|
|
507
|
+
#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF))
|
|
508
|
+
|
|
509
|
+
X86Microarchitecture GetX86Microarchitecture(const X86Info* info) {
|
|
510
|
+
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_GENUINE_INTEL)) {
|
|
511
|
+
switch (CPUID(info->family, info->model)) {
|
|
512
|
+
case CPUID(0x04, 0x01):
|
|
513
|
+
case CPUID(0x04, 0x02):
|
|
514
|
+
case CPUID(0x04, 0x03):
|
|
515
|
+
case CPUID(0x04, 0x04):
|
|
516
|
+
case CPUID(0x04, 0x05):
|
|
517
|
+
case CPUID(0x04, 0x07):
|
|
518
|
+
case CPUID(0x04, 0x08):
|
|
519
|
+
case CPUID(0x04, 0x09):
|
|
520
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/80486
|
|
521
|
+
return INTEL_80486;
|
|
522
|
+
case CPUID(0x05, 0x01):
|
|
523
|
+
case CPUID(0x05, 0x02):
|
|
524
|
+
case CPUID(0x05, 0x04):
|
|
525
|
+
case CPUID(0x05, 0x07):
|
|
526
|
+
case CPUID(0x05, 0x08):
|
|
527
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/p5
|
|
528
|
+
return INTEL_P5;
|
|
529
|
+
case CPUID(0x05, 0x09):
|
|
530
|
+
case CPUID(0x05, 0x0A):
|
|
531
|
+
// https://en.wikichip.org/wiki/intel/quark
|
|
532
|
+
return INTEL_LAKEMONT;
|
|
533
|
+
case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz
|
|
534
|
+
case CPUID(0x06, 0x35):
|
|
535
|
+
case CPUID(0x06, 0x36):
|
|
536
|
+
case CPUID(0x06, 0x70): // https://en.wikichip.org/wiki/intel/atom/230
|
|
537
|
+
// https://en.wikipedia.org/wiki/Bonnell_(microarchitecture)
|
|
538
|
+
return INTEL_ATOM_BNL;
|
|
539
|
+
case CPUID(0x06, 0x37):
|
|
540
|
+
case CPUID(0x06, 0x4C):
|
|
541
|
+
// https://en.wikipedia.org/wiki/Silvermont
|
|
542
|
+
return INTEL_ATOM_SMT;
|
|
543
|
+
case CPUID(0x06, 0x5C):
|
|
544
|
+
// https://en.wikipedia.org/wiki/Goldmont
|
|
545
|
+
return INTEL_ATOM_GMT;
|
|
546
|
+
case CPUID(0x06, 0x7A):
|
|
547
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/goldmont_plus
|
|
548
|
+
return INTEL_ATOM_GMT_PLUS;
|
|
549
|
+
case CPUID(0x06, 0x8A):
|
|
550
|
+
case CPUID(0x06, 0x96):
|
|
551
|
+
case CPUID(0x06, 0x9C):
|
|
552
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/tremont
|
|
553
|
+
return INTEL_ATOM_TMT;
|
|
554
|
+
case CPUID(0x06, 0x0E):
|
|
555
|
+
case CPUID(0x06, 0x0F):
|
|
556
|
+
case CPUID(0x06, 0x16):
|
|
557
|
+
// https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture)
|
|
558
|
+
return INTEL_CORE;
|
|
559
|
+
case CPUID(0x06, 0x17):
|
|
560
|
+
case CPUID(0x06, 0x1D):
|
|
561
|
+
// https://en.wikipedia.org/wiki/Penryn_(microarchitecture)
|
|
562
|
+
return INTEL_PNR;
|
|
563
|
+
case CPUID(0x06, 0x1A):
|
|
564
|
+
case CPUID(0x06, 0x1E):
|
|
565
|
+
case CPUID(0x06, 0x1F):
|
|
566
|
+
case CPUID(0x06, 0x2E):
|
|
567
|
+
// https://en.wikipedia.org/wiki/Nehalem_(microarchitecture)
|
|
568
|
+
return INTEL_NHM;
|
|
569
|
+
case CPUID(0x06, 0x25):
|
|
570
|
+
case CPUID(0x06, 0x2C):
|
|
571
|
+
case CPUID(0x06, 0x2F):
|
|
572
|
+
// https://en.wikipedia.org/wiki/Westmere_(microarchitecture)
|
|
573
|
+
return INTEL_WSM;
|
|
574
|
+
case CPUID(0x06, 0x2A):
|
|
575
|
+
case CPUID(0x06, 0x2D):
|
|
576
|
+
// https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings
|
|
577
|
+
return INTEL_SNB;
|
|
578
|
+
case CPUID(0x06, 0x3A):
|
|
579
|
+
case CPUID(0x06, 0x3E):
|
|
580
|
+
// https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings
|
|
581
|
+
return INTEL_IVB;
|
|
582
|
+
case CPUID(0x06, 0x3C):
|
|
583
|
+
case CPUID(0x06, 0x3F):
|
|
584
|
+
case CPUID(0x06, 0x45):
|
|
585
|
+
case CPUID(0x06, 0x46):
|
|
586
|
+
// https://en.wikipedia.org/wiki/Haswell_(microarchitecture)
|
|
587
|
+
return INTEL_HSW;
|
|
588
|
+
case CPUID(0x06, 0x3D):
|
|
589
|
+
case CPUID(0x06, 0x47):
|
|
590
|
+
case CPUID(0x06, 0x4F):
|
|
591
|
+
case CPUID(0x06, 0x56):
|
|
592
|
+
// https://en.wikipedia.org/wiki/Broadwell_(microarchitecture)
|
|
593
|
+
return INTEL_BDW;
|
|
594
|
+
case CPUID(0x06, 0x4E):
|
|
595
|
+
case CPUID(0x06, 0x5E):
|
|
596
|
+
// https://en.wikipedia.org/wiki/Skylake_(microarchitecture)
|
|
597
|
+
return INTEL_SKL;
|
|
598
|
+
case CPUID(0x06, 0x55):
|
|
599
|
+
if (info->stepping >= 6 && info->stepping <= 7) {
|
|
600
|
+
// https://en.wikipedia.org/wiki/Cascade_Lake_(microprocessor)
|
|
601
|
+
return INTEL_CCL;
|
|
602
|
+
}
|
|
603
|
+
return INTEL_SKL;
|
|
604
|
+
case CPUID(0x06, 0x66):
|
|
605
|
+
// https://en.wikipedia.org/wiki/Cannon_Lake_(microarchitecture)
|
|
606
|
+
return INTEL_CNL;
|
|
607
|
+
case CPUID(0x06, 0x7D): // client
|
|
608
|
+
case CPUID(0x06, 0x7E): // client
|
|
609
|
+
case CPUID(0x06, 0x9D): // NNP-I
|
|
610
|
+
case CPUID(0x06, 0x6A): // server
|
|
611
|
+
case CPUID(0x06, 0x6C): // server
|
|
612
|
+
// https://en.wikipedia.org/wiki/Ice_Lake_(microprocessor)
|
|
613
|
+
return INTEL_ICL;
|
|
614
|
+
case CPUID(0x06, 0x8C):
|
|
615
|
+
case CPUID(0x06, 0x8D):
|
|
616
|
+
// https://en.wikipedia.org/wiki/Tiger_Lake_(microarchitecture)
|
|
617
|
+
return INTEL_TGL;
|
|
618
|
+
case CPUID(0x06, 0x8F):
|
|
619
|
+
// https://en.wikipedia.org/wiki/Sapphire_Rapids
|
|
620
|
+
return INTEL_SPR;
|
|
621
|
+
case CPUID(0x06, 0x8E):
|
|
622
|
+
switch (info->stepping) {
|
|
623
|
+
case 9:
|
|
624
|
+
return INTEL_KBL; // https://en.wikipedia.org/wiki/Kaby_Lake
|
|
625
|
+
case 10:
|
|
626
|
+
return INTEL_CFL; // https://en.wikipedia.org/wiki/Coffee_Lake
|
|
627
|
+
case 11:
|
|
628
|
+
return INTEL_WHL; // https://en.wikipedia.org/wiki/Whiskey_Lake_(microarchitecture)
|
|
629
|
+
case 12:
|
|
630
|
+
return INTEL_CML; // https://en.wikichip.org/wiki/intel/microarchitectures/comet_lake
|
|
631
|
+
default:
|
|
632
|
+
return X86_UNKNOWN;
|
|
633
|
+
}
|
|
634
|
+
case CPUID(0x06, 0x9E):
|
|
635
|
+
if (info->stepping > 9) {
|
|
636
|
+
// https://en.wikipedia.org/wiki/Coffee_Lake
|
|
637
|
+
return INTEL_CFL;
|
|
638
|
+
} else {
|
|
639
|
+
// https://en.wikipedia.org/wiki/Kaby_Lake
|
|
640
|
+
return INTEL_KBL;
|
|
641
|
+
}
|
|
642
|
+
case CPUID(0x06, 0x97):
|
|
643
|
+
case CPUID(0x06, 0x9A):
|
|
644
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake
|
|
645
|
+
return INTEL_ADL;
|
|
646
|
+
case CPUID(0x06, 0xA5):
|
|
647
|
+
case CPUID(0x06, 0xA6):
|
|
648
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/comet_lake
|
|
649
|
+
return INTEL_CML;
|
|
650
|
+
case CPUID(0x06, 0xA7):
|
|
651
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/rocket_lake
|
|
652
|
+
return INTEL_RCL;
|
|
653
|
+
case CPUID(0x06, 0xB7):
|
|
654
|
+
case CPUID(0x06, 0xBA):
|
|
655
|
+
case CPUID(0x06, 0xBF):
|
|
656
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/raptor_lake
|
|
657
|
+
return INTEL_RPL;
|
|
658
|
+
case CPUID(0x06, 0x85):
|
|
659
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/knights_mill
|
|
660
|
+
return INTEL_KNIGHTS_M;
|
|
661
|
+
case CPUID(0x06, 0x57):
|
|
662
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/knights_landing
|
|
663
|
+
return INTEL_KNIGHTS_L;
|
|
664
|
+
case CPUID(0x0B, 0x00):
|
|
665
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/knights_ferry
|
|
666
|
+
return INTEL_KNIGHTS_F;
|
|
667
|
+
case CPUID(0x0B, 0x01):
|
|
668
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/knights_corner
|
|
669
|
+
return INTEL_KNIGHTS_C;
|
|
670
|
+
case CPUID(0x0F, 0x01):
|
|
671
|
+
case CPUID(0x0F, 0x02):
|
|
672
|
+
case CPUID(0x0F, 0x03):
|
|
673
|
+
case CPUID(0x0F, 0x04):
|
|
674
|
+
case CPUID(0x0F, 0x06):
|
|
675
|
+
// https://en.wikichip.org/wiki/intel/microarchitectures/netburst
|
|
676
|
+
return INTEL_NETBURST;
|
|
677
|
+
default:
|
|
678
|
+
return X86_UNKNOWN;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_CENTAUR_HAULS)) {
|
|
682
|
+
switch (CPUID(info->family, info->model)) {
|
|
683
|
+
case CPUID(0x06, 0x0F):
|
|
684
|
+
case CPUID(0x06, 0x19):
|
|
685
|
+
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang
|
|
686
|
+
return ZHAOXIN_ZHANGJIANG;
|
|
687
|
+
case CPUID(0x07, 0x1B):
|
|
688
|
+
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
|
|
689
|
+
return ZHAOXIN_WUDAOKOU;
|
|
690
|
+
case CPUID(0x07, 0x3B):
|
|
691
|
+
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
|
|
692
|
+
return ZHAOXIN_LUJIAZUI;
|
|
693
|
+
case CPUID(0x07, 0x5B):
|
|
694
|
+
return ZHAOXIN_YONGFENG;
|
|
695
|
+
default:
|
|
696
|
+
return X86_UNKNOWN;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_SHANGHAI)) {
|
|
700
|
+
switch (CPUID(info->family, info->model)) {
|
|
701
|
+
case CPUID(0x06, 0x0F):
|
|
702
|
+
case CPUID(0x06, 0x19):
|
|
703
|
+
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang
|
|
704
|
+
return ZHAOXIN_ZHANGJIANG;
|
|
705
|
+
case CPUID(0x07, 0x1B):
|
|
706
|
+
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
|
|
707
|
+
return ZHAOXIN_WUDAOKOU;
|
|
708
|
+
case CPUID(0x07, 0x3B):
|
|
709
|
+
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
|
|
710
|
+
return ZHAOXIN_LUJIAZUI;
|
|
711
|
+
case CPUID(0x07, 0x5B):
|
|
712
|
+
return ZHAOXIN_YONGFENG;
|
|
713
|
+
default:
|
|
714
|
+
return X86_UNKNOWN;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD)) {
|
|
718
|
+
switch (CPUID(info->family, info->model)) {
|
|
719
|
+
// https://en.wikichip.org/wiki/amd/cpuid
|
|
720
|
+
case CPUID(0xF, 0x04):
|
|
721
|
+
case CPUID(0xF, 0x05):
|
|
722
|
+
case CPUID(0xF, 0x07):
|
|
723
|
+
case CPUID(0xF, 0x08):
|
|
724
|
+
case CPUID(0xF, 0x0C):
|
|
725
|
+
case CPUID(0xF, 0x0E):
|
|
726
|
+
case CPUID(0xF, 0x0F):
|
|
727
|
+
case CPUID(0xF, 0x14):
|
|
728
|
+
case CPUID(0xF, 0x15):
|
|
729
|
+
case CPUID(0xF, 0x17):
|
|
730
|
+
case CPUID(0xF, 0x18):
|
|
731
|
+
case CPUID(0xF, 0x1B):
|
|
732
|
+
case CPUID(0xF, 0x1C):
|
|
733
|
+
case CPUID(0xF, 0x1F):
|
|
734
|
+
case CPUID(0xF, 0x21):
|
|
735
|
+
case CPUID(0xF, 0x23):
|
|
736
|
+
case CPUID(0xF, 0x24):
|
|
737
|
+
case CPUID(0xF, 0x25):
|
|
738
|
+
case CPUID(0xF, 0x27):
|
|
739
|
+
case CPUID(0xF, 0x2B):
|
|
740
|
+
case CPUID(0xF, 0x2C):
|
|
741
|
+
case CPUID(0xF, 0x2F):
|
|
742
|
+
case CPUID(0xF, 0x41):
|
|
743
|
+
case CPUID(0xF, 0x43):
|
|
744
|
+
case CPUID(0xF, 0x48):
|
|
745
|
+
case CPUID(0xF, 0x4B):
|
|
746
|
+
case CPUID(0xF, 0x4C):
|
|
747
|
+
case CPUID(0xF, 0x4F):
|
|
748
|
+
case CPUID(0xF, 0x5D):
|
|
749
|
+
case CPUID(0xF, 0x5F):
|
|
750
|
+
case CPUID(0xF, 0x68):
|
|
751
|
+
case CPUID(0xF, 0x6B):
|
|
752
|
+
case CPUID(0xF, 0x6F):
|
|
753
|
+
case CPUID(0xF, 0x7F):
|
|
754
|
+
case CPUID(0xF, 0xC1):
|
|
755
|
+
return AMD_HAMMER;
|
|
756
|
+
case CPUID(0x10, 0x02):
|
|
757
|
+
case CPUID(0x10, 0x04):
|
|
758
|
+
case CPUID(0x10, 0x05):
|
|
759
|
+
case CPUID(0x10, 0x06):
|
|
760
|
+
case CPUID(0x10, 0x08):
|
|
761
|
+
case CPUID(0x10, 0x09):
|
|
762
|
+
case CPUID(0x10, 0x0A):
|
|
763
|
+
return AMD_K10;
|
|
764
|
+
case CPUID(0x11, 0x03):
|
|
765
|
+
// http://developer.amd.com/wordpress/media/2012/10/41788.pdf
|
|
766
|
+
return AMD_K11;
|
|
767
|
+
case CPUID(0x12, 0x00):
|
|
768
|
+
case CPUID(0x12, 0x01):
|
|
769
|
+
// https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf
|
|
770
|
+
return AMD_K12;
|
|
771
|
+
case CPUID(0x14, 0x00):
|
|
772
|
+
case CPUID(0x14, 0x01):
|
|
773
|
+
case CPUID(0x14, 0x02):
|
|
774
|
+
// https://www.amd.com/system/files/TechDocs/47534_14h_Mod_00h-0Fh_Rev_Guide.pdf
|
|
775
|
+
return AMD_BOBCAT;
|
|
776
|
+
case CPUID(0x15, 0x01):
|
|
777
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer
|
|
778
|
+
return AMD_BULLDOZER;
|
|
779
|
+
case CPUID(0x15, 0x02):
|
|
780
|
+
case CPUID(0x15, 0x10):
|
|
781
|
+
case CPUID(0x15, 0x11):
|
|
782
|
+
case CPUID(0x15, 0x13):
|
|
783
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/piledriver
|
|
784
|
+
// https://www.amd.com/system/files/TechDocs/48931_15h_Mod_10h-1Fh_Rev_Guide.pdf
|
|
785
|
+
return AMD_PILEDRIVER;
|
|
786
|
+
case CPUID(0x15, 0x30):
|
|
787
|
+
case CPUID(0x15, 0x38):
|
|
788
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/steamroller
|
|
789
|
+
return AMD_STREAMROLLER;
|
|
790
|
+
case CPUID(0x15, 0x60):
|
|
791
|
+
case CPUID(0x15, 0x65):
|
|
792
|
+
case CPUID(0x15, 0x70):
|
|
793
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/excavator
|
|
794
|
+
return AMD_EXCAVATOR;
|
|
795
|
+
case CPUID(0x16, 0x00):
|
|
796
|
+
case CPUID(0x16, 0x26):
|
|
797
|
+
return AMD_JAGUAR;
|
|
798
|
+
case CPUID(0x16, 0x30):
|
|
799
|
+
return AMD_PUMA;
|
|
800
|
+
case CPUID(0x17, 0x01):
|
|
801
|
+
case CPUID(0x17, 0x11):
|
|
802
|
+
case CPUID(0x17, 0x18):
|
|
803
|
+
case CPUID(0x17, 0x20):
|
|
804
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/zen
|
|
805
|
+
return AMD_ZEN;
|
|
806
|
+
case CPUID(0x17, 0x08):
|
|
807
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/zen%2B
|
|
808
|
+
return AMD_ZEN_PLUS;
|
|
809
|
+
case CPUID(0x17, 0x31):
|
|
810
|
+
case CPUID(0x17, 0x47):
|
|
811
|
+
case CPUID(0x17, 0x60):
|
|
812
|
+
case CPUID(0x17, 0x68):
|
|
813
|
+
case CPUID(0x17, 0x71):
|
|
814
|
+
case CPUID(0x17, 0x90):
|
|
815
|
+
case CPUID(0x17, 0x98):
|
|
816
|
+
case CPUID(0x17, 0xA0):
|
|
817
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_2
|
|
818
|
+
return AMD_ZEN2;
|
|
819
|
+
case CPUID(0x19, 0x00):
|
|
820
|
+
case CPUID(0x19, 0x01):
|
|
821
|
+
case CPUID(0x19, 0x08):
|
|
822
|
+
case CPUID(0x19, 0x21):
|
|
823
|
+
case CPUID(0x19, 0x30):
|
|
824
|
+
case CPUID(0x19, 0x40):
|
|
825
|
+
case CPUID(0x19, 0x44):
|
|
826
|
+
case CPUID(0x19, 0x50):
|
|
827
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_3
|
|
828
|
+
return AMD_ZEN3;
|
|
829
|
+
case CPUID(0x19, 0x10):
|
|
830
|
+
case CPUID(0x19, 0x61):
|
|
831
|
+
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_4
|
|
832
|
+
return AMD_ZEN4;
|
|
833
|
+
default:
|
|
834
|
+
return X86_UNKNOWN;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_HYGON_GENUINE)) {
|
|
838
|
+
switch (CPUID(info->family, info->model)) {
|
|
839
|
+
case CPUID(0x18, 0x00):
|
|
840
|
+
case CPUID(0x18, 0x01):
|
|
841
|
+
return AMD_ZEN;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return X86_UNKNOWN;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
848
|
+
// CacheInfo
|
|
849
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
850
|
+
|
|
851
|
+
static const CacheLevelInfo kEmptyCacheLevelInfo;
|
|
852
|
+
|
|
853
|
+
static CacheLevelInfo GetCacheLevelInfo(const uint32_t reg) {
|
|
854
|
+
const int UNDEF = -1;
|
|
855
|
+
const int KiB = 1024;
|
|
856
|
+
const int MiB = 1024 * KiB;
|
|
857
|
+
switch (reg) {
|
|
858
|
+
case 0x01:
|
|
859
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
860
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
861
|
+
.cache_size = 4 * KiB,
|
|
862
|
+
.ways = 4,
|
|
863
|
+
.line_size = UNDEF,
|
|
864
|
+
.tlb_entries = 32,
|
|
865
|
+
.partitioning = 0};
|
|
866
|
+
case 0x02:
|
|
867
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
868
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
869
|
+
.cache_size = 4 * MiB,
|
|
870
|
+
.ways = 0xFF,
|
|
871
|
+
.line_size = UNDEF,
|
|
872
|
+
.tlb_entries = 2,
|
|
873
|
+
.partitioning = 0};
|
|
874
|
+
case 0x03:
|
|
875
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
876
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
877
|
+
.cache_size = 4 * KiB,
|
|
878
|
+
.ways = 4,
|
|
879
|
+
.line_size = UNDEF,
|
|
880
|
+
.tlb_entries = 64,
|
|
881
|
+
.partitioning = 0};
|
|
882
|
+
case 0x04:
|
|
883
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
884
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
885
|
+
.cache_size = 4 * MiB,
|
|
886
|
+
.ways = 4,
|
|
887
|
+
.line_size = UNDEF,
|
|
888
|
+
.tlb_entries = 8,
|
|
889
|
+
.partitioning = 0};
|
|
890
|
+
case 0x05:
|
|
891
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
892
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
893
|
+
.cache_size = 4 * MiB,
|
|
894
|
+
.ways = 4,
|
|
895
|
+
.line_size = UNDEF,
|
|
896
|
+
.tlb_entries = 32,
|
|
897
|
+
.partitioning = 0};
|
|
898
|
+
case 0x06:
|
|
899
|
+
return (CacheLevelInfo){.level = 1,
|
|
900
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
901
|
+
.cache_size = 8 * KiB,
|
|
902
|
+
.ways = 4,
|
|
903
|
+
.line_size = 32,
|
|
904
|
+
.tlb_entries = UNDEF,
|
|
905
|
+
.partitioning = 0};
|
|
906
|
+
case 0x08:
|
|
907
|
+
return (CacheLevelInfo){.level = 1,
|
|
908
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
909
|
+
.cache_size = 16 * KiB,
|
|
910
|
+
.ways = 4,
|
|
911
|
+
.line_size = 32,
|
|
912
|
+
.tlb_entries = UNDEF,
|
|
913
|
+
.partitioning = 0};
|
|
914
|
+
case 0x09:
|
|
915
|
+
return (CacheLevelInfo){.level = 1,
|
|
916
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
917
|
+
.cache_size = 32 * KiB,
|
|
918
|
+
.ways = 4,
|
|
919
|
+
.line_size = 64,
|
|
920
|
+
.tlb_entries = UNDEF,
|
|
921
|
+
.partitioning = 0};
|
|
922
|
+
case 0x0A:
|
|
923
|
+
return (CacheLevelInfo){.level = 1,
|
|
924
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
925
|
+
.cache_size = 8 * KiB,
|
|
926
|
+
.ways = 2,
|
|
927
|
+
.line_size = 32,
|
|
928
|
+
.tlb_entries = UNDEF,
|
|
929
|
+
.partitioning = 0};
|
|
930
|
+
case 0x0B:
|
|
931
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
932
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
933
|
+
.cache_size = 4 * MiB,
|
|
934
|
+
.ways = 4,
|
|
935
|
+
.line_size = UNDEF,
|
|
936
|
+
.tlb_entries = 4,
|
|
937
|
+
.partitioning = 0};
|
|
938
|
+
case 0x0C:
|
|
939
|
+
return (CacheLevelInfo){.level = 1,
|
|
940
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
941
|
+
.cache_size = 16 * KiB,
|
|
942
|
+
.ways = 4,
|
|
943
|
+
.line_size = 32,
|
|
944
|
+
.tlb_entries = UNDEF,
|
|
945
|
+
.partitioning = 0};
|
|
946
|
+
case 0x0D:
|
|
947
|
+
return (CacheLevelInfo){.level = 1,
|
|
948
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
949
|
+
.cache_size = 16 * KiB,
|
|
950
|
+
.ways = 4,
|
|
951
|
+
.line_size = 64,
|
|
952
|
+
.tlb_entries = UNDEF,
|
|
953
|
+
.partitioning = 0};
|
|
954
|
+
case 0x0E:
|
|
955
|
+
return (CacheLevelInfo){.level = 1,
|
|
956
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
957
|
+
.cache_size = 24 * KiB,
|
|
958
|
+
.ways = 6,
|
|
959
|
+
.line_size = 64,
|
|
960
|
+
.tlb_entries = UNDEF,
|
|
961
|
+
.partitioning = 0};
|
|
962
|
+
case 0x1D:
|
|
963
|
+
return (CacheLevelInfo){.level = 2,
|
|
964
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
965
|
+
.cache_size = 128 * KiB,
|
|
966
|
+
.ways = 2,
|
|
967
|
+
.line_size = 64,
|
|
968
|
+
.tlb_entries = UNDEF,
|
|
969
|
+
.partitioning = 0};
|
|
970
|
+
case 0x21:
|
|
971
|
+
return (CacheLevelInfo){.level = 2,
|
|
972
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
973
|
+
.cache_size = 256 * KiB,
|
|
974
|
+
.ways = 8,
|
|
975
|
+
.line_size = 64,
|
|
976
|
+
.tlb_entries = UNDEF,
|
|
977
|
+
.partitioning = 0};
|
|
978
|
+
case 0x22:
|
|
979
|
+
return (CacheLevelInfo){.level = 3,
|
|
980
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
981
|
+
.cache_size = 512 * KiB,
|
|
982
|
+
.ways = 4,
|
|
983
|
+
.line_size = 64,
|
|
984
|
+
.tlb_entries = UNDEF,
|
|
985
|
+
.partitioning = 2};
|
|
986
|
+
case 0x23:
|
|
987
|
+
return (CacheLevelInfo){.level = 3,
|
|
988
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
989
|
+
.cache_size = 1 * MiB,
|
|
990
|
+
.ways = 8,
|
|
991
|
+
.line_size = 64,
|
|
992
|
+
.tlb_entries = UNDEF,
|
|
993
|
+
.partitioning = 2};
|
|
994
|
+
case 0x24:
|
|
995
|
+
return (CacheLevelInfo){.level = 2,
|
|
996
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
997
|
+
.cache_size = 1 * MiB,
|
|
998
|
+
.ways = 16,
|
|
999
|
+
.line_size = 64,
|
|
1000
|
+
.tlb_entries = UNDEF,
|
|
1001
|
+
.partitioning = 0};
|
|
1002
|
+
case 0x25:
|
|
1003
|
+
return (CacheLevelInfo){.level = 3,
|
|
1004
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1005
|
+
.cache_size = 2 * MiB,
|
|
1006
|
+
.ways = 8,
|
|
1007
|
+
.line_size = 64,
|
|
1008
|
+
.tlb_entries = UNDEF,
|
|
1009
|
+
.partitioning = 2};
|
|
1010
|
+
case 0x29:
|
|
1011
|
+
return (CacheLevelInfo){.level = 3,
|
|
1012
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1013
|
+
.cache_size = 4 * MiB,
|
|
1014
|
+
.ways = 8,
|
|
1015
|
+
.line_size = 64,
|
|
1016
|
+
.tlb_entries = UNDEF,
|
|
1017
|
+
.partitioning = 2};
|
|
1018
|
+
case 0x2C:
|
|
1019
|
+
return (CacheLevelInfo){.level = 1,
|
|
1020
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1021
|
+
.cache_size = 32 * KiB,
|
|
1022
|
+
.ways = 8,
|
|
1023
|
+
.line_size = 64,
|
|
1024
|
+
.tlb_entries = UNDEF,
|
|
1025
|
+
.partitioning = 0};
|
|
1026
|
+
case 0x30:
|
|
1027
|
+
return (CacheLevelInfo){.level = 1,
|
|
1028
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
1029
|
+
.cache_size = 32 * KiB,
|
|
1030
|
+
.ways = 8,
|
|
1031
|
+
.line_size = 64,
|
|
1032
|
+
.tlb_entries = UNDEF,
|
|
1033
|
+
.partitioning = 0};
|
|
1034
|
+
case 0x40:
|
|
1035
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1036
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1037
|
+
.cache_size = UNDEF,
|
|
1038
|
+
.ways = UNDEF,
|
|
1039
|
+
.line_size = UNDEF,
|
|
1040
|
+
.tlb_entries = UNDEF,
|
|
1041
|
+
.partitioning = 0};
|
|
1042
|
+
case 0x41:
|
|
1043
|
+
return (CacheLevelInfo){.level = 2,
|
|
1044
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1045
|
+
.cache_size = 128 * KiB,
|
|
1046
|
+
.ways = 4,
|
|
1047
|
+
.line_size = 32,
|
|
1048
|
+
.tlb_entries = UNDEF,
|
|
1049
|
+
.partitioning = 0};
|
|
1050
|
+
case 0x42:
|
|
1051
|
+
return (CacheLevelInfo){.level = 2,
|
|
1052
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1053
|
+
.cache_size = 256 * KiB,
|
|
1054
|
+
.ways = 4,
|
|
1055
|
+
.line_size = 32,
|
|
1056
|
+
.tlb_entries = UNDEF,
|
|
1057
|
+
.partitioning = 0};
|
|
1058
|
+
case 0x43:
|
|
1059
|
+
return (CacheLevelInfo){.level = 2,
|
|
1060
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1061
|
+
.cache_size = 512 * KiB,
|
|
1062
|
+
.ways = 4,
|
|
1063
|
+
.line_size = 32,
|
|
1064
|
+
.tlb_entries = UNDEF,
|
|
1065
|
+
.partitioning = 0};
|
|
1066
|
+
case 0x44:
|
|
1067
|
+
return (CacheLevelInfo){.level = 2,
|
|
1068
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1069
|
+
.cache_size = 1 * MiB,
|
|
1070
|
+
.ways = 4,
|
|
1071
|
+
.line_size = 32,
|
|
1072
|
+
.tlb_entries = UNDEF,
|
|
1073
|
+
.partitioning = 0};
|
|
1074
|
+
case 0x45:
|
|
1075
|
+
return (CacheLevelInfo){.level = 2,
|
|
1076
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1077
|
+
.cache_size = 2 * MiB,
|
|
1078
|
+
.ways = 4,
|
|
1079
|
+
.line_size = 32,
|
|
1080
|
+
.tlb_entries = UNDEF,
|
|
1081
|
+
.partitioning = 0};
|
|
1082
|
+
case 0x46:
|
|
1083
|
+
return (CacheLevelInfo){.level = 3,
|
|
1084
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1085
|
+
.cache_size = 4 * MiB,
|
|
1086
|
+
.ways = 4,
|
|
1087
|
+
.line_size = 64,
|
|
1088
|
+
.tlb_entries = UNDEF,
|
|
1089
|
+
.partitioning = 0};
|
|
1090
|
+
case 0x47:
|
|
1091
|
+
return (CacheLevelInfo){.level = 3,
|
|
1092
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1093
|
+
.cache_size = 8 * MiB,
|
|
1094
|
+
.ways = 8,
|
|
1095
|
+
.line_size = 64,
|
|
1096
|
+
.tlb_entries = UNDEF,
|
|
1097
|
+
.partitioning = 0};
|
|
1098
|
+
case 0x48:
|
|
1099
|
+
return (CacheLevelInfo){.level = 2,
|
|
1100
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1101
|
+
.cache_size = 3 * MiB,
|
|
1102
|
+
.ways = 12,
|
|
1103
|
+
.line_size = 64,
|
|
1104
|
+
.tlb_entries = UNDEF,
|
|
1105
|
+
.partitioning = 0};
|
|
1106
|
+
case 0x49:
|
|
1107
|
+
return (CacheLevelInfo){.level = 2,
|
|
1108
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1109
|
+
.cache_size = 4 * MiB,
|
|
1110
|
+
.ways = 16,
|
|
1111
|
+
.line_size = 64,
|
|
1112
|
+
.tlb_entries = UNDEF,
|
|
1113
|
+
.partitioning = 0};
|
|
1114
|
+
case (0x49 | (1 << 8)):
|
|
1115
|
+
return (CacheLevelInfo){.level = 3,
|
|
1116
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1117
|
+
.cache_size = 4 * MiB,
|
|
1118
|
+
.ways = 16,
|
|
1119
|
+
.line_size = 64,
|
|
1120
|
+
.tlb_entries = UNDEF,
|
|
1121
|
+
.partitioning = 0};
|
|
1122
|
+
case 0x4A:
|
|
1123
|
+
return (CacheLevelInfo){.level = 3,
|
|
1124
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1125
|
+
.cache_size = 6 * MiB,
|
|
1126
|
+
.ways = 12,
|
|
1127
|
+
.line_size = 64,
|
|
1128
|
+
.tlb_entries = UNDEF,
|
|
1129
|
+
.partitioning = 0};
|
|
1130
|
+
case 0x4B:
|
|
1131
|
+
return (CacheLevelInfo){.level = 3,
|
|
1132
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1133
|
+
.cache_size = 8 * MiB,
|
|
1134
|
+
.ways = 16,
|
|
1135
|
+
.line_size = 64,
|
|
1136
|
+
.tlb_entries = UNDEF,
|
|
1137
|
+
.partitioning = 0};
|
|
1138
|
+
case 0x4C:
|
|
1139
|
+
return (CacheLevelInfo){.level = 3,
|
|
1140
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1141
|
+
.cache_size = 12 * MiB,
|
|
1142
|
+
.ways = 12,
|
|
1143
|
+
.line_size = 64,
|
|
1144
|
+
.tlb_entries = UNDEF,
|
|
1145
|
+
.partitioning = 0};
|
|
1146
|
+
case 0x4D:
|
|
1147
|
+
return (CacheLevelInfo){.level = 3,
|
|
1148
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1149
|
+
.cache_size = 16 * MiB,
|
|
1150
|
+
.ways = 16,
|
|
1151
|
+
.line_size = 64,
|
|
1152
|
+
.tlb_entries = UNDEF,
|
|
1153
|
+
.partitioning = 0};
|
|
1154
|
+
case 0x4E:
|
|
1155
|
+
return (CacheLevelInfo){.level = 2,
|
|
1156
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1157
|
+
.cache_size = 6 * MiB,
|
|
1158
|
+
.ways = 24,
|
|
1159
|
+
.line_size = 64,
|
|
1160
|
+
.tlb_entries = UNDEF,
|
|
1161
|
+
.partitioning = 0};
|
|
1162
|
+
case 0x4F:
|
|
1163
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1164
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1165
|
+
.cache_size = 4 * KiB,
|
|
1166
|
+
.ways = UNDEF,
|
|
1167
|
+
.line_size = UNDEF,
|
|
1168
|
+
.tlb_entries = 32,
|
|
1169
|
+
.partitioning = 0};
|
|
1170
|
+
case 0x50:
|
|
1171
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1172
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1173
|
+
.cache_size = 4 * KiB,
|
|
1174
|
+
.ways = UNDEF,
|
|
1175
|
+
.line_size = UNDEF,
|
|
1176
|
+
.tlb_entries = 64,
|
|
1177
|
+
.partitioning = 0};
|
|
1178
|
+
case 0x51:
|
|
1179
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1180
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1181
|
+
.cache_size = 4 * KiB,
|
|
1182
|
+
.ways = UNDEF,
|
|
1183
|
+
.line_size = UNDEF,
|
|
1184
|
+
.tlb_entries = 128,
|
|
1185
|
+
.partitioning = 0};
|
|
1186
|
+
case 0x52:
|
|
1187
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1188
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1189
|
+
.cache_size = 4 * KiB,
|
|
1190
|
+
.ways = UNDEF,
|
|
1191
|
+
.line_size = UNDEF,
|
|
1192
|
+
.tlb_entries = 256,
|
|
1193
|
+
.partitioning = 0};
|
|
1194
|
+
case 0x55:
|
|
1195
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1196
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1197
|
+
.cache_size = 2 * MiB,
|
|
1198
|
+
.ways = 0xFF,
|
|
1199
|
+
.line_size = UNDEF,
|
|
1200
|
+
.tlb_entries = 7,
|
|
1201
|
+
.partitioning = 0};
|
|
1202
|
+
case 0x56:
|
|
1203
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1204
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1205
|
+
.cache_size = 4 * MiB,
|
|
1206
|
+
.ways = 4,
|
|
1207
|
+
.line_size = UNDEF,
|
|
1208
|
+
.tlb_entries = 16,
|
|
1209
|
+
.partitioning = 0};
|
|
1210
|
+
case 0x57:
|
|
1211
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1212
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1213
|
+
.cache_size = 4 * KiB,
|
|
1214
|
+
.ways = 4,
|
|
1215
|
+
.line_size = UNDEF,
|
|
1216
|
+
.tlb_entries = 16,
|
|
1217
|
+
.partitioning = 0};
|
|
1218
|
+
case 0x59:
|
|
1219
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1220
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1221
|
+
.cache_size = 4 * KiB,
|
|
1222
|
+
.ways = 0xFF,
|
|
1223
|
+
.line_size = UNDEF,
|
|
1224
|
+
.tlb_entries = 16,
|
|
1225
|
+
.partitioning = 0};
|
|
1226
|
+
case 0x5A:
|
|
1227
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1228
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1229
|
+
.cache_size = 2 * MiB,
|
|
1230
|
+
.ways = 4,
|
|
1231
|
+
.line_size = UNDEF,
|
|
1232
|
+
.tlb_entries = 32,
|
|
1233
|
+
.partitioning = 0};
|
|
1234
|
+
case 0x5B:
|
|
1235
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1236
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1237
|
+
.cache_size = 4 * KiB,
|
|
1238
|
+
.ways = UNDEF,
|
|
1239
|
+
.line_size = UNDEF,
|
|
1240
|
+
.tlb_entries = 64,
|
|
1241
|
+
.partitioning = 0};
|
|
1242
|
+
case 0x5C:
|
|
1243
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1244
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1245
|
+
.cache_size = 4 * KiB,
|
|
1246
|
+
.ways = UNDEF,
|
|
1247
|
+
.line_size = UNDEF,
|
|
1248
|
+
.tlb_entries = 128,
|
|
1249
|
+
.partitioning = 0};
|
|
1250
|
+
case 0x5D:
|
|
1251
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1252
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1253
|
+
.cache_size = 4,
|
|
1254
|
+
.ways = UNDEF,
|
|
1255
|
+
.line_size = UNDEF,
|
|
1256
|
+
.tlb_entries = 256,
|
|
1257
|
+
.partitioning = 0};
|
|
1258
|
+
case 0x60:
|
|
1259
|
+
return (CacheLevelInfo){.level = 1,
|
|
1260
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1261
|
+
.cache_size = 16 * KiB,
|
|
1262
|
+
.ways = 8,
|
|
1263
|
+
.line_size = 64,
|
|
1264
|
+
.tlb_entries = UNDEF,
|
|
1265
|
+
.partitioning = 0};
|
|
1266
|
+
case 0x61:
|
|
1267
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1268
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1269
|
+
.cache_size = 4 * KiB,
|
|
1270
|
+
.ways = 0xFF,
|
|
1271
|
+
.line_size = UNDEF,
|
|
1272
|
+
.tlb_entries = 48,
|
|
1273
|
+
.partitioning = 0};
|
|
1274
|
+
case 0x63:
|
|
1275
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1276
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1277
|
+
.cache_size = 2 * MiB,
|
|
1278
|
+
.ways = 4,
|
|
1279
|
+
.line_size = UNDEF,
|
|
1280
|
+
.tlb_entries = 4,
|
|
1281
|
+
.partitioning = 0};
|
|
1282
|
+
case 0x66:
|
|
1283
|
+
return (CacheLevelInfo){.level = 1,
|
|
1284
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1285
|
+
.cache_size = 8 * KiB,
|
|
1286
|
+
.ways = 4,
|
|
1287
|
+
.line_size = 64,
|
|
1288
|
+
.tlb_entries = UNDEF,
|
|
1289
|
+
.partitioning = 0};
|
|
1290
|
+
case 0x67:
|
|
1291
|
+
return (CacheLevelInfo){.level = 1,
|
|
1292
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1293
|
+
.cache_size = 16 * KiB,
|
|
1294
|
+
.ways = 4,
|
|
1295
|
+
.line_size = 64,
|
|
1296
|
+
.tlb_entries = UNDEF,
|
|
1297
|
+
.partitioning = 0};
|
|
1298
|
+
case 0x68:
|
|
1299
|
+
return (CacheLevelInfo){.level = 1,
|
|
1300
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1301
|
+
.cache_size = 32 * KiB,
|
|
1302
|
+
.ways = 4,
|
|
1303
|
+
.line_size = 64,
|
|
1304
|
+
.tlb_entries = UNDEF,
|
|
1305
|
+
.partitioning = 0};
|
|
1306
|
+
case 0x70:
|
|
1307
|
+
return (CacheLevelInfo){.level = 1,
|
|
1308
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
1309
|
+
.cache_size = 12 * KiB,
|
|
1310
|
+
.ways = 8,
|
|
1311
|
+
.line_size = UNDEF,
|
|
1312
|
+
.tlb_entries = UNDEF,
|
|
1313
|
+
.partitioning = 0};
|
|
1314
|
+
case 0x71:
|
|
1315
|
+
return (CacheLevelInfo){.level = 1,
|
|
1316
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
1317
|
+
.cache_size = 16 * KiB,
|
|
1318
|
+
.ways = 8,
|
|
1319
|
+
.line_size = UNDEF,
|
|
1320
|
+
.tlb_entries = UNDEF,
|
|
1321
|
+
.partitioning = 0};
|
|
1322
|
+
case 0x72:
|
|
1323
|
+
return (CacheLevelInfo){.level = 1,
|
|
1324
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
1325
|
+
.cache_size = 32 * KiB,
|
|
1326
|
+
.ways = 8,
|
|
1327
|
+
.line_size = UNDEF,
|
|
1328
|
+
.tlb_entries = UNDEF,
|
|
1329
|
+
.partitioning = 0};
|
|
1330
|
+
case 0x76:
|
|
1331
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1332
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1333
|
+
.cache_size = 2 * MiB,
|
|
1334
|
+
.ways = 0xFF,
|
|
1335
|
+
.line_size = UNDEF,
|
|
1336
|
+
.tlb_entries = 8,
|
|
1337
|
+
.partitioning = 0};
|
|
1338
|
+
case 0x78:
|
|
1339
|
+
return (CacheLevelInfo){.level = 2,
|
|
1340
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1341
|
+
.cache_size = 1 * MiB,
|
|
1342
|
+
.ways = 4,
|
|
1343
|
+
.line_size = 64,
|
|
1344
|
+
.tlb_entries = UNDEF,
|
|
1345
|
+
.partitioning = 0};
|
|
1346
|
+
case 0x79:
|
|
1347
|
+
return (CacheLevelInfo){.level = 2,
|
|
1348
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1349
|
+
.cache_size = 128 * KiB,
|
|
1350
|
+
.ways = 8,
|
|
1351
|
+
.line_size = 64,
|
|
1352
|
+
.tlb_entries = UNDEF,
|
|
1353
|
+
.partitioning = 2};
|
|
1354
|
+
case 0x7A:
|
|
1355
|
+
return (CacheLevelInfo){.level = 2,
|
|
1356
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1357
|
+
.cache_size = 256 * KiB,
|
|
1358
|
+
.ways = 8,
|
|
1359
|
+
.line_size = 64,
|
|
1360
|
+
.tlb_entries = UNDEF,
|
|
1361
|
+
.partitioning = 2};
|
|
1362
|
+
case 0x7B:
|
|
1363
|
+
return (CacheLevelInfo){.level = 2,
|
|
1364
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1365
|
+
.cache_size = 512 * KiB,
|
|
1366
|
+
.ways = 8,
|
|
1367
|
+
.line_size = 64,
|
|
1368
|
+
.tlb_entries = UNDEF,
|
|
1369
|
+
.partitioning = 2};
|
|
1370
|
+
case 0x7C:
|
|
1371
|
+
return (CacheLevelInfo){.level = 2,
|
|
1372
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1373
|
+
.cache_size = 1 * MiB,
|
|
1374
|
+
.ways = 8,
|
|
1375
|
+
.line_size = 64,
|
|
1376
|
+
.tlb_entries = UNDEF,
|
|
1377
|
+
.partitioning = 2};
|
|
1378
|
+
case 0x7D:
|
|
1379
|
+
return (CacheLevelInfo){.level = 2,
|
|
1380
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1381
|
+
.cache_size = 2 * MiB,
|
|
1382
|
+
.ways = 8,
|
|
1383
|
+
.line_size = 64,
|
|
1384
|
+
.tlb_entries = UNDEF,
|
|
1385
|
+
.partitioning = 0};
|
|
1386
|
+
case 0x7F:
|
|
1387
|
+
return (CacheLevelInfo){.level = 2,
|
|
1388
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1389
|
+
.cache_size = 512 * KiB,
|
|
1390
|
+
.ways = 2,
|
|
1391
|
+
.line_size = 64,
|
|
1392
|
+
.tlb_entries = UNDEF,
|
|
1393
|
+
.partitioning = 0};
|
|
1394
|
+
case 0x80:
|
|
1395
|
+
return (CacheLevelInfo){.level = 2,
|
|
1396
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1397
|
+
.cache_size = 512 * KiB,
|
|
1398
|
+
.ways = 8,
|
|
1399
|
+
.line_size = 64,
|
|
1400
|
+
.tlb_entries = UNDEF,
|
|
1401
|
+
.partitioning = 0};
|
|
1402
|
+
case 0x82:
|
|
1403
|
+
return (CacheLevelInfo){.level = 2,
|
|
1404
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1405
|
+
.cache_size = 256 * KiB,
|
|
1406
|
+
.ways = 8,
|
|
1407
|
+
.line_size = 32,
|
|
1408
|
+
.tlb_entries = UNDEF,
|
|
1409
|
+
.partitioning = 0};
|
|
1410
|
+
case 0x83:
|
|
1411
|
+
return (CacheLevelInfo){.level = 2,
|
|
1412
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1413
|
+
.cache_size = 512 * KiB,
|
|
1414
|
+
.ways = 8,
|
|
1415
|
+
.line_size = 32,
|
|
1416
|
+
.tlb_entries = UNDEF,
|
|
1417
|
+
.partitioning = 0};
|
|
1418
|
+
case 0x84:
|
|
1419
|
+
return (CacheLevelInfo){.level = 2,
|
|
1420
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1421
|
+
.cache_size = 1 * MiB,
|
|
1422
|
+
.ways = 8,
|
|
1423
|
+
.line_size = 32,
|
|
1424
|
+
.tlb_entries = UNDEF,
|
|
1425
|
+
.partitioning = 0};
|
|
1426
|
+
case 0x85:
|
|
1427
|
+
return (CacheLevelInfo){.level = 2,
|
|
1428
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1429
|
+
.cache_size = 2 * MiB,
|
|
1430
|
+
.ways = 8,
|
|
1431
|
+
.line_size = 32,
|
|
1432
|
+
.tlb_entries = UNDEF,
|
|
1433
|
+
.partitioning = 0};
|
|
1434
|
+
case 0x86:
|
|
1435
|
+
return (CacheLevelInfo){.level = 2,
|
|
1436
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1437
|
+
.cache_size = 512 * KiB,
|
|
1438
|
+
.ways = 4,
|
|
1439
|
+
.line_size = 32,
|
|
1440
|
+
.tlb_entries = UNDEF,
|
|
1441
|
+
.partitioning = 0};
|
|
1442
|
+
case 0x87:
|
|
1443
|
+
return (CacheLevelInfo){.level = 2,
|
|
1444
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1445
|
+
.cache_size = 1 * MiB,
|
|
1446
|
+
.ways = 8,
|
|
1447
|
+
.line_size = 64,
|
|
1448
|
+
.tlb_entries = UNDEF,
|
|
1449
|
+
.partitioning = 0};
|
|
1450
|
+
case 0xA0:
|
|
1451
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1452
|
+
.cache_type = CPU_FEATURE_CACHE_DTLB,
|
|
1453
|
+
.cache_size = 4 * KiB,
|
|
1454
|
+
.ways = 0xFF,
|
|
1455
|
+
.line_size = UNDEF,
|
|
1456
|
+
.tlb_entries = 32,
|
|
1457
|
+
.partitioning = 0};
|
|
1458
|
+
case 0xB0:
|
|
1459
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1460
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1461
|
+
.cache_size = 4 * KiB,
|
|
1462
|
+
.ways = 4,
|
|
1463
|
+
.line_size = UNDEF,
|
|
1464
|
+
.tlb_entries = 128,
|
|
1465
|
+
.partitioning = 0};
|
|
1466
|
+
case 0xB1:
|
|
1467
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1468
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1469
|
+
.cache_size = 2 * MiB,
|
|
1470
|
+
.ways = 4,
|
|
1471
|
+
.line_size = UNDEF,
|
|
1472
|
+
.tlb_entries = 8,
|
|
1473
|
+
.partitioning = 0};
|
|
1474
|
+
case 0xB2:
|
|
1475
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1476
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1477
|
+
.cache_size = 4 * KiB,
|
|
1478
|
+
.ways = 4,
|
|
1479
|
+
.line_size = UNDEF,
|
|
1480
|
+
.tlb_entries = 64,
|
|
1481
|
+
.partitioning = 0};
|
|
1482
|
+
case 0xB3:
|
|
1483
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1484
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1485
|
+
.cache_size = 4 * KiB,
|
|
1486
|
+
.ways = 4,
|
|
1487
|
+
.line_size = UNDEF,
|
|
1488
|
+
.tlb_entries = 128,
|
|
1489
|
+
.partitioning = 0};
|
|
1490
|
+
case 0xB4:
|
|
1491
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1492
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1493
|
+
.cache_size = 4 * KiB,
|
|
1494
|
+
.ways = 4,
|
|
1495
|
+
.line_size = UNDEF,
|
|
1496
|
+
.tlb_entries = 256,
|
|
1497
|
+
.partitioning = 0};
|
|
1498
|
+
case 0xB5:
|
|
1499
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1500
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1501
|
+
.cache_size = 4 * KiB,
|
|
1502
|
+
.ways = 8,
|
|
1503
|
+
.line_size = UNDEF,
|
|
1504
|
+
.tlb_entries = 64,
|
|
1505
|
+
.partitioning = 0};
|
|
1506
|
+
case 0xB6:
|
|
1507
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1508
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1509
|
+
.cache_size = 4 * KiB,
|
|
1510
|
+
.ways = 8,
|
|
1511
|
+
.line_size = UNDEF,
|
|
1512
|
+
.tlb_entries = 128,
|
|
1513
|
+
.partitioning = 0};
|
|
1514
|
+
case 0xBA:
|
|
1515
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1516
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1517
|
+
.cache_size = 4 * KiB,
|
|
1518
|
+
.ways = 4,
|
|
1519
|
+
.line_size = UNDEF,
|
|
1520
|
+
.tlb_entries = 64,
|
|
1521
|
+
.partitioning = 0};
|
|
1522
|
+
case 0xC0:
|
|
1523
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1524
|
+
.cache_type = CPU_FEATURE_CACHE_TLB,
|
|
1525
|
+
.cache_size = 4 * KiB,
|
|
1526
|
+
.ways = 4,
|
|
1527
|
+
.line_size = UNDEF,
|
|
1528
|
+
.tlb_entries = 8,
|
|
1529
|
+
.partitioning = 0};
|
|
1530
|
+
case 0xC1:
|
|
1531
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1532
|
+
.cache_type = CPU_FEATURE_CACHE_STLB,
|
|
1533
|
+
.cache_size = 4 * KiB,
|
|
1534
|
+
.ways = 8,
|
|
1535
|
+
.line_size = UNDEF,
|
|
1536
|
+
.tlb_entries = 1024,
|
|
1537
|
+
.partitioning = 0};
|
|
1538
|
+
case 0xC2:
|
|
1539
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1540
|
+
.cache_type = CPU_FEATURE_CACHE_DTLB,
|
|
1541
|
+
.cache_size = 4 * KiB,
|
|
1542
|
+
.ways = 4,
|
|
1543
|
+
.line_size = UNDEF,
|
|
1544
|
+
.tlb_entries = 16,
|
|
1545
|
+
.partitioning = 0};
|
|
1546
|
+
case 0xC3:
|
|
1547
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1548
|
+
.cache_type = CPU_FEATURE_CACHE_STLB,
|
|
1549
|
+
.cache_size = 4 * KiB,
|
|
1550
|
+
.ways = 6,
|
|
1551
|
+
.line_size = UNDEF,
|
|
1552
|
+
.tlb_entries = 1536,
|
|
1553
|
+
.partitioning = 0};
|
|
1554
|
+
case 0xCA:
|
|
1555
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1556
|
+
.cache_type = CPU_FEATURE_CACHE_STLB,
|
|
1557
|
+
.cache_size = 4 * KiB,
|
|
1558
|
+
.ways = 4,
|
|
1559
|
+
.line_size = UNDEF,
|
|
1560
|
+
.tlb_entries = 512,
|
|
1561
|
+
.partitioning = 0};
|
|
1562
|
+
case 0xD0:
|
|
1563
|
+
return (CacheLevelInfo){.level = 3,
|
|
1564
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1565
|
+
.cache_size = 512 * KiB,
|
|
1566
|
+
.ways = 4,
|
|
1567
|
+
.line_size = 64,
|
|
1568
|
+
.tlb_entries = UNDEF,
|
|
1569
|
+
.partitioning = 0};
|
|
1570
|
+
case 0xD1:
|
|
1571
|
+
return (CacheLevelInfo){.level = 3,
|
|
1572
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1573
|
+
.cache_size = 1 * MiB,
|
|
1574
|
+
.ways = 4,
|
|
1575
|
+
.line_size = 64,
|
|
1576
|
+
.tlb_entries = UNDEF,
|
|
1577
|
+
.partitioning = 0};
|
|
1578
|
+
case 0xD2:
|
|
1579
|
+
return (CacheLevelInfo){.level = 3,
|
|
1580
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1581
|
+
.cache_size = 2 * MiB,
|
|
1582
|
+
.ways = 4,
|
|
1583
|
+
.line_size = 64,
|
|
1584
|
+
.tlb_entries = UNDEF,
|
|
1585
|
+
.partitioning = 0};
|
|
1586
|
+
case 0xD6:
|
|
1587
|
+
return (CacheLevelInfo){.level = 3,
|
|
1588
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1589
|
+
.cache_size = 1 * MiB,
|
|
1590
|
+
.ways = 8,
|
|
1591
|
+
.line_size = 64,
|
|
1592
|
+
.tlb_entries = UNDEF,
|
|
1593
|
+
.partitioning = 0};
|
|
1594
|
+
case 0xD7:
|
|
1595
|
+
return (CacheLevelInfo){.level = 3,
|
|
1596
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1597
|
+
.cache_size = 2 * MiB,
|
|
1598
|
+
.ways = 8,
|
|
1599
|
+
.line_size = 64,
|
|
1600
|
+
.tlb_entries = UNDEF,
|
|
1601
|
+
.partitioning = 0};
|
|
1602
|
+
case 0xD8:
|
|
1603
|
+
return (CacheLevelInfo){.level = 3,
|
|
1604
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1605
|
+
.cache_size = 4 * MiB,
|
|
1606
|
+
.ways = 8,
|
|
1607
|
+
.line_size = 64,
|
|
1608
|
+
.tlb_entries = UNDEF,
|
|
1609
|
+
.partitioning = 0};
|
|
1610
|
+
case 0xDC:
|
|
1611
|
+
return (CacheLevelInfo){.level = 3,
|
|
1612
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1613
|
+
.cache_size = 1 * 1536 * KiB,
|
|
1614
|
+
.ways = 12,
|
|
1615
|
+
.line_size = 64,
|
|
1616
|
+
.tlb_entries = UNDEF,
|
|
1617
|
+
.partitioning = 0};
|
|
1618
|
+
case 0xDD:
|
|
1619
|
+
return (CacheLevelInfo){.level = 3,
|
|
1620
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1621
|
+
.cache_size = 3 * MiB,
|
|
1622
|
+
.ways = 12,
|
|
1623
|
+
.line_size = 64,
|
|
1624
|
+
.tlb_entries = UNDEF,
|
|
1625
|
+
.partitioning = 0};
|
|
1626
|
+
case 0xDE:
|
|
1627
|
+
return (CacheLevelInfo){.level = 3,
|
|
1628
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1629
|
+
.cache_size = 6 * MiB,
|
|
1630
|
+
.ways = 12,
|
|
1631
|
+
.line_size = 64,
|
|
1632
|
+
.tlb_entries = UNDEF,
|
|
1633
|
+
.partitioning = 0};
|
|
1634
|
+
case 0xE2:
|
|
1635
|
+
return (CacheLevelInfo){.level = 3,
|
|
1636
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1637
|
+
.cache_size = 2 * MiB,
|
|
1638
|
+
.ways = 16,
|
|
1639
|
+
.line_size = 64,
|
|
1640
|
+
.tlb_entries = UNDEF,
|
|
1641
|
+
.partitioning = 0};
|
|
1642
|
+
case 0xE3:
|
|
1643
|
+
return (CacheLevelInfo){.level = 3,
|
|
1644
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1645
|
+
.cache_size = 4 * MiB,
|
|
1646
|
+
.ways = 16,
|
|
1647
|
+
.line_size = 64,
|
|
1648
|
+
.tlb_entries = UNDEF,
|
|
1649
|
+
.partitioning = 0};
|
|
1650
|
+
case 0xE4:
|
|
1651
|
+
return (CacheLevelInfo){.level = 3,
|
|
1652
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1653
|
+
.cache_size = 8 * MiB,
|
|
1654
|
+
.ways = 16,
|
|
1655
|
+
.line_size = 64,
|
|
1656
|
+
.tlb_entries = UNDEF,
|
|
1657
|
+
.partitioning = 0};
|
|
1658
|
+
case 0xEA:
|
|
1659
|
+
return (CacheLevelInfo){.level = 3,
|
|
1660
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1661
|
+
.cache_size = 12 * MiB,
|
|
1662
|
+
.ways = 24,
|
|
1663
|
+
.line_size = 64,
|
|
1664
|
+
.tlb_entries = UNDEF,
|
|
1665
|
+
.partitioning = 0};
|
|
1666
|
+
case 0xEB:
|
|
1667
|
+
return (CacheLevelInfo){.level = 3,
|
|
1668
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1669
|
+
.cache_size = 18 * MiB,
|
|
1670
|
+
.ways = 24,
|
|
1671
|
+
.line_size = 64,
|
|
1672
|
+
.tlb_entries = UNDEF,
|
|
1673
|
+
.partitioning = 0};
|
|
1674
|
+
case 0xEC:
|
|
1675
|
+
return (CacheLevelInfo){.level = 3,
|
|
1676
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1677
|
+
.cache_size = 24 * MiB,
|
|
1678
|
+
.ways = 24,
|
|
1679
|
+
.line_size = 64,
|
|
1680
|
+
.tlb_entries = UNDEF,
|
|
1681
|
+
.partitioning = 0};
|
|
1682
|
+
case 0xF0:
|
|
1683
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1684
|
+
.cache_type = CPU_FEATURE_CACHE_PREFETCH,
|
|
1685
|
+
.cache_size = 64 * KiB,
|
|
1686
|
+
.ways = UNDEF,
|
|
1687
|
+
.line_size = UNDEF,
|
|
1688
|
+
.tlb_entries = UNDEF,
|
|
1689
|
+
.partitioning = 0};
|
|
1690
|
+
case 0xF1:
|
|
1691
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1692
|
+
.cache_type = CPU_FEATURE_CACHE_PREFETCH,
|
|
1693
|
+
.cache_size = 128 * KiB,
|
|
1694
|
+
.ways = UNDEF,
|
|
1695
|
+
.line_size = UNDEF,
|
|
1696
|
+
.tlb_entries = UNDEF,
|
|
1697
|
+
.partitioning = 0};
|
|
1698
|
+
case 0xFF:
|
|
1699
|
+
return (CacheLevelInfo){.level = UNDEF,
|
|
1700
|
+
.cache_type = CPU_FEATURE_CACHE_NULL,
|
|
1701
|
+
.cache_size = UNDEF,
|
|
1702
|
+
.ways = UNDEF,
|
|
1703
|
+
.line_size = UNDEF,
|
|
1704
|
+
.tlb_entries = UNDEF,
|
|
1705
|
+
.partitioning = 0};
|
|
1706
|
+
default:
|
|
1707
|
+
return kEmptyCacheLevelInfo;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
// From https://www.felixcloutier.com/x86/cpuid#tbl-3-12
|
|
1712
|
+
static void ParseLeaf2(const Leaves* leaves, CacheInfo* info) {
|
|
1713
|
+
Leaf leaf = leaves->leaf_2;
|
|
1714
|
+
// The least-significant byte in register EAX (register AL) will always return
|
|
1715
|
+
// 01H. Software should ignore this value and not interpret it as an
|
|
1716
|
+
// informational descriptor.
|
|
1717
|
+
leaf.eax &= 0xFFFFFF00; // Zeroing out AL. 0 is the empty descriptor.
|
|
1718
|
+
// The most significant bit (bit 31) of each register indicates whether the
|
|
1719
|
+
// register contains valid information (set to 0) or is reserved (set to 1).
|
|
1720
|
+
if (IsBitSet(leaf.eax, 31)) leaf.eax = 0;
|
|
1721
|
+
if (IsBitSet(leaf.ebx, 31)) leaf.ebx = 0;
|
|
1722
|
+
if (IsBitSet(leaf.ecx, 31)) leaf.ecx = 0;
|
|
1723
|
+
if (IsBitSet(leaf.edx, 31)) leaf.edx = 0;
|
|
1724
|
+
|
|
1725
|
+
uint8_t data[16];
|
|
1726
|
+
#if __STDC_VERSION__ >= 201112L
|
|
1727
|
+
_Static_assert(sizeof(Leaf) == sizeof(data), "Leaf must be 16 bytes");
|
|
1728
|
+
#endif
|
|
1729
|
+
copy((char*)(data), (const char*)(&leaf), sizeof(data));
|
|
1730
|
+
for (size_t i = 0; i < sizeof(data); ++i) {
|
|
1731
|
+
const uint8_t descriptor = data[i];
|
|
1732
|
+
if (descriptor == 0) continue;
|
|
1733
|
+
info->levels[info->size] = GetCacheLevelInfo(descriptor);
|
|
1734
|
+
info->size++;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
static const CacheInfo kEmptyCacheInfo;
|
|
1739
|
+
|
|
1740
|
+
// For newer Intel CPUs uses "CPUID, eax=0x00000004".
|
|
1741
|
+
// https://www.felixcloutier.com/x86/cpuid#input-eax-=-04h--returns-deterministic-cache-parameters-for-each-level
|
|
1742
|
+
// For newer AMD CPUs uses "CPUID, eax=0x8000001D"
|
|
1743
|
+
static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id,
|
|
1744
|
+
CacheInfo* old_info) {
|
|
1745
|
+
CacheInfo info = kEmptyCacheInfo;
|
|
1746
|
+
for (int index = 0; info.size < CPU_FEATURES_MAX_CACHE_LEVEL; ++index) {
|
|
1747
|
+
const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, index);
|
|
1748
|
+
int cache_type_field = ExtractBitRange(leaf.eax, 4, 0);
|
|
1749
|
+
CacheType cache_type;
|
|
1750
|
+
if (cache_type_field == 1)
|
|
1751
|
+
cache_type = CPU_FEATURE_CACHE_DATA;
|
|
1752
|
+
else if (cache_type_field == 2)
|
|
1753
|
+
cache_type = CPU_FEATURE_CACHE_INSTRUCTION;
|
|
1754
|
+
else if (cache_type_field == 3)
|
|
1755
|
+
cache_type = CPU_FEATURE_CACHE_UNIFIED;
|
|
1756
|
+
else
|
|
1757
|
+
// Intel Processor Identification and the CPUID Instruction Application
|
|
1758
|
+
// Note 485 page 37 Table 5-10. Deterministic Cache Parameters.
|
|
1759
|
+
// We skip cache parsing in case null of cache type or cache type in the
|
|
1760
|
+
// range of 4-31 according to documentation.
|
|
1761
|
+
break;
|
|
1762
|
+
int level = ExtractBitRange(leaf.eax, 7, 5);
|
|
1763
|
+
int line_size = ExtractBitRange(leaf.ebx, 11, 0) + 1;
|
|
1764
|
+
int partitioning = ExtractBitRange(leaf.ebx, 21, 12) + 1;
|
|
1765
|
+
int ways = ExtractBitRange(leaf.ebx, 31, 22) + 1;
|
|
1766
|
+
int tlb_entries = leaf.ecx + 1;
|
|
1767
|
+
int cache_size = ways * partitioning * line_size * tlb_entries;
|
|
1768
|
+
info.levels[info.size] = (CacheLevelInfo){.level = level,
|
|
1769
|
+
.cache_type = cache_type,
|
|
1770
|
+
.cache_size = cache_size,
|
|
1771
|
+
.ways = ways,
|
|
1772
|
+
.line_size = line_size,
|
|
1773
|
+
.tlb_entries = tlb_entries,
|
|
1774
|
+
.partitioning = partitioning};
|
|
1775
|
+
++info.size;
|
|
1776
|
+
}
|
|
1777
|
+
// Override CacheInfo if we successfully extracted Deterministic Cache
|
|
1778
|
+
// Parameters.
|
|
1779
|
+
if (info.size > 0) *old_info = info;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
typedef struct {
|
|
1783
|
+
int level;
|
|
1784
|
+
int cache_id;
|
|
1785
|
+
CacheType cache_type;
|
|
1786
|
+
} CacheLevelInfoLegacyAMD;
|
|
1787
|
+
|
|
1788
|
+
static int GetWaysLegacyAMD(int cache_level, const uint32_t cache_id) {
|
|
1789
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf page 23
|
|
1790
|
+
// CPUID.8000_0005_ECX[23:16] L1 data cache associativity.
|
|
1791
|
+
// CPUID.8000_0005_EDX[23:16] L1 instruction cache associativity.
|
|
1792
|
+
if (cache_level == 1) {
|
|
1793
|
+
return ExtractBitRange(cache_id, 23, 16);
|
|
1794
|
+
}
|
|
1795
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf page 24
|
|
1796
|
+
// See Table 4: L2/L3 Cache and TLB Associativity Field Definition.
|
|
1797
|
+
// CPUID.8000_0006_ECX[15:12] L2 cache associativity.
|
|
1798
|
+
// CPUID.8000_0006_EDX[15:12] L3 cache associativity.
|
|
1799
|
+
const int ways = ExtractBitRange(cache_id, 15, 12);
|
|
1800
|
+
switch (ways) {
|
|
1801
|
+
case 0x0:
|
|
1802
|
+
case 0x1:
|
|
1803
|
+
case 0x2:
|
|
1804
|
+
case 0x4:
|
|
1805
|
+
return ways;
|
|
1806
|
+
case 0x6:
|
|
1807
|
+
return 8;
|
|
1808
|
+
case 0x8:
|
|
1809
|
+
return 16;
|
|
1810
|
+
case 0xA:
|
|
1811
|
+
return 32;
|
|
1812
|
+
case 0xB:
|
|
1813
|
+
return 48;
|
|
1814
|
+
case 0xC:
|
|
1815
|
+
return 64;
|
|
1816
|
+
case 0xD:
|
|
1817
|
+
return 96;
|
|
1818
|
+
case 0xE:
|
|
1819
|
+
return 128;
|
|
1820
|
+
case 0xF:
|
|
1821
|
+
return 255;
|
|
1822
|
+
default:
|
|
1823
|
+
return -1; // Reserved
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
static int GetCacheSizeLegacyAMD(int cache_level, const uint32_t cache_id) {
|
|
1828
|
+
switch (cache_level) {
|
|
1829
|
+
case 1:
|
|
1830
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf page 23
|
|
1831
|
+
// CPUID.8000_0005_ECX[31:24] L1 data cache size in KB.
|
|
1832
|
+
// CPUID.8000_0005_EDX[31:24] L1 instruction cache size KB.
|
|
1833
|
+
return ExtractBitRange(cache_id, 31, 24);
|
|
1834
|
+
case 2:
|
|
1835
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf page 25
|
|
1836
|
+
// CPUID.8000_0006_ECX[31:16] L2 cache size in KB.
|
|
1837
|
+
return ExtractBitRange(cache_id, 31, 16);
|
|
1838
|
+
case 3:
|
|
1839
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf page 25
|
|
1840
|
+
// CPUID.8000_0006_EDX[31:18] L3 cache size.
|
|
1841
|
+
// Specifies the L3 cache size is within the following range:
|
|
1842
|
+
// (L3Size[31:18] * 512KB) <= L3 cache size < ((L3Size[31:18]+1) * 512KB).
|
|
1843
|
+
return ExtractBitRange(cache_id, 31, 18) * 512;
|
|
1844
|
+
default:
|
|
1845
|
+
return 0;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
#define LEGACY_AMD_MAX_CACHE_LEVEL 4
|
|
1850
|
+
|
|
1851
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf
|
|
1852
|
+
// CPUID Fn8000_0005_E[A,B,C,D]X, Fn8000_0006_E[A,B,C,D]X - TLB and Cache info
|
|
1853
|
+
static void ParseCacheInfoLegacyAMD(const uint32_t max_ext, CacheInfo* info) {
|
|
1854
|
+
const Leaf cache_tlb_leaf1 = SafeCpuIdEx(max_ext, 0x80000005, 0);
|
|
1855
|
+
const Leaf cache_tlb_leaf2 = SafeCpuIdEx(max_ext, 0x80000006, 0);
|
|
1856
|
+
|
|
1857
|
+
const CacheLevelInfoLegacyAMD legacy_cache_info[LEGACY_AMD_MAX_CACHE_LEVEL] =
|
|
1858
|
+
{(CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf1.ecx,
|
|
1859
|
+
.cache_type = CPU_FEATURE_CACHE_DATA,
|
|
1860
|
+
.level = 1},
|
|
1861
|
+
(CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf1.edx,
|
|
1862
|
+
.cache_type = CPU_FEATURE_CACHE_INSTRUCTION,
|
|
1863
|
+
.level = 1},
|
|
1864
|
+
(CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf2.ecx,
|
|
1865
|
+
.cache_type = CPU_FEATURE_CACHE_UNIFIED,
|
|
1866
|
+
.level = 2},
|
|
1867
|
+
(CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf2.edx,
|
|
1868
|
+
.cache_type = CPU_FEATURE_CACHE_UNIFIED,
|
|
1869
|
+
.level = 3}};
|
|
1870
|
+
|
|
1871
|
+
const int KiB = 1024;
|
|
1872
|
+
const int UNDEF = -1;
|
|
1873
|
+
for (int i = 0; i < LEGACY_AMD_MAX_CACHE_LEVEL; ++i) {
|
|
1874
|
+
const int level = legacy_cache_info[i].level;
|
|
1875
|
+
const int cache_id = legacy_cache_info[i].cache_id;
|
|
1876
|
+
const CacheType cache_type = legacy_cache_info[i].cache_type;
|
|
1877
|
+
const int cache_size = GetCacheSizeLegacyAMD(level, cache_id);
|
|
1878
|
+
if (cache_size == 0) break;
|
|
1879
|
+
info->levels[i] =
|
|
1880
|
+
(CacheLevelInfo){.level = level,
|
|
1881
|
+
.cache_type = cache_type,
|
|
1882
|
+
.cache_size = cache_size * KiB,
|
|
1883
|
+
.ways = GetWaysLegacyAMD(level, cache_id),
|
|
1884
|
+
.line_size = ExtractBitRange(cache_id, 7, 0),
|
|
1885
|
+
.tlb_entries = UNDEF,
|
|
1886
|
+
.partitioning = UNDEF};
|
|
1887
|
+
++info->size;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
CacheInfo GetX86CacheInfo(void) {
|
|
1892
|
+
CacheInfo info = kEmptyCacheInfo;
|
|
1893
|
+
const Leaves leaves = ReadLeaves();
|
|
1894
|
+
if (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL) ||
|
|
1895
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) ||
|
|
1896
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI)) {
|
|
1897
|
+
ParseLeaf2(&leaves, &info);
|
|
1898
|
+
ParseCacheInfo(leaves.max_cpuid_leaf, 4, &info);
|
|
1899
|
+
} else if (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) ||
|
|
1900
|
+
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE)) {
|
|
1901
|
+
// If CPUID Fn8000_0001_ECX[TopologyExtensions]==0
|
|
1902
|
+
// then CPUID Fn8000_0001_E[D,C,B,A]X is reserved.
|
|
1903
|
+
// https://www.amd.com/system/files/TechDocs/25481.pdf
|
|
1904
|
+
if (IsBitSet(leaves.leaf_80000001.ecx, 22)) {
|
|
1905
|
+
ParseCacheInfo(leaves.max_cpuid_leaf_ext, 0x8000001D, &info);
|
|
1906
|
+
} else {
|
|
1907
|
+
ParseCacheInfoLegacyAMD(leaves.max_cpuid_leaf_ext, &info);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
return info;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1914
|
+
// Definitions for introspection.
|
|
1915
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1916
|
+
#define INTROSPECTION_TABLE \
|
|
1917
|
+
LINE(X86_FPU, fpu, , , ) \
|
|
1918
|
+
LINE(X86_TSC, tsc, , , ) \
|
|
1919
|
+
LINE(X86_CX8, cx8, , , ) \
|
|
1920
|
+
LINE(X86_CLFSH, clfsh, , , ) \
|
|
1921
|
+
LINE(X86_MMX, mmx, , , ) \
|
|
1922
|
+
LINE(X86_AES, aes, , , ) \
|
|
1923
|
+
LINE(X86_ERMS, erms, , , ) \
|
|
1924
|
+
LINE(X86_F16C, f16c, , , ) \
|
|
1925
|
+
LINE(X86_FMA4, fma4, , , ) \
|
|
1926
|
+
LINE(X86_FMA3, fma3, , , ) \
|
|
1927
|
+
LINE(X86_VAES, vaes, , , ) \
|
|
1928
|
+
LINE(X86_VPCLMULQDQ, vpclmulqdq, , , ) \
|
|
1929
|
+
LINE(X86_BMI1, bmi1, , , ) \
|
|
1930
|
+
LINE(X86_HLE, hle, , , ) \
|
|
1931
|
+
LINE(X86_BMI2, bmi2, , , ) \
|
|
1932
|
+
LINE(X86_RTM, rtm, , , ) \
|
|
1933
|
+
LINE(X86_RDSEED, rdseed, , , ) \
|
|
1934
|
+
LINE(X86_CLFLUSHOPT, clflushopt, , , ) \
|
|
1935
|
+
LINE(X86_CLWB, clwb, , , ) \
|
|
1936
|
+
LINE(X86_SSE, sse, , , ) \
|
|
1937
|
+
LINE(X86_SSE2, sse2, , , ) \
|
|
1938
|
+
LINE(X86_SSE3, sse3, , , ) \
|
|
1939
|
+
LINE(X86_SSSE3, ssse3, , , ) \
|
|
1940
|
+
LINE(X86_SSE4_1, sse4_1, , , ) \
|
|
1941
|
+
LINE(X86_SSE4_2, sse4_2, , , ) \
|
|
1942
|
+
LINE(X86_SSE4A, sse4a, , , ) \
|
|
1943
|
+
LINE(X86_AVX, avx, , , ) \
|
|
1944
|
+
LINE(X86_AVX_VNNI, avx_vnni, , , ) \
|
|
1945
|
+
LINE(X86_AVX2, avx2, , , ) \
|
|
1946
|
+
LINE(X86_AVX512F, avx512f, , , ) \
|
|
1947
|
+
LINE(X86_AVX512CD, avx512cd, , , ) \
|
|
1948
|
+
LINE(X86_AVX512ER, avx512er, , , ) \
|
|
1949
|
+
LINE(X86_AVX512PF, avx512pf, , , ) \
|
|
1950
|
+
LINE(X86_AVX512BW, avx512bw, , , ) \
|
|
1951
|
+
LINE(X86_AVX512DQ, avx512dq, , , ) \
|
|
1952
|
+
LINE(X86_AVX512VL, avx512vl, , , ) \
|
|
1953
|
+
LINE(X86_AVX512IFMA, avx512ifma, , , ) \
|
|
1954
|
+
LINE(X86_AVX512VBMI, avx512vbmi, , , ) \
|
|
1955
|
+
LINE(X86_AVX512VBMI2, avx512vbmi2, , , ) \
|
|
1956
|
+
LINE(X86_AVX512VNNI, avx512vnni, , , ) \
|
|
1957
|
+
LINE(X86_AVX512BITALG, avx512bitalg, , , ) \
|
|
1958
|
+
LINE(X86_AVX512VPOPCNTDQ, avx512vpopcntdq, , , ) \
|
|
1959
|
+
LINE(X86_AVX512_4VNNIW, avx512_4vnniw, , , ) \
|
|
1960
|
+
LINE(X86_AVX512_4VBMI2, avx512_4vbmi2, , , ) \
|
|
1961
|
+
LINE(X86_AVX512_SECOND_FMA, avx512_second_fma, , , ) \
|
|
1962
|
+
LINE(X86_AVX512_4FMAPS, avx512_4fmaps, , , ) \
|
|
1963
|
+
LINE(X86_AVX512_BF16, avx512_bf16, , , ) \
|
|
1964
|
+
LINE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, , , ) \
|
|
1965
|
+
LINE(X86_AVX512_FP16, avx512_fp16, , , ) \
|
|
1966
|
+
LINE(X86_AMX_BF16, amx_bf16, , , ) \
|
|
1967
|
+
LINE(X86_AMX_TILE, amx_tile, , , ) \
|
|
1968
|
+
LINE(X86_AMX_INT8, amx_int8, , , ) \
|
|
1969
|
+
LINE(X86_PCLMULQDQ, pclmulqdq, , , ) \
|
|
1970
|
+
LINE(X86_SMX, smx, , , ) \
|
|
1971
|
+
LINE(X86_SGX, sgx, , , ) \
|
|
1972
|
+
LINE(X86_CX16, cx16, , , ) \
|
|
1973
|
+
LINE(X86_SHA, sha, , , ) \
|
|
1974
|
+
LINE(X86_POPCNT, popcnt, , , ) \
|
|
1975
|
+
LINE(X86_MOVBE, movbe, , , ) \
|
|
1976
|
+
LINE(X86_RDRND, rdrnd, , , ) \
|
|
1977
|
+
LINE(X86_DCA, dca, , , ) \
|
|
1978
|
+
LINE(X86_SS, ss, , , ) \
|
|
1979
|
+
LINE(X86_ADX, adx, , , ) \
|
|
1980
|
+
LINE(X86_LZCNT, lzcnt, , , ) \
|
|
1981
|
+
LINE(X86_GFNI, gfni, , , ) \
|
|
1982
|
+
LINE(X86_MOVDIRI, movdiri, , , ) \
|
|
1983
|
+
LINE(X86_MOVDIR64B, movdir64b, , , ) \
|
|
1984
|
+
LINE(X86_FS_REP_MOV, fs_rep_mov, , , ) \
|
|
1985
|
+
LINE(X86_FZ_REP_MOVSB, fz_rep_movsb, , , ) \
|
|
1986
|
+
LINE(X86_FS_REP_STOSB, fs_rep_stosb, , , ) \
|
|
1987
|
+
LINE(X86_FS_REP_CMPSB_SCASB, fs_rep_cmpsb_scasb, , , )
|
|
1988
|
+
#define INTROSPECTION_PREFIX X86
|
|
1989
|
+
#define INTROSPECTION_ENUM_PREFIX X86
|
|
1990
|
+
#include "define_introspection.inl"
|
|
1991
|
+
|
|
1992
|
+
#define X86_MICROARCHITECTURE_NAMES \
|
|
1993
|
+
LINE(X86_UNKNOWN) \
|
|
1994
|
+
LINE(ZHAOXIN_ZHANGJIANG) \
|
|
1995
|
+
LINE(ZHAOXIN_WUDAOKOU) \
|
|
1996
|
+
LINE(ZHAOXIN_LUJIAZUI) \
|
|
1997
|
+
LINE(ZHAOXIN_YONGFENG) \
|
|
1998
|
+
LINE(INTEL_80486) \
|
|
1999
|
+
LINE(INTEL_P5) \
|
|
2000
|
+
LINE(INTEL_LAKEMONT) \
|
|
2001
|
+
LINE(INTEL_CORE) \
|
|
2002
|
+
LINE(INTEL_PNR) \
|
|
2003
|
+
LINE(INTEL_NHM) \
|
|
2004
|
+
LINE(INTEL_ATOM_BNL) \
|
|
2005
|
+
LINE(INTEL_WSM) \
|
|
2006
|
+
LINE(INTEL_SNB) \
|
|
2007
|
+
LINE(INTEL_IVB) \
|
|
2008
|
+
LINE(INTEL_ATOM_SMT) \
|
|
2009
|
+
LINE(INTEL_HSW) \
|
|
2010
|
+
LINE(INTEL_BDW) \
|
|
2011
|
+
LINE(INTEL_SKL) \
|
|
2012
|
+
LINE(INTEL_CCL) \
|
|
2013
|
+
LINE(INTEL_ATOM_GMT) \
|
|
2014
|
+
LINE(INTEL_ATOM_GMT_PLUS) \
|
|
2015
|
+
LINE(INTEL_ATOM_TMT) \
|
|
2016
|
+
LINE(INTEL_KBL) \
|
|
2017
|
+
LINE(INTEL_CFL) \
|
|
2018
|
+
LINE(INTEL_WHL) \
|
|
2019
|
+
LINE(INTEL_CML) \
|
|
2020
|
+
LINE(INTEL_CNL) \
|
|
2021
|
+
LINE(INTEL_ICL) \
|
|
2022
|
+
LINE(INTEL_TGL) \
|
|
2023
|
+
LINE(INTEL_SPR) \
|
|
2024
|
+
LINE(INTEL_ADL) \
|
|
2025
|
+
LINE(INTEL_RCL) \
|
|
2026
|
+
LINE(INTEL_RPL) \
|
|
2027
|
+
LINE(INTEL_KNIGHTS_M) \
|
|
2028
|
+
LINE(INTEL_KNIGHTS_L) \
|
|
2029
|
+
LINE(INTEL_KNIGHTS_F) \
|
|
2030
|
+
LINE(INTEL_KNIGHTS_C) \
|
|
2031
|
+
LINE(INTEL_NETBURST) \
|
|
2032
|
+
LINE(AMD_HAMMER) \
|
|
2033
|
+
LINE(AMD_K10) \
|
|
2034
|
+
LINE(AMD_K11) \
|
|
2035
|
+
LINE(AMD_K12) \
|
|
2036
|
+
LINE(AMD_BOBCAT) \
|
|
2037
|
+
LINE(AMD_PILEDRIVER) \
|
|
2038
|
+
LINE(AMD_STREAMROLLER) \
|
|
2039
|
+
LINE(AMD_EXCAVATOR) \
|
|
2040
|
+
LINE(AMD_BULLDOZER) \
|
|
2041
|
+
LINE(AMD_JAGUAR) \
|
|
2042
|
+
LINE(AMD_PUMA) \
|
|
2043
|
+
LINE(AMD_ZEN) \
|
|
2044
|
+
LINE(AMD_ZEN_PLUS) \
|
|
2045
|
+
LINE(AMD_ZEN2) \
|
|
2046
|
+
LINE(AMD_ZEN3) \
|
|
2047
|
+
LINE(AMD_ZEN4)
|
|
2048
|
+
|
|
2049
|
+
const char* GetX86MicroarchitectureName(X86Microarchitecture value) {
|
|
2050
|
+
#define LINE(ENUM) [ENUM] = STRINGIZE(ENUM),
|
|
2051
|
+
static const char* kMicroarchitectureNames[] = {X86_MICROARCHITECTURE_NAMES};
|
|
2052
|
+
#undef LINE
|
|
2053
|
+
if (value >= X86_MICROARCHITECTURE_LAST_) return "unknown microarchitecture";
|
|
2054
|
+
return kMicroarchitectureNames[value];
|
|
2055
|
+
}
|