Chinaunix首页 | 论坛 | 博客
  • 博客访问: 44603
  • 博文数量: 37
  • 博客积分: 1676
  • 博客等级: 上尉
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-09 23:21
文章分类
文章存档

2010年(37)

我的朋友

分类: LINUX

2010-05-09 23:23:36

URN Logo
 »  »  »  »  » setup_IO_APIC末尾处,check_timer是啥意思啊?
announcement 声明: 本页内容为的内容镜像,文章的版权以及其他所有的相关权利属于和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
(finished)
(finished)
(finished)
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  系统和网络安全
  
  
  
  
  
  
  
  
  
  
  
  
  
setup_IO_APIC末尾处,check_timer是啥意思啊?
 -  [2007-11-26 18:12 | 5,256 byte(s)]
 
 -  [2007-11-27 09:59 | 5,137 byte(s)]
 
Subjectsetup_IO_APIC末尾处,check_timer是啥意思啊? 
Author    Posted2007-11-26 18:12    Length5,256 byte(s)
[] [Print] 
我列的是2.4.32版,代码如下 


static inline void check_timer(void)
{
extern int timer_ack;
int pin1, pin2;
int vector;

disable_8259A_irq(0);
vector = assign_irq_vector(0);
set_intr_gate(vector, interrupt[0]);

apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1);
timer_ack = 1;
enable_8259A_irq(0);

pin1 = find_isa_irq_pin(0, mp_INT);
pin2 = find_isa_irq_pin(0, mp_ExtINT);

printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d ", vector, pin1, pin2);

if (pin1 != -1) {
unmask_IO_APIC_irq(0);
if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) {
disable_8259A_irq(0);
setup_nmi();
enable_8259A_irq(0);
check_nmi_watchdog();
}
return;
}
clear_IO_APIC_pin(0, pin1);
printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC ");
}

printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
if (pin2 != -1) {
printk(" ..... (found pin %d) ...", pin2);
setup_ExtINT_IRQ0_pin(pin2, vector);
if (timer_irq_works()) {
printk("works. ");
if (pin1 != -1)
replace_pin_at_irq(0, 0, pin1, 0, pin2);
else
add_pin_to_irq(0, 0, pin2);
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
check_nmi_watchdog();
}
return;
}
clear_IO_APIC_pin(0, pin2);
}
printk(" failed. ");

if (nmi_watchdog) {
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI
Watchdog! ");
nmi_watchdog = 0;
}

printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");

disable_8259A_irq(0);
irq_desc[0].handler = &lapic_irq_type;
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
enable_8259A_irq(0);

if (timer_irq_works()) {
printk(" works. ");
return;
}
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
printk(" failed. ");

printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");

init_8259A(0);
make_8259A_irq(0);
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);

unlock_ExtINT_logic();

if (timer_irq_works()) {
printk(" works. ");
return;
}
printk(" failed
src="http://www.linuxforum.net/forum/images/icons/frown.gif">. ");
panic("IO-APIC + timer doesn't work! pester
}






以下根据我个人的理解: 

进入时的初始状态是 
1) BP的LINT0启用,AP的LINT0屏蔽 
2) IO APIC 中,所有对应mp_INT的管脚启用,所有对应mp_ExtINT的管脚屏蔽 
3) 8259中,部分未连接至IO APIC,只连接至8259的IRQ启用 

函数check_timer的流程是: 

第一部分: 假设,Timer作为mp_INT,连接至IO APIC。 
操作,Local APIC的LINT0屏蔽,IO APIC的pin1作为mp_INT启用,8259的IRQ0启用 
疑问,为什么8259的IRQ0启用?谁来给8259一个INTA信号? 

第二部分: 假设,BIOS错误,timer事实上作为mp_INT连接至IO 
APIC,但mp_floating_table中显示的是Ext_INT。 
对应,printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A 
... "); 
操作,Local APIC的LINT0屏蔽,IO 
APIC的pin2作为mp_INT启用,8259的IRQ0启用 
疑问,为什么8259的IRQ0启用?而且这个假设和printk中的提示不是驴唇不对马嘴么? 

第三部分: 假设,Timer直连BP的LINT0。 
对应,printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); 
操作,Local APIC的LINT0作为Fixed启用,而不是作为ExtINT,IO 
APIC的pin1和pin2屏蔽,8259的IRQ0启用 
疑问,为什么8259的IRQ0启用?而且这个假设和printk中的提示驴唇不对马嘴。 

第四部分: 假设,Timer连8259,8259连BP的LINT0。 
对应,printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); 
操作,Local APIC的LINT0作为Ext_INT启用,IO 
APIC的pin1和pin2屏蔽,8259的IRQ0启用 

