25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: memory_ppc.c,v 1.20 2005/11/22 21:56:18 debug Exp $ |
* $Id: memory_ppc.c,v 1.22 2005/12/20 18:20:55 debug Exp $ |
29 |
* |
* |
30 |
* Included from cpu_ppc.c. |
* Included from cpu_ppc.c. |
31 |
*/ |
*/ |
44 |
int ppc_bat(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags, |
int ppc_bat(struct cpu *cpu, uint64_t vaddr, uint64_t *return_addr, int flags, |
45 |
int user) |
int user) |
46 |
{ |
{ |
47 |
int i, pp, regnr; |
int i, istart = 0, iend = 8, pp; |
48 |
|
|
49 |
|
if (flags & FLAG_INSTR) |
50 |
|
iend = 4; |
51 |
|
else |
52 |
|
istart = 4; |
53 |
|
|
54 |
if (cpu->cd.ppc.bits != 32) { |
if (cpu->cd.ppc.bits != 32) { |
55 |
fatal("TODO: ppc_bat() for non-32-bit\n"); |
fatal("TODO: ppc_bat() for non-32-bit\n"); |
60 |
exit(1); |
exit(1); |
61 |
} |
} |
62 |
|
|
63 |
/* 4 instruction BATs, 4 data BATs... */ |
/* Scan either the 4 instruction BATs or the 4 data BATs: */ |
64 |
for (i=0; i<8; i++) { |
for (i=istart; i<iend; i++) { |
65 |
regnr = SPR_IBAT0U + i * 2; |
int regnr = SPR_IBAT0U + i * 2; |
66 |
uint32_t upper = cpu->cd.ppc.spr[regnr]; |
uint32_t upper = cpu->cd.ppc.spr[regnr]; |
67 |
uint32_t lower = cpu->cd.ppc.spr[regnr + 1]; |
uint32_t lower = cpu->cd.ppc.spr[regnr + 1]; |
68 |
uint32_t phys = lower & BAT_RPN, ebs = upper & BAT_EPI; |
uint32_t phys = lower & BAT_RPN, ebs = upper & BAT_EPI; |
69 |
uint32_t mask = ((upper & BAT_BL) << 15) | 0x1ffff; |
uint32_t mask = ((upper & BAT_BL) << 15) | 0x1ffff; |
70 |
|
|
|
/* Instruction BAT, but not instruction lookup? Then skip. */ |
|
|
if (i < 4 && !(flags & FLAG_INSTR)) |
|
|
continue; |
|
|
if (i >= 4 && (flags & FLAG_INSTR)) |
|
|
continue; |
|
|
|
|
71 |
/* Not valid in either supervisor or user mode? */ |
/* Not valid in either supervisor or user mode? */ |
72 |
if (user && !(upper & BAT_Vu)) |
if (user && !(upper & BAT_Vu)) |
73 |
continue; |
continue; |
107 |
static int get_pte_low(struct cpu *cpu, uint64_t pteg_select, |
static int get_pte_low(struct cpu *cpu, uint64_t pteg_select, |
108 |
uint32_t *lowp, uint32_t cmp) |
uint32_t *lowp, uint32_t cmp) |
109 |
{ |
{ |
110 |
|
unsigned char *d = memory_paddr_to_hostaddr(cpu->mem, pteg_select, 1) |
111 |
|
+ (pteg_select & ((1 << BITS_PER_MEMBLOCK) - 1)); |
112 |
int i; |
int i; |
|
uint32_t upper; |
|
|
unsigned char d[8]; |
|
113 |
|
|
114 |
for (i=0; i<8; i++) { |
for (i=0; i<8; i++) { |
115 |
cpu->memory_rw(cpu, cpu->mem, pteg_select + i*8, |
uint32_t *ep = (uint32_t *) (d + (i << 3)), upper; |
116 |
&d[0], 8, MEM_READ, PHYSICAL | NO_EXCEPTIONS); |
upper = *ep; |
117 |
upper = (d[0]<<24)+(d[1]<<16)+(d[2]<<8)+d[3]; |
upper = BE32_TO_HOST(upper); |
118 |
|
|
119 |
/* Valid PTE, and correct api and vsid? */ |
/* Valid PTE, and correct api and vsid? */ |
120 |
if (upper == cmp) { |
if (upper == cmp) { |
121 |
*lowp = ((d[4]<<24)+(d[5]<<16)+(d[6]<<8)+d[7]); |
uint32_t lo = ep[1]; |
122 |
|
lo = BE32_TO_HOST(lo); |
123 |
|
*lowp = lo; |
124 |
return 1; |
return 1; |
125 |
} |
} |
126 |
} |
} |