pmon start.s 2

start.S是pmon遮盖整个源码编译后生成的gzrom.bin文件过程中第一个被链接的文件,整个程序的开始就从start.S开始.
整个程序的第一行代码是从start开始的.
#ifndef _KERNEL
#define _KERNEL
#endif


#include <asm.h>
#include <regnum.h>
#include <cpu.h>
#include <pte.h>


#include "pmon/dev/ns16550.h"
#include "target/prid.h"
#include "target/sbd.h"
#include "target/bonito.h"
#include "target/via686b.h"
#include "target/i8254.h"
#include "target/isapnpreg.h"
//#define DEBUG_LOCORE



/***(qiaochong) memeory initialization use macro,not smbbus ***/
          /*bit 31: DDR配置结束标志,1表示结束,只读*/
#define DDR_DQS_SELECT (0<<30)    /*bit 30 选择数据来源,0: 双沿采样;1:DQS采样*/
#define DDR_DIMM_DIC (1<<29)           /*bit 29 标识DIMM_slot0是否插有内存条。
                                0:无;1:有;*/
#define DDR_DIMM_MODULE_NUM (3<<27)    /*bit 28:27 DIMM0/DIMM1上MOUDLE的数目:
        2’b00:DIMM1: 1; DIMM0: 1
        2’b01:DIMM1: 1; DIMM0: 2
        2’b10:DIMM1: 2; DIMM0: 1
        2’b11:DIMM1: 2; DIMM0: 2
        */
#define DDR_IS_SEQ  (1<<26)            /*bit 26 义突发式读写时的块内顺序,
        1’b0:顺序;1’b1:交替,现在只支持交替方式*/
#define DDR_TYPE (5<<22) /*bit 25:22 表2:DDR 控制器所支持的DDR SDRAM 计芯片类型
        BITS Density Org.  Row Addr.  Col Addr.
        0000 64Mb 16Mb X 4 DA[11:0] DA[9:0]
         128Mb 16Mb X 8
        0001 64Mb 8Mb X 8 DA[11:0] DA[8:0]
         128Mb 8Mb X 16 
        0010 64Mb 4Mb X 16 DA[11:0] DA[7:0]
        0011 128Mb 32Mb X 4 DA[11:0] DA[11],DA[9:0]
        0100 256Mb 64Mb X 4 DA[12:0] DA[11],DA[9:0]
          512Mb 64Mb X 8 
        0101 256Mb 32Mb X 8 DA[12:0] DA[9:0]
          512Mb 32Mb X 16
        0110 256Mb 16Mb X 16 DA[12:0] DA[8:0]
        0111 512Mb 128Mb X 4 DA[12:0] DA[12:11],DA[9:0]
        1000 1Gb 256Mb X 4 DA[13:0] DA[12:11],DA[9:0]
        1001 1Gb 128Mb X 8 DA[13:0] DA[11],DA[9:0]
        1010 1Gb 64Mb X 16 DA[13:0] DA[9:0]
        */
#define DDR_tREF  (100<<10) /*bit 21:10 SDRAM刷新操作之间计数(主频100MHz):
        780      7.8us
        1560     15.6us
        SDRAM刷新操作之间计数(主频133MHz):
        1040      7.8us
        2080      15.6us
        SDRAM刷新操作之间计数(主频166MHz):
        1300      7.8us
        2600      15.6us
        */
#define DDR_TRCD (1<<9) /*bit 9 行地址有效到列地址有效之间需经过的计数
        1’b0   2 cycles(DDR100)
        1’b1   3 cycles(DDR266、DDR333)*/
#define DDR_TRPC (1<<7) /*bit 8:7 AUTO_REFRESH到ACTIVE之间需经过的计数
        2’b00  Null 
        2’b01  8 cylces (DDR100)
        2’b10  10 cycles(DDR266)
        2’b11  12 cycles(DDR333)
        */
#define DDR_TRAS (0<<6) /*bit 6 ACTIVE到PRECHARGE之间需经过的计数
        1’b0   5 cycles(DDR100)
        1’b1   7 cycles(DDR266、DDR333)  
        */
#define DDR_TCAS (3<<4) /*bit 5:4 从读命令到第一个数据到来需经过的计数
        2’b00  1.5 cycles
        2’b01  2 cycles
        2’b10  2.5 cycles
        2’b11  3 cycles
        */
#define DDR_TWR (0<<3) /*bit 3 写操作最后一个数据到PRECHARGE之间需经过的计数
        1’b0   2 cycles(DDR100)
        1’b1   3 cycles(DDR266、DDR333)
        */
#define DDR_TRP (1<<2) /*bit 2 PRECHARGE命令执行时间计数
        1’b0   2 cycles(DDR100)
        1’b1   3 cycles(DDR266、DDR333)
        */
#define DDR_TRC (1<<0) /*bit 1:0 ACTIVE与ACTIVE/AUTO_REFRESH命令之间计数
        2’b00  Null
        2’b01  7 cycles(DDR100)
        2’b10  9 cycles(DDR266)
        2’b11  10cycles(DDR333)
        注(由于precharge和ras cas的延时加起来正好满足这个延时,所以在DDR控制器里没有具体考虑这个参数)
        */
#define sdcfg_DATA DDR_DQS_SELECT|DDR_DIMM_DIC|DDR_DIMM_MODULE_NUM|DDR_IS_SEQ|DDR_TYPE|DDR_tREF|DDR_TRCD|DDR_TRPC|DDR_TRAS|DDR_TCAS|DDR_TWR|DDR_TRP|DDR_TRC


#ifdef DEBUG_LOCORE
#define TTYDBG(x) \
 .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop
#else
#define TTYDBG(x)
#endif


#define PRINTSTR(x) \
 .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop


#define CONFIG_CACHE_64K_4WAY 1


#define tmpsize  s1
#define msize  s2
#define bonito  s4
#define dbg   s5
#define sdCfg  s6


#define CP0_CONFIG $16
#define CP0_TAGLO  $28
#define CP0_TAGHI  $29


#define DDR100 0x1d441091 
/* 
#define DDR100 0x0c011091*/
#define DDR266 0x0410435e
#define DDR300 0x041453df


#define DDR_DQ 0xbff00030             /*  zgj  */
 *   Register usage:
 *
 * s0 link versus load offset, used to relocate absolute adresses.
 * s1 free
 * s2 memory size.
 * s3 free.
 * s4 Bonito base address.
 * s5 dbg.
 * s6 sdCfg.
 * s7 rasave.
 * s8 L3 Cache size.
 */
/*?为什么有这种约定*/
/*上面说明的在本程序中子程序寄存器s0-s8(寄存器毫16-23,30)的默认使用规则*/
 .set noreorder /*防止汇编器为了在分支延迟槽中填充有用指令而打乱代码次序*/
 .globl _start/*声明__start start  __main为全局地址*/
 .globl start
 .globl __main
