龙芯软件开发(24)-- PCI设备初始化2_龙芯pci中断绑定-程序员宅基地

技术标签: 嵌入式软件开发  

龙芯软件开发(24)-- PCI设备初始化2

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/caimouse/article/details/1483128
在汇编的代码里,已经进行了串口初始化,在这里更进一步初始化串口,它是通过调用下面的代码实现的:
#define SUPERIO_CFG_REG 0x85
上面定义南桥里串口寄存器地址。
 
static void initSerial(void)
{
    pcitag_t tag;
    char confval,val;
    /* 使能串口
     * 这个需要在汇编代码serialinit中设置
     * */
#define E2_EPP 2
#define E2_S1 (1<<2)
#define E2_S2 (1<<3)
#define E2_FLOPPY (1<<4)
    /* 配置super io*/
    tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, VTSB_ISA_FUNC);
    confval=_pci_conf_readn(tag,SUPERIO_CFG_REG,1);
    _pci_conf_writen(tag,SUPERIO_CFG_REG,confval|2,1);  
上面根据 VT82C686B 来操作,主要是设置 SUPER IO 能配置,也就是设置 0x85 寄存器的第二位为 1 时为开始配置。根据 VT82C686B 的操作流程如下:
第一步,设置 0x85 寄存器的第二位的为 1 时可以配置。
第二步,写一个要操作的索引到 0x3F0 ,然后写配置的数据到 0x3F1 。当要配置多端口时,可以重复地写不同的索引和配置。
第三步,设置 0x85 寄存器的第二位的为 0 时结束配置。
 
 
#ifdef HIGH_SPEED_SERIAL
    linux_outb(0xee,0x3f0);
    val=linux_inb(0x3f1);
    linux_outb(val|0xc0,0x3f1); /* both ports on high speed*/
#endif
   
#if 0
    outb(PCI_IO_SPACE_BASE+0x3f0,0xe7);
    outb(PCI_IO_SPACE_BASE+0x3f1,(COM1_BASE_ADDR-PCI_IO_SPACE_BASE)>>2); /* com1 serial base address*/
 
    outb(PCI_IO_SPACE_BASE+0x3f0,0xe8);
    outb(PCI_IO_SPACE_BASE+0x3f1,(COM2_BASE_ADDR-PCI_IO_SPACE_BASE)>>2); /* com2 serial base address*/
#endif
 
    linux_outb(0xe2,0x3f0);
    val=linux_inb(0x3f1);
    linux_outb(val|E2_S2|E2_S1,0x3f1);
    _pci_conf_writen(tag,SUPERIO_CFG_REG,confval,1);
上面操作索引为 0xE2 ,设置的配置值的意思是打开并口为 EPP 模式,串口 1 和串口 2 打开,并且软驱打开。
 
    printf("0x3f8=%x/n",linux_inb(0x3f0));
上面显示 0x3F0 的值。
 
}
 
接着来看初始化键盘,
static void init_keyboard(void)
{
    pcitag_t tag;
    tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, VTSB_ISA_FUNC);
    _pci_conf_writen(tag,0x5a,0xff,1);
}
上面是打开键盘和 RTC 的功能,打开声音功能,打开 SD 数据线 4—7 的信号为 1 。
 
接着下来,就是初始化 IDE 端口的功能了,在龙芯里 IDE 主要接硬盘和光驱。它的代码如下:
#define IDE_CHIPEN_REG 0x40
#define IDE_CFG_REG 0x41
static void initIDE(void)
{
    pcitag_t tag;
    char val;
    /* 南桥外设默认都是非使能状态,我们这里将其一一使能*/
    /* 硬盘使能*/
#if 1
       /* IDE controller enable */
       tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, VTSB_ISA_FUNC);
       val=_pci_conf_readn(tag,0x48,1);
       val=val & ~2;
       _pci_conf_writen(tag,0x48,val,1);
上面打开 IDE 功能,由于南桥里定义 0 为使用,所以上面置第二位的值为 0 。
 
       /* IDE IRQ Route */
       val=_pci_conf_readn(tag,0x4a,1);
       val=(val&0xf0)|0x4;
       _pci_conf_writen(tag,0x4a,val,1);
上面设置第一个 IDE 使用 14 号中断源,第二个 IDE 使用 15 号中断源。
 
#endif
 
       tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, VTSB_IDE_FUNC);
 
       /* enable IO space */
       _pci_conf_writen(tag,0x04,7,1);
       上面使用 IO 空间,使用内存空间并设置为总线主设备。
 
       /* set to compatible mode */
       _pci_conf_writen(tag,0x09,0x8A,1);
       上面全部设置为固定模式。也就是主 IDE 的命令寄存器是 0x1F0—0x1F7 ,从 IDE 的命令寄存器是 0x170—0x177 。
 
       /* latency */
       _pci_conf_writen(tag,0x0d,0xd0,1);
       上面设置 RTC 时钟使用 VBAT 电压。
 
       /* set to legacy interrupt */
       _pci_conf_writen(tag,0x3d,0x00,1);
       上面设置中断方式为一般方式。
 
 
       /* enable primary/secondary channel */
       _pci_conf_writen(tag,0x40,0xb,0x1);   
       上面打开 IDE 第一和第二通道。
 
 
       /* disable prefetch buffer & post write buffer */
       _pci_conf_writen(tag,0x41,0x2,0x1);   
       _pci_conf_writen(tag,0x43,0xa,0x1);   
       上面关闭所有 IDE 缓冲区,配置 FIFO 的最大值为一半。
 
 
       /* set zero wait state for master read/write
        * to make ict nb happy
        */
       _pci_conf_writen(tag,0x44,0x0,1); 
       上面设置读写等待信号为 0 电平。
 
 
 
       /* disable memory read multiple/memory write and invalidate
        */
       _pci_conf_writen(tag,0x45,0x0,1); 
       上面关闭内存读写多个命令。
 
