atb.c
3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <PR/bcp.h>
#include <PR/os.h>
#include <PR/os_bbatb.h>
#undef ATB_DEBUG
#ifdef ATB_DEBUG
#define PRINTF osSyncPrintf
#else
#define PRINTF(x, args...)
#endif
u32 osBbAtbGetVAddr()
{
u32 addr;
addr = IO_READ(PI_ATB_BUFFER_LO_REG+4);
addr &= PI_ATBL_VADDR_MASK;
addr = addr >> PI_ATBL_VADDR_SHIFT;
addr = addr << 14;
return addr;
}
/* for now, atb uses an entry for each 16KB block.
* assume device 0.
*/
s32 osBbAtbSetup(u32 vAddrBase, u16 *fsBlockList, u32 maxListLen)
{
int atbIndx, maxPow2, lenRun, numBlks, indx, entryBlksPow2, runStart = 0;
u32 vAddr, atbLower;
if((vAddrBase&(~((1<<14)-1)))==0)
return BB_ATB_FAIL;
/* the dummy entry for init */
IO_WRITE(PI_ATBU_REG, PI_ATBU_IV | /* IV */
(0<<PI_ATBU_DEV_SHIFT) | /* device */
PI_ATBU_PERM_PIO | PI_ATBU_PERM_DMA | /* perm */
(0<<PI_ATBU_SIZE_SHIFT)); /* size */
IO_WRITE(PI_ATB_BUFFER_LO_REG,
0 | (((vAddrBase>>14)-1) << PI_ATBL_VADDR_SHIFT) );
atbIndx=1;
vAddr=vAddrBase;
for(numBlks=0; fsBlockList[numBlks]!=0; numBlks++){
if(numBlks == (maxListLen-1))
return BB_ATB_FAIL;
}
do{
for(maxPow2=0; ((vAddr>>(14+maxPow2))&1)==0; maxPow2++){}
PRINTF("vAddr = %08x, maxPow2 = %d\n",vAddr,maxPow2);
/* determine lenRun */
for(indx=runStart, lenRun=1,entryBlksPow2=0;
(fsBlockList[indx]+1)==fsBlockList[indx+1] &&
entryBlksPow2<maxPow2;
indx++){
if( (++lenRun & ((1<<(entryBlksPow2+1))-1) ) == 0 )
entryBlksPow2++;
}
/*
* setup atb entry using entryBlksPow2, runStart
*/
PRINTF("Run start = %d, length = %d\n",runStart,(1<<entryBlksPow2));
/* setup atb entry upper bits */
IO_WRITE(PI_ATBU_REG, (0<<PI_ATBU_DEV_SHIFT) | /* device */
PI_ATBU_PERM_PIO | PI_ATBU_PERM_DMA | /* perm */
(entryBlksPow2<<PI_ATBU_SIZE_SHIFT)); /* size */
atbLower=(((u32)fsBlockList[runStart]) << PI_ATBL_PADDR_SHIFT) |
((vAddr>>14) << PI_ATBL_VADDR_SHIFT);
PRINTF("atbLower = %08x\n",atbLower);
IO_WRITE(PI_ATB_BUFFER_LO_REG+atbIndx*4,atbLower);
atbIndx++;
vAddr+=(1<<entryBlksPow2)*16*1024;
runStart+=(1<<entryBlksPow2);
} while(runStart<numBlks);
/* map rest of entries with same last entry */
IO_WRITE(PI_ATBU_REG, (0<<PI_ATBU_DEV_SHIFT) | /* device */
PI_ATBU_PERM_PIO | PI_ATBU_PERM_DMA | /* perm */
(0<<PI_ATBU_SIZE_SHIFT)); /* size */
atbLower=(((u32)fsBlockList[0]) << PI_ATBL_PADDR_SHIFT) |
((vAddr>>14) << PI_ATBL_VADDR_SHIFT);
PRINTF("vAddr = %08x, maxPow2 = %d\n",vAddr,maxPow2);
PRINTF("Run start = %d, length = %d\n",0,1);
PRINTF("atbLower = %08x\n",atbLower);
PRINTF("%d atb entries\n", atbIndx);
while(atbIndx < PI_ATB_NUM_ENTRIES){
IO_WRITE(PI_ATB_BUFFER_LO_REG+atbIndx*4,atbLower);
atbIndx++;
}
return BB_ATB_SUCCESS;
}