_start:
start:
 .globl stack /*声明stack为全局变量,并设置其地址为PMON起始代码后面16K的地方,MIPS体系结构的cpu上电执行的第一条指令位于物理地址0X1fc00000的地方开始执行,此处被北桥映射为flash的0地址,但start的值在最终生成的rom镜像gzrom中是由链接时候指定的地址0X81000000(参照/zloader/Makefile.inc GZROMSTARTADDR?=0xffffffff81000000),那么stack的值为0X80ffd000,注意这里虽然设置了栈在ram空间,但并没有使用,因为在Kseg0中,cache还没有设置,并且这里提到的地址是逻辑地址,而不关物理地址是如何映射的,mips体系结构是不能直接物理寻址的,总要从逻辑地址映射到物理地址,不同的段映射方法不同,具体的知识请自行查阅.注意:在位置无关代码的执行,到底其程序地址是否和物理地址一致,并没有关系,如果需要寻址某个逻辑地址,一般可用相对PC寻址解决,或者在已经知道物理地址的情况下,根据物理地址和程序地址的关系进行调整,程序计数器(PC)存放的是程序地址*/
stack = start - 0x4000  /* Place PMON stack below PMON start in RAM */
                               /*定义符号stack 并赋值为start后面16K的地址值,在实际汇编的时候才会展开*/
/* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! 根据mips异常向量表,BEV=1时,reset异常的程序地址为0xbfc00000-0xbfc00200,有0x200个字,可以存储128条指令,但要去除后面ext_map_and_reboot对齐到0x100,占去了64条指令,故这里只能最多有64条指令,何来16条指令?*/
/*协处理器cp0寄存器的定义在sys/arch/mips/include/cpu.h中定义,zero,t0,sp,gp等处理器寄存器的习惯用法定义在sys/arch/mips/include/regdef.h中*/
 mtc0 zero, COP_0_STATUS_REG/*将status和cause寄存器清零,复位时status初值为0x30400004,表示发生了复位等错误,运行在内核模式,协处理器0和1可用.清零后,主要是关闭所有中断,清除复位错误,协处理器1不可用,处理器运行在内核模式*/
 mtc0 zero, COP_0_CAUSE_REG
 li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location */
 mtc0 t0, COP_0_STATUS_REG   /*SR_BOOT_EXC_VEC=0x00400000设置status中的BEV为1,例外向量的入口地址从0xbfc00000开始,也就是从映射到给地址的rom开始*/
 la sp, stack  /*初始化堆栈指针*/
 la gp, _gp  /*初始化全局指针,其中_gp是有链接器定义的全局指针变量,sp和gp均需要需要展开,这两条指令会变为4条这样子就有了15条指令*/


 bal uncached  /* Switch to uncached address space */
 nop                     /*这里需要说明的是,此时程序地址是从0xbfc00000开始的,跳转后,ra=pc+8即bal locate 的加载地址,从反汇编可知,此时pc=0xbfc00000,那么ra=0xbfc00028,与UNCACHED_MEMORY_ADDR或后ra=0xbfc00028,这是从rom加载的时候,若是从其他地址加载,就需要进行地址修正了,此外,副作用是清空流水线和预取指令*/


 bal locate   /* Get current execute address */
 nop


uncached:/*地址修正,*/
 or ra, UNCACHED_MEMORY_ADDR/*UNCACHED_MEMORY_ADDR=0xa0000000,参照sys/arch/mips/include/cpu.h,先加载UNCACHED_MEMORY_ADDR,然后or,汇编为2条指令,故共16条指令*/
 j ra
 nop


/*
 *  Reboot vector usable from outside pmon.
 *//*该段在这里做什么,值得思考.从后面的代码可以看出,此处主要是为了出了异常之后,PMON重新启动的入口地址*/
 .align 8
ext_map_and_reboot:
 bal CPU_TLBClear
 nop


 li a0, 0xc0000000
 li a1, 0x40000000
 bal CPU_TLBInit
 nop
 la v0, tgt_reboot
 la v1, start
 subu v0, v1
 lui v1, 0xffc0
 addu v0, v1
 jr v0
 nop


/*
 *  Exception vectors here for rom, before we are up and running. Catch
 *  whatever comes up before we have a fully fledged exception handler.
 */                                      /*这里是例外向量,其实啥都没做,就是输出一些相关的信息,然后跳到统一的ex
_common出来处理,这是靠对齐来保证位于位于MIPS体系机构相应的中断向量处,如.align 9  则以2^9为间隔对齐,换成16进制,就是以0x200为间隔*/
 .align 9   /* bfc00200 TLB替换(32位) */
 la a0, v200_msg            
 bal stringserial
 nop
 b exc_common


 .align 7   /* bfc00280 TLB替换(64位)*/
 la a0, v280_msg
 bal stringserial
 nop
 b exc_common


/* Cache error */
 .align 8   /* bfc00300 cache出错*/
 PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ")
 mfc0 a0, COP_0_CACHE_ERR
 bal hexserial
 nop
 b exc_common


/* General exception */
 .align 7   /* bfc00380 普通中断*/
 la a0, v380_msg
 bal stringserial
 nop
 b exc_common
 
 .align 8   /* bfc00400 不可识别的中断*/
 la a0, v400_msg
 bal stringserial
 nop



 
exc_common:
 PRINTSTR("\r\nCAUSE=")
 mfc0 a0, COP_0_CAUSE_REG
 bal hexserial
 nop
 PRINTSTR("\r\nSTATUS=")
 mfc0 a0, COP_0_STATUS_REG
 bal hexserial
 nop
 PRINTSTR("\r\nERRORPC=")
 mfc0 a0, COP_0_ERROR_PC
 bal hexserial
 nop
 PRINTSTR("\r\nEPC=")
 mfc0 a0, COP_0_EXC_PC
 bal hexserial
 nop
 PRINTSTR("\r\nDERR0=")
 cfc0 a0, COP_0_DERR_0
 bal hexserial
 nop
 PRINTSTR("\r\nDERR1=")
 cfc0 a0, COP_0_DERR_1
 bal hexserial
 nop


// b ext_map_and_reboot  /*跳转到reset异常入口 0x100相对地址*/
 nop


 .align 8
  nop
 .align 8
 .word read
 .word write
 .word open
 .word close
 .word nullfunction
 .word printf
 .word vsprintf
 .word nullfunction
 .word nullfunction
 .word getenv
 .word nullfunction
 .word nullfunction
 .word nullfunction
 .word nullfunction
/*
 *  We get here from executing a bal to get the PC value of the current execute
 *  location into ra. Check to see if we run from ROM or if this is ramloaded.
 */