#if 1
       _pci_conf_writen(tag, 0x10, 0x1f1,4);
       上面设置第一个 IDE 的命令基地址为 0x1F1.
 
       _pci_conf_writen(tag, 0x14, 0x3f5,4);
       上面设置第一个 IDE 的控制和状态寄存器的基地址为 0x3F5 。
 
       _pci_conf_writen(tag, 0x18, 0x171,4);
       _pci_conf_writen(tag, 0x1c, 0x375,4);
       上面设置第二个 IDE 的命令和状态基地址。
 
 
       _pci_conf_writen(tag, 0x20, 0xcc1,4);
       上面设置总线控制的基地址。
 
#endif
 
}
 
接着初始化中断控制,代码如下:
#define IRQ_ROUTE_REG1 0x51
#define IRQ_ROUTE_REG2 0x52
#define IRQ_ROUTE_REG4 0x55
#define IRQ_ROUTE_REG5 0x56
#define IRQ_ROUTE_REG6 0x57
#define PCI_IRQ_TYPE_REG 0x54
#define IRQ(x) x
#define PARALLEL_IRQ     (IRQ(7)<<4)
#define FLOPPY_IRQ       (IRQ(6))
#define COM1_IRQ     (IRQ(4))
#define COM2_IRQ     (IRQ(3)<<4)
#define PCIA_IRQ     (IRQ(10)<<4)
#define PCIB_IRQ     (IRQ(11))
#define PCIC_IRQ     (IRQ(12)<<4)
#define PCID_IRQ     (IRQ(13)<<4)
 
static void initIRQ(void)
{
    pcitag_t tag;
    char val;
    tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, VTSB_ISA_FUNC);
   
    _pci_conf_writen(tag,IRQ_ROUTE_REG1,PARALLEL_IRQ|FLOPPY_IRQ,1);    上面启用并口和软盘中断。
 
   
    _pci_conf_writen(tag,IRQ_ROUTE_REG2,COM2_IRQ|COM1_IRQ,1);  
    上面启用串口 1 和串口 2 中断。
 
 
    val=_pci_conf_readn(tag,IRQ_ROUTE_REG4,1);
    val &=0xf;
    val |=PCIA_IRQ;
    _pci_conf_writen(tag,IRQ_ROUTE_REG4,val,1);  
    上面配置 PCI 的 A 插槽的中断为 10 号。
 
 
    _pci_conf_writen(tag,IRQ_ROUTE_REG5,PCIC_IRQ|PCIB_IRQ,1);  
    上面设置 B,C 的中断号 11 , 12 。
 
    val=_pci_conf_readn(tag,IRQ_ROUTE_REG6,1);
    val &=0xf0;
    val |=PCID_IRQ;
    _pci_conf_writen(tag,IRQ_ROUTE_REG6,val,1);  
    上面设置 D 的中断为 13 。
 
 
    val=_pci_conf_readn(tag,PCI_IRQ_TYPE_REG,1);
    val &= 0xf0;
    _pci_conf_writen(tag,PCI_IRQ_TYPE_REG,PARALLEL_IRQ|FLOPPY_IRQ,1);  上面设置为低电平中断模式。
 
}
 
这样就初始化中断源了。接着就启用 IO 的功能,如下:
static void enable_io_decode(void)
{
    pcitag_t tag;
    char val;
    tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, VTSB_ISA_FUNC);
    /*enable on-board io*/
    val=_pci_conf_readn(tag,0x81,1);  
    _pci_conf_writen(tag,0x81,val|0x80,1);
    /*enable com1 and com2*/
    _pci_conf_writen(tag,0x83,0x80|0x1| 0x8,1);  
}
 
经历上面很多寄存器的初始化,才把南桥的功能设置完成。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44936219/article/details/102703607

智能推荐

监听网络变化--含7.0以上适配_android.net.conn.connectivity_change-程序员宅基地

文章浏览阅读3.7k次,点赞3次,收藏7次。我们知道最早监听网络变化,是通过广播,静态或动态注册广播,处理"android.net.conn.CONNECTIVITY_CHANGE"这个action就可以了intent就可以了。我们发现"android.net.conn.CONNECTIVITY_CHANGE"这个action已经加了注解@Deprecated,不推荐使用了。根据注释说明,7.0及以上静态注册广播(manifest中)..._android.net.conn.connectivity_change

