Как программно отключить немаскируемые прерывания? - PullRequest
4 голосов
/ 28 марта 2019

Я читал, что для временного отключения подкачки в соответствии с руководством по системному программированию Intel (том 3, глава 9.9) я должен отключить прерывания, прежде чем делать что-либо еще. Я могу легко отключить маскируемые прерывания с помощью cli, но все руководство говорит об отключении NMI:

Прерывания NMI могут быть отключены с помощью внешней схемы. (Программное обеспечение должно гарантировать, что во время переключение режимов работы.)

Я нашел код, похожий на код C, для отключения NMI на этой странице OSDEV , но я не совсем понимаю, что это должно означать

void NMI_enable() {
    outb(0x70, inb(0x70) & 0x7F);
 }

 void NMI_disable() {
    outb(0x70, inb(0x70) | 0x80);
 }

создается впечатление, что этот код не имеет контекста и не имеет смысла, не зная, что делают функции outb и inb.

Ответы [ 2 ]

5 голосов
/ 28 марта 2019

«с внешней схемой» означает, что на плате имеются выводы перед выводами NMI чипа процессора, и если эти вентили отключены (закрыты), никакие сигналы прерывания не достигнут выводов NMI чипа процессора.

Возможно, вызовы outb активируют / деактивируют эти ворота.

NMI означает немаскируемость, и это означает, что вы не можете отключить их только с помощью программного обеспечения.

3 голосов
/ 28 марта 2019

ЦПУ имеет вывод немаскируемого прерывания (NMI) (или аппаратный эквивалент), который используется для запуска NMI.Существует внешняя схема (или аппаратный эквивалент) для предотвращения попадания NMI в CPU.Начиная с 80286 механизм использовался через порты ввода-вывода, связанные с контроллером CMOS / Realtime Clock (RTC).Этот тот же механизм все еще используется в аппаратном обеспечении сегодня.

Порты CMOS / RTC - 0x70 и 0x71.Порт 0x70 используется для выбора адреса CMOS / RTC для чтения или записи.Верхние 2 бита адреса CMOS / RTC не являются частью реального адреса.Самый верхний бит был переопределен как тумблер NMI.Если вы записываете байт в порт 0x70, где установлен бит 7 (старший значащий бит), NMI отключается.Если вы записываете значение, в котором бит 7 сброшен, то NMI включаются.

Функции inb и outb являются C оболочками вокруг низкого уровня IN (байт) и OUT (байт) инструкции.Эти инструкции читают и записывают в пространство порта ввода-вывода.Этот C код из NMI_enable:

outb(0x70, inb(0x70) & 0x7F);

является эквивалентом:

uint8_t curbyte = inb(0x70);   /* Read current port 0x70 state */
outb(0x70, curbyte & 0x7F);    /* Update current state by clearing NMI bit */
                               /* and write new value back to port 0x70 */

0x7f - это битовая комбинация 01111111. ANDing 01111111 с текущим байтомочищает самый верхний бит (включение NMI).

Этот C код из NMI_disable:

outb(0x70, inb(0x70) | 0x80);

Эквивалент:

uint8_t curbyte = inb(0x70);   /* Read current port 0x70 state */
outb(0x70, curbyte | 0x80);    /* Update current state by setting NMI bit */
                               /* and write new value back to port 0x70 */

0x80 - это битовая комбинация 10000000. ORing 10000000 с текущим байтом устанавливает старший бит (отключение NMI).

...