locate:/*ramloadded 加载地址为0x81000000*/
 la s0,start  /*无论是gzram还是gzram,start的均为0x81000000*/
 subu s0,ra,s0   /*从rom执行的时候ra=0xbfc00030,若从ram加载,则ra=0x81000030*/
 and s0,0xffff0000 /*s0只是测试用的,没有多少实际意义*/


 li t0,SR_BOOT_EXC_VEC
 mtc0 t0,COP_0_STATUS_REG/*重新设置satus为0x00400000,cause=0x00000000*/
        mtc0    zero,COP_0_CAUSE_REG
 .set noreorder /*这里似乎多余,前面已经定义了*/


  li bonito,PHYS_TO_UNCACHED(BONITO_REG_BASE)
  /*下面这一段的宏定义,是针对bonito北桥的一些数据定义*/
/*#define bonito  s4   本文件定义
  #define PHYS_TO_UNCACHED(x)  ((unsigned)(x) | UNCACHED_MEMORY_ADDR) 参照sys/arch/mips/include/cpu.h 
  #define BONITO_REG_BASE   0x1fe00000 参照Targets/Bonito2fdev/include/bonito.h
 反汇编就是  lui     $s4,0xbfe0
*/
#define MOD_MASK 0x00000003
#define MOD_B  0x00000000 /* byte "modifier" */
#define MOD_H  0x00000001 /* halfword "modifier" */
#define MOD_W  0x00000002 /* word "modifier" */
#if __mips64
# define MOD_D  0x00000003 /* doubleword "modifier" */
#endif


#define OP_MASK  0x000000fc
#define OP_EXIT  0x00000000 /* exit (status) */
#define OP_DELAY 0x00000008 /* delay (cycles) */
#define OP_RD  0x00000010 /* read (addr) */
#define OP_WR  0x00000014 /* write (addr, val) */
#define OP_RMW  0x00000018 /* read-modify-write (addr, and, or) */
#define OP_WAIT  0x00000020 /* wait (addr, mask, value) */


#define WR_INIT(mod,addr,val) \
 .word OP_WR|mod,PHYS_TO_UNCACHED(addr);\
 .word (val),0
 
#define RD_INIT(mod,addr) \
 .word OP_RD|mod,PHYS_TO_UNCACHED(addr);\
 .word 0,0
 
#define RMW_INIT(mod,addr,and,or) \
 .word OP_RMW|mod,PHYS_TO_UNCACHED(addr);\
 .word (and),(or)
 
#define WAIT_INIT(mod,addr,and,or) \
 .word OP_WAIT|mod,PHYS_TO_UNCACHED(addr);\
 .word (mask),(val)


#define DELAY_INIT(cycles) \
 .word OP_DELAY,(cycles);\
 .word 0,0
 
#define EXIT_INIT(status) \
 .word OP_EXIT,(status);\
 .word 0,0


#define BONITO_INIT(r,v) WR_INIT(MOD_W,BONITO_BASE+/**/r,v)
#define BONITO_BIS(r,b) RMW_INIT(MOD_W,BONITO_BASE+(r),~0,b)
#define BONITO_BIC(r,b) RMW_INIT(MOD_W,BONITO_BASE+(r),~(b),0)
#define BONITO_RMW(r,c,s) RMW_INIT(MOD_W,BONITO_BASE+(r),~(c),s)
 
#define CFGADDR(idsel,function,reg) ((1<<(11+(idsel)))+((function)<<8)+(reg))
#define _ISABWR_INIT(mod,function,isabreg,val) \
 WR_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG,CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)>>16) ; \
        RD_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG) ; \
 WR_INIT(mod,PCI_CFG_SPACE+(CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)&0xffff),val)
 
#define _ISABRD_INIT(mod,function,isabreg) \
 WR_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG,CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)>>16) ; \
        RD_INIT(MOD_W,BONITO_BASE+BONITO_PCIMAP_CFG) ; \
 RD_INIT(mod,PCI_CFG_SPACE+(CFGADDR(PCI_IDSEL_VIA686B,function,isabreg)&0xffff))



#define _ISAWR_INIT(isareg,val) \
 WR_INIT(MOD_B,PCI_IO_SPACE+(isareg),val)
 
#define _ISARD_INIT(isareg) \
 RD_INIT(MOD_B,PCI_IO_SPACE+(isareg))
 


#define ISABBWR_INIT(function,isabreg,val) \
 _ISABWR_INIT(MOD_B,function,(isabreg),val)
#define ISABHWR_INIT(function,isabreg,val) \
 _ISABWR_INIT(MOD_H,function,(isabreg),val)
#define ISABWWR_INIT(function,isabreg,val) \
 _ISABWR_INIT(MOD_W,function,isabreg,val)
#define ISAWR_INIT(isareg,val) \
 _ISAWR_INIT(isareg,val)
#define ISARD_INIT(isareg) \
 _ISARD_INIT(isareg)


 bal 1f 
 nop


 /* bonito endianess */
 BONITO_BIC(BONITO_BONPONCFG,BONITO_BONPONCFG_CPUBIGEND)
 /* 
          展开变成
          .word 0x00000018|0x00000002,((0x1fe00000+((0x100+0x00)))|0xa0000000);
          .word (~(0x00004000)),(0)
         */
 BONITO_BIC(BONITO_BONGENCFG,BONITO_BONGENCFG_BYTESWAP|BONITO_BONGENCFG_MSTRBYTESWAP)
 BONITO_BIS(BONITO_BONPONCFG, BONITO_BONPONCFG_IS_ARBITER)
 
        /*
         * In certain situations it is possible for the Bonito ASIC
         * to come up with the PCI registers uninitialised, so do them here
         */