计算机学习目标_bytetrack+yolov5 c++-程序员宅基地

文章浏览阅读291次。开个坑_bytetrack+yolov5 c++

fatal error: filesystem: 没有那个文件或目录_fatal error: filesystem: no such file or directory-程序员宅基地

文章浏览阅读4.8k次,点赞12次,收藏39次。fatal error: filesystem: 没有那个文件或目录_fatal error: filesystem: no such file or directory

2020起重机械指挥作业考试题库及起重机械指挥模拟考试系统_换算英制直径5分钢丝绳为公制多少毫米?()。-程序员宅基地

文章浏览阅读1k次。题库来源:安全生产模拟考试一点通公众号小程序2020起重机械指挥作业考试题库及起重机械指挥模拟考试系统,包含起重机械指挥作业考试题库答案解析及起重机械指挥模拟考试系统练习。由安全生产模拟考试一点通公众号结合国家起重机械指挥考试最新大纲及起重机械指挥考试真题出具,有助于起重机械指挥考试试题考前练习。1、【判断题】指挥人员负责对可能出现的事故采取必要的防范措施。(√)2、【判断题】手势信号包括通用手势信号、专用手势信号和其它指挥信号。()(×)3、【判断题】吊装用的短环链,不..._换算英制直径5分钢丝绳为公制多少毫米?()。

大数据应用丨大数据时代的医学公共数据库与数据挖掘技术简介_dryad数据库-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏25次。本文我们将介绍几种数据库和数据挖掘技术,帮助临床研究人员更好地理解和应用数据库技术。数据挖掘技术可以从大量数据中寻找潜在有价值的信息,主要分为数据准备、数据挖掘、以及结果表达和分析。数据库技术是研究、管理和应用数据库的一门软件科学。通过研究数据库的结构、存储、设计、管理和应用的基本理论和实现方法,对数据库中的数据进行处理和分析。_dryad数据库

随便推点

SpringBoot整合Elastic-job实现_springboot + elasticjob-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏13次。SpringBoot整合Elastic-job实现【基本整合】:原理参考:Elastic-Job原理(1)引用pom依赖:<dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-core</artifactId> <..._springboot + elasticjob

Attensleep:一种基于注意力的单通道EEG睡眠分期深度学习方法_an attention-based deep learning approach for slee-程序员宅基地

文章浏览阅读791次。AttenSleep 基于注意力的深度学习架构从单通道EEG信号中进行睡眠阶段分类从基于多分辨率卷积神经网络( MRCNN )和自适应特征重标定( AFR )的特征提取模块入手。MRCNN可以提取低频和高频特征,而AFR可以通过建模特征之间的相互依赖关系来提高提取特征的质量。第二个模块是时间上下文编码器( TCE ),它利用多头注意力机制来捕获提取特征之间的时间依赖关系。特别地,多头注意力利用因果卷积对输入特征中的时间关系进行建模。使用三个公共数据集来评估提出的AttnSleep模型的性能。_an attention-based deep learning approach for sleep stage classification wit

Myeclipse技巧-程序员宅基地

文章浏览阅读71次。在了解MyEclipse使用技巧之前我们来看看MyEclipse是什么呢?简单而言,MyEclipse是Eclipse的插件,也是一款功能强大的J2EE集成开发环境,支持代码编写、配置、测试以及除错。下面让我们看看MyEclipse使用技巧的具体内容。MyEclipse使用技巧第一步: 取消自动validationvalidation有一堆,什么xml、jsp、jsf..._myeclipse是什么

c语言统计数组每个数出现的次数,统计数组中某个元素出现的次数和重复的次数...-程序员宅基地

文章浏览阅读8.9k次。//出现的次数function times(arr){var m=0,times=0;//m是数组中的元素,times用来统计出现的次数// for循环遍历arr数组for(var i=0;iif(arr[i]==m){times++;//数组中有相同值就加1}}return times;console.log(times);//这是打印出的出现的次数}times([0, 1, 2, 0, 1, ..._c语言统计数组中每个数字出现的次数

Jmeter连接InfluxDB2.0.4_influxdborganization jmeter-程序员宅基地

文章浏览阅读2.5k次,点赞5次,收藏14次。Jmeter连接InfluxDB2.0.4问题描述:在用Jmeter+InfluxDB构建监控时,因为docker构建的InfluxDB的版本是2.0.4,按照网上的教程进行后端监听器的填写,但是一直出现错误提示401等问题。网上的教程大多是1.X版本的,怀疑是数据库版本不一致导致的数据无法写入,通过调研,问题已解决。以下为配置方法。一、InfluxDB搭建完成后,查看Organization和Bucket名称,这里是ORZ_test和bucket_nameOrganization在这里我的理解_influxdborganization jmeter

关于第三方支付,看这篇文章就够了!-程序员宅基地

文章浏览阅读1.6k次。目录 目录 1、第三方支付概述 2、第三方支付起源 PayPal 支付宝 3、牌照发放 4、支付牌照 5、第三方支付参与者 6、第三方支付行业监管 监管意图对第三方支付可能产生的影响..._第三方支付本行对本行的费用

推荐文章

热门文章

相关标签