2 акт. обработчика PCI IRQ на разных линиях вешают систему
-
По роду деятельности, я сталкивался часто с тем, что "железные баги" - на самом деле обычно баги либо в таблице ACPI, либо в самом коде BIOS. А ядро Linux содежит много обходных путей, для "исправления" этих ошибок.
XVilka
В любом случае этот баг не на нашей стороне.
В любом случае этот баг не на нашей стороне.
Нам от этого не легче.
Мне легче. Не надо искать ошибку там, где её нет.
Чтобы не создавать отдельную тему спрошу здесь. Если админы/модераторы посчитают необходимым выделить в отдельную тему, то не возражаю.
Вопрос относительно обработчика прерывания. В свое время я написал код поддержки DMA. Добавлен в ядро он был программистом, гипотетически покинувшим проект, методом "реверс-инжиниринга" из выложенного мной бинарника ядра. Впрочем не суть есть важно, код был относительно рабочий и почти не менялся много лет. В коде я сделал переключение обработчика на нормальный:
и пустой обработчик:
В настоящее время, по сути, эти переменные используются как флаги. Однако одновременно с этим меняется и обработчик прерывания.
Так вот вопрос в том правильна ли такая логика. Может стоит сам обработчик оставлять с постоянным указателем? Теоретически пока код не подал команду на считывание или запись, то прерывание возникать не должно, но что происходит на практике я не знаю.
Код нормального обработчика прерывания и нулевого выглядит так:
Т.е. получается пустой обработчик не сбрасывает прерывание. Может ли это вызывать проблемы тоже вопрос.
Может имеет смысл сделать так:
Также у меня есть подозрение, что это может быть причиной зависания в некоторых случаях для контроллеров работающих в PIO режиме.
З.Ы. На pushad и popad просьба внимание не обращать, я знаю что это "жирно", но это не вопрос данного обсуждения.
Вопрос относительно обработчика прерывания. В свое время я написал код поддержки DMA. Добавлен в ядро он был программистом, гипотетически покинувшим проект, методом "реверс-инжиниринга" из выложенного мной бинарника ядра. Впрочем не суть есть важно, код был относительно рабочий и почти не менялся много лет. В коде я сделал переключение обработчика на нормальный:
Spoiler:
Code: Select all
mov [irq14_func], hdd_irq14
mov [irq15_func], hdd_irq15
Spoiler:
Code: Select all
mov [irq14_func], hdd_irq_null
mov [irq15_func], hdd_irq_null
Так вот вопрос в том правильна ли такая логика. Может стоит сам обработчик оставлять с постоянным указателем? Теоретически пока код не подал команду на считывание или запись, то прерывание возникать не должно, но что происходит на практике я не знаю.
Код нормального обработчика прерывания и нулевого выглядит так:
Spoiler:
Code: Select all
align 4
hdd_irq14:
pushfd
cli
pushad
mov [irq14_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popad
popfd
align 4
hdd_irq_null:
ret
Может имеет смысл сделать так:
Spoiler:
Code: Select all
align 4
hdd_irq14_null:
pushfd
cli
pushad
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popad
popfd
ret
align 4
hdd_irq15_null:
pushfd
cli
pushad
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
popad
popfd
ret
З.Ы. На pushad и popad просьба внимание не обращать, я знаю что это "жирно", но это не вопрос данного обсуждения.
Всем чмоки в этом проекте! Засуньте эти 11 лет себе в жопу!
Mario_r4
Лучше всего ставить обработчик через attach_int_handler
для примера клавиатураи исправить Для расшареных PCI IRQ обработчик должен возвращать ненулевое значение, если прерывание было обработано. Для линий ISA IRQ всегда ненулевое.
Лучше всего ставить обработчик через attach_int_handler
для примера клавиатура
Code: Select all
stdcall attach_int_handler, 1, irq1, 0
Code: Select all
align 16
irq_serv:
; .irq_1:
; push 1
; jmp .main
; etc...
irq_serv_h 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15
irq_serv_h 16, 17, 18, 19, 20, 21, 22, 23
purge irq_serv_h
align 16
.main:
save_ring3_context
mov ebp, [esp + 32]
mov bx, app_data;os_data
mov ds, bx
mov es, bx
cmp [v86_irqhooks+ebp*8], 0
jnz v86_irq
cmp bp, 6
jnz @f
push ebp
call [fdc_irq_func]
pop ebp
@@:
; cmp bp, 14
; jnz @f
; push ebp
; call [irq14_func]
; pop ebp
;@@:
; cmp bp, 15
; jnz @f
; push ebp
; call [irq15_func]
; pop ebp
;@@:
bts [irq_active_set], ebp
lea esi, [irqh_tab+ebp*8] ; esi= list head
mov ebx, esi
.next:
Last edited by Serge on Wed Jul 03, 2013 10:13 am, edited 1 time in total.
Serge
Это то и так понятно, ты по теме чего сказать можешь? Могут возникать прерывания без посыла команды?
Это то и так понятно, ты по теме чего сказать можешь? Могут возникать прерывания без посыла команды?
Всем чмоки в этом проекте! Засуньте эти 11 лет себе в жопу!
Какой команды ?
Mario_r4 wrote:В настоящее время, по сути, эти переменные используются как флаги. Однако одновременно с этим меняется и обработчик прерывания.
Так вот вопрос в том правильна ли такая логика. Может стоит сам обработчик оставлять с постоянным указателем? Теоретически пока код не подал команду на считывание или запись, то прерывание возникать не должно, но что происходит на практике я не знаю.
Всем чмоки в этом проекте! Засуньте эти 11 лет себе в жопу!
Mario_r4
Не должно.
Не должно.
Spoiler:
Как совет. Перепиши всю обработку прерываний на драйверную модель и всё сразу упростится. Тем более что для pci irq всё равно надо писать обработчик. Примеров уже много, а если что непонятно, я постараюсь помочь.Меня смущает процедура irq_serv в файле core/irq.inc
Пришлось убрать:
а также добавить:
иначе не работало на некоторых машинах и выдавало на доску "K : warning: relinking handler from IRQ%d to IRQ%d\n".
Так вот это ненормально, если я буду назначать обработчик прерывания при загрузке по факту наличия контроллера. Код то динамически не поменяется ведь, а номер прерывания для SATA IDE меняется, в отличие от PATA IDE.
Также в коде целая портянка глубокомысленных размышлений, не знаю под чьим авторством:
Так жить нельзя! Как быть?
Пришлось убрать:
Code: Select all
cmp ebp, 14
jz .fail
cmp ebp, 15
jz .fail
Code: Select all
cmp ebp, 14
jz .try_next_irq
cmp ebp, 15
jz .try_next_irq
Так вот это ненормально, если я буду назначать обработчик прерывания при загрузке по факту наличия контроллера. Код то динамически не поменяется ведь, а номер прерывания для SATA IDE меняется, в отличие от PATA IDE.
Также в коде целая портянка глубокомысленных размышлений, не знаю под чьим авторством:
Spoiler:
Code: Select all
; There is at least one configuration with one device which generates IRQ
; that is not the same as it should be according to PCI config space.
; For that device, the handler is registered at wrong IRQ.
; As a workaround, when nobody acknowledges the generated IRQ,
; try to ask all other registered handlers; if some handler acknowledges
; the IRQ this time, relink it to the current IRQ list.
; To make this more reliable, for every handler keep number of times
; that it has acknowledged an IRQ, and assume that handlers with at least one
; acknowledged IRQ are registered properly.
; Note: this still isn't 100% correct, because two IRQs can fire simultaneously,
; the better way would be to find the correct IRQ, but I don't know how to do
; this in that case.
; Also, [fdc_irq_func], [irq14_func], [irq15_func] could process interrupt
; but do not return whether they did it, so just ignore IRQs 6, 14, 15.
Всем чмоки в этом проекте! Засуньте эти 11 лет себе в жопу!
Mario
Хак писала Вероника. Имхо в этом случае лучше включить APIC, пусть это и требует некоторых телодвижений.
Ты ставишь обработчики irq 14 и 15 через attach_int_handler ? И возвращаешь ненулевое значение, если прерывание обработано ? А а legacy надо всегда ненулевое. Тебе наверное надо два типа обработчиков, для режима ISA и PCI.
Хак писала Вероника. Имхо в этом случае лучше включить APIC, пусть это и требует некоторых телодвижений.
Ты ставишь обработчики irq 14 и 15 через attach_int_handler ? И возвращаешь ненулевое значение, если прерывание обработано ? А а legacy надо всегда ненулевое. Тебе наверное надо два типа обработчиков, для режима ISA и PCI.
Этот код CleverMouse написала для одного из моих компьютеров (на работе), где без этого кода он зависал: viewtopic.php?f=30&t=2305 (пункт 8 в списке).Mario_r4 wrote:Меня смущает процедура irq_serv в файле core/irq.inc
иначе не работало на некоторых машинах и выдавало на доску "K : warning: relinking handler from IRQ%d to IRQ%d\n".
Также в коде целая портянка глубокомысленных размышлений, не знаю под чьим авторством:Code: Select all
; There is at least one configuration with one device which generates IRQ ; that is not the same as it should be according to PCI config space.
Зачем мне APIC для SATA в режиме эмуляции IDE? А если в компьютере тупо нету APIC?Serge wrote:Имхо в этом случае лучше включить APIC, пусть это и требует некоторых телодвижений.
Да, да, не уверен что всегда. К тому же в eBox весьма странный Native mode на PATA контроллере.Serge wrote:Ты ставишь обработчики irq 14 и 15 через attach_int_handler? И возвращаешь ненулевое значение, если прерывание обработано ? А а legacy надо всегда ненулевое.
Зачем мне ISA? Где ты видел в современных комперах IDE контроллер на ISA? Там только флопик на IRQ6 висит же.Serge wrote:Тебе наверное надо два типа обработчиков, для режима ISA и PCI.
Я еще не разобрался что передается третьим параметром пр