#define PCI_CLASS_BRIDGE  0x06
#define PCI_CLASS_SHIFT   24
#define PCI_SUBCLASS_BRIDGE_HOST 0x00
#define PCI_SUBCLASS_SHIFT  16
#define PCI_COMMAND_IO_ENABLE  0x00000001
#define PCI_COMMAND_MEM_ENABLE  0x00000002
#define PCI_COMMAND_MASTER_ENABLE 0x00000004
#define PCI_COMMAND_STATUS_REG  0x04
#define PCI_MAP_IO   0X00000001
#define PCI_CFG_SPACE   BONITO_PCICFG_BASE


        BONITO_INIT(BONITO_PCICLASS,(PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT) | (PCI_SUBCLASS_BRIDGE_HOST << PCI_SUBCLASS_SHIFT))
 BONITO_INIT(BONITO_PCICMD, BONITO_PCICMD_PERR_CLR|BONITO_PCICMD_SERR_CLR|BONITO_PCICMD_MABORT_CLR|BONITO_PCICMD_MTABORT_CLR|BONITO_PCICMD_TABORT_CLR|BONITO_PCICMD_MPERR_CLR)
 //BONITO_INIT(BONITO_PCILTIMER, 0)
 BONITO_INIT(BONITO_PCILTIMER, 255)
 BONITO_INIT(BONITO_PCIBASE0, 0)
 BONITO_INIT(BONITO_PCIBASE1, 0)
 BONITO_INIT(BONITO_PCIBASE2, 0)
 BONITO_INIT(BONITO_PCIEXPRBASE, 0)
 BONITO_INIT(BONITO_PCIINT, 0)


 BONITO_BIS(BONITO_PCICMD, BONITO_PCICMD_PERRRESPEN)
 
 BONITO_BIS(BONITO_PCICMD, PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE)
 
    BONITO_BIC(BONITO_BONGENCFG, 0x80)  #陆没?鹿iobc


 #BONITO_BIS(BONITO_BONGENCFG, BONITO_BONGENCFG_BUSERREN)


 /* Set debug mode */
 BONITO_BIS(BONITO_BONGENCFG, BONITO_BONGENCFG_DEBUGMODE)


    /******** added to init southbridge*/
 
 /* Set the SMB base address */
 ISABWWR_INIT(4, SMBUS_IO_BASE_ADDR, SMBUS_IO_BASE_VALUE | 0x1)
 /* enable the host controller */
 ISABHWR_INIT(4, SMBUS_HOST_CONFIG_ADDR, SMBUS_HOST_CONFIG_ENABLE_BIT)
 /* enable the SMB IO ports */
 ISABBWR_INIT(4, PCI_COMMAND_STATUS_REG, PCI_COMMAND_IO_ENABLE)
 
/* 15us ISA bus refresh clock */
#define ISAREFRESH (PT_CRYSTAL/(1000000/15))
 ISARD_INIT(CTC_PORT+PT_CONTROL)
 
 /* program i8254 ISA refresh counter */
 ISAWR_INIT(CTC_PORT+PT_CONTROL,PTCW_SC(PT_REFRESH)|PTCW_16B|PTCW_MODE(MODE_RG))
 ISAWR_INIT(CTC_PORT+PT_REFRESH, ISAREFRESH & 0xff)
 ISAWR_INIT(CTC_PORT+PT_REFRESH, ISAREFRESH >> 8)


                                                                        
 EXIT_INIT(0)
        /*展开
        .word 0x00000000,(0)
        .word 0,0    
        参数初始化完成    
*/


#define Init_Op 0
#define Init_A0 4
#define Init_A1 8
#define Init_A2 12
#define Init_Size 16
/*下面开始初始化北桥*/
1: move a0,ra/*ra此时的值为BONITO_BIC(BONITO_BONPONCFG,BONITO_BONPONCFG_CPUBIGEND)的地址,即初始化数据开始的地址*/
reginit:   /* local name */
 lw t3, Init_Op(a0) 
 lw t0, Init_A0(a0)
 and t4,t3,OP_MASK
 
 
 /* 
  * EXIT(STATUS) 
  */
 bne t4, OP_EXIT, 8f
 nop
 move v0,t0
 b .done
 nop
 
 /* 
  * DELAY(CYCLES) 
  */
8: bne t4, OP_DELAY, 8f
 nop
1: bnez t0,1b
 subu t0,1
 b .next
 nop 
 /* 
  * READ(ADDR) 
  */
8: bne t4,OP_RD,8f
 nop
 and t4,t3,MOD_MASK
 
 bne t4,MOD_B,1f
 nop
 lbu t5,0(t0)
 b .next
 nop
1: bne t4,MOD_H,1f
 nop
 lhu t5,0(t0)
 b .next
 nop
1: bne t4,MOD_W,1f
 nop
#if __mips64
 lwu t5,0(t0)
#else 
 lw t5,0(t0)
#endif
 b .next
 nop
1: 
#if __mips64
 lw t5,0(t0)
 b .next
 nop
#else
 b .fatal
 nop
#endif
 
 /* 
  * WRITE(ADDR,VAL) 
  */
8: bne t4,OP_WR,8f
 nop
 lw t1,Init_A1(a0)
 and t4,t3,MOD_MASK
 
 bne t4,MOD_B,1f
 nop
 sb t1,0(t0)
 b .next
 nop
1: bne t4,MOD_H,1f
 nop
 sh t1,0(t0)
 b .next
 nop
1: bne t4,MOD_W,1f
 nop
 sw t1,0(t0)
 b .next
 nop
 
1: 
#if __mips64
 sd t1,0(t0)
 b .next
 nop
#else
 b .fatal
 nop
#endif
  
 
 /* 
  * RMW(ADDR,AND,OR) 
  */
8: bne t4,OP_RMW,8f
 nop
 lw t1,Init_A1(a0)
 lw t2,Init_A2(a0)
 and t4,t3,MOD_MASK
 
 bne t4,MOD_B,1f
 nop
 lbu t4,0(t0)
 and t4,t1
 or t4,t2
 sb t4,0(t0)
 b .next
 nop
1: bne t4,MOD_H,1f
 nop
 lhu t4,0(t0)
 and t4,t1
 or t4,t2
 sh t4,0(t0)
 b .next
 nop
1: bne t4,MOD_W,1f
 nop
 lw t4,0(t0)
 and t4,t1
 or t4,t2
 sw t4,0(t0)
 b .next
 nop
 
1:  
#if __mips64
 ld t4,0(t0)
 and t4,t1
 or t4,t2
 sd t4,0(t0)
 b .next
 nop
#else 
 b .fatal
 nop
#endif
  
 
 /* 
  * WAIT(ADDR,MASK,VAL) 
  */
8: bne t4,OP_WAIT,8f
 nop
 lw t1,Init_A1(a0)
 lw t2,Init_A2(a0)
 and t4,t3,MOD_MASK
 
 bne t4,MOD_B,1f
 nop
3: lbu t4,0(t0)
 and t4,t1
 bne t4,t2,3b
 nop
 b .next
 nop
1: bne t4,MOD_H,1f
 nop
3: lhu t4,0(t0)
 and t4,t1
 bne t4,t2,3b
 nop
 b .next
 nop
1: bne t4,MOD_W,1f
 nop
3: lw t4,0(t0)
 and t4,t1
 bne t4,t2,3b
 nop
 b .next
 nop
1:  
#if __mips64
3: ld t4,0(t0)
 and t4,t1
 bne t4,t2,3b
 nop
 b .next
 nop
#else 
 b .fatal 
 nop
#endif
 
 
.next: addu a0,Init_Size
 b reginit 
 nop 
 
8:
.fatal: b .done
 nop
 bal  stuck
 nop
