ReactOS源代码分析APIC机制
来源:互联网 发布:乌鲁木齐seo 公司 编辑:程序博客网 时间:2024/06/18 04:21
上图是APIC的组成,其中PIIX3是一个和之前标准中断控制器兼容的中断控制器,而Host-to-PCI桥是系统中与外设相连的桥(可能是北桥)。APIC包含IOAPIC和Local APIC,Local APIC包含在处理器内部,Local APIC用于处理器之间的相互中断,而IOAPIC处于系统芯片组中,IOAPIC用于处理外部IO提交的中断。IOAPIC和Local APIC通过APIC总线进行数据和控制的传送。不过,在IOAPIC和Local APIC之间传递的不是简单地电平信息,所有的中断在IOAPIC中编码成中断消息之后传递给Local APIC。
IOAPIC包含一系列可以变成的寄存器,这些寄存器中的IOREGSEL和IOWIN被编码到处理器的内存地址空间中,同时可以利用这两个寄存器间接访问其他的APIC寄存器。在Windows系统中将Local APIC的地址映射到映射到物理地址0XFFE00000,IOAPIC默认的物理地址是0XFEC00000。当然,物理地址最终还是要调整为虚拟地址进行访问的。Local APIC映射到内存地址空间的虚拟地址为0XFFFE0000,而IOAPIC映射的虚拟地址是0XFFD06000.
为了访问IOAPIC的寄存器,首先写一个字节到IOREGSEL寄存器中。这8位作为IOAPIC中将被访问的寄存器的索引号,而IOWIN寄存器中的数据将被写入到指定的寄存器中,需要注意的是IOWIN被当做一个双字格式进行访问。下表是每个寄存器在IOAPIC中的偏移,而Local APIC中的寄存器相对IOAPIC要多,在英特尔的官方文档的第三册的第十章有介绍。
Local APIC中相应寄存器的偏移在APIC.h头文件中有定义。
APIC系统支持255个中断向量,但是Intel保留了0-15号向量,可用的向量是16-25,同时引进一个概念叫做任务优先级。windows系统中的IRQL等于任务优先级/16,所以可用的优先级是2-15.这个任务优先级存放在本地APIC的任务优先级寄存器TPR中。优先级低于TPR优先级的中断都会被屏蔽,而同一个任务优先级中的16个中断向量可以进一步细粒度地区分中断的优先级。
VOIDFORCEINLINEApicRaiseIrql(KIRQL Irql){ ApicWrite(APIC_TPR, IrqlToTpr(Irql));}
这是提升系统的IRQL的操作,写操作的实现根据上面的介绍很简单.利用APIC_TPR作为偏移,APIC中的IOREGSEL作为基地址,然后将IrqToTpr作为数据存放到IOWIN中,就实现将相应的TPR写入到Local APIC的任务优先级寄存器中。
下面是IOAPIC中关于IO重定位表的定义:
typedef union _IOAPIC_REDIRECTION_REGISTER{ ULONGLONG LongLong; struct { ULONG Long0; ULONG Long1; }; struct { ULONGLONG Vector:8; ULONGLONG DeliveryMode:3; ULONGLONG DestinationMode:1; ULONGLONG DeliveryStatus:1; ULONGLONG Polarity:1; ULONGLONG RemoteIRR:1; ULONGLONG TriggerMode:1; ULONGLONG Mask:1; ULONGLONG Reserved:39; ULONGLONG Destination:8; };} IOAPIC_REDIRECTION_REGISTER;
通过上面的定义可以发现,整个IO重定位表一项包含8个字节。最低8位表示中断向量,正好是256项。然后三位表示中断的发送模式,主要定义目标对中断的相应操作。接下来一位用于指示最高8位怎样指定处理中断的目标,因为有可能需要指定处理中断的处理器。而发送状态位则指示整个中断发送之后的状态。polarity设置中断激发的电平。remoteIRR则用于设置水平激发的中断,当IOAPIC接受中断的时候,设置这个位为1,在中断处理之后设置这个位为0.TriggerMode则用于指示激发模式。Mask则用于设置这个中断是否被屏蔽。
BOOLEANNTAPIHalEnableSystemInterrupt( IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode){ IOAPIC_REDIRECTION_REGISTER ReDirReg; PKPRCB Prcb = KeGetCurrentPrcb(); UCHAR Index; Index = HalpVectorToIndex[Vector]; if (Index == 0xff) { return FALSE; } ReDirReg = ApicReadIORedirectionEntry(Index); if (ReDirReg.Vector != Vector) { ReDirReg.Vector = Vector; ReDirReg.DeliveryMode = APIC_MT_LowestPriority; ReDirReg.DestinationMode = APIC_DM_Logical; ReDirReg.Destination = 0; } if (ReDirReg.DestinationMode == APIC_DM_Logical) { ReDirReg.Destination |= ApicLogicalId(Prcb->Number); } ReDirReg.TriggerMode = 1 - InterruptMode; ReDirReg.Mask = FALSE; ApicWriteIORedirectionEntry(Index, ReDirReg); return TRUE;}
上面是对APIC中的中断重定位表的设置,首先读取原来的IO重定位表,如果和现在的目标向量不对应则重新设置中断向量,以及发送模式和目标,最后将修改后的重定位表填充到APIC的表项当中。
KIRQLFASTCALLHalpVectorToIrql(UCHAR Vector){ return TprToIrql(Vector);}UCHARFASTCALLHalpVectorToIrq(UCHAR Vector){ return HalpVectorToIndex[Vector];}上面两个函数体现了中断向量和IRQL以及中断信号的管理。TprToIrql通过将Vector除以16得到索引号寻找数组当中的Irql,实质上这里的vector更像是一个任务优先级。而Vector也会有一个函数将其进行一定的映射,得到IDT表项的入口索引,在中断发生的时候作为IDT的索引查找系统中的中断处理向量。
- ReactOS源代码分析APIC机制
- ReactOS分析windows APC机制
- ReactOS分析windows DPC机制(1)
- 根据ReactOS源代码分析windows蓝屏处理过程
- Linux APIC 详细分析
- Linux APIC 详细分析
- APIC
- ReactOS分析CriticalSection
- ReactOS分析MDL实现
- 毛德操老师重磅著作::Windows 内核情景分析--采用开源代码ReactOS
- Lenix消息机制源代码分析
- ReactOS实践(一) ReactOS 源代码编译以及VMWare下运行
- Jbpm Delegation机制源代码分析和实例
- linux epoll机制源代码分析一数据结构
- Zookeeper源代码阅读分析之watcher机制
- dubbo 配置管理机制以及源代码分析
- hadoop 2.6 Trash清除机制源代码分析
- Android 消息机制原理 (源代码分析)
- LAMP-网站架构
- eclipse反编译插件jad myeclipse2013实测
- leveldb源码解析1——内存管理类Arena
- 【OpenCV学习笔记】【函数学习】十六(Rect参数介绍)
- xcode6中自动布局autolayout和sizeclass的使用
- ReactOS源代码分析APIC机制
- 在 Mac OS X 中启用和使用“root”用户
- uva11129
- WARNING: Failed to set buffer limit on IPC interconnect socket
- uva 11129(二分)
- HDU 5003 Osu!(数学题)
- ElasticSearch 权威指南
- 下划线EditText-UnderlineEditText-笔记
- 大话设计模式总结