疑问,这次我到是明白为什么启用8259,但是问题在于随后的unlock_ExtINT_logic,注释的意思� 
孟笫鞘止じ�8259一个INTA,这是为什么?而且这个假设和printk中的提示驴唇不对马嘴。 

[] [Print] 
SubjectRe: setup_IO_APIC末尾处,check_timer是啥意思啊? 
Author    Posted2007-11-27 09:59    Length5,137 byte(s)
[] [Print] 
我以前的注释,自己也忘了什么意思了,呵呵 


/*
* This code may look a bit paranoid, but it's supposed to cooperate with
* a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
* is so screwy. Thanks to Brian Perkins for testing/hacking this beast
幸运的是只有定时器IRQ有点怪僻的
* fanatically on his truly buggy board.
*/
static inline void check_timer(void)
{
extern int timer_ack;
int pin1, pin2;
int vector;

/*
* get/set the timer IRQ vector:
*/
disable_8259A_irq(0);
vector = assign_irq_vector(0);
set_intr_gate(vector, interrupt[0]);

/*
* Subtle, code in do_timer_interrupt() expects an AEOI
* mode for the 8259A whenever interrupts are routed
* through I/O APICs. Also IRQ0 has to be enabled in
* the 8259A which implies the virtual wire has to be
* disabled in the local APIC.
*/
//禁用LVT0
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1);//aeoi
timer_ack = 1;//需要ack
enable_8259A_irq(0);//enable,但是LVT0和ioapic被禁用

pin1 = find_isa_irq_pin(0, mp_INT);
pin2 = find_isa_irq_pin(0, mp_ExtINT);

//..TIMER: vector=0x31 pin1=2 pin2=0
/*
index type irqtype irqflag srcbus srcbusirq dstapic dstirq trigg IRQ Vec
5 03 03(Ext) 05 00 02 00 04 00 edge 00
7 03 00 05 00 02 00 04 02 edge 00 31
*/
printk(KERN_INFO "..TIMER: vector=%d pin1=%d pin2=%d ", vector, pin1, pin2);

if (pin1 != -1) {
/*说明IRQ0是通过IOAPIC
* Ok, does IRQ0 through the IOAPIC work?
*/
unmask_IO_APIC_irq(0);//开启中断,重定向表已经在前面设定了
if (timer_irq_works()) {
if (nmi_watchdog) {
disable_8259A_irq(0);
setup_nmi();//并不还原,??????????
enable_8259A_irq(0);
nmi_irq_works();
}
return;
}
//失败,清除重定向表
clear_IO_APIC_pin(0, pin1);
//..MP-BIOS bug: 8254 timer not connected to IO-APIC
//...trying to set up timer (IRQ0) through the 8259A ...
//..... (found pin 0) ...works.

//MPBIOS的配置指出了,怎么会是bug?
printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC ");
}

printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
if (pin2 != -1) {//主8259A的INTR接到pin上
printk(" ..... (found pin %d) ...", pin2);
/*
* legacy devices should be connected to IO APIC #0
*/
//通过ExtInt试图开启timer
setup_ExtINT_IRQ0_pin(pin2, vector);
if (timer_irq_works()) {
printk("works. ");
if (nmi_watchdog) {
setup_nmi();
nmi_irq_works();
}
return;
}
/*
* Cleanup, just in case ...
*/
//失败,清除重定向表
clear_IO_APIC_pin(0, pin2);
}
printk(" failed. ");

if (nmi_watchdog) {
printk(KERN_WARNING "timer doesnt work through the IO-APIC - disabling NMI
Watchdog! ");
nmi_watchdog = 0;
}

printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");

disable_8259A_irq(0);
irq_desc[0].handler = &lapic_irq_type;
//假设IRQ0直接连在line0上,目前只有timer(IRQ0)被启用
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
enable_8259A_irq(0);

if (timer_irq_works()) {
printk(" works. ");
return;
}
//禁用
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
printk(" failed. ");

printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");

init_8259A(0);//no aeoi
make_8259A_irq(0);
//假设IRQ0通过8259A连在line0上,目前只有timer(IRQ0)被启用
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);

//??????启动ExtInt模式
unlock_ExtINT_logic();

if (timer_irq_works()) {
printk(" works. ");
return;
}
printk(" failed
src="http://www.linuxforum.net/forum/images/icons/frown.gif">. ");
panic("IO-APIC + timer doesn't work! pester
}
----
Good better best,never let it rest.
[] [Print] 
« Previous thread 
 
Next thread » 
   

Copyright © 2007~2009 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
webmaster: 
This page created on 2009-09-07 16:26:33, cost 0.0204310417175 ms.
阅读(1259) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:nmi watchdog &panics

给主人留下些什么吧!~~