Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1299688
  • 博文数量: 554
  • 博客积分: 10425
  • 博客等级: 上将
  • 技术积分: 7555
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-09 09:49
文章分类

全部博文(554)

文章存档

2012年(1)

2011年(1)

2009年(8)

2008年(544)

分类:

2008-04-11 15:17:20


设备内存
第7 章• 设备访问:程控I/O 119
示例7–1 映射设置(续)
*/
dev_acc_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
dev_acc_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
/*
* Map in the csr register (register 0)
*/
if (ddi_regs_map_setup(dip, CSR_REG, (caddr_t *)&(pio_p->csr), 0,
sizeof (Pio_csr), &dev_acc_attr, &pio_p->csr_handle) != DDI_SUCCESS) {
mutex_destroy(&pio_p->mutex);
ddi_soft_state_free(pio_softstate, instance);
return (DDI_FAILURE);
}
/*
* Map in the data register (register 1)
*/
if (ddi_regs_map_setup(dip, DATA_REG, (caddr_t *)&(pio_p->data), 0,
sizeof (uchar_t), &dev_acc_attr, &pio_p->data_handle) \
!= DDI_SUCCESS) {
mutex_destroy(&pio_p->mutex);
ddi_regs_map_free(&pio_p->csr_handle);
设备内存
120 编写设备驱动程序• 2006 年11 月
示例7–1 映射设置(续)
ddi_soft_state_free(pio_softstate, instance);
return (DDI_FAILURE);
}
设备访问函数
驱动程序结合使用ddi_get8(9F) 和ddi_put8(9F) 系列例程以及ddi_regs_map_setup(9F) 返回
的句柄,以与设备相互传送数据。DDI 框架自动处理为满足主机或设备的字节序格式所需
的任何字节交换,并强制实施设备可能具有的任何存储排序约束。
DDI 提供了用于传送8 位、16 位、32 位和64 位数据的接口,以及用于重复传送多个值的接
口。有关这些接口的完整列表和说明,请参见
ddi_get8(9F)、ddi_put8(9F)、ddi_rep_get8(9F) 和ddi_rep_put8(9F) 系列例程的手册页。
以下示例建立在示例7–1 的基础上。在示例7–1 中,驱动程序映射了设备的CSR 寄存器和
数据寄存器。在本示例中,调用驱动程序的write(9E) 入口点时,会将数据缓冲区写入(每
次一个字节)设备。
示例7–2映射设置:缓冲区
static int
pio_write(dev_t dev, struct uio *uiop, cred_t *credp)
{
int retval;
int error = OK;
Pio *pio_p = ddi_get_soft_state(pio_softstate, getminor(dev));
if (pio_p == NULL)
return (ENXIO);
mutex_enter(&pio_p->mutex);
设备访问函数
第7 章• 设备访问:程控I/O 121
示例7–2 映射设置:缓冲区(续)
/*
* enable interrupts from the device by setting the Interrupt
* Enable bit in the devices CSR register
*/
ddi_put8(pio_p->csr_handle, pio_p->csr,
(ddi_get8(pio_p->csr_handle, pio_p->csr) | PIO_INTR_ENABLE));
while (uiop->uio_resid > 0) {
/*
* This device issues an IDLE interrupt when it is ready
* to accept a character; the interrupt can be cleared
* by setting PIO_INTR_CLEAR. The interrupt is reasserted
* after the next character is written or the next time
* PIO_INTR_ENABLE is toggled on.
*
* wait for interrupt (see pio_intr)
*/
cv_wait(&pio_p->cv, &pio_p->mutex);
/*
* get a character from the user’s write request
* fail the write request if any errors are encountered
*/
设备访问函数
122 编写设备驱动程序• 2006 年11 月
示例7–2 映射设置:缓冲区(续)
if ((retval = uwritec(uiop)) == -1) {
error = retval;
break;
}
/*
* pass the character to the device by writing it to
* the device’s data register
*/
ddi_put8(pio_p->data_handle, pio_p->data, (uchar_t)retval);
}
/*
* disable interrupts by clearing the Interrupt Enable bit
* in the CSR
*/
ddi_put8(pio_p->csr_handle, pio_p->csr,
(ddi_get8(pio_p->csr_handle, pio_p->csr) & ~PIO_INTR_ENABLE));
mutex_exit(&pio_p->mutex);
return (error);
}
设备访问函数
第7 章• 设备访问:程控I/O 123
备用设备访问接口
除通过ddi_get8(9F) 和ddi_put8(9F) 接口系列实现所有设备访问之外,Solaris OS 还提供特
定于特殊总线实现的接口。虽然在某些平台上这些函数会更加有效,但使用这些例程会限
制驱动程序在设备的各总线版本间保持可移植的能力。
访问内存空间
对于内存映射访问,设备寄存器会出现在内存地址空间中。驱动程序可以将ddi_getX 系列
例程和ddi_putX 系列用作标准设备访问接口的备用接口。
访问I/O 空间
对于I/O 空间访问,设备寄存器会出现在I/O 空间中,其中每个可寻址元素都称为I/O 端
口。驱动程序可以将ddi_io_get8(9F) 和ddi_io_put8(9F) 例程用作标准设备访问接口的备
用接口。
PCI 配置空间访问
要在不使用常规设备访问接口的情况下访问PCI 配置空间,驱动程序需要通过调用
pci_config_setup(9F)(而非ddi_regs_map_setup(9F))来映射PCI 配置空间。然后,驱动
程序可以调用pci_config_get8(9F) 和pci_config_put8(9F) 接口系列,以访问PCI 配置空
间。
设备访问函数
124 编写设备驱动程序• 2006 年11 月
中断处理程序
本章介绍用于处理中断的机制,如注册、服务以及删除中断。本章提供有关以下主题的信
息:
 第125 页中的“中断处理程序概述”
 第125 页中的“设备中断”
 第131 页中的“注册中断”
 第143 页中的“中断处理程序的职责”
 第145 页中的“处理高级别中断”
