APIC Timer

Тема в разделе "WASM.OS.DEVEL", создана пользователем SadKo, 28 мар 2008.

  1. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Приветствую!
    Пытаюсь сейчас запустить таймеры APIC всех процессоров в SMP, но не очень-то получается. В смысле, на qemu пашет, а в реальности всё намного плачевнее (виснет ap-проц, либо падает bsp).
    В Intel Manual только описание регистров и режимов.
    У кого-нибудь есть какой-нибудь материал/примеры по программированию APIC (в том числе, и таймеров)?
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Покажи код, так трудно что-то сказать. Насколько я понимаю, ты это делаешь прямо в своей ОС, но проще сделать тестовый пример на ассемблере, который запустит таймеры, чтобы защититься от посторонних ошибок. И нам легче разбирать будет.
     
  3. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Так, с APIC BSP разобрался. Оказывается, ребутал у меня систему код, который работает с VESA (потому что грузилась IDT реального режима, а прерывания таймера APIC не маскировались. Как следствие - фолт по неизвестному адресу, тому, который прописан в IDT реального режима за вектором таймера).
    А вот с AP непонятно пока. После включения прерываний выпадает exception, при этом кода ошибки нет (выпадают, в основном, исключения 0x08, 0x0e и 0x0d). При чём, я не уверен, что это именно exception, а больше подозреваю, что какое-то аппаратное прерывание, приходящееся на векторы исключений. Очень похоже на векторы PIC.
    Вопросы:
    1. если APIC эмулируется как PIC, нужно ли проводить инициализацию PIC на каждом процессоре?
    2. какие прерывания после STI могут приходить на AP-процессор?
     
  4. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    SadKo
    IDT/GDT для каждого AP инициализированы?
    1. скорее PIC может эмулироваться через APIC
    2. в PIC архитектуре, PIC связан только с BP, независимо от того, в контексте какого процессора идет его программирование
    3. в APIC архитектуре, APIC может быть связан с любым AP и BP через таблицу перенаправлений прерываний
    программировать ее можно в контексте любого процессора
    как вывод, в любой архитектуре, инициализацию достаточно произвести единожды
    STI выполнен для AP?
    тогда любые внешние: SMI, NMI, маскируемые
    если размаскированы элементы LVT, тогда еще набор локальных
     
  5. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    IDT и GDT у процессоров общие. Проблема не возникала, пока на AP-процессоре не сделал STI. Решил протрассировать код. После STI выполняется N инструкций и выпадает в исключение, при чём, не обязательно одно и то же. Да и вообще сдаётся мне, что это не исключение. Код на BSP выполняется нормально.

    Таблица перенаправлений прерываний - это I/O APIC?
     
  6. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    да

    перед STI на AP просмотри ее (таблицу) из BSP на предмет наличия идентификаторов AP
    и соответствующих векторов в каждом элементе
    какой режим обработки прерываний активен после STI? (PIC, Virtual-Wire, Symmetric)
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    значит в любом случае дело либо в NMI, либо в маскируемых прерываниях
    можешь создать в IDT 256 дескрипторов с фиктивными обработчиками и посмотреть номер вектора при генерации прерывания
     
  8. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Я это собирался проделать. В ближайшее время возьмусь. Всё же интересно, что творится.
    А есть какие-нибудь хорошие доки по IO APIC?
     
  9. TheDeath

    TheDeath New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2003
    Сообщения:
    66
    Адрес:
    Russia,Новосибирск
    1. Intel MultiProcessor Specification,1997
    2. Intel System Programming Guide
    3. то же но от AMD
     
  10. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Спасибо. Сейчас просто времени мало во всём этом разбираться, но тема очень интересная. Буду отписываться по мере продвижения.
     
  11. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Собрал статистику по прерываниям (сделал IDT для AP-проца, считаю количество сработавших прерываний).
    Получил следующие цифры:
    прерывание 0x08 - один раз.
    прерывание 0x0c - один раз.
    прерывание 0x20 - постоянно инкрементируется.
    прерывание 0x21 - два раза.
    прерывание 0x27 - постоянно инкрементируется.

    Повесил APIC Timer на 254 прерывание, таймер срабатывает регулярно, инкрементируя счётчик.
    "PIC Master" запрограммирован на базовый вектор 0x20, "Slave" - на вектор 0x28.
    На BSP проце используются прерывания от таймера, от клавиатуры, от ATA, от FDC и от мыши.

    Spurious Vector установил в 0x1f.

    Как можно объяснить выскакивание прерываний 0x08 и 0x0c?
     
  12. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    это не могут быть исключения?
     
  13. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Нет, не могут, поскольку поток, запущенный на AP-процессоре, крутится нормально.

    Единственное. я, похоже, перепутал прерывание 0x0c и 0x0e (да, почерк у меня корявый). У меня есть такое предположение: эти прерывания стояли в очереди у Local APIC до тех пор, пока я не разрешил прерывания (sti), при чём, произошли до того, как был перепрограммирован "PIC" (например, на этапе загрузки BIOS/чтении бутсектора и пр.).

    Есть ли какой-нибудь способ сбросить очередь прерываний в APIC? 0x08 - вполне закономерно, таймер, 0x0e - прерывание от дисковода. У меня уже была проблема, когда второй проц спонтанно вешал первый (приходило левое прерывание на второй проц). Лечилось это программированием APIC в VirtualWire Mode. Возможно, это и послужило причиной такого зависания. Вопрос теперь стоит в другом: как убрать из очереди эти запросы?
     
  14. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    нет
    после выбора бита в IRR, он обнуляется, а соответстующий ему бит в ISR устанавливается
    т. е если не запрещать маскируемые прерывания, то биты в IRR будут обнулены APIC-ом в процессе вызова обработчиков
    можно попытаться 256 раз записать 0 в EOI регистр при запрещенных прерываниях
    хотя не факт, что таким образом IRR обнулится: в мануале написано неоднозначно
     
  15. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    SadKo
    Перепроверь статистику, а то она у тебя кривая какая то до безобразия.
    Хотя вроде и закономерно.

    rei3er
    Вроде все описанно. В MP какраз таки и говориться что надо очистить и запретить в I/O APIC
    В I/O APIC написано что прерывание может не сразу доставляться. Как запретить понятно там бит есть, как очист
    ить хм надо почитать повнимательнее. Можно цикл запустить пока бит о доставке в 0 невыставиться.
     
  16. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Pavia
    я про IRR и ISR Local APIC-а
     
  17. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Получилось очистить запросы на прерывание таким образом:
    1. читаем Local APIC IRR
    2. Пишем 0 в Local APIC EOI
    3. повторяем с пункта 1 256 раз
    После чего все фейковые счётчики прерываний равны 0.

    Есть идея, как это сделать более красиво:
    1. читаем IRR
    2. читаем ISR
    3. IRR == ISR == 0 ? Если нет, то посылаем EOI и возвращаемся к 1
    4. повторяем 1-3 для всех частей IRR и ISR (256/32 = 8 раз)
     
  18. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    странно, что вы сразу так не сделали ;)
     
  19. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    rei3er
    У него тоже самое бит 12 в регистрах LVT
     
  20. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    вы о чем? причем здесь LVT?
    речь идет о том, как избежать вызова обработчиков прерываний по векторам 0xC, 0xE