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

在汇编的代码里,已经进行了串口初始化,在这里更进一步初始化串口,它是通过调用下面的代码实现的:
#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);
}
经历上面很多寄存器的初始化,才把南桥的功能设置完成。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值