Модуль FixTsc для китайских материнских плат x79 (x79 v2.72B, x79g v1.21, ...). Исправляет расхождение tsc счётчика на CPU0 после тёплого сброса CPU (от IvtQpiandMrcInit) в DXE фазе UEFI BIOS. Актуально для плат, у которых сломан сон (не разведено питание оперативной памяти от дежурного питания) и холодный сброс процессора невозможен без последующего тёплого сброса CPU для завершения тренинга контроллера оперативной памяти. На процессорах Xeon E5 присутствует аппаратный баг (erratum bt81, erratum ca105), из-за которого счётчики tsc не сбрасываются на всех остальных ядрах CPU кроме первого при тёплом сбросе. Комбинация этих двух факторов ломает синхронизацию tsc счётчика и операционная система вынуждена использовать другой счётчик (hpet), который сильно влияет на производительность приложений и игр в худшую сторону, снижая её иногда на порядок. Моя программа запускает код чтения tsc на CPU1 через StartupThisAP и через барьер делает это одновременно со чтением tsc на CPU0, делает 9 замеров и вычисляет расхождение, на которое корректируется tsc на CPU0, цикл повторяется до тех пор, пока не будет расхождение в пределах допустимого. Лог ядра Linux 6.12 на стоковом UEFI BIOS: # dmesg | grep -i tsc [ 0.000000] tsc: Fast TSC calibration using PIT [ 0.000000] tsc: Detected 2500.010 MHz processor [ 0.015749] TSC deadline timer available [ 1.348887] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x24094323722, max_idle_ns: 440795281912 ns [ 1.589406] TSC synchronization [CPU#0 -> CPU#1]: [ 1.591401] Measured 1829190741277596 cycles TSC warp between CPUs, turning off TSC clock. [ 1.591405] tsc: Marking TSC unstable due to check_tsc_sync_source failed После добавления DXE модуля FixTsc в UEFI BIOS: # dmesg | grep -i tsc [ 0.000000] tsc: Fast TSC calibration using PIT [ 0.000000] tsc: Detected 2500.004 MHz processor [ 0.021585] TSC deadline timer available [ 1.460988] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x24093d6e846, max_idle_ns: 440795249997 ns [ 2.921558] clocksource: Switched to clocksource tsc-early [ 4.954187] tsc: Refined TSC clocksource calibration: 2499.998 MHz [ 4.963273] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x240937b9988, max_idle_ns: 440795218083 ns [ 4.979845] clocksource: Switched to clocksource tsc Если значение "cycles TSC warp between CPUs" очень маленькое (до нескольких сотен), то нужно подобрать значение PERFECT, которое подобрано экспериментальным образом. При значении 0 разброс 35 циклов, при значении 130 разброс 42 цикла, я взял середину, при которой tsc лучше всего синхронизирован. Так же предусмотрена отладка через пост-карту, для этого нужно раскомментировать строку "#define DEBUG_TSCFIX" и пересобрать модуль. Тогда на пост-карту будут выводиться 3 пост-кода по пол секунды, первый означает количество циклов записи счётчика, второй и третий означают минимальное и максимальное измеренное отклонение счётчиков, чтобы перевести в десятичный вид, нужно сначала вычесть число 80h. Это сделано для того, чтобы не терять отрицательные значения. Например, коды 1e 6f 89 означают, что программа сделала 30 циклов записи счётчика и последние 9 замеров показали минимальное расхождение на -17 тактов и максимальное расхождение на 9 тактов относительно PERFECT. Программа проверена на двух конфигурациях: x79 v2.72B с процессором Xeon E5 2697 v2 x79g v1.21 с процессором Xeon E5 2696 v2 Программа собирается как UEFI DXE модуль через edk2 (я использовал от Mosby). Рядом с файлами должна лежать папка edk2: git clone https://github.com/tianocore/edk2/tree/d46aa46c8361194521391aa581593e556c707c6e --recursive Команды для сборки под Debian 13: source init.sh chmod +x build.sh ./build.sh Собранный модуль (файл TscFix.ffs) вшить в дамп биоса через UEFITool 0.25.1 в конец списка (Insert after...) DXE модулей (после CRBDXE, CspLibDxe, OEMOEMDXE), должен появиться GUID 45766765-6E79-204C-6170-696B20545343 и текст TscFix. Модуль не должен лежать в списке PEI модулей. Прошивать дамп биоса на свой страх и риск.