单片机学习国产龙芯-软件开发_第1页
单片机学习国产龙芯-软件开发_第2页
单片机学习国产龙芯-软件开发_第3页
单片机学习国产龙芯-软件开发_第4页
单片机学习国产龙芯-软件开发_第5页
已阅读5页,还剩165页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

龙芯软件开发非常高兴可以订购到龙芯电 龙芯软件开发(15)--搬家前的准 龙芯软件开发(16)--内存参数.....................................................................................................................龙芯软件开发(17)--初始化龙芯2E缓 龙芯软件开发(18)--乾坤大挪移,从ROM到 龙芯软件开发(19)--C函数..........................................................................................................................龙芯软件开发(20)--频率和初始化实时时 龙芯软件开发(21)--调试与功能选 龙芯软件开发(22)--初始化环境参 龙芯软件开发(23)--PCI设备初始 龙芯软件开发(24)--PCI设备初始化 龙芯软件开发(25)--PCI设备初始化 龙芯软件开发(26)--PCI设备初始化 龙芯软件开发(27)--网络初始 龙芯软件开发(28)--显示卡初始 龙芯软件开发(29)--键盘初始 龙芯软件开发(30)--自动加载操作系 龙芯软件开发(31)--PCI设备查找细 龙芯软件开发(32)--USB协议深入分 龙芯软件开发(33)--USB协议深入分 龙芯软件开发(34)-USB协议深入分析设备描述符配置 龙芯软件开发(35)-USB协议深入分析设备描述符配置 龙芯软件开发(36)-USB协议深入分析返回设备描述 龙芯软件开发(37)-USB协议深入分析返回设备描述 龙芯软件开发(38)-USB协议深入分析设置USB地 龙芯软件开发(39)-USB协议深入分析配 龙芯软件开发(40)-USB协议深入分析字符串描述 龙芯软件开发系

