Отключение / включение прерываний на архитектурах x86 - PullRequest
0 голосов
/ 06 февраля 2019

Я использую NetBSD 5.1 для систем x86.При изучении кода, связанного с драйвером, я вижу, что мы используем splraise и spllower , чтобы блокировать или разрешать прерывания.Я искал некоторые механизмы в Интернете, чтобы понять, как эти механизмы работают в реальности.Не получил никакой реальной информации об этом.

Когда я разобрал, я получил механизм, но все еще не понимаю, как все эти инструкции по сборке дают мне результат.Я знаю инструкции по x86 по отдельности, но не знаю, как все это работает в целом.

Нужна ваша помощь в понимании принципов работы системы x86.Я понимаю, что нам нужно отключить Interrupt Enable (IE) bit, но эта сборка, кажется, делает больше, чем просто эту работу.Нужна помощь.

  (gdb) x/50i splraise
   0xc0100d40:  mov    0x4(%esp),%edx
   0xc0100d44:  mov    %fs:0x214,%eax
   0xc0100d4a:  cmp    %edx,%eax
   0xc0100d4c:  ja     0xc0100d55
   0xc0100d4e:  mov    %edx,%fs:0x214
   0xc0100d55:  ret
   0xc0100d56:  lea    0x0(%esi),%esi
   0xc0100d59:  lea    0x0(%edi,%eiz,1),%edi
   (gdb) p spllower
   $38 = {<text variable, no debug info>} 0xc0100d60
   0xc0100d60:  mov    0x4(%esp),%ecx
   0xc0100d64:  mov    %fs:0x214,%edx
   0xc0100d6b:  cmp    %edx,%ecx
   0xc0100d6d:  push   %ebx
   0xc0100d6e:  jae,pn 0xc0100d8f
   0xc0100d71:  mov    %fs:0x210,%eax
   0xc0100d77:  test   %eax,%fs:0x244(,%ecx,4)
   0xc0100d7f:  mov    %eax,%ebx
   0xc0100d81:  jne,pn 0xc0100d91
   0xc0100d84:  cmpxchg8b %fs:0x210
   0xc0100d8c:  jne,pn 0xc0100d71
   0xc0100d8f:  pop    %ebx
   0xc0100d90:  ret
   0xc0100d91:  pop    %ebx
   0xc0100d92:  jmp    0xc0100df0
   0xc0100d97:  mov    %esi,%esi
   0xc0100d99:  lea    0x0(%edi,%eiz,1),%edi
   0xc0100da0:  mov    0x4(%esp),%ecx
   0xc0100da4:  mov    %fs:0x214,%edx
   0xc0100dab:  cmp    %edx,%ecx
   0xc0100dad:  push   %ebx
   0xc0100dae:  jae,pn 0xc0100dcf
   0xc0100db1:  mov    %fs:0x210,%eax
   0xc0100db7:  test   %eax,%fs:0x244(,%ecx,4)
   0xc0100dbf:  mov    %eax,%ebx
   0xc0100dc1:  jne,pn 0xc0100dd1
   0xc0100dc4:  cmpxchg8b %fs:0x210
   0xc0100dcc:  jne,pn 0xc0100db1
   0xc0100dcf:  pop    %ebx
   0xc0100dd0:  ret
   0xc0100dd1:  pop    %ebx
   0xc0100dd2:  jmp    0xc0100df0
   0xc0100dd7:  mov    %esi,%esi
   0xc0100dd9:  lea    0x0(%edi,%eiz,1),%edi
   0xc0100de0:  nop
   0xc0100de1:  jmp    0xc0100df0

Код, похоже, использует вспомогательную функцию cx8_spllower , начиная с адреса 0xc0100da0 .

1 Ответ

0 голосов
/ 06 февраля 2019

Сброс [E|R]FLAGS.IE, например, CLI отключает все (маскируемые) прерывания на процессоре.По ряду причин это может быть нежелательно (например, вы хотите разрешить некоторые или, возможно, вам не нужны накладные расходы на виртуализацию CLI в виртуальной машине).

Еще один способ достижения цели - этоскажите контроллеру прерываний (PIC 8259 или Pentium APIC / IOAPIC), что вы не хотите обслуживать прерывания, приоритет которых ниже определенного уровня.Для этого вам необходимо установить связь с контроллером, который сам может быть связан с дополнительными издержками (общение как с реальным, так и с виртуальным оборудованием является медленным).

Вариант последнего состоит в том, чтобы сохранить текущий уровень / приоритет прерывания впеременная и позволяет прерываниям входить, но на самом деле обслуживают только тех, чей уровень / приоритет не ниже текущего в этой переменной.Те, кто не обслуживается, будут помечены как ожидающие и будут полностью обслужены, когда текущий уровень / приоритет упадет достаточно низко.Вот почему splraise() намного проще, чем spllower().

Эта переменная уровня / приоритета в разных местах и ​​версиях кода имеет разные названия: CPL (не путать с процессорами текущий уровень привилегий ), SPL (?), ILEVEL.

Это мое текущее, ограниченное понимание реализации.Есть еще несколько деталей.

Вот некоторые подсказки, которые я нашел и использовал для ответа:

...