.done: 
              
 bal  superio_init/*初始化南桥的superio*/
 nop
 
 bal initserial/*初始化南桥的串口*/
 nop
 
 PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n")
 PRINTSTR("ERRORPC=")
 mfc0 a0, COP_0_ERROR_PC
 bal hexserial
 nop


 PRINTSTR(" CONFIG=")
 mfc0 a0, COP_0_CONFIG
 bal hexserial
 nop
 PRINTSTR("\r\n")
 
 PRINTSTR(" PRID=")
 mfc0 a0, COP_0_PRID
 bal hexserial
 nop
 PRINTSTR("\r\n")


 /* 
  * Now determine DRAM configuration and size by
  * reading the I2C EEROM on the DIMMS
  */


#include "i2c.S"/*初始化I2C总线*/
 beqz msize,.nodimm
 nop
 b 2f
 nop
.nodimm:
 move dbg,a0
 PRINTSTR ("\r\nNo DIMM in all slots,use default configure\r\n")
 li  msize,0x10000000
  li sdCfg,0x055043df         /* zgj-8-7-14-13 */
2:
 PRINTSTR("DIMM SIZE=")
 move a0,msize
 bal hexserial
 nop
 PRINTSTR("\r\n")


 li t0, 0xbff00008
 sd sdCfg, 0(t0)


 #### gx 2006-03-17: mode ####
 #li t1,0x20
 li t1,0x28
 li t0, 0xbff00000
 sw t1,0(t0)
 nop
 li t1,0x0
 li t0, 0xbff00000
 sw t1,0x30(t0)
 nop


 PRINTSTR("sdcfg=");
 move a0,sdCfg
 bal hexserial
 nop
 PRINTSTR("\r\n");
 PRINTSTR("msize=");
 move a0,msize
 bal hexserial
 nop
 PRINTSTR("\r\n")


 
skipdimm:


 li t1,0  # accumulate pcimembasecfg settings
  
 /* set bar0 mask and translation to point to SDRAM */
 sub t0,msize,1
 not t0
 srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT
 and t0,BONITO_PCIMEMBASECFG_MEMBASE0_MASK
 or t1,t0
 
 li t0,0x00000000
 srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT
 and t0,BONITO_PCIMEMBASECFG_MEMBASE0_TRANS
 or t1,t0
 or t1,BONITO_PCIMEMBASECFG_MEMBASE0_CACHED


 /* set bar1 to minimum size to conserve PCI space */
 li t0, ~0
 srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT
 and t0,BONITO_PCIMEMBASECFG_MEMBASE1_MASK
 or t1,t0
 
 li t0,0x00000000
 srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT
 and t0,BONITO_PCIMEMBASECFG_MEMBASE1_TRANS
 or t1,t0
 or t1,BONITO_PCIMEMBASECFG_MEMBASE1_CACHED


 sw t1,BONITO_PCIMEMBASECFG(bonito)


 /* enable configuration cycles now */
 lw t0,BONITO_BONPONCFG(bonito)
 and t0,~BONITO_BONPONCFG_CONFIG_DIS
 sw t0,BONITO_BONPONCFG(bonito)


 PRINTSTR("Init SDRAM Done!\r\n");


 


/*
 *  Reset and initialize caches to a known state.
 */
#define IndexStoreTagI 0x08
#define IndexStoreTagD 0x09
#define IndexStoreTagS 0x0b
#define IndexStoreTagT 0x0a
#define FillI  0x14


/*
 *  RM7000 config register bits.
 */
#define CF_7_SE         (1 << 3)        /* Secondary cache enable */
#define CF_7_SC         (1 << 31)       /* Secondary cache not present */
#define CF_7_TE         (1 << 12)       /* Tertiary cache enable */
#define CF_7_TC         (1 << 17)       /* Tertiary cache not present */
#define CF_7_TS         (3 << 20)       /* Tertiary cache size */
#define CF_7_TS_AL      20              /* Shift to align */
#define NOP8 nop;nop;nop;nop;nop;nop;nop;nop
do_caches:
 TTYDBG("Sizing caches...\r\n");


 mfc0 t3, COP_0_CONFIG /* t3 = original config */
 and t3, 0xffffeff0  /* Make sure coherency is OK */


 and t3, ~(CF_7_TE|CF_7_SE|CF_7_TC|CF_7_SC)  /* disable L2/L3 cache */
 mtc0    t3, COP_0_CONFIG


 li t2, 4096


 srl t1, t3, 9
 and t1, 3
 sllv s3, t2, t1  /* s3 = I cache size */


#ifdef CONFIG_CACHE_64K_4WAY 
        sll     s3,2
#endif


 and t1, t3, 0x20
 srl t1, t1, 1
 addu s4, t1, 16  /* s4 = I cache line size */


 srl t1, t3, 6
 and t1, 3
 sllv s5, t2, t1  /* s5 = D cache size */


#ifdef CONFIG_CACHE_64K_4WAY
        sll     s5,2
#endif


 and t1, t3, 0x10
 addu s6, t1, 16  /* s6 = D cache line size */
 TTYDBG("Init caches...\r\n")


 li s7, 0                   /* no L2 cache */
 li s8, 0                   /* no L3 cache */


#if 0
        mfc0    a0, COP_0_PRID
        li      a1, 0x6301
        bne     a0,a1,1f
        nop
#endif
 TTYDBG("godson2 caches found\r\n")
        bal     godson2_cache_init
        nop


 /* close L2 cache */
 li      a0, 0xbfe00164
        sw      zero, 0(a0);


        mfc0   a0,COP_0_CONFIG
        and    a0,a0,~((1<<12) | 3)
 or     a0,a0,2
        mtc0   a0,COP_0_CONFIG


#ifdef DEBUG_LOCORE
 TTYDBG("Init caches done, cfg = ")
 mfc0 a0, COP_0_CONFIG
 bal hexserial
 nop
 TTYDBG("\r\n\r\n")
#endif


/* zhb */
#if 0
/* li t0, 0  */
/* li t1, 0x90000 */
/*1: addiu t0, 1  */
/* bne t0, t1, 1b */
 nop


 TTYDBG("Testing memory...\r\n")
 
 li t7, 10
tmem:
 li t0, 0xa0000000+1*1024*1024
 li t1, 0xa0000000
 li t2, 0xffffffff
1:
 sw t2, 0(t1)
 lw t3, 0(t1)
 bne t3, t2, 1f
 nop
 not t2
 sw t2, 0(t1)
 lw t3, 0(t1)
 bne t3, t2, 1f
 nop
 not t2
 subu t2, 1
 addu t1, 4
 beq t1, t0, 2f
 nop
 and t4, t1, 0x000fffff
 bnez t4, skipdot
 li a0, '.'
 bal tgt_putchar
 nop
skipdot:
 b 1b
 nop
