龙芯软件开发(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

智能推荐

TCP通信丢包主要问题及具体问题分析_tcp的客户端发送报文给服务器,不产生丢包或网络阻塞,但是数据不一致是因为-程序员宅基地

文章浏览阅读7.3k次。今天在公司问老大,公司的项目底层,是使用的TCP,因为可靠,自动断线重连,在底层都实现了,但是我记得TCP也会有掉包的问题,所以这文章就诞生了——关于TCP掉包的问题,TCP是基于不可靠的网络实现可靠的传输,肯定也会存在掉包的情况。 如果通信中发现缺少数据或者丢包,那么,最大的可能在于程序发送的过程或者接收的过程出现问题。 例如服务器给客户端发大量数据,Send的频率很高,_tcp的客户端发送报文给服务器,不产生丢包或网络阻塞,但是数据不一致是因为

docker php7.2 mac,PHP开发环境01 - Mac下使用Docker配置PHP环境(只限于学习)-程序员宅基地

文章浏览阅读193次。视频地址学徒卡夫 - 卡夫的Mac 03 - Mac下使用Docker配置PHP环境https://www.bilibili.com/vide...安装 Docker下载镜像# 安装基础镜像 - ubuntu:14.04# 拉取镜像(拉取镜像经常会失败,尝试几次就好了)docker pull ubuntu:14.04# 设置以守护进程在后台运行docker run -dit --name my-l..._mac laravel php7docker环境镜像

numpy中的高斯分布函数 normal 的具体详解_numpy normal-程序员宅基地

文章浏览阅读1.5w次,点赞5次,收藏18次。1、高斯分布的概率密度函数为:2、 在numpy中:numpy.random.normal(loc=0.0, scale=1.0, size=None)3、具体参数详解loc:float 此概率分布的均值(对应着整个分布的中心centre)scale:float 此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)size:int o..._numpy normal

查看NVIDIA 显卡信息和CUDA信息命令。_nvidia-smi看cuda数量-程序员宅基地

文章浏览阅读1w次,点赞4次,收藏4次。1,nvidia-smi :查看NVIDIA 显卡信息。注意要先添加环境变量。 2,nvcc -V:查看CUDA版本_nvidia-smi看cuda数量

动态数组实现Point对象栈类_point类型的栈-程序员宅基地

文章浏览阅读1k次。动态数组实现Point对象栈类1.new运算符new的功能是动态分配内存,或者称为动态创建堆对象,语法形式为new 数据类型(初始化参数列表);如int *point;point = new int(2);动态分配了用于存放int类型数据的内存空间,并将初值2存入该空间中,然后将首地址赋给指针point。new也可以创建数组类型对象,这时需要给出数组的结构说明。..._point类型的栈

比尔•盖茨:我怎样工作?_我的工作方式比尔盖茨-程序员宅基地

文章浏览阅读1.9k次。我怎样工作? “纸张在我的日常工作中作用不大。” 作者: Bill Gates _我的工作方式比尔盖茨

随便推点

MySQL 基本操作_alter table zhsq_yw_person drop birth-程序员宅基地

文章浏览阅读922次。MySQL_alter table zhsq_yw_person drop birth

世界上最著名的操作系统是用什么语言编写的?_操作系统是用什么写的-程序员宅基地

文章浏览阅读2.9w次,点赞96次,收藏250次。Unix 与 C 语言的关系Unix 确实是用 C 语言编写的,而且是世界上第一个用 C 语言编写的操作系统。但是 Unix 是怎么产生的?C 语言又是怎么产生的?Unix 为什么要用 C 语言来编写?相信看完这篇文章你很快就会有了答案。Multics 和 Unix1964年,在 Unix 诞生之前,美国贝尔实验室、通用电气、和麻省理工学院联合开发了一个项目,叫做 Multics操作系统。Multics 在当时取得了巨大的成功,因为它给了人们一个真正可用并且很稳定的操作系统。当时从学校._操作系统是用什么写的

webservice接口调用报错 org.apache.cxf.service.factory.ServiceConstructionException: Failed to create servi-程序员宅基地

文章浏览阅读4.4w次。org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service. at org.apache.cxf.wsdl11.WSDLServiceFactory.&lt;init&gt;(WSDLServiceFactory.java:76) at org.apach..._org.apache.cxf.service.factory.serviceconstructionexception: failed to creat

LeGO-LOAM 源码阅读笔记(imageProjecion.cpp)_lego_loam full_cloud_info-程序员宅基地

文章浏览阅读6.7k次,点赞21次,收藏89次。LeGO-LOAM是一种在LOAM之上进行改进的激光雷达建图方法,建图效果比LOAM要好,但是建图较为稀疏,计算量也更小了。本文原地址:wykxwyc的博客github注释后LeGO-LOAM源码:LeGO-LOAM_NOTED关于代码的详细理解,建议阅读:1.地图优化代码理解2.图像重投影代码理解3.特征关联代码理解4.LeGO-LOAM中的数学公式推导以上博客会随时更新,如果..._lego_loam full_cloud_info

36: ansible基础 、 Ansible ad-hoc 、 总结和答疑_unsupported parameters for (file) module: register-程序员宅基地

文章浏览阅读695次。CASE Top NSD AUTOMATION DAY01 案例1:部署Ansible 案例2:Ansible ad-hoc应用一 案例3:Ansible ad-hoc应用二 ..._unsupported parameters for (file) module: register. supported parameters inc

Xj123.biz 新疆维文网址导航站正式开通了!-程序员宅基地

文章浏览阅读1k次。为什么80%的码农都做不了架构师?>>> ..._维文网址