首页
社区
课程
招聘
[求助]关于多核系统下修改中断频率问题
发表于: 2011-3-28 10:11 7972

[求助]关于多核系统下修改中断频率问题

2011-3-28 10:11
7972
最近做一个项目,需要修改系统中断频率,让时钟中断周期由原来的15ms左右(我电脑上是这个值)降到100us的级别。
    我打印出I/O APIC中的时钟中断对应的重定向表显示中断向量为D1(通过挂钩IDT,已验证),并且此中断只发给cpu0.所以我以为系统时钟中断一定是8254的中断先发给I/O APIC,然后再发给Local APIC,最后发给CPU。那么我只要修改8254的频率即可。然后我按照8254的编程规范修改其通道0的计时器初值(实验中,我发现系统原先的计数值在1028左右,8254的频率好像是1.9M左右,那么这么算下来就是0.5—1ms一次,目前我了解的就这么多,至于现今多核CPU中的具体情况,实在找不到资料,希望大牛能指点小弟),修改初值成功,但是我在应用程序中验证的时候,中断延迟还是15ms左右,一点变化都没有,苦恼啊。。。
    还有一点就是每个cpu的Local APIC中都有定时计数器(查资料说它的Clk是基于总线频率的,并且我打印出计数器初值,显示200000000,改变此值对时钟中断以及计数的函数没有发现有任何影响),并且在FFE00380处有它对应的中断向量,我打印它的中断向量,发现它的中断号是FD,但是我挂钩IDT中对应的FD的例程,没有任何反映,不知道这个定时中断是干什么的?
    目前我实在是无计可施了,希望懂此的大牛指点小弟啊,拜谢拜谢

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
怎么没人回复啊,我要悲剧了。。。
2011-3-28 11:15
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
已解决,哈哈!
2011-4-6 21:23
0
雪    币: 50
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
怎么解决的?共享下吧。
2011-4-6 21:55
0
雪    币: 401
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你都已经解决了我再回帖是不是很招人鄙视。。。简单说一下我的理解吧。

8254的三个通道的时钟输入CLK不是CPU输出的CLK,而是PCLK,频率大概是1.19318MHz,通道0就是用于系统计时的,初始化代码如下:
mov        al, 36h
out         43h, al
mov        al, 0
out         40h, al
out         40h, al
首先向43h端口发送数据36h,这个端口是8254的方式控制寄存器,格式如下:

│7│6│5│4│3│2│1│0│  Mode Control Register
   │ │  │  │  │  │   │  └──── 0=16 binary counter, 1=4 decade BCD counter
   │ │  │  │  └  ┴ ─┴───── counter mode bits
   │ │  └─┴────────── read/write/latch format bits
   └─┴───────────── counter select bits (also 8254 read back command)

所以36h的含义是,计数器选择的是计时器0、写16位计数器、方式3、格式是二进制,方式3指的是OUT端输出方波,当设置了要计数的值之后,在下一个CLK下降沿就开始递减计数,然后向40h即通道0送了两个数据0,因为是递减计数,所以其实数据应该是2^16=65536,显然是在计时65536个PCLK,65536 * 1 / 1.19318MHz = 0.054925……,大概55ms,用于计时24小时的话会有误差,所以在主8259的IR0中断例程中修正了0B0h个PCLK……

结合这一个再看一下8254通道1的设置就可以了,通道1是用于系统刷新DRAM的,假设刷新时间为15微秒,初始化例程就像下面这样写:
mov        al, 54h
out         43h, al
mov        al, 12h
out         41h, al

18 * 1 / 1.19318MHz = 15.086 微秒....
2011-4-7 08:02
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
5楼分析的我已试过,只修改它的话在当前多核系统下是没有用的,因为多核系统下,8254连接到IOAPIC中的IRQ2,我打印出它的中断重定向表的64位重定向表项是:0x100FF(低32位),0x6F000000(高32位),第17位为1表示此中断是屏蔽的,所以我之前修改8254的通道一的计数寄存器是没有效果的。在IOAPIC中时钟中断对应的是IRQ8,我打印出它对应的64位重定性表项是:0x8D1(低32位),0x1000000(高32位,它的高8位为1表示只把时钟中断发给主CPU,然后)。所以我把IRQ8的64位重定向表copy到IRQ2中,然后把IRQ8对应的屏蔽位(第十七位)置为1,这样就屏蔽了原来的时钟中断。设置好上述两个重定向表项,然后对8254进行编程即可实现任意时钟周期。
     试验中,我把时钟周期由原来的15ms改为1ms后,前端的界面那些小动画忽忽的闪啊,而且双击基本用不了了(必须点的足够块才有双击效果)。玩dota时,有点小问题,显示我开始游戏后就秒了,悲剧啊。通过上述观察,已基本确定时钟频率已修改。但是目前我还没有找到一种能通过正规的编程来验证它,正在寻觅中,有哪位达人有什么好想法然后告诉我,先在此拜谢
2011-4-7 11:31
0
雪    币: 401
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
IOAPIC没接触过,只在DOS下对8254编过程,建议翻一下BIOS代码看有帮助没,也或许是OS的原因?

PS:IOAPIC指的是82093AA么?Intel有它的手册可以下载,或许有帮助:http://www.intel.com/design/chipsets/datashts/29056601.pdf
2011-4-7 13:24
0
游客
登录 | 注册 方可回帖
返回
//