Помогите разобраться с таймером

Тема в разделе "WASM.ASSEMBLER", создана пользователем Avenger, 21 янв 2012.

  1. Avenger

    Avenger New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2012
    Сообщения:
    5
    Добрый день,
    есть некоторая фирмварь, которую очень хочется загрузить и заставить работать.
    Фирмварь изначально рассчитана на работу в защищенном режиме и оригинального загрузчика к ней нет. Поэтому начал писать свой загрузчик (враппер который запускается из биоса). Проблемы загрузки фирмвари в память, настройки защищенного режима и передачи управления на фирмварь вроде преодолел.
    Но дальше появились проблемы уже в самой фирмвари - похоже какой-то цикл калибровки задержек:
    Код (Text):
    1. xor     ecx, ecx
    2. xor     ebx, ebx
    3. jmp     short loop1_entry
    4.  
    5. loop1:
    6. inc     ecx
    7.  
    8. loop1_entry:
    9. mov     edx, 20h
    10. in      al, dx
    11. test    al, 1
    12. jz      short loop1
    13.  
    14. mov     eax, 80h
    15. mov     dl, 61h
    16. out     dx, al
    17. jmp     short loop2_entry
    18.  
    19. loop2:
    20. inc     ecx
    21.  
    22. loop2_entry:
    23. mov     edx, 20h
    24. in      al, dx
    25. test    al, 1
    26. jnz     short loop2
    27.  
    28. inc     ebx
    29. cmp     ebx, 99
    30. jle     short loop1_entry
    31.  
    32. mov     dx, 10000
    33. lea     eax, [ecx+5000]
    34. mov     ecx, edx
    35. xor     edx, edx
    36. div     ecx
    Перед этим куском кода таймер настраивается на 1000Hz и Mode3 (Square wave).
    Если прерывания не включать - то зацикливается на loop2, если поставить пустой обработчик на IRQ0 (просто писать 0x20 в порт 0x20) - то IRR регистр скидыватся в 0 и код зацикливается на loop1.
    Подозреваю что обработчик IRQ0 должен как-то менять свое поведение согласно внутреннему счетчику таймера, но так как раньше дела с таймерами не имел - просто пока не могу представить для чего это нужно.

    Если кто-то видел/знает подобные конструкции - подскажите для чего это необходимо и как правильно написать обработчик.
     
  2. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Avenger
    Насколько понимаю, данный кусок кода просто ждёт 1/10 секунды, и подсчитывает сколько раз он за это время успеет прочитать порт, правда зачем в порт 61h записывает 80h, а в конце число чтений делится на 10000, непонятно.
     
  3. Avenger

    Avenger New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2012
    Сообщения:
    5
    Black_mirror
    Да, 1/10 секунды тут прослеживается, но EBX инкрементируется только если IRQ0 уже обслужено (IRR бит0 = 0, т.е. из порта 0x20 вернется бит0 = 0). Но при таком условии оно просто не выйдет из loop1 :dntknw:
    Соответственно обработчик IRQ0 должен не обрабатывать некоторое количество прерываний..., так как выход из loop1 это IRR=1 а выход из loop2 это IRR=0. Если IRQ0 всегда обрабатывается - то код никогда не дойдет до инкрементации EBX.

    Очень похоже что обработчик IRQ0 зависит от вывода 0x80 в порт 0x61... Но документация Intel (на ICH7 например) говорит что биты 4-7 read-only.
     
  4. Avenger

    Avenger New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2012
    Сообщения:
    5
    Кажется я понял.
    Запись 0x80 в порт 0x61 делает ресет IRQ0 (при использовании PS/2 контроллера)
    Соответственно код действительно ждет 1/10 секунды при условии отстутствия каких либо irq-хендлеров. Т.е. записью в порт 0x61 он сам подтверждает получение IRQ0.

    Но так как я этот код запускал на QEMU - там это просто не реализовано :dntknw: и на порту 0x61 "слушает" исключительно PC Speaker. Соответственно запись 0х80 ни на что не влияла, и код "зависал".
     
  5. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
  6. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
    Pavia
    Ой не врите. Младшие 4 бита 61-го порта R/W, старший нибл ридонли:
    0 R/W Вход GATE PIT.
    1 R/W Отключает спикер(запилена логическое & с выходом на спикер).
    2, 3 R/W Управляет шинами хз.
    4 R Регенерация памяти связана с этой линией.
    5 R Выход счётчика PIT.
    6, 7 R Сигнализирует ошибки на шине или рам.
     
  7. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    У intel этот бит обозначен как read only начиная от PIIx4 заканчивая ICH8.
    От материки к материке значение всего порта менялось, так что все не проверял.
    А вот на PS/2 да 80h отвечает за сброс защёлки IRQ0
     
  8. Avenger

    Avenger New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2012
    Сообщения:
    5
    А вопрос в догонку - получается что порт 61h должен слушать какой-то свой контроллер, который уже форвардит реквесты на ICHx ?
    Так как должен же быть какой-то уровень совместимости с PS/2... где бы про него почитать...

    ЗЫ. Эта фирмвать работает на х86-совместимом железе и не только на чипсетах от Intel. Гарантировано запускается на Geode и вполне возможно на некоторых NForce чипсетах. Т.е. какой-то уровень совместимости должен быть в не зависимости от того что пишет интел в своих документах.
     
  9. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
    Avenger
    А как вы будите управлять к примеру спикером, без записи в этот порт ?

    Путём магии мб ?
     
  10. Avenger

    Avenger New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2012
    Сообщения:
    5
    kejcerfcrv
    Так спикер не затрагивается режимом совместимости:
    Код (Text):
    1. 0061    w   KB controller port B (ISA, EISA)   (PS/2 port A is at 0092)
    2.         system control port for compatibility with 8255
    3.          bit 7  (1= IRQ 0 reset )
    4.          bit 6-4    reserved
    5.          bit 3 = 1  channel check enable
    6.          bit 2 = 1  parity check enable
    7.          bit 1 = 1  speaker data enable
    8.          bit 0 = 1  timer 2 gate to speaker enable
    Биты 0 и 1 точно также отвечают за спикер, как и в документации Intel. Вопрос в том что старшие четыре бита по документации read-only... Но если это работает на реальном железе, значит в чипсете реализована совместимость с PS/2 - вот и интересно где это искать.
    (Так как я хочу запустить эту фирмварь на QEMU - то соотв. мне нужно реализовать эмуляцию этой совместимости самому...)