Browse Source

must clear tlb or set pagemask to 16k on boot.

cache alias+random excecute will affect cache flush.
add cp0 acess,tlbdump,cachedum commandp.
chage sata driver a little.
master
root 16 years ago
parent
commit
2fe1018c4c
  1. 44
      Targets/Bonito2fdev/Bonito/start_firewall.S
  2. 1
      Targets/Bonito2fdev/Bonito/tgt_machdep.c
  3. 4
      pmon/arch/mips/cache.S
  4. 297
      pmon/cmds/mycmd.c
  5. 64
      sys/dev/pci/atpsata.c

44
Targets/Bonito2fdev/Bonito/start_firewall.S

@ -810,49 +810,10 @@ do_caches:
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
@ -1109,7 +1070,7 @@ stuck:
LEAF(CPU_TLBClear)
li a3, 0 # First TLB index.
li a2, PG_SIZE_4K
li a2, PG_SIZE_16K
MTC0 a2, COP_0_TLB_PG_MASK # Whatever...
1:
@ -1127,6 +1088,9 @@ LEAF(CPU_TLBClear)
bne a3, a2, 1b
nop
li a3,4
mtc0 a3,$22 #flush itlb
jr ra
nop
END(CPU_TLBClear)

1
Targets/Bonito2fdev/Bonito/tgt_machdep.c

@ -371,6 +371,7 @@ volatile int *p=0xbfe00108;
tgt_printf("memsz %d\n",memsz);
/*enable float*/
tgt_fpuenable();
CPU_TLBClear();
#if PCI_IDSEL_CS5536 != 0
superio_reinit();

4
pmon/arch/mips/cache.S

@ -209,7 +209,7 @@ LEAF(CPU_ConfigCache)
srl t1, v0, 9 # Get I cache size.
and t1, 7
li t2, 4096
sll t4, t2, 4 #t1 # t4 = Initial I set size.
sll t4, t2, t1 # t4 = Initial I set size.
and t2, v0, 0x20
srl t2, t2, 1 # Get I cache line size.
@ -219,7 +219,7 @@ LEAF(CPU_ConfigCache)
srl t1, v0, 6 # Get D cache size.
and t1, 7
li t2, 4096 # Fixed page size.
sll t5, t2, 4 #t1
sll t5, t2, t1
and t2, v0, 0x10
addu t2, t2, 16 # Get D cache line size.

297
pmon/cmds/mycmd.c