1:
 TTYDBG("Memory test failed at ");
 move a0, t1
 bal hexserial
 nop
 TTYDBG("\r\nWrite=");
 move a0, t2
 bal hexserial
 nop
 TTYDBG("\r\nRead=");
 move a0, t3
 bal hexserial
 nop
1:
 b 1b
 nop
2:
 TTYDBG("Testing ok...\r\n");
 sub t7,1
 beqz t7, 1f
 nop
 b tmem
 nop
1: 
 b 1b
 nop
#endif
#include "machine/newtest/mydebug.S"
bootnow:
 TTYDBG("Copy PMON to execute location...\r\n")
#ifdef DEBUG_LOCORE
 TTYDBG("  start = 0x")
 la a0, start
 bal hexserial
 nop
 TTYDBG("\r\n  s0 = 0x")
 move a0, s0
 bal hexserial
 nop
 TTYDBG("\r\n")
#endif
 la a0, start
 li a1, 0xbfc00000
 la a2, _edata
        or      a0, 0xa0000000
        or      a2, 0xa0000000
 subu t1, a2, a0
 srl t1, t1, 2


 move t0, a0
 move t1, a1
 move t2, a2


 /* copy text section */
 
1: and t3,t0,0x0000ffff
 bnez t3,2f
 nop
 move a0,t0
 bal hexserial
 nop
 li a0,'\r'
 bal  tgt_putchar
 nop
2: lw t3, 0(t1)
 nop
 sw t3, 0(t0)
 addu t0, 4
 addu t1, 4
 bne t2, t0, 1b
 nop


 PRINTSTR("\ncopy text section done.\r\n")
 
 /* Clear BSS */
 la a0, _edata
 la a2, _end
2: sw zero, 0(a0)
 bne a2, a0, 2b
 addu a0, 4



 TTYDBG("Copy PMON to execute location done.\r\n")
/* zhb */
#if 0
zhb:
 TTYDBG("Testing...\r\n")
 la a0, start
 li a1, 0xbfc00000
 la a2, _edata
        or      a0, 0xa0000000
        or      a2, 0xa0000000
/* subu s6, a2, a0*/
/* srl s6, s6, 2*/


 move t0, a0
 move t1, a1
 move t2, a2
 /* copy text section */
 
1: lw t4, 0(t1)
 nop
 lw t5, 0(t0)
 addu t0, 4
 addu t1, 4
 beq t4, t5, 2f
 nop
 move a0, t0
 subu a0, 4
 bal hexserial
 nop
 TTYDBG (" ")
 move a0, t4
 bal hexserial
 nop
 TTYDBG (" ")
 move a0, t5
 bal hexserial
 nop
 TTYDBG ("\r\n")
2: bne t2, t0, 1b
 nop
 TTYDBG ("test ok!\r\n")
/*
3: beqz zero, 3b
 nop
*/
#endif


 


 TTYDBG("sp=");
 move a0, sp
 bal hexserial
 nop


 li a0, 4096*1024
 sw a0, CpuTertiaryCacheSize /* Set L3 cache size */


#if 0
        mfc0   a0,COP_0_CONFIG
        and    a0,a0,0xfffffff8
        or     a0,a0,0x3
        mtc0   a0,COP_0_CONFIG
#endif


 move a0,msize
 srl a0,20


    /* pass pointer to kseg1 tgt_putchar */
    la  a1, tgt_putchar
 addu a1,a1,s0


    la  a2, stringserial
 addu a2,a2,s0


 la v0, initmips
 jalr v0
 nop
stuck:
#ifdef DEBUG_LOCORE
 TTYDBG("Dumping GT64240 setup.\r\n")
 TTYDBG("offset----data------------------------.\r\n")
 li s3, 0
1:
 move a0, s3
 bal hexserial
 nop
 TTYDBG(": ")
2:
 add a0, s3, bonito
 lw a0, 0(a0)
 bal hexserial
 addiu s3, 4
 TTYDBG(" ")
 li a0, 0xfff
 and a0, s3
 beqz a0, 3f
 li a0, 0x01f
 and a0, s3
 bnez a0, 2b
 TTYDBG("\r\n")
 b 1b
 nop
3:
 b 3b
 nop


#else
 b stuck
 nop
#endif
/*
 *  Clear the TLB. Normally called from start.S.
 */
#if __mips64
#define MTC0 dmtc0
#else 
#define MTC0 mtc0
#endif
LEAF(CPU_TLBClear)
 li a3, 0   # First TLB index.


 li a2, PG_SIZE_4K
 MTC0   a2, COP_0_TLB_PG_MASK   # Whatever...


1:
 MTC0   zero, COP_0_TLB_HI # Clear entry high.
 MTC0   zero, COP_0_TLB_LO0 # Clear entry low0.
 MTC0   zero, COP_0_TLB_LO1 # Clear entry low1.


 mtc0    a3, COP_0_TLB_INDEX # Set the index.
 addiu a3, 1
 li a2, 64
 nop
 nop
 tlbwi    # Write the TLB


 bne a3, a2, 1b
 nop


 jr ra
 nop
END(CPU_TLBClear)


/*
 *  Set up the TLB. Normally called from start.S.
 */
LEAF(CPU_TLBInit)
 li a3, 0   # First TLB index.


 li a2, PG_SIZE_16M
 MTC0   a2, COP_0_TLB_PG_MASK   # All pages are 16Mb.


1:
 and a2, a0, PG_SVPN
 MTC0   a2, COP_0_TLB_HI # Set up entry high.


 move a2, a0
 srl a2, a0, PG_SHIFT 
 and a2, a2, PG_FRAME
 ori a2, PG_IOPAGE
 MTC0   a2, COP_0_TLB_LO0 # Set up entry low0.
 addu a2, (0x01000000 >> PG_SHIFT)
 MTC0   a2, COP_0_TLB_LO1 # Set up entry low1.


 mtc0    a3, COP_0_TLB_INDEX # Set the index.
 addiu a3, 1
 li a2, 0x02000000
 subu a1, a2
 nop
 tlbwi    # Write the TLB


 bgtz a1, 1b
 addu a0, a2   # Step address 32Mb.


 jr ra
 nop
END(CPU_TLBInit)


LEAF(stringserial)
 move a2, ra
 addu a1, a0, s0
 lbu a0, 0(a1)
1:
 beqz a0, 2f
 nop
 bal tgt_putchar
 addiu a1, 1
 b 1b
 lbu a0, 0(a1)


2:
 j a2
 nop
END(stringserial)


LEAF(outstring)
 move a2, ra
 move a1, a0
 lbu a0, 0(a1)
1:
 beqz a0, 2f
 nop
 bal tgt_putchar
 addiu a1, 1
 b 1b
 lbu a0, 0(a1)


2:
 j a2
 nop
END(outstring)