非常高兴可以订购到龙从上看到龙芯CPU发布,到现在看到龙芯电脑的发布,真是太让人兴奋!这是自己的CPU啦,一定要支持ARM9龙梦公司的地址,然后就去发过去,让他们确认一下。最后通过了他们的确认,就这样就可以订购到龙还想在上面REACTOS。龙芯软件开发(1)--BIOS ent.php?aid=236 PMON源码 gxemul模拟器 能运行龙梦BIOS和内核的模拟器,版本龙芯软件开发(2)--汇编资MIPSAssemblyLanguageMIPSAssemblyLanguageProgrammer’s...LanguageProgDoc.pdfMIPSAssembly.../download/rs-05.pdf...L.instructions.htmlMIPS32 龙芯软件开发(3)--常问问对于一个新答:MIPS指令。答:MIPS的名字为“ puterwithoutinterlockedpipelinestages”的缩写。另外一个通常的非正式的说法是“Millionsofinstructionspersecond”。在64位的CPU上运行。龙芯软件开发(4)--主要介解一下龙芯电脑的主要组成,下面先从网上的龙梦电脑的组成来入手。它的配置如下:ICTNB2E(ALTERAEP2C20F484),功耗0.1-0.3VIAVT82C686B,33MHz32-bitPCI内存内存插槽200线,14cmx18cm龙芯软件开发(5)--北桥南桥的作北桥是基于In 理CPU,RAM,AGP端口或PCIExpress,还有南桥之间的通信。北桥(NorthBridge)是主板组中起主导作用的最重要的组成部分,也称为主桥(HostBridge。一般来说,组的名称就是以北桥的名称来命名的,例如英特尔845E组的北桥是82845E,875P组的北桥是82875P等等。北桥负责与CPU的联系并控制内存、AGP、PCI数据在北桥内部传输,提供对CPU的类型和主频、系统的前端总线频率、内存的类型(SDRAM,DDRSDRAM以及RDRAM等等)和最大容量、ISA/PCI/AGP插槽、ECC纠错等支持,整合型组的北桥还集成了显示。北桥就是主板上离CPU最近的,这主要是考虑到北桥与处理器之间的通信最密切,为了提高通信性能而缩短传输距离。因为北桥的数据处理量非常大,发热量也越来越大,所以现在的北桥都覆盖着散热片用来加强北桥的散热,有些主板的北桥还会配合风扇进行散热。因为北桥的主要功能是控制内存,技术就完全不一样,而是不同的组北桥间肯定在一些地方有差别。由于已经发布的AMDK8的CPU将内存控制器集成在了CPU内部,于是支持K8组的北桥变得简化多了,甚至还能采用单组结构。这也许将是一种大趋势,北桥的功能会逐渐单一化,为了简老早就发布了不少单组。 入设备之间的通信。/输出,LAN,Audio,USB,BIOSHub龙芯软件开发(6)--CPU在开发软件中,对于CPU的了解就是最重要的了。无论什么指令都需要CPU来执行。现在就来看看龙芯2E的龙芯2号增强型处理器(简称“龙芯2E”)计算技术研制的、具有自主知识的642E1GHz39.93SPECCPU2000500分,是目前全球除美日之外性能最高的通用处理器。龙芯2E采用四发射的动态量超流水线结构,实现了先进的转移猜测、寄存器重命名、动态调度、以2E90纳米CMOS工艺,是大陆地区第90计技术的处理器。晶470035750MHz5-7线级别,还有ALU的个数,在这里有四个ALU。龙芯软件开发(7)--编译PMON一、SVN工由于要PMON代码,就要使用SVN工具。目前,所有的代码都是按版本控制形式保存在服务器上的,并且没有打包的代码,这样就需要使用SVN的工具来代码。如果在WINDOWS下,就要WINDOWS的SVN工具。如果在LINUX下,就需要LINUX的GETIT工具。二、帐先到上面一个帐号,然后才能登录进入开发,否则不能登录进去的,由于目前没有开通诺名功能。帐号后,就可以登录,然后通过SVN的工具下载 piler下面找到交叉编译器,它的名称是mips-elf.tar.gz。这是一个压缩包,当然要解压后才能使用。那么需要解压到那里呢?通常都 上面已经把交叉编译器安装好后,并不能直接在任何路径里就运行它。比如到目录到它,就需要把它所在的加到当前环境变量里,这样才可进行编译。而在LINUX下,设置环境变量,需exportexport 在我没有问kkmao之前,根本就不知道还需要这样的一个过程。因此,就编译不通过。由于PMON是根据配置选择不同的源程序进行编译,所以就需要一个工具来分析那个配置文件,而这个工具就是pmoncfg。生成tools/pmoncfgmakepmoncfgTargets/Bonito/confBonitoBonito.notebook件,为了方便运行,就进行符号连接。再接着运行pmoncfg工具来生成目标源程序的。执行下面令:ln-sBonito.notebookBonitotools/pmoncfg/pmoncfg这样就形成目标Bonito 着再到zloader make,或者直接到zloader下面make, (模拟器也可以运行gxemul-0.3.8-good.tar.gz源程序,然后进入到里,运行./configuremakefile文件。接着运make件就可以生成模gxemulpmon.bin贝到这个下,就可以如下./gxemul-Xebonito这样就可以运行PMON了,上面令行意思是输出到X窗口,而代码ROM开始地址是0xbfc00000,也就是在我的LINUX里可以编译通过gxemul-0.4.2.current.tar.gz,但运行它时,就不支持-X参数,这个问题我也龙芯软件开发(8)--理解龙芯2E寄存器和内对于软件开发人员来说,一个CPU最重要的部分就是寄存器、内存布局和指令。龙芯2E逻辑上是有32个定点通用寄存器(其中0号固定为0),32个浮点寄存器,一个hi,一个lo,以及若干cp0控制寄存器,两个 0,可能主要用途是清空内存地址空间,以及做一些与或非的操作,访lllll l l FPS8S0..S7 RA二、寄存kuseg:0x0000000-0x7FFFFFFF(2G):这些地址是用户态可用的地址。有MMU的机器里,这些地址将一概被MMU作转换。除非MMU的设置被建立好,这2G地址是不可用的。对于没有MMU的机器,存取这2G地址的后依具体机器相关。你的CPU具体厂商提供的手册将会告诉你关于这方面的MMUMIPSkseg0:0x800000000x9FFFFFFF(512M):把最清零,然后把它们映射到物理地址低段512M(0x00000000-0x1FFFFFFF)。因为这种映射是很简数据的存放位置。对于有MMU的系统,操作系统会存放在这个区域。kseg1:0xA00000000xBFFFFFFF(512M):3将使用这段地址空间去存取你的初始化ROM。大多数人在这段空间使用I/O寄存器。kseg2:0xC0000000-0xFFFFFFFF(1G):这段地址空间只能在态下使用并且要经过MMU的转换。在MMU设置好之前,不能存取这段区域。除非你在写一个真正的操作系统,一般来说你不需要使用这段地址空龙芯软件开发(9)--理解龙芯2E几个汇编问lw$9,0($8) jalmyfuncmovea0, addiu 龙芯软件开发(102E每个CPU都有自己独特的指令,比如X86结构的CPU有IN的指令系统,MIPS的CPU也有自己的指令系做出响应的。如果发送一条不是CPU的指令,就会导致CPU执行,并且会引起CPU异常。龙芯里,每条指令都是固定长度:324个字节。因此,任何指令段的代码长度,一定要4字节的倍数,绝对不要出现不是4的倍数,否则就让CPU不能运行了。从龙芯的使用手册中可以看到,每条CPU指令都是一条32位的指令字,这些指令都是字对齐的。指令集包含2-1(I-型(J-型)和寄存器指令(J-型。使用简单几种指令格式可以简化指令译码,并且使得编译器根据这三种指令格式可以合成的复杂操作(使用频率LoadandStore访存指令在主存和通用寄存器之间移动数据。访存指令都是立即数指令(I-型,因为该指令模式所支持的唯一访存模式就是基址寄存器加上16位的对齐的偏移量。Computational计算型指令完成寄存器值的算术,逻辑,移位,乘法和除法操作。计算型指令包含了寄存个16位的立即数。龙芯2E微处理器还实现了自定义的乘法,除法和模操作指令,其方法是使用一个通用的JumpandBranch跳转和分支指令改变程序的控制流。绝对地址跳转被称为“jump(跳转)”(J-型或者R-型),PC(指令计数器)相关的跳转指令被称为“branch(分支)”(I-型。跳转指令的返回地址保存在第31号寄存器中。CoprocessorI2E器有两个协处理器:0号协处理器(系统处理器)和1号协处理器(浮点协处理器。号协处理器(CP1)指令包括浮点指令,多指令,和龙芯扩展的定点计算指令。这些指令都是在浮点寄Exception异常指令引起跳转,根据异常号比较结果跳转到通用异常处理向量。这些指令包括R-型和MIPSIIIIIIMIPSIIIIIIIIIIIIIIII2-2CPU(ALUMIPSIId=((signed)ssignedj1:0jId=((unsigned)sunsignedj1:0jIIIIIMIPS加II减IId=((signed)s<(signed)t)?Id=((unsigned)s<(unsigned)t)?I与I或IIIMIPS乘II除IIIIIIMIPSJIIIIIIIIIIIIMIPSIIIIIId=(longlong)s<<(shift+32)d=(longlongunsigned)s>>(shift%32)d=(longlongsigned)s>>(shift%32+32)MIPSIIMIPSOpCode MIPSII龙芯软件开发(11)--龙芯2E运行的第一行天生万物,万物始于天。同样,龙芯2E要运行起来,那么就少不了程序。那么龙芯2E的开天是从那里开程序,去看看龙芯的初始化阶段都做了些什么事情,有没有做坏事情呢?哈哈,这个很难说的。如果有BUG的出现,就会干出各种各样的坏事情。0xBFC000000x1FC00000PMONROMFlashPMONstart.S .globl.globl

.globlstack=start- /*PlacePMONstackbelowPMONstartinRAM/*NOTE!!Notmorethat16instructionshere!!!Rightnowit'sFULL!*/ zero,COP_0_STATUS_REG zero,lit0,SR_BOOT_EXC_VEC/*ExceptiontoBoostrapLocation*/ t0,COP_0_STATUS_REGlasp,stacklagp,_gpbal /*Switchtouncachedaddressspaceballocate /*Getcurrentexecuteaddress*/orra, /*2006-12-28OK,从上面看到,第一行程序运行的就是mtc0zero,COP_0_STATUS_REG。找到了第一行运行的程序,但这 GCC,那么它的汇编 .globl.globl .globlstack=start- /*PlacePMONstackbelowPMONstartinRAM在这里定义了子程序的名称_startstartstack/*NOTE!!Notmorethat16instructionshere!!!Rightnowit'sFULL!*/ zero,COP_0_STATUS_REG zero,lit0,SR_BOOT_EXC_VEC/*ExceptiontoBoostrapLocation*/ t0,COP_0_STATUS_REGlasp,stacklagp,_gp由于龙芯的地址空间决定,这里的代码过32条指令,因为后面紧跟着是其它中断向量的地址。接着,CP0状态寄存器COP_0_STATUS_REGCOP_0_CAUSE_REG寄存器全部清空为0lit0SR_BOOT_EXC_VEC接BEVCP0TLB设置引导程序的堆栈空间,lasp,stacksplagp,_gp_gp全baluncached /*Switchtouncachedaddressspace*/ballocate /*Getcurrentexecuteaddress*/orra, 就跳到uncached这里运行,先来看看bal指令会做些什么事情,通常bal指令会算出相对于PC寄存器的偏移量,然后把PC+8指令地址放到RA寄存器里,也就是把ballocate指令地址放到RA寄存器,以便可以返回。由于龙芯2E的加电时启动地址是0xBFC00000,那么放在RA里的值就是0xBFCO0028。后面orra,UNCACHED_MEMORY_ADDR,这里进行是与0xA00000000的或运算,也就是说从ROM加载时,不会改变返回地址RA的值。主要是从其它地址空间运行这段程序时才会引起跳转的地址空间的转换。所以接着就跳回来到 locate位置并执行ballocate指令,这样就跳到locate的位置执行程序了。龙芯软件开发(122E摸索 ands0,0xffff0000 .set …bal/*bonitoendianess*/BONITO_BIS(BONITO_BONPONCFG,BONITO_BONPONCFG_IS_ARBITER)…0481:move /*localname*/lwt3,Init_Op(a0)lwt0,Init_A0(a0)andt4,t3,OP_MASK*bnet4,OP_EXIT,8fb.done…跳到locate里執行的,首先计算跳转时代码的长度,保存s0。接着把物理地址保存到bonito寄存器,后面bal1f1标号地方运行。在1标号的地方,取跳转时压入的RA寄存器的值,然后通过寄存器相对寻址的方式,取得跳转指令后面保存的参数,并保存到t3,t0寄存器。后面就运行bne t4,OP_EXIT,8f这句了,在这里作是否初始化寄存器完成的判断,如果没有完成,就会跳到后面8标号处运行,然后经历一系列的设置后,直到OP_EXIT标志出现。看到前面有一行EXIT_INIT(0,这里就是说这个数据结构已经结构了,它的宏定义如下:#defineEXIT_INIT(status).word.word PRINTSTR("\r\nPMON2000MIPSInitializing.Standby...\r\n") balhexserialPRINTSTR(" balhexserialPRINTSTR(" balhexserial/*2006-12-29于在这段程序里,主要做了两件大事情,一是初始化南桥VIA686B,一是初始化串口输出。初始化的办法,就是加一个指示灯,这也叫“点灯”。只要串口能输出字符串后,使用串口调试就成为基本的CP0ID龙芯软件开发(13)--配置南桥进入调试串口输出东西。先来看superio_init实现代码:#definePCICONF_WRITEB(dev,func,reg,data)\ a0,CFGADDR(dev,func,reg);\ a1,PHYS_TO_UNCACHED(PCI_CFG_SPACE); a2,a0,0xffff; a1,a2; a0,16; a2,BONITO_BASE+BONITO_PCIMAP_CFG; a0,BONITO_PCIMAP_CFG(bonito);\ a0,zero,data;\ #definePCICONF_WRITEW(dev,func,reg,data)\ a0,CFGADDR(dev,func,reg);\ a1,PHYS_TO_UNCACHED(PCI_CFG_SPACE); a2,a0,0xffff; a1,a2; a0,16; a2,BONITO_BASE+BONITO_PCIMAP_CFG; a0,BONITO_PCIMAP_CFG(bonito);\ a0,zero,data;\ #definePCICONF_ORB(dev,func,reg,data)\ a0,CFGADDR(dev,func,reg);\ a1,PHYS_TO_UNCACHED(PCI_CFG_SPACE); a2,a0,0xffff; a1,a2; a0,16; a2,BONITO_BASE+BONITO_PCIMAP_CFG; a0,BONITO_PCIMAP_CFG(bonito);\ zero,BONITO_PCIMAP_CFG(bonito);\lbua2,(a1);\oria2,data; a0,BONITO_PCIMAP_CFG(bonito);\ zero,BONITO_PCIMAP_CFG(bonito);sb#defineSUPERIO_WR(idx,data) v0,BONITO_PCIIO_BASE_VA+0x3f0; v1,zero,idx; v1,(v0);\ #defineE2_EPP#defineE2_S1#defineE2_S2#defineE2_FLOPPY(1<<4)/*positivedecode*//*enableRTC/PS2/KBC*/SUPERIO_WR(0xe2,E2_S2|E2_S1|E2_EPP|E2_FLOPPY)/*enableserialandfloppy*/SUPERIO_WR(0xe3,0x3f0>>2)/*floppybaseaddress*/SUPERIO_WR(0xe6,0x378>>2)/*parallelport*/SUPERIO_WR(0xe7,0x3f8>>2)/*setserialport1baseaddr0x3f8*/SUPERIO_WR(0xe8,0x2f8>>2)/*setserialport2baseaddr0x2f8*/SUPERIO_WR(0xee,0xc0)/*bothportsonhighspeed*/lui$a0,0x1lui$a1,0xbfe8 or$a1,$a1,$a2srl$a0,$a0,0x10lui$a2,0x1fe0sw$a0,280($s4)li$a0,0x7后面那些都是设置SUPERIO端口,分配地址。lav0,liv1,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4sbv1,NSREG(NS16550_FIFO)(v0)liv1,sbv1,liv1,NS16550HZ/2/(16*CONS_BAUD)sbv1,NSREG(NS16550_DATA)(v0)srlv1,sbv1,NSREG(NS16550_IER)(v0)liv1,CFCR_8BITSsbv1,liv1,sbv1,liv1,sbv1, /*2006-12-30于这里先获取COM1的址,是通过内存映射地址实现的。接着把FIFO的设置,设置CFCR寄存器,设置波特NS16550HZ台电脑上,就可看到调试信息输出来,当然还可以实现源码级调试了。龙芯软件开发(14)--串口PRINTSTR(" PRINTSTR(x).rdata;98:.ascizx;.text;laa0,98b;balstringserial;98:.ascizla现在又去查看stringserial的代码,它如下: a2,ra a1,a0,s0lbua0,0(a1) baladdiua1,1 lbua0, 上面代码,先把返回地址ra保存到a2,然后计算字符串的地址,接着通过lbu获取第一个字符,在beqz里addiub1b面还有一行lbua0,0(a1)。由于龙芯是流水线的CPU,当跳转发生时,已经把后面那一条指令解释执行完成了,所以a0里总是保存的字符。 a2, lia3,7rola0,a1,4 a1,a0anda0,0xflav0,hexchar v0,s0 v0,a0lbua0,0(v0) a3, a3,- 是做8次的计数。bneza3,1b lav0,lav0,lbuv1,andv1,LSR_TXRDY v1,1bsba0, v1,lav0,bnev0,v1,1b 龙芯软件开发(15)--搬家前的准任何人在搬家前,都需要把新房子修建好,然后再经过装修才能住到新房子里,然而这里的启动程序也不例而是内存空间。由于在ROM运行的速度都是比较慢,并且空间有限,不能随时更改ROM里的内容。同时为了下MMSDRAM在龙芯电脑里,使用的内存是标准的笔记本内存,也就是叫做SO-DIMM一条线表示时钟信号,一条线表示数据信号,不管数据是,还是写入,都是通过数据线来进行的。无论命令,而不同地址的设备就不会响应后面令。为什么DIMM内存上的EEPROM,就需要按I2C的协议PRINTSTR("DIMM/*onlyonememoryslot,slaveaddress blia1,lia0,0xa1#savea1movet1,a1movea0,v0#restorea1movea1,t1addiu v0,0x20bleua1,v0,1bli#setsomeparametersfor#ranknumberandDDRtypefieldwillbefilledlater#tocheck:fixTCAS?lisdCfg,0x341043dflia0,0xa1/*readDIMMmemorytype(mustbeDDRAM)*/#lia1,2 PRINTSTR("readmemory/*readDIMMnumberofrows*/lia0,0xa1lia1,3 a0, v0, s1, v0,PRINTSTR("readnumberof2:/*readDIMMnumberofcols*/lia0,0xa1lia1,4 v0, t1,bnet1,0,10fbnev0,2,20fliv0, 20:bnev0,1,21fliv0, 21:bnev0,0,22fliv0, 22:bnev0,3,33fliv0, 10:bnet1,1,11fbnev0,3,20fliv0, 20:bnev0,2,21fliv0, 21:bnev0,1,liv0, 22:bnev0,4,33fliv0, 11:bnet1,2,33fbnev0,4,20fliv0, 20:bnev0,3,21fliv0, 21:bnev0,2,33fliv0, 33:PRINTSTR("DDRtypenotsupported!\r\n");34:b #bit25:22isDDRtypefieldsllv0,22orsdCfg,v0/*readDIMMmemorysizeperside*/lia0,0xa1lia1,31 slltmpsize,v0,22 #multiplyby4MPRINTSTR("readmemorysizeper2:/*readDIMMnumberofblocks-per-ddrram*/lia1,17balPRINTSTR("readblocksper2:/*readDIMMnumberofsides(banks)*/lia1,5slltmpsize,1#msize*=2orsdCfg,0x1<<27PRINTSTR("readnumberof2:/*readDIMMwidth*/lia1,6 PRINTSTR("read2:addu PRINTSTR("\r\nNoDIMMinslot") balhexserial #limsize,0x#lisdCfg,0x3d9043df#~133MHzlimsize,0xli PRINTSTR("DIMM balhexseriallit0,0xbff00008sdsdCfg,0(t0)####gx2006-03-17:modelit1,0x28lit0,0xbff00000sdt1,0(t0)lilit0,0xbff00000sdt1,0x30(t0)####setuphighmemorywindow#### t1,0x msize,t1,luit1,0x2000luit1,0x1000 balhexserial balhexserialli #accumulatepcimembasecfg/*setbar0maskandtranslationtopointtoSDRAMsubnotandt0,BONITO_PCIMEMBASECFG_MEMBASE0_MASKorliandt0,BONITO_PCIMEMBASECFG_MEMBASE0_TRANSoror/*setbar1tominimumsizetoconservePCIspace*/lit0,~0andt0,BONITO_PCIMEMBASECFG_MEMBASE1_MASKorliandt0,BONITO_PCIMEMBASECFG_MEMBASE1_TRANSororsw/*enableconfigurationcyclesnow*/lwt0,BONITO_BONPONCFG(bonito)andsw/*2007-1-1于*/PRINTSTR("InitSDRAMDone!\r\n");龙芯软件开发(16)--内存参数lia1,0x0lia0,0xa1数i2cread是怎么样I2C数据。/*a0:slaveaddressa1:regoff/*setdeviceaddressliv0,0xbfd00000+lia0,0xa1sba0,0(v0);/*storeregisteroffsetliv0,0xbfd00000+ sba1,0(v0);/*readbytedataprotocol*/liv0,0x08liv1,0xbfd00000+sbv0,/*makesureSMBhostreadytostart,important!--zfx*/liv1,0xbfd00000+SMBUS_HOST_STATUSlbuv0,0(v1)andiv0,v0,0x1fbeqzv0,1fsbv0,lbuv0, #flushthe/*startliv1,0xbfd00000+lbuv0,0(v1)oriv0,v0,0x40sbv0,0(v1);/*waitliv1,0xbfd00000+lia1,#if/*delay*/lia0,0x1000 addiua0,-addiua1,-1 lbuv0,andiv0,bnezv0,1b#IDEL?liv1,0xbfd00000+lbuv0,0(v1)andiv0,v0,0x1fbeqzv0,1fsbv0, lbuv0, #flushtheliv1,0xbfd00000+lbuv0,第2字节表示内存类型。3字节表示行地址位数。4字节表示列地址位数。第5字节表示排数。6字节表示数据宽度(低字节。第7字节表示数据宽度(高字节。第8字节表示信号电平。第10字节表示SDRAM时间。第11字节表示配置类型。第16字节表示支持突发传输长度。23SDRM钟。2最大指数倍。第24字节表示SDRAM时间。34字节表示输入数据建立时间。第35字节表示输入数据保持时间。62字节表示SPD版本号。其它的字节,就要参考SPD文档了。后面一大段程序就是实现了这些参数,然后根据这些参数来设置龙芯内存的SDRAM寄存器。/*2007-1-2于*/PRINTSTR("DIMM balhexseriallit0,0xbff00008sdsdCfg,0(t0)####gx2006-03-17:modelit1,0x28lit0,0xbff00000sdt1,0(t0)lilit0,0xbff00000sdt1,0x30(t0)####setuphighmemorywindow#### t1,0x msize,t1,luit1,0x2000luit1,0x1000 balhexserial balhexserial龙芯软件开发(17)--初始化2ECPU,都具有大量的缓存。由于很多程序都具有局部循环特性,使用缓存就可以大大地提高CPU效率。比如像下面的程序:intnSum=for(inti=0;i<10000;{nSum+=}64K,64K512K。一级缓存采用虚地址索引和物理地址标SYNC,只要运行这条指令,就可TTYDBG("Sizing t3,COP_0_CONFIG/*t3=originalconfigandt3, /*MakesurecoherencyisOKandt3,~(CF_7_TE|CF_7_SE|CF_7_TC|CF_7_SC)/*disableL2/L3cache*/ t3,COP_0_CONFIGlit2,srlt1,t3,andt1, s3,t2, /*s3=Icachesize#ifdef andt1,t3,0x20srlt1,t1,1 s4,t1, /*s4=Icachelinesizesrlt1,t3,6andt1,3 s5,t2, /*s5=Dcachesize#ifdef andt1,t3, s6,t1,16 /*s6=Dcachelinesize*/TTYDBG("Initcaches...\r\n")lis7, /*noL2cachelis8, /*noL3cacheCPUIDIDCPUTTYDBG("godson2cachesfound\r\n")balgodson2_cache_init####part2#### t4, t5,t4,0x0e00srlt5,t5,9 t6,t4,0x01c0srlt6,t6,6addiut6,t6,11addiut5,t5,11addiut4,$0,1 t6,t4,t6srlt6,1 t5,t4,srladdiut7,$0,2####part3####luia0,0x8000 a1,$0,t5 a2,$0, ,a1=icache_size,a2=dcache_size#a3,v0andv1usedaslocalregisters $0, v0,$0,a0 v1,a0,1:slta3,v0,v1beqa3,$0,1f $0,cacheIndex_Store_Tag_D,0x0(v0) $0,CP0_TAGLOcacheIndex_Store_Tag_D,0x1(v0) $0,CP0_TAGLO $0,CP0_TAGLOcacheIndex_Store_Tag_D,0x3(v0)beq$0,$0,1baddiuv0,v0,上面的代码是通过循环初始化64K数据缓存。首先使用mtc0指令清空TagLo寄存器,然后把0x80000000开始的内存映射到数据缓存索引,它是通过指令cache来进行的。Index_Store_Tag_D的值是0x05,意思就是v0寄存的值加0x0TagLoTagHi。这样就把64K数据缓存指向了0x80000000开始的64K内存了。#if$0,v0,$0,v1,a0,a3,v0,a3,$0,$0,Index_Store_Tag_S,$0,Index_Store_Tag_S,$0, Index_Store_Tag_S, $0, $0,$0,1b v0,v0, v0,$0,a0 v1,a0,128*10241:slta3,v0,v1beqa3,$0,1fcacheIndex_Writeback_Inv_S,0x0(v0)cacheIndex_Writeback_Inv_S,0x1(v0)cacheIndex_Writeback_Inv_S,0x2(v0)cacheIndex_Writeback_Inv_S,0x3(v0)beq$0,$0,1baddiuv0,v0,0x20#endif v0,$0,a0 v1,a0,1:slta3,v0,v1beqa3,$0,1fcacheIndex_Invalidate_I,0x0(v0)#cacheIndex_Invalidate_I,0x1(v0)#cacheIndex_Invalidate_I,0x2(v0)#cacheIndex_Invalidate_I,beq$0,$0,1baddiuv0,v0, v0,$0,a0 v1,a0,1:slta3,v0,v1beqa3,$0,1fcacheIndex_Writeback_Inv_D,0x0(v0)cacheIndex_Writeback_Inv_D,0x1(v0)cacheIndex_Writeback_Inv_D,cacheIndex_Writeback_Inv_D,beq$0,$0,1baddiuv0,v0,0x20TTYDBG("cacheinitpanic\r\n");1:b 0x800000000x9FFFFFFF的虚拟内存运行,这样在内存运行的代码就非常快了。龙芯软件开发(18)--乾坤大挪移,从ROM到的存取速度比ROM里快很多,并且可以随时修改数据,而在ROM是不能修改的,就算可以修改,也是非常慢的。#####xuhua########opencp1#if1

后先用通过0x24000000来打开浮点协处理器,把值改写回到状态寄存器。/*closeL2cache a0,0xbfe00164 a0,a0,~((1<<12)|3) TTYDBG("CopyPMONtoexecutelocation...\r\n")#ifdefDEBUG_LOCORETTYDBG("start=0x")laa0,startTTYDBG("\r\ns0=0x") a0,s0balhexseriallaa0,lia1,0xbfc00000laa2,_edata a0, t1,a2,a0srlt1,t1,2 t0, t1, t2,0000,a1ROM0xbfc00000,a2RAM/*copytextsection*/1:andt3,t0,0x0000ffff li 2:lwt3,0(t1)swt3,0(t0) t0, t1,4bnet2,t0,1bPRINTSTR("\ncopytextsection/*ClearBSSlaa0,laa2,_end2:swzero,0(a0)bnea2,a0,2b a0,4TTYDBG("CopyPMONtoexecutelocationmovea0,sp#iflia0,swa0,CpuTertiaryCacheSize/*SetL3cachesizesrl/*passpointertokseg1tgt_putchar*/laa1,tgt_putcharaddulaa2,stringserialaddua2,a2,s0lav0,initmips 上面代码先把内存大小msize放到参数0里,把输出字符函数指针放到参数1里,把字符串输出函数指针放到参数2里,然后取得C函数initmips地址,直接跳到那里运行,不再返回来。不过,后面还有一#ifdefTTYDBG("DumGT64240lis3,0

movea0,s3balhexserialTTYDBG(":adda0,s3,bonitolwa0,0(a0)addius3,4TTYDBG("")lia0,0xfffanda0,s3 a0,3flia0,0x01fanda0,s3 a0,2b 减少BUG的出现。龙芯软件开发(19)--C经历了漫长的汇编,最终走到光明的C世界了,进入高级语言环境,会让开发更方便,写更少的语句就可以实现的功能。从这里开始,就初始化PCI局部线所有设备,初始化南桥所有的功能,初始化IDE硬盘,上次分析移动代码里,就知道代码已经移到0x80000000开始运行了。initmips(unsignedint{SetupmemoryaddressdecoderstomapentireButfirstmoveawaybootrommaptohigh#ifGT_WRITE(BOOTCS_LOW_DECODE_ADDRESS,BOOT_BASE>>GT_WRITE(BOOTCS_HIGH_DECODE_ADDRESS,(BOOT_BASE-1+BOOT_SIZE)>>memorysize=memsz>256?256<<20:memsz<<memorysize_high=memsz>256?(memsz-256)<<20:srl#if{intstart=0xintend=0x+while(start<end)asmvolatile("cache"cache1,1(%0)\r\n""cache1,2(%0)\r\n""cache"cachestart+=}}

volatile("mfc0"and$2,$2,0xfffffff8\r\n""or $2,$2,2\r\n""mtc0$2,$16\r\n"ProbeclockfrequencyssodelayswillworkInitPMONandcpuinfotab[0]=&DBGREG;Setupexceptionbcopy(MipsException,(char*)TLB_MISS_EXC_VEC,MipsExceptionEnd-MipsException);bcopy(MipsException,(char*)GEN_EXC_VEC,MipsExceptionEnd-MipsException);CPU_SetSR(0,printf("BEVinSRsetto#if/*memtest*/printf("memtestdone\n");}/*2007-1-5于C是实现非常复杂的功能的。比如显示卡,就是最复杂的部份,由于它的BIOS代码是X86CPU执行的,不能直接在龙芯2E里运行,这样就变得非常复杂了,因此龙芯2E里就要实现一个模拟X86CPU功能才能运行显示卡的BIOS程序。不知道那天有了我们自己的显示卡厂商,才可能开发适用龙芯2E的显示卡BIOS,这样才龙芯软件开发(20)- 频率和初始化实时时前面已经介绍进入C语言世界,就会实现的功能,支持的应用。现在就来仔细地分析源程序,并且首先来的函数 Returnstheexternalclockfrequency,usuallythebus{if(md_cpufreq==0)}}static{#ifdefinti,timeout,cur,sec,SBD_DISPLAY("FREQ",#if

md_pipefreq= /*Defaults*/md_cpufreq= md_pipefreq= /*NBFPGA*/md_cpufreq= clk_invalid=#ifdefSBD_DISPLAY("FREI",Dothenexttwicefortworeasons.Firstmakesureweruncache.Secondmakesuresynchedonsecondupdate.(Punfor(i=2;i!=0;i--)cnt=timeout= while(CMOS_READ(DS_REG_CTLA)&DS_CTLA_UIP);sec=dowhile(CMOS_READ(DS_REG_CTLA)&cur=}while(timeout!=0&&cur==cnt=CPU_GetCOUNT()-cnt;if(timeout==0){ /*Getoutifclockisnotrunning}}*Calculatetheexternalbusclockif(timeout!={clk_invalid=0;md_pipefreq=cnt/10000;md_pipefreq*=20000;/*wehavenosimplewaytoreadmultipliermd_cpufreq }#endif/*HAVE_TOD}staticvoid{intyear,month,date,hour,min,sec;CMOS_WRITE(DS_CTLA_DV1,DS_REG_CTLA);CMOS_WRITE(DS_CTLB_24|DS_CTLB_DM|DS_CTLB_SET,DS_REG_CTLB);CMOS_WRITE(0,DS_REG_CTLC);CMOS_WRITE(0,year=month=CMOS_READ(DS_REG_MONTH);date=CMOS_READ(DS_REG_DATE);hour=CMOS_READ(DS_REG_HOUR);min=CMOS_READ(DS_REG_MIN);sec=CMOS_READ(DS_REG_SEC);if((year>99)||(month<1||month>12)(date<1||date>31)||(hour>23)||(min>59)||(sec>59)){printf("RTCtimeinvalid,resettoepoch.\n");*/CMOS_WRITE(3,DS_REG_YEAR);CMOS_WRITE(1,DS_REG_DATE);CMOS_WRITE(0,DS_REG_HOUR);CMOS_WRITE(0,DS_REG_MIN);CMOS_WRITE(0,DS_REG_SEC);}CMOS_WRITE(DS_CTLB_24|DS_CTLB_DM,//printf("RTC:%02d-%02d-%02d year,month,date,hour,min,}CPU龙芯软件开发(21)--调试与功能选*InitPMONandcpuinfotab[0]=&DBGREG;*PMON2000entrypoint.Calledafterinitialdbginit(char{intmemsize,freq; fs[10], /*memsize=init();/*DoallconstructorinitialisationSBD_DISPLAY("ENVI",envinit#if/*Turnoncachesunlessoptedout*/if(!getenv("nocache"))SBD_DISPLAY("SBDD",#ifdefSBD_DISPLAY("NETI",#ifNCMD_HIST>SBD_DISPLAY("HSTI",上面初始化是否缓存过去令#ifNMOD_SYMBOLS>SBD_DISPLAY("SYMI",#ifdefSBD_DISPLAY("DEMO",SBD_DISPLAY("SBDE",initial_sr|=tgt_enable(tgt_getmachtype#ifdefStatus=initial_sr&~SR_FR;/*don'tconfusenaiveclients*//*Setupinitialconsoleterminalstate*/ioctl(STDIN,TCGETA,&consterm);printf("\n*PMON2000Professional*");printf("\nConfiguration[%s,%s",TARGETNAME,BYTE_ORDER==BIG_ENDIAN?"EB":"EL");#ifdef#ifNSD>#ifNWD>printf("]\nVersion:%s.\n",printf("Supportedloaders[%s]\n",getExecString());printf("Supportedfilesystems[%s]\n",getFSString());printf("ThissoftwaremayberedistributedundertheBSDfreq=tgt_pipefreq();sprintf(fs,"%d",fp=fs+strlen(fs)-fp[3]=fp[2]=fp[1]=fp[0]=printf("%sMHz",freq=tgt_cpufreq();sprintf(fs,"%d",freq);fp=fs+strlen(fs)-6;fp[3]='\0';fp[2]=fp[1]=fp[0]=printf("/Bus@%sMHz\n",CPUprintf("Memorysize%3dMB(%3dMBLowmemory,%3dMBHighmemory).\n",(memsize>>20),#ifdefined(SMP)printf("\n");md_setpc(NULL,(int32_t)CLIENTPC);md_setsp(NULL,tgt_clienttos());#ifdefs=getenv("al");autoload(s);s=getenv("autoboot");autorun(s);}C++init(),如下:{staticintinitialized=CallglobalArrangetocallglobaldestructorsatif{initialized=1;}}ctorsGCC这些全局初始化函数,很多全局变量是没有定义的值,本来你编程时初始化为100的值,可能只是0或者任意的数值。现在又立即去看函数ctors()的实现,如下:staticvoid{void(**p)(void) +while} { =.;LONG((CTOR_END

CTOR_LIST)/4-} {

= =LONG((

DTOR_LIST)/4-}

=编译器就会根据上面的连接生成全局初始化函数和全局析构函数,并且每个函数是按照4字节的指龙芯软件开发(22)--初始化环境参envinit{intSBD_DISPLAY("MAPV",/*extractnvramvariablesintolocalcopy*/bzero(envvar,sizeof(envvar));envinited=1;SBD_DISPLAY("STDV",/*setdefaults(onlyifnotsetatall)*/for(i=0;stdenvtab[i].name;i++){if(!getenv(stdenvtab[i].name))setenv(stdenvtab[i].name,}}}envvartgt_mapenv(_setenv)设置环境变量参数,设置环境变量已经初始化,最后初始化标准的stdenvtab环境变量。*ReadinenvironmentfromNV-ramandtgt_mapenv(int P((char*,char{char*ep;char*nvram;intCheckintegrityoftheNVRAMenvarea.Ifnotininitializeitto#ifdefNVRAM_IN_FLASHnvram=(char*)((tgt_flashmap())->fl_map_base+FLASH_OFFS);printf("nvram=%08x\n",(unsignedint)nvram);if(fl_devident(nvram,NULL)==0||cksum(nvram+NVRAM_OFFS,NVRAM_SIZE,0)!=0)nvram=(char*)malloc(512);上面分配内存,然后从时钟上那些参数出来,由于时钟在CPU断电后,还会继续保存数据。接if(cksum(nvram,NVRAM_SIZE,0)!={printf("NVRAMisinvalid!\n");nvram_invalid=1;}elsenvram+=NVRAM_OFFS;ep=nvram+2;;while(*ep!=0)char*val=0,*p=env;i=0;while((*p++=*ep++)&&(ep<=nvram+NVRAM_SIZE-1)&&i++<{if((*(p-1)=='=')&&(val==NULL))*(p-1)=val=}}if(ep<=nvram+NVRAM_SIZE-1&&i<{(*func)(env,}elsenvram_invalid=2;}}}EthernetaddressforGalileoethernetisstoredinthesixbytesofnvramstorage.Setenvironmenttobcopy(&nvram[ETHER_OFFS],hwethadr,sprintf(env,"%02x:%02x:%02x:%02x:%02x:%02x",hwethadr[0],hwethadr[1],hwethadr[2],hwethadr[3],hwethadr[4],hwethadr[5]);(*func)("ethaddr",#ifdefno_thank_yousprintf(env,"%d",memorysize/(1024*1024));(*func)("memsize",env);sprintf(env,"%d",memorysize_high/(1024*1024));(*func)("highmemsize",env);sprintf(env,"%d",md_pipefreq);(*func)("cpuclock",env);sprintf(env,"%d",md_cpufreq);(*func)("busclock",env);} staticstruct{ }stdenvtab[]=

P((char*,char{"brkcmd","l-r@cpc1",0},#ifdefHAVE_QUAD{"datasize","-b","-b-h-w-d"},{"datasize","-b","-b-h-w"},{"dlecho","off","offon{"dlproto","none","noneXonXoffEtxAck"},#ifdefINET{"bootp","no","nosecprisave"},{"hostport","tty0",{"inalpha","hex","hex{"inbase",INBASE_DEFAULT,INBASE_STRING},#ifNCMD_MORE>0{"moresz","10",0,chg_moresz},{"prompt","PMON>",{"regstyle","sw","hwsw"},#ifdefHAVE_QUAD{"regsize","32","32{"rptcmd","trace","offon{"trabort","^K",{"ulcr","cr","crlf{"uleof","%",#ifdefPMON_DEBUGGER/*XXX:Patriktemp{"validpc","_ftextetext",0,chg_validpc},{"heaptop",SETCLIENTPC,0,{"showsym","yes","no{"fpfmt","both","bothdoublesingle{"fpdis","yes","noyes"},#ifdefined(TGT_DEFENV)龙芯软件开发(23)--PCI这样就需要一样东西把这些设备转换才能连接到PCI局部总线上,这个东西就是南桥的。在龙芯电脑里VT82C686,在汇编已经初始化它的串口输出,在这里会更进一步初始化其它功能。现在就来看{*Gatherinfoaboutandconfigure*/{CpuOnboardCacheOn=}elseCpuOnboardCacheOn=}{CpuExternalCacheOn=}elseCpuExternalCacheOn=}_pci_businit(1);/*PCIbusinitialization}void{}龙芯软件开发(24)--PCI#defineSUPERIO_CFG_REGstaticvoid{pcitag_ttag;#defineE2_EPP2#defineE2_S1#defineE2_S2#defineE2_FLOPPY/*配置superio*/配置。根据VT82C686B的操作流程如下:#ifdefHIGH_SPEED_SERIALlinux_outb(val|0xc0,0x3f1);/*bothportsonhighspeed*/#ifoutb(PCI_IO_SPACE_BASE+0x3f1,(COM1_BASE_ADDR-PCI_IO_SPACE_BASE)>>2);/*com1serialbaseoutb(PCI_IO_SPACE_BASE+0x3f1,(COM2_BASE_ADDR-PCI_IO_SPACE_BASE)>>2);/*com2serialbase0x3F0}staticvoid{pcitag_ttag=_pci_make_tag(VTSB_BUS,VTSB_DEV,}#defineIDE_CHIPEN_REG0x40#defineIDE_CFG_REG0x41staticvoidinitIDE(void){charval;#if/*IDEcontrollerenableval=val&~2;/*IDEIRQRoute*/tag=_pci_make_tag(VTSB_BUS,VTSB_DEV,/*enableIOspace/*settocompatiblemode上面全部设置为固定模式。也就是主IDE令寄存器是0x1F0—0x1F7,从IDE令寄存器/*latencyRTCVBAT/*settolegacyinterrupt/*enableprimary/secondarychannel/*disableprefetchbuffer&postwritebuffer/*setzerowaitstateformaster*tomakeictnb0/*disablememoryreadmultiple/memorywriteand#if}

_pci_conf_writen(tag,0x10,_pci_conf_writen(tag,0x14,_pci_conf_writen(tag,0x18,_pci_conf_writen(tag,0x1c,_pci_conf_writen(tag,0x20, #defineIRQ_ROUTE_REG10x51#defineIRQ_ROUTE_REG20x52#defineIRQ_ROUTE_REG40x55#defineIRQ_ROUTE_REG50x56#defineIRQ_ROUTE_REG60x57#definePCI_IRQ_TYPE_REG0x54#defineIRQ(x)x#definePARALLEL_IRQ #defineFLOPPY_IRQ #defineCOM1_IRQ #defineCOM2_IRQ #definePCIA_IRQ #definePCIB_IRQ #definePCIC_IRQ #define staticvoid{charval;tag=_pci_make_tag(VTSB_BUS,VTSB_DEV, 12val&=0xf;valPCI的A10B,C11,12val&=0xf0;valD13val&=0xf0;_pci_conf_writen(tag,PCI_IRQ_TYPE_REG,PARALLEL_IRQ|FLOPPY_IRQ,1);上面设置为低电平中断模}staticvoid{charval;tag=_pci_make_tag(VTSB_BUS,VTSB_DEV,/*enableon-boardio*//*enablecom1and_pci_conf_writen(tag,0x83,0x80|0x1|}龙芯软件开发(25)--PCI_pci_businit(1);/*PCIbusinitialization_pci_businit(int{charv=getenv("pciverbose");if(v){_pciverbose=}/*intialisethePCIbridge*/if(/*init*/1){SBD_DISPLAY("PCIH",init=_pci_hwinit(init,&def_bus_iot,&def_bus_memt);pci_roots=init;if(init<}{intstructpci_deviceif(_pciverbose)printf("settingup%dbus\n",}for(i=0,pb=_pci_head;i<pci_roots;i++,pb=pb->next)_pci_scan_dev(pb,i,0,}}}_pci_hwinit(initialise,iot,memt)intinitialise;bus_space_tag_tiot;bus_space_tag_tmemt;{/*pcire

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论