Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Обработка внешнего вектора прерываний PowerPC
Как было описано ранее, процессор переходит по адресу 0x500 в случае внешнего прерывания. Перед тем как продолжить рассмотрение макроса EXCEPTION () в файле head. S, мы рассмотрим следующие строки кода, которые связываются, загружаются Асинхронный поток выполнения и отображаются в память таким образом, чтобы они находились по отступу 0x500. Эта аппаратная таблица переходов работает аналогично ГОТ на х86. arch/ppc/kernel/head.S 453 /* External interrupt */ 454 EXCEPTION(0x500, Hardwarelnterrupt, do_IRQ, EXC_XFER_LITE) Далее вызывается третий параметр, do_IRQ(). Давайте рассмотрим соответствующую функцию. arch/ppc/kernel/irq.с 510 void do_IRQ(struct pt_regs *regs) 511 { 512 int irq, first = 1; 513 irq_enter(); 523 while ((irq = ppc_md.get_irq(regs)) > = 0) { 524 ppc_irq_dispatch_handler(regs, irq); 525 first = 0;
526 } 527 if (irq! = -2 & & first) 528 /* С точки зрения SMP это небезопасно... но кого это волнует? */ 529 ppc_spurious_interrupts++; 531 } Строки 513-530 Сообщают коду приоритетного обслуживания прерываний, что мы находимся внутри аппаратного прерывания. Строка 523 Чтение из контроллера прерываний незаконченного прерывания и преобразование его в номер IRQ (до тех пор, пока не будут обработаны все прерывания). Строка 524 ppc_ircx_dispatch_handler () обрабатывает прерывание. (Мы рассмотрим эту функцию позже.) Функция ppc_irq__dispatch_handler () практически идентична функции do_IRQ () для х86: arch/ppc/kernel/irq.с Глава 3 • Процессы: принципиальная модель выполнения 428 void ppc__irq_dispatch_handler(struct pt_regs *regs, int irg) 429 { 43 0 int status; 431 struct irqaction *action; 432 irq_desc__t *desc = irq_desc + irq; 433
434 kstat_this_cpu.irqs[irq]++; 435 spin_lock(& desc-> lock); 43 6 ack_irq(irq);
441 status = desc-> status & ~(IRQ_REPLAY | IRQ_WAITING); 442 if (! (status & IRQ_PER_CPU)) 443 status |= IRQ_PENDING; /* мы хотим это обработать */ 449 action = NULL; 450 if (likely(! (status & (IRQ__DISABLED | IRQ_INPROGRESS) ) ) ) { 451 action = desc-> action; 452 if (! action ||! action-> handler) { 453 ppc_spurious_interrupts++; 454 printk(KERN_JDEBUG " Unhandled interrupt %x, disabled\n", irq); 455 /* Мы не будем вызывать здесь disable_irq, потому что иначе попадем в тупик */ 456 ++desc-> depth; 457 desc-> status |= IRQ_DISABLED; 458 mask_irq(irq); 459 /* Это настоящее прерывание, находящееся в eoi, 460 к которому мы хотим перейти */ 461 goto out; 462 } 463 status & = ~IRQ_PENDING; /* поручение обработки*/ 464 if (! (status & IRQ_PER_CPU)) 465 status |= IRQ_INPROGRESS; /* мы выполняем обработку */ 466 } 567 desc-> status = status; 489 for (;; ) { 490 spin_unlock(& desc-> lock); 491 handle_irq_event(irq, regs, action); 492 spin_lock(& desc-> lock); 493 494 if (likely(! (desc-> status & IRQ_PENDING))) 495 break; 496 desc-> status & = ~IRQ_PENDING; 497 } 498 out: 499 desc-> status & = -IRQ_INPROGRESS; Асинхронный поток выполнения 511 } Строка 432 Получает IRQ из параметров и получает доступ к соответствующей irq_desc. Строка 435 Получает циклическую блокировку описателя IRQ в случае конкурентного доступа к тому же прерыванию другим процессором. Строка 436 Посылает подтверждение оборудованию. Оборудование реагирует соответствующим образом, предотвращая дальнейшую обработку прерываний этого типа до тех пор, пока обработка данного не будет завершена. Строки 441-443 Очистка флагов IRQ REPLAY и IRQ WAITING. В этом случае IRQ_REPLAY демонстрирует, что IRQ сбрасывается ранее и перепосылается. IRQ WAITING обозначает, что IRQ протестировано. (Оба случая выходят за рамки данного обсуждения.) В однопроцессорных системах устанавливается флаг IRQ_PENDING, который показывает, что мы выполняем обработку прерывания. Строка 450 Этот блок кода проверяет состояние, при котором мы не будем обрабатывать прерывание. Если установлены IRQ DISABLED или IRQ_INPROGRESS, мы можем пропустить этот блок кода. Флаг IRQ_DISABLED устанавливается, когда мы не хотим, чтобы система отвечала на определенную линию IRQ. Указывает, что прерывание будет обрабатываться процессором. Этот флаг используется в том случае, когда второй процессор многопроцессорной системы пытается обработать то же самое прерывание. Строки 451-462 Здесь мы проверяем существование обработчика. Если нет, мы делает перерыв и переходим на метку «out» в строке 498. Строки 463-465 В этой точке мы очищаем все три состояния для необслуживаемых прерываний, как было поручено. Устанавливается флаг IRQ_INPROGRESS, а флаг IRQ PENDING снимается, это означает, что прерывание обработано. Строки 489-497 Здесь производится обслуживание прерываний. Перед обслуживанием прерываний снимается циклическая блокировка с описателя прерывания. После того как бло- Глава 3 • Процессы: принципиальная модель выполнения кировка снята, вызывается вспомогательная функция handle_irq_event (). Эта функция выполняет обработчик прерывания. По завершении снова устанавливается блокировка описателя. Если флаг IRQ PENDING не установлен (другим процессором) во время обработки IRQ, цикл прерывается. В противном случае служба опять прерывается. Обработка прерывания системного таймера PowerPC Как указано в timer_init (), декрементор жестко привязан к 0x900. Мы можем считать, что счетчик терминала достигнут и вызван обработчик timer_interrupt () в arch/kernel/time.с: arch/ppc/kernel/head.S /* Декрементор */ 479 EXCEPTION(0x900, Decremented timer_interrupt, EXC_XFER_LITE) Вот функция timer_interrupt (): arch/ppc/kernel/time.с 145 void timer_interrupt(struct pt_regs * regs) 146 { 152 if (atomic_read(& ppc_n_lost_.interrupts)! = 0) 153 do__IRQ(regs); 155 irq_enter(); 159 if (! user_mode(regs)) 160 ppc_do_profile(instruction_pointer(regs)); 165 write_seqlock(& xtime_lock); 167 do_timer (regs); 189 if (ppc_md.set__rtc_time(xtime. tv_sec+l + time_offset) == 0) 195 write_sequnlock(& xtime_lock); 198 set_dec(next_dec); 208 irq_exit(); 209 } Популярное:
|
Последнее изменение этой страницы: 2016-03-25; Просмотров: 975; Нарушение авторского права страницы