@ -720,7 +720,90 @@ static int setkbd(int argc,char **argv)
#endif
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define printk printf
#define CKSEG0 0xffffffff80000000ULL
static char *msk2str(unsigned int mask)
{
static char str[20];
switch (mask) {
case PM_4K: return "4kb";
case PM_16K: return "16kb";
case PM_64K: return "64kb";
case PM_256K: return "256kb";
case PM_1M: return "1Mb";
case PM_4M: return "4Mb";
case PM_16M: return "16Mb";
case PM_64M: return "64Mb";
case PM_256M: return "256Mb";
}
sprintf(str,"%08x",mask);
return str;
}
#define BARRIER() \
__asm__ __volatile__( \
".set\tnoreorder\n\t" \
"nop;nop;nop;nop;nop;nop;nop\n\t" \
".set\treorder");
void dump_tlb(int first, int last)
{
unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
unsigned int s_index, pagemask, c0, c1, i;
s_entryhi = read_c0_entryhi();
s_index = read_c0_index();
asid = s_entryhi & 0xff;
for (i = first; i <= last; i++) {
write_c0_index(i);
BARRIER();
tlb_read();
BARRIER();
pagemask = read_c0_pagemask();
entryhi = read_c0_entryhi();
entrylo0 = read_c0_entrylo0();
entrylo1 = read_c0_entrylo1();
/* Unused entries have a virtual address of CKSEG0. */
if ((entryhi & ~0x1ffffUL) != CKSEG0
&& (entryhi & 0xff) == asid) {
/*
* Only print entries in use
*/
printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
c0 = (entrylo0 >> 3) & 7;
c1 = (entrylo1 >> 3) & 7;
printk("va=%011lx asid=%02lx\n",
(entryhi & ~0x1fffUL),
entryhi & 0xff);
printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ",
(entrylo0 << 6) & PAGE_MASK, c0,
(entrylo0 & 4) ? 1 : 0,
(entrylo0 & 2) ? 1 : 0,
(entrylo0 & 1));
printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n",
(entrylo1 << 6) & PAGE_MASK, c1,
(entrylo1 & 4) ? 1 : 0,
(entrylo1 & 2) ? 1 : 0,
(entrylo1 & 1));
}
}
printk("\n");
write_c0_entryhi(s_entryhi);
write_c0_index(s_index);
}
int tlbdump(int argc,char **argv)
{
dump_tlb(0,63);
return 0;
}
static int tlbset(int argc,char **argv)
{
@ -1797,10 +1880,223 @@ else
return 0;
}
//----------------------------------
//
#ifdef __mips
static int __cp0syscall1(int type,unsigned long long addr,union commondata *mydata)
{
long long data8;
if(type!=8)return -1;
addr=addr>>3;
switch((long)addr&0x1f)
{
case 0:
asm("dmfc0 %0,$0 ":"=r"(data8));break;
case 1:
asm("dmfc0 %0,$1 ":"=r"(data8));break;
case 2:
asm("dmfc0 %0,$2 ":"=r"(data8));break;
case 3:
asm("dmfc0 %0,$3 ":"=r"(data8));break;
case 4:
asm("dmfc0 %0,$4 ":"=r"(data8));break;
case 5:
asm("dmfc0 %0,$5 ":"=r"(data8));break;
case 6:
asm("dmfc0 %0,$6 ":"=r"(data8));break;
case 7:
asm("dmfc0 %0,$7 ":"=r"(data8));break;
case 8:
asm("dmfc0 %0,$8 ":"=r"(data8));break;
case 9:
asm("dmfc0 %0,$9 ":"=r"(data8));break;
case 10:
asm("dmfc0 %0,$10":"=r"(data8));break;
case 11:
asm("dmfc0 %0,$11 ":"=r"(data8));break;
case 12:
asm("dmfc0 %0,$12 ":"=r"(data8));break;
case 13:
asm("dmfc0 %0,$13 ":"=r"(data8));break;
case 14:
asm("dmfc0 %0,$14 ":"=r"(data8));break;
case 15:
asm("dmfc0 %0,$15 ":"=r"(data8));break;
case 16:
asm("dmfc0 %0,$16 ":"=r"(data8));break;
case 17:
asm("dmfc0 %0,$17 ":"=r"(data8));break;
case 18:
asm("dmfc0 %0,$18 ":"=r"(data8));break;
case 19:
asm("dmfc0 %0,$19 ":"=r"(data8));break;
case 20:
asm("dmfc0 %0,$20 ":"=r"(data8));break;
case 21:
asm("dmfc0 %0,$21 ":"=r"(data8));break;
case 22:
asm("dmfc0 %0,$22 ":"=r"(data8));break;
case 23:
asm("dmfc0 %0,$23 ":"=r"(data8));break;
case 24:
asm("dmfc0 %0,$24 ":"=r"(data8));break;
case 25:
asm("dmfc0 %0,$25 ":"=r"(data8));break;
case 26:
asm("dmfc0 %0,$26 ":"=r"(data8));break;
case 27:
asm("dmfc0 %0,$27 ":"=r"(data8));break;
case 28:
asm("dmfc0 %0,$28 ":"=r"(data8));break;
case 29:
asm("dmfc0 %0,$29 ":"=r"(data8));break;
case 30:
asm("dmfc0 %0,$30 ":"=r"(data8));break;
case 31:
asm("dmfc0 %0,$31 ":"=r"(data8));break;
}
*(long long *)mydata->data8=data8;
return 0;
}
static int __cp0syscall2(int type,unsigned long long addr,union commondata *mydata)
{
long long data8;
if(type!=8)return -1;
addr=addr>>3;
data8=*(long long *)mydata->data8;
switch((long)addr&0x1f)
{
case 0:
asm("dmtc0 %0,$0 "::"r"(data8));break;
case 1:
asm("dmtc0 %0,$1 "::"r"(data8));break;
case 2:
asm("dmtc0 %0,$2 "::"r"(data8));break;
case 3:
asm("dmtc0 %0,$3 "::"r"(data8));break;
case 4:
asm("dmtc0 %0,$4 "::"r"(data8));break;
case 5:
asm("dmtc0 %0,$5 "::"r"(data8));break;
case 6:
asm("dmtc0 %0,$6 "::"r"(data8));break;
case 7:
asm("dmtc0 %0,$7 "::"r"(data8));break;
case 8:
asm("dmtc0 %0,$8 "::"r"(data8));break;
case 9:
asm("dmtc0 %0,$9 "::"r"(data8));break;
case 10:
asm("dmtc0 %0,$10"::"r"(data8));break;
case 11:
asm("dmtc0 %0,$11 "::"r"(data8));break;
case 12:
asm("dmtc0 %0,$12 "::"r"(data8));break;
case 13:
asm("dmtc0 %0,$13 "::"r"(data8));break;
case 14:
asm("dmtc0 %0,$14 "::"r"(data8));break;
case 15:
asm("dmtc0 %0,$15 "::"r"(data8));break;
case 16:
asm("dmtc0 %0,$16 "::"r"(data8));break;
case 17:
asm("dmtc0 %0,$17 "::"r"(data8));break;
case 18:
asm("dmtc0 %0,$18 "::"r"(data8));break;
case 19:
asm("dmtc0 %0,$19 "::"r"(data8));break;
case 20:
asm("dmtc0 %0,$20 "::"r"(data8));break;
case 21:
asm("dmtc0 %0,$21 "::"r"(data8));break;
case 22:
asm("dmtc0 %0,$22 "::"r"(data8));break;
case 23:
asm("dmtc0 %0,$23 "::"r"(data8));break;
case 24:
asm("dmtc0 %0,$24 "::"r"(data8));break;
case 25:
asm("dmtc0 %0,$25 "::"r"(data8));break;
case 26:
asm("dmtc0 %0,$26 "::"r"(data8));break;
case 27:
asm("dmtc0 %0,$27 "::"r"(data8));break;
case 28:
asm("dmtc0 %0,$28 "::"r"(data8));break;
case 29:
asm("dmtc0 %0,$29 "::"r"(data8));break;
case 30:
asm("dmtc0 %0,$30 "::"r"(data8));break;
case 31:
asm("dmtc0 %0,$31 "::"r"(data8));break;
}
return 0;
}
static int mycp0s(int argc,char **argv)
{
syscall1=__cp0syscall1;
syscall2=__cp0syscall2;
syscall_addrtype=0;
return 0;
}
static int cache_type=1;/*0:D,1:S*/
static int dumpcache(int argc,char **argv)
{
unsigned long taglo,taghi;
int way;
unsigned long long phytag;
unsigned long addr;
long len;
if(argc!=3)return -1;
addr=strtoul(argv[1],0,0);
len=strtoul(argv[2],0,0);
for(;len>0;len-=32,addr+=32)
{
for(way=0;way<=3;way++)
{
if(argv[0][0]=='s')
{
asm("cache %3,(%2);mfc0 %0,$28;mfc0 %1,$29":"=r"(taglo),"=r"(taghi):"r"(addr|way),"i"(7));
phytag= ((((unsigned long long)taglo>>13)&0xfffff)<<17)|((((unsigned long long)taghi&0xf))<<36);
printf("\n%08x:state=%d,phyaddr=%010llx,taglo=%08x,taghi=%08x\n",addr|way,(taglo>>10)&3,phytag,taglo,taghi);
}
else
{
asm("cache %3,(%2);mfc0 %0,$28;mfc0 %1,$29":"=r"(taglo),"=r"(taghi):"r"(addr|way),"i"(5));
phytag= ((((unsigned long long)taglo>>8)&0xffffff)<<12)|((((unsigned long long)taghi&0xf))<<36);
printf("\n%08x:state=%d,phyaddr=%010llx,way=%d,mode=%d,taglo=%08x,taghi=%08x\n",addr|way,(taglo>>6)&3,phytag,(taglo>>4)&3,(taghi>>29)&7,taglo,taghi);
}
}
}
return 0;
}
#endif
//----------------------------------
static const Cmd Cmds[] =
{
{"MyCmds"},
{"cp0s", "", 0, "access cp0", mycp0s, 0, 99, CMD_REPEAT},
{"scachedump", "", 0, "access Scache tag",dumpcache, 0, 99, CMD_REPEAT},
{"dcachedump", "", 0, "access Dcache tag",dumpcache, 0, 99, CMD_REPEAT},
{"pcs", "bus dev func", 0, "select pci dev function", mypcs, 0, 99, CMD_REPEAT},
{"disks", "disk", 0, "select disk", mydisks, 0, 99, CMD_REPEAT},
{"d1", "[addr] [count]", 0, "dump address byte", dump, 0, 99, CMD_REPEAT},
@ -1819,6 +2115,7 @@ static const Cmd Cmds[] =
{"tlbset","viraddr phyaddr [-x]",0,"tlbset viraddr phyaddr [-x]",tlbset,0,99,CMD_REPEAT},
{"tlbtest","viraddr phyaddr ",0,"tlbset viraddr phyaddr ",tlbtest,0,99,CMD_REPEAT},
{"tlbclear","",0,"tlbclear",tlbclear,0,99,CMD_REPEAT},
{"tlbdump","",0,"tlbdump",tlbdump,0,99,CMD_REPEAT},
{"tlbinit","addr size",0,"tlbinit phaddr=vaddr",tlbinit,0,99,CMD_REPEAT},
{"cache","[0 1]",0,"cache [0 1]",setcache,0,99,CMD_REPEAT},
{"loop","count cmd...",0,"loopcmd count cmd...",loopcmd,0,99,CMD_REPEAT},

64
sys/dev/pci/atpsata.c

@ -364,7 +364,7 @@ int init_sata(int dev,u32 reg)
/* Allocate receive fis */
length = 256;
length = sizeof(*receive_fis);
align = 256;
#if MY_MALLOC
sata->receive_fis_offset = (void *)malloc(length + align);
@ -381,7 +381,7 @@ int init_sata(int dev,u32 reg)
sata->receive_fis = receive_fis;
/* Zero all of receive fis */
memset((void *)sata->receive_fis_offset, 0, length + align);
pci_sync_cache(0,sata->receive_fis_offset,length + align,1);
pci_sync_cache(0,sata->receive_fis_offset,length + align,0);
/* Allocate command descriptor for all command */
length = sizeof(struct cmd_desc) * SATA_HC_MAX_CMD;
@ -511,6 +511,7 @@ static int atp_ata_exec_ata_cmd(struct atp_sata *sata, struct cfis *cfis,
prde->dbc = (u32)(dbc);
prde_count++;
prde++;
len=0;
break;
} else
{
@ -524,6 +525,8 @@ static int atp_ata_exec_ata_cmd(struct atp_sata *sata, struct cfis *cfis,
}
}
if(len)printf("left %d\n",len);
if(cfis->command == 0x61 || cfis->command == 0x35)
is_write = 1;
else if(cfis->command == 0x60 || cfis->command == 0x25)
@ -563,10 +566,11 @@ static int atp_ata_exec_ata_cmd(struct atp_sata *sata, struct cfis *cfis,
{
outb(reg + 0x0074,status);
}
pci_sync_cache(0,cmd_hdr,256,1);
pci_sync_cache(0,sata->cmd_desc,8192,1);
pci_sync_cache(0,sata->receive_fis,512,1);
pci_sync_cache(0,buffer,buffer_length,is_write);
pci_sync_cache(0,cmd_hdr,sizeof(*cmd_hdr),1);
pci_sync_cache(0,cmd_desc,sizeof(*cmd_desc),1);
pci_sync_cache(0,sata->receive_fis,sizeof(*sata->receive_fis),0);
if(buffer && buffer_length)pci_sync_cache(0,buffer,buffer_length,is_write);
outb(reg +0x0074,inb(reg +0x0074)&0xfe);
outl(reg + 0x0038,ci_map);
/* Wait command completed for 1s */
/* if (ata_wait_register(reg + 0x0038, ci_map, ci_map, 1000))
@ -577,6 +581,7 @@ static int atp_ata_exec_ata_cmd(struct atp_sata *sata, struct cfis *cfis,
printf("\n\rNCQ command time out\n\r");
}
*/
for(i = 0;i < 1000;i ++)
{
if((inl(reg + 0x0038) & ci_map) == 0)
@ -591,6 +596,10 @@ static int atp_ata_exec_ata_cmd(struct atp_sata *sata, struct cfis *cfis,
printf("\n0x0038 not cleared,time out\n");
return -2;
}
while(inl(reg + 0x0010)==0xffffffff)
{
myudelay(100);
}
for(i = 0;i < 1000;i ++)
{
if(inb(reg + 0x0010) & 0x03)
@ -663,11 +672,11 @@ static void atp_sata_identify(int dev, u16 *id,int tag)
cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag];
dma_buffer = vtophys((u32)id);
cmd_desc = sata->cmd_desc + tag;
((cfis_t*)(sata->cmd_desc->cfis))->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
((cfis_t*)(sata->cmd_desc->cfis))->FIS_Flag = 1;
((cfis_t*)(sata->cmd_desc->cfis))->pm_port_c = 0x0;
((cfis_t*)(sata->cmd_desc->cfis))->device = 0xe0;
((cfis_t*)(sata->cmd_desc->cfis))->command = ATA_CMD_ID_ATA;
((cfis_t*)(cmd_desc->cfis))->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
((cfis_t*)(cmd_desc->cfis))->FIS_Flag = 1;
((cfis_t*)(cmd_desc->cfis))->pm_port_c = 0x0;
((cfis_t*)(cmd_desc->cfis))->device = 0xe0;
((cfis_t*)(cmd_desc->cfis))->command = ATA_CMD_ID_ATA;
prde = (prd_entry_t*)cmd_desc->prdt;
memset((void*)prde,0,sizeof(prd_entry_t));
@ -682,9 +691,9 @@ static void atp_sata_identify(int dev, u16 *id,int tag)
ci_map = 0x00000001 << tag;
pci_sync_cache(0,cmd_hdr,256,1);
pci_sync_cache(0,sata->cmd_desc,8192,1);
pci_sync_cache(0,sata->receive_fis,512,1);
pci_sync_cache(0,cmd_hdr,sizeof(*cmd_hdr),1);
pci_sync_cache(0,cmd_desc,sizeof(*cmd_desc),1);
pci_sync_cache(0,sata->receive_fis,sizeof(*sata->receive_fis),0);
pci_sync_cache(0,id,ATA_ID_WORDS * 2,0);
outl(sata->reg_base + 0x0038,ci_map);
for (i = 0 ; i < 1000 ; i++)
@ -699,6 +708,7 @@ static void atp_sata_identify(int dev, u16 *id,int tag)
}
if (i >= 1000)
{
printf("\n0x0038 not cleared,time out\n");
// time out
outb(sata->reg_base + 0x0018,0x16);
outb(sata->reg_base + 0x0018,0x17);
@ -717,6 +727,7 @@ static void atp_sata_identify(int dev, u16 *id,int tag)
}
if (i >= 1000)
{
printf("\nreceive no rfis,time out\n");
// time out
outb(sata->reg_base + 0x0018,0x16);
outb(sata->reg_base + 0x0018,0x17);
@ -892,21 +903,22 @@ int atp_sata_software_reset(int dev,int tag)
u32 ci_map;
memset((void *)sata->cmd_desc, 0, 64);
cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag];
cmd_desc = sata->cmd_desc + tag;
memset((void*)cmd_hdr,0,0x400);
// sata->cmd_hdr->cmd_slot[tag].PortMultiplier = 0x0f;
cmd_hdr->CommandFISLen = 0x05;
cmd_hdr->ClearBusy = 1;
// cmd_hdr->PortMultiplier = 0x0f;
cmd_hdr->ctba = vtophys((u32)(sata->cmd_desc));
// ((cfis_t*)(sata->cmd_desc->cfis))->pm_port_c = 0x0f;;
((cfis_t*)(sata->cmd_desc->cfis))->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
((cfis_t*)(sata->cmd_desc->cfis))->FIS_Flag = 0;
((cfis_t*)(sata->cmd_desc->cfis))->control = 0x04; //RST bit =1
cmd_hdr->ctba = vtophys((u32)(cmd_desc));
// ((cfis_t*)(cmd_desc->cfis))->pm_port_c = 0x0f;;
((cfis_t*)(cmd_desc->cfis))->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
((cfis_t*)(cmd_desc->cfis))->FIS_Flag = 0;
((cfis_t*)(cmd_desc->cfis))->control = 0x04; //RST bit =1
ci_map = 0x00000001 << tag;
SATADEBUG
pci_sync_cache(0,cmd_hdr,256,1);
pci_sync_cache(0,sata->cmd_desc,8192,1);
pci_sync_cache(0,sata->receive_fis,512,1);
pci_sync_cache(0,cmd_hdr,sizeof(*cmd_hdr),1);
pci_sync_cache(0,cmd_desc,sizeof(*cmd_desc),1);
pci_sync_cache(0,sata->receive_fis,sizeof(*sata->receive_fis),0);
// ci_map = 0x00000001 << 7;
outl(sata->reg_base + 0x0038,ci_map);
@ -917,10 +929,10 @@ SATADEBUG
myudelay(10);
cmd_hdr->ClearBusy = 0;
((cfis_t*)sata->cmd_desc->cfis)->control = 0; //RST bit = 0
pci_sync_cache(0,cmd_hdr,256,1);
pci_sync_cache(0,sata->cmd_desc,8192,1);
pci_sync_cache(0,sata->receive_fis,512,1);
((cfis_t*)cmd_desc->cfis)->control = 0; //RST bit = 0
pci_sync_cache(0,cmd_hdr,sizeof(*cmd_hdr),1);
pci_sync_cache(0,cmd_desc,sizeof(*cmd_desc),1);
pci_sync_cache(0,sata->receive_fis,sizeof(*sata->receive_fis),0);
outl(sata->reg_base + 0x0038,ci_map);
while (inl(sata->reg_base + 0x0038) & ci_map)
{

Loading…
Cancel
Save