中断处理程序概述
中断是指设备发送给CPU 的硬件信号。中断将通知CPU 需要注意设备,并且CPU 应该停
止任何当前活动并对设备进行响应。如果CPU 可用,即未执行具有较高优先级的任务,则
CPU 会暂停当前线程。然后,CPU 会调用此设备的中断处理程序。中断处理程序的工作是
服务设备并防止此设备中断。处理程序返回后,CPU 便会恢复出现中断之前的活动。
DDI/DKI 提供了用于注册和服务中断的接口。已添加了新接口,用于执行以下任务:
 确定中断类型和注册要求
 屏蔽中断
 获取中断待处理信息
 获取和设置优先级信息
设备中断
I/O 总线以两种常用方法来实现中断:向量化和轮询。这两种方法通常都会提供总线中断优
先级别。向量化设备还会提供中断向量。轮询设备则不提供中断向量。
为了与不断发展的总线技术保持同步,Solaris OS 已经得到了增强,可适应更新类型的中断
以及已经使用多年的较为传统的中断。具体来说,操作系统目前可识别三种类型的中断:
8第8 章
125
 传统中断-传统或固定中断是指使用早期总线技术的中断。使用这些技术,可通过一个
或多个“带外”(即,独立于总线的主线)连线的外部管脚来发送信号,告知出现中断。
较新的总线技术(如PCI Express)通过带内机制模拟传统中断来维持软件兼容性。主机
OS 将这些模仿中断视为传统中断。
 消息告知中断-消息告知中断(message-signalled interrupt, MSI) 使用带内消息而不是使用
管脚,可在主桥(host bridge) 中确定中断的地址。(有关主桥(host bridge) 的更多信息,
请参见第550 页中的“PCI 局部总线”。)MSI 可以将数据与中断消息一起发送。每个
MSI 都不是共享的,这样可以保证指定给某一设备的MSI 在系统中是唯一的。一个PCI
函数最多可以请求32 条MSI 消息。
 扩展消息告知中断-扩展消息告知中断(Extended message-signalled interrupt, MSI-X) 是