LEAF(hexserial)
 move a2, ra
 move a1, a0
 li a3, 7
1:
 rol a0, a1, 4
 move a1, a0
 and a0, 0xf
 la v0, hexchar
 addu v0, s0
 addu v0, a0
 bal tgt_putchar
 lbu a0, 0(v0)


 bnez a3, 1b
 addu a3, -1


 j a2
 nop
END(hexserial)


LEAF(tgt_putchar)
 la v0, COM1_BASE_ADDR
1:
 lbu v1, NSREG(NS16550_LSR)(v0)
 and v1, LSR_TXRDY
 beqz v1, 1b
 nop


 sb a0, NSREG(NS16550_DATA)(v0)
#ifdef HAVE_NB_SERIAL
 move v1,v0
 la v0, COM3_BASE_ADDR
 bne v0,v1,1b
 nop
#endif
 j ra
 nop 
END(tgt_putchar)


/* baud rate definitions, matching include/termios.h */
#define B0      0
#define B50     50      
#define B75     75
#define B110    110
#define B134    134
#define B150    150
#define B200    200
#define B300    300
#define B600    600
#define B1200   1200
#define B1800   1800
#define B2400   2400
#define B4800   4800
#define B9600   9600
#define B19200  19200
#define B38400  38400
#define B57600  57600
#define B115200 115200


LEAF(initserial)
 la v0, COM1_BASE_ADDR
  la a0, NS16550HZ/2/(16*CONS_BAUD)
1:
 li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
 sb v1, NSREG(NS16550_FIFO)(v0)
 li v1, CFCR_DLAB
 sb v1, NSREG(NS16550_CFCR)(v0)
 sb a0, NSREG(NS16550_DATA)(v0)
 srl v1, 8
 sb v1, NSREG(NS16550_IER)(v0)
 li v1, CFCR_8BITS
 sb v1, NSREG(NS16550_CFCR)(v0)
 li v1, MCR_DTR|MCR_RTS
 sb v1, NSREG(NS16550_MCR)(v0)
 li v1, 0x0
 sb v1, NSREG(NS16550_IER)(v0)
#ifdef HAVE_NB_SERIAL
 move v1,v0
 la v0, COM3_BASE_ADDR
  li a0, NS16550HZ/(16*CONS_BAUD)
 bne v0,v1,1b
 nop
#endif
 j ra
 nop
END(initserial)



/* a0: slave address 
   a1: reg off
*/
LEAF(i2cread)
        /* set device address */
        li  v0, 0xbfd00000 + SMBUS_HOST_ADDRESS


        sb  a0, 0(v0);


        /* store register offset */
        li  v0, 0xbfd00000 + SMBUS_HOST_COMMAND
        sb  a1, 0(v0);


        /* read byte data protocol */
        li  v0, 0x08
        li  v1, 0xbfd00000 + SMBUS_HOST_CONTROL
        sb  v0, 0(v1);


        /* make sure SMB host ready to start, important!--zfx */
        li  v1, 0xbfd00000 + SMBUS_HOST_STATUS
        lbu v0, 0(v1)
        andi v0,v0, 0x1f
        beqz  v0,1f
        nop
        sb  v0, 0(v1)
        lbu v0, 0(v1)   #flush the write
1:


        /* start */
        li  v1, 0xbfd00000 + SMBUS_HOST_CONTROL
        lbu v0, 0(v1)
        ori v0, v0, 0x40
        sb  v0, 0(v1);


        /* wait */
        li  v1, 0xbfd00000 + SMBUS_HOST_STATUS
1:


#if 0
        /* delay */
        li a0, 0x1000
2:
        bnez    a0,2b
        addiu   a0, -1
#endif


        lbu  v0, 0(v1)
        andi v0, SMBUS_HOST_STATUS_BUSY
        bnez  v0, 1b  #IDEL ?
        nop


        li  v1, 0xbfd00000 + SMBUS_HOST_STATUS
        lbu v0, 0(v1)
        andi v0,v0, 0x1f
        beqz  v0,1f
        nop
        sb  v0, 0(v1)   #reset
        lbu v0, 0(v1)   #flush the write
1:


        li  v1, 0xbfd00000 + SMBUS_HOST_DATA0
        lbu  v0, 0(v1)


        jr      ra
        nop
END(i2cread)


__main:
 j ra
 nop



 .rdata
transmit_pat_msg:
 .asciz "\r\nInvalid transmit pattern.  Must be DDDD or DDxDDx\r\n"
v200_msg:
 .asciz "\r\nPANIC! Unexpected TLB refill exception!\r\n"
v280_msg:
 .asciz "\r\nPANIC! Unexpected XTLB refill exception!\r\n"
v380_msg:
 .asciz "\r\nPANIC! Unexpected General exception!\r\n"
v400_msg:
 .asciz "\r\nPANIC! Unexpected Interrupt exception!\r\n"
hexchar:
 .ascii "0123456789abcdef"


 .text
 .align 2
/*
 *   I2C Functions used in early startup code to get SPD info from
 *   SDRAM modules. This code must be entirely PIC and RAM independent.
 */


/* Delay macro */
#define DELAY(count) \
 li v0, count; \
99:   \
 bnz vo, 99b;\
 addiu v0, -1



#define I2C_INT_ENABLE 0x80
#define I2C_ENABLE 0x40
#define I2C_ACK  0x04
#define I2C_INT_FLAG 0x08
#define I2C_STOP_BIT 0x10
#define I2C_START_BIT 0x20


#define I2C_AMOD_RD 0x01


#define BUS_ERROR    0x00
#define START_CONDITION_TRA   0x08
#define RSTART_CONDITION_TRA   0x10
#define ADDR_AND_WRITE_BIT_TRA_ACK_REC  0x18
#define ADDR_AND_READ_BIT_TRA_ACK_REC  0x40
#define SLAVE_REC_WRITE_DATA_ACK_TRA  0x28
#define MAS_REC_READ_DATA_ACK_NOT_TRA  0x58


#define Index_Store_Tag_D   0x05
#define Index_Invalidate_I   0x00
#define Index_Writeback_Inv_D   0x01
#define Index_Store_Tag_S   0x0b
#define Index_Writeback_Inv_S   0x03


LEAF(nullfunction)
 jr ra
 nop
END(nullfunction)


LEAF(godson2_cache_init)
####part 2####
cache_detect_2way:
 mfc0 t4, CP0_CONFIG
 andi t5, t4, 0x0e00
 srl t5, t5, 9
 andi t6, t4, 0x01c0
 srl t6, t6, 6
 addiu t6, t6, 11
 addiu t5, t5, 11
 addiu t4, $0, 1
 sllv t6, t4, t6
 srl t6,1
 sllv t5, t4, t5
 srl t5,1
 addiu t7, $0, 2
