科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件PCI设备初始化2

PCI设备初始化2

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在汇编的代码里,已经进行了串口初始化,在这里更进一步初始化串口,

作者:caimouse 来源:CSDN 2008年1月22日

关键字: 初始化 设备 PCI Linux

  • 评论
  • 分享微博
  • 分享邮件
在汇编的代码里,已经进行了串口初始化,在这里更进一步初始化串口,它是通过调用下面的代码实现的:
#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);  
    上面配置PCIA插槽的中断为10号。
 
 
    _pci_conf_writen(tag,IRQ_ROUTE_REG5,PCIC_IRQ|PCIB_IRQ,1);  
    上面设置B,C的中断号1112
 
    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);  
}
 
经历上面很多寄存器的初始化,才把南桥的功能设置完成。
 

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章