MSI 的增强版本。MSI-X 中断具有以下新增的优点:
 支持2048 条而不是32 条消息
 针对每条消息支持独立的消息地址和消息数据
 支持按消息屏蔽
 软件分配的向量少于硬件请求的向量时可具有更大灵活性。软件可以在多个MSI-X
插槽中重用相同的MSI-X 地址和数据。
注– 一些较新的总线技术(如PCI Express)要求使用MSI,但是可以使用INTx 仿真来处理
传统中断。INTx 仿真是为了兼容,但是这并不是一种好的做法。
高级别中断
总线会在总线中断级别设置设备中断的优先级。然后,总线中断级别将映射到处理器中断
级别。映射到高于调度程序优先级别的CPU 中断优先级的总线中断级别称为高级别中断。
高级别中断处理程序仅限于调用以下DDI 接口:
 使用与高级别中断关联的iblock cookie 初始化的互斥锁上的mutex_enter(9F) 和
mutex_exit(9F)
 ddi_intr_trigger_softint(9F)
 ddi_getX/ddi_putX 系列的例程
总线中断级别本身无法确定设备是否会发生高级别中断:给定的总线中断级别可以在一个
平台上映射到高级别中断,而在其他平台上映射到普通中断。
虽然驱动程序可以选择是否支持带有高级别中断的设备,但是会始终要求驱动程序检查中
断级别。函数ddi_intr_get_hilevel(9F) 可返回对应于高级别中断的最低优先级别。可以将
该值与来自ddi_intr_get_pri(9F) 的其他优先级值进行比较,以确定其他优先级值是否实际
为高级别中断。
设备中断
126 编写设备驱动程序• 2006 年11 月
传统中断
系统仅有的有关设备中断的信息为总线中断的优先级别(例如,SPARC 计算机中S 总线上
的IPL)和中断请求编号(例如,x86 计算机中ISA 总线上的IRQ)。
注册中断处理程序之后,系统会将其添加到每个IPL 或IRQ 的潜在中断处理程序的列表
中。出现中断时,系统必须确定与给定的IPL 或IRQ 关联的所有设备中实际导致此中断的
设备。系统会针对指定的IPL 或IRQ 调用所有中断处理程序,直到一个处理程序声明中断
为止。
以下总线可以支持轮询中断:
 S 总线
 ISA
 PCI
标准消息告知中断和扩展消息告知中断
标准(MSI) 和扩展(MSI-X) 消息告知中断均作为带内消息实现。消息告知中断可作为使用软
件指定的地址和值的写操作进行发送。
MSI 中断
常规PCI 规范包括可选的消息告知中断(Message Signaled Interrupt, MSI) 支持。MSI 中断是
作为发送的写操作实现的带内消息。MSI 的地址和数据由软件指定,并特定于主桥(host
bridge)。由于消息是带内消息,因此消息的接收可用于“推送”与中断关联的数据。根据定
义,MSI 中断是独享的。指定给设备的每条MSI 消息保证在系统中均为唯一消息。PCI 函数
可以请求1 到32 条MSI 消息,以2 的幂形式表示。请注意,系统软件为函数分配的MSI 消
息数可以少于函数所请求的数量。可限制主桥(host bridge) 中为设备分配的唯一MSI 消息的
数量。
MSI-X 中断
MSI-X 中断是MSI 中断的增强版本。使用MSI-X,函数最多可以分配2048 条消息。MSI-X
消息相互独立。
通过MSI-X 中断,未分配的中断向量允许使用相同的MSI 地址/数据对和中断处理程序,该
中断处理程序的参数和之前设置的中断向量一样。在此类情况下,请使用
ddi_intr_dup_handler(9F) 获取新的中断句柄。
软件中断
Solaris DDI/DKI 支持软件中断,也称为软中断。软中断通过软件而不是硬件设备启动。另
外,还必须在系统中添加和删除这些中断的处理程序。软中断处理程序在中断上下文中运
行,因此可用于执行许多属于中断处理程序的任务。
 
 
 

以上文章转自于 : http://developers.sun.com.cn/
阅读(506) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~