####part 3####
 lui a0, 0x8000
 addu a1, $0, t5
 addu a2, $0, t6
cache_init_d2way:
#a0=0x80000000, a1=icache_size, a2=dcache_size
#a3, v0 and v1 used as local registers
 mtc0 $0, CP0_TAGHI
 addu v0, $0, a0
 addu v1, a0, a2
1: slt a3, v0, v1
 beq a3, $0, 1f
 nop
 mtc0 $0, CP0_TAGLO
 cache Index_Store_Tag_D, 0x0(v0)
 mtc0 $0, CP0_TAGLO
 cache Index_Store_Tag_D, 0x1(v0)
 mtc0 $0, CP0_TAGLO
 cache   Index_Store_Tag_D, 0x2(v0)
 mtc0 $0, CP0_TAGLO
 cache   Index_Store_Tag_D, 0x3(v0)
 beq $0, $0, 1b
 addiu v0, v0, 0x20


#if 1
1:
cache_init_l24way:
        mtc0    $0, CP0_TAGHI
        addu    v0, $0, a0
        addu    v1, a0, 128*1024
1:      slt     a3, v0, v1
        beq     a3, $0, 1f
        nop
        mtc0    $0, CP0_TAGLO
        cache   Index_Store_Tag_S, 0x0(v0)
        mtc0    $0, CP0_TAGLO
        cache   Index_Store_Tag_S, 0x1(v0)
        mtc0    $0, CP0_TAGLO
        cache   Index_Store_Tag_S, 0x2(v0)
        mtc0    $0, CP0_TAGLO
        cache   Index_Store_Tag_S, 0x3(v0)
        beq     $0, $0, 1b
        addiu   v0, v0, 0x20



1:
cache_flush_4way:
 addu v0, $0, a0
 addu v1, a0, 128*1024
1: slt a3, v0, v1
 beq a3, $0, 1f
 nop
 cache Index_Writeback_Inv_S, 0x0(v0)
 cache Index_Writeback_Inv_S, 0x1(v0)
 cache Index_Writeback_Inv_S, 0x2(v0)
 cache Index_Writeback_Inv_S, 0x3(v0)
 beq $0, $0, 1b
 addiu v0, v0, 0x20
# endif


1:
cache_flush_i2way:
 addu v0, $0, a0
 addu v1, a0, a1
1: slt a3, v0, v1
 beq a3, $0, 1f
 nop
 cache Index_Invalidate_I, 0x0(v0)
# cache Index_Invalidate_I, 0x1(v0)
# cache Index_Invalidate_I, 0x2(v0)
# cache Index_Invalidate_I, 0x3(v0)
 beq $0, $0, 1b
 addiu v0, v0, 0x20
1:
cache_flush_d2way:
 addu v0, $0, a0
 addu v1, a0, a2
1: slt a3, v0, v1
 beq a3, $0, 1f
 nop
 cache Index_Writeback_Inv_D, 0x0(v0)
 cache Index_Writeback_Inv_D, 0x1(v0)
 cache Index_Writeback_Inv_D, 0x2(v0)
 cache Index_Writeback_Inv_D, 0x3(v0)
 beq $0, $0, 1b
 addiu v0, v0, 0x20
1:
cache_init_finish:
 nop
 jr ra
 nop


cache_init_panic:
 TTYDBG("cache init panic\r\n");
1: b 1b
 nop
 .end godson2_cache_init


#define PCICONF_WRITEB(dev,func,reg,data) \
 li      a0,CFGADDR(dev,func,reg); \
 li      a1,PHYS_TO_UNCACHED(PCI_CFG_SPACE); \
        and     a2,a0,0xffff; \
 or      a1,a2; \
 srl     a0,16; \
 li      a2,BONITO_BASE+BONITO_PCIMAP_CFG; \
     sw      a0,BONITO_PCIMAP_CFG(bonito); \
     lw      zero,BONITO_PCIMAP_CFG(bonito); \
     or a0,zero,data; \
 sb      a0,(a1);


#define PCICONF_WRITEW(dev,func,reg,data) \
 li      a0,CFGADDR(dev,func,reg); \
 li      a1,PHYS_TO_UNCACHED(PCI_CFG_SPACE); \
        and     a2,a0,0xffff; \
 or      a1,a2; \
 srl     a0,16; \
 li      a2,BONITO_BASE+BONITO_PCIMAP_CFG; \
     sw      a0,BONITO_PCIMAP_CFG(bonito); \
     lw      zero,BONITO_PCIMAP_CFG(bonito); \
     or a0,zero,data; \
 sw      a0,(a1);
#define PCICONF_ORB(dev,func,reg,data) \
 li      a0,CFGADDR(dev,func,reg); \
        li      a1,PHYS_TO_UNCACHED(PCI_CFG_SPACE); \
        and     a2,a0,0xffff; \
        or      a1,a2; \
        srl     a0,16; \
        li      a2,BONITO_BASE+BONITO_PCIMAP_CFG; \
        sw      a0,BONITO_PCIMAP_CFG(bonito); \
        lw      zero,BONITO_PCIMAP_CFG(bonito); \
     lbu a2,(a1); \
     ori a2,data; \
        sw      a0,BONITO_PCIMAP_CFG(bonito); \
        lw      zero,BONITO_PCIMAP_CFG(bonito); \
     sb a2,(a1);
#define SUPERIO_WR(idx,data) \
        li  v0,BONITO_PCIIO_BASE_VA+0x3f0; \
        or      v1,zero,idx; \
        sb      v1,(v0); \
        or  v1,zero,data; \
        sb      v1,1(v0);


#define E2_EPP 2
#define E2_S1 (1<<2)
#define E2_S2 (1<<3)
#define E2_FLOPPY (1<<4)
    
LEAF(superio_init)


 PCICONF_WRITEW(PCI_IDSEL_VIA686B,0,4,7);
 /*positive decode*/
 PCICONF_ORB(PCI_IDSEL_VIA686B,0,0x81,0x80);
 PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x83,0x80|0x1| 0x8);
 PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x85,3);
 /* enable RTC/PS2/KBC */
 PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x5A,7);


 SUPERIO_WR(0xe2,E2_S2|E2_S1|E2_EPP|E2_FLOPPY) /*enable serial and floppy */
 SUPERIO_WR(0xe3,0x3f0>>2) /*floppy base address*/
 SUPERIO_WR(0xe6,0x378>>2) /*parallel port*/
 SUPERIO_WR(0xe7,0x3f8>>2) /*set serial port1 base addr 0x3f8*/
 SUPERIO_WR(0xe8,0x2f8>>2) /*set serial port2 base addr 0x2f8*/
 SUPERIO_WR(0xee,0xc0) /* both ports on high speed*/


 PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x85,1)
 jr ra
 nop
END(superio_init)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值