您的位置: 延庆信息网 > 历史

PCI设备初始化2

发布时间:2019-09-13 20:01:40

在汇编的代码里,已经进行了串口初始化,在这里更进一步初始化串口,它是通过调用下面的代码实现的:

#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);

}

经历上面很多寄存器的初始化,才把南桥的功能设置完成。

查看本文来源

婴儿便秘的解决方法
治疗血栓
动脉硬化中成药
宝宝营养不良有什么表现
猜你会喜欢的
猜你会喜欢的