25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_mips.c,v 1.77 2007/04/10 17:52:27 debug Exp $ |
* $Id: cpu_mips.c,v 1.79 2007/04/28 09:19:51 debug Exp $ |
29 |
* |
* |
30 |
* MIPS core CPU emulation. |
* MIPS core CPU emulation. |
31 |
*/ |
*/ |
624 |
uint64_t lo0 = cop0->tlbs[j].lo0; |
uint64_t lo0 = cop0->tlbs[j].lo0; |
625 |
uint64_t lo1 = cop0->tlbs[j].lo1; |
uint64_t lo1 = cop0->tlbs[j].lo1; |
626 |
uint64_t mask = cop0->tlbs[j].mask; |
uint64_t mask = cop0->tlbs[j].mask; |
627 |
|
uint64_t psize; |
628 |
|
|
629 |
|
mask |= (1 << (pageshift+1)) - 1; |
630 |
|
/* here mask = e.g. 0x1fff for 4KB pages */ |
631 |
|
|
632 |
printf("%3i: ", j); |
printf("%3i: ", j); |
633 |
|
|
634 |
switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) { |
switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) { |
635 |
case MMU3K: |
case MMU3K: |
636 |
if (!(lo0 & R2K3K_ENTRYLO_V)) { |
if (!(lo0 & R2K3K_ENTRYLO_V)) { |
656 |
default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){ |
default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){ |
657 |
case MMU32: |
case MMU32: |
658 |
printf("vaddr=0x%08"PRIx32" ", |
printf("vaddr=0x%08"PRIx32" ", |
659 |
(uint32_t) hi); |
(uint32_t) (hi & ~mask)); |
660 |
break; |
break; |
661 |
case MMU10K: |
default:/* R4x00, R1x000, MIPS64, etc. */ |
|
default:/* R4000 etc. */ |
|
662 |
printf("vaddr=%016"PRIx64" ", |
printf("vaddr=%016"PRIx64" ", |
663 |
(uint64_t) hi); |
(uint64_t) (hi & ~mask)); |
664 |
} |
} |
665 |
if (hi & TLB_G) |
if (hi & TLB_G) |
666 |
printf("(global): "); |
printf("(global): "); |
672 |
|
|
673 |
if (!(lo0 & ENTRYLO_V)) |
if (!(lo0 & ENTRYLO_V)) |
674 |
printf(" p0=(invalid) "); |
printf(" p0=(invalid) "); |
675 |
else |
else { |
676 |
printf(" p0=0x%09"PRIx64" ", (uint64_t) |
uint64_t paddr = lo0 & ENTRYLO_PFN_MASK; |
677 |
(((lo0&ENTRYLO_PFN_MASK) >> |
paddr >>= ENTRYLO_PFN_SHIFT; |
678 |
ENTRYLO_PFN_SHIFT) << pageshift)); |
paddr <<= pageshift; |
679 |
|
paddr &= ~(mask >> 1); |
680 |
|
printf(" p0=0x%09"PRIx64" ", |
681 |
|
(uint64_t) paddr); |
682 |
|
} |
683 |
printf(lo0 & ENTRYLO_D? "D" : " "); |
printf(lo0 & ENTRYLO_D? "D" : " "); |
684 |
|
|
685 |
if (!(lo1 & ENTRYLO_V)) |
if (!(lo1 & ENTRYLO_V)) |
686 |
printf(" p1=(invalid) "); |
printf(" p1=(invalid) "); |
687 |
else |
else { |
688 |
printf(" p1=0x%09"PRIx64" ", (uint64_t) |
uint64_t paddr = lo1 & ENTRYLO_PFN_MASK; |
689 |
(((lo1&ENTRYLO_PFN_MASK) >> |
paddr >>= ENTRYLO_PFN_SHIFT; |
690 |
ENTRYLO_PFN_SHIFT) << pageshift)); |
paddr <<= pageshift; |
691 |
printf(lo1 & ENTRYLO_D? "D" : " "); |
paddr &= ~(mask >> 1); |
692 |
mask |= (1 << (pageshift+1)) - 1; |
printf(" p1=0x%09"PRIx64" ", |
693 |
switch (mask) { |
(uint64_t) paddr); |
|
case 0x7ff: printf(" (1KB)"); break; |
|
|
case 0x1fff: printf(" (4KB)"); break; |
|
|
case 0x7fff: printf(" (16KB)"); break; |
|
|
case 0x1ffff: printf(" (64KB)"); break; |
|
|
case 0x7ffff: printf(" (256KB)"); break; |
|
|
case 0x1fffff: printf(" (1MB)"); break; |
|
|
case 0x7fffff: printf(" (4MB)"); break; |
|
|
case 0x1ffffff: printf(" (16MB)"); break; |
|
|
case 0x7ffffff: printf(" (64MB)"); break; |
|
|
default:printf(" (mask=%08x?)", (int)mask); |
|
694 |
} |
} |
695 |
|
printf(lo1 & ENTRYLO_D? "D" : " "); |
696 |
|
|
697 |
|
/* convert e.g. 0x1fff to 4096 */ |
698 |
|
psize = (mask + 1) >> 1; |
699 |
|
|
700 |
|
if (psize >= 1024 && psize <= 256*1024) |
701 |
|
printf(" (%iKB)", (int) (psize >> 10)); |
702 |
|
else if (psize >= 1024*1024 && psize <= |
703 |
|
64*1024*1024) |
704 |
|
printf(" (%iMB)", (int) (psize >> 20)); |
705 |
|
else |
706 |
|
printf(" (?)"); |
707 |
|
|
708 |
printf("\n"); |
printf("\n"); |
709 |
} |
} |
710 |
} |
} |
1680 |
debug("cpu%i: ", cpu->cpu_id); |
debug("cpu%i: ", cpu->cpu_id); |
1681 |
debug("config_select1 = 0x"); |
debug("config_select1 = 0x"); |
1682 |
if (cpu->is_32bit) |
if (cpu->is_32bit) |
1683 |
debug("%08"PRIx32, (uint32_t)cpu->cd.mips.cop0_config_select1); |
debug("%08"PRIx32, |
1684 |
|
(uint32_t)cpu->cd.mips.cop0_config_select1); |
1685 |
else |
else |
1686 |
debug("%016"PRIx64, (uint64_t)cpu->cd.mips.cop0_config_select1); |
debug("%016"PRIx64, |
1687 |
|
(uint64_t)cpu->cd.mips.cop0_config_select1); |
1688 |
debug("\n"); |
debug("\n"); |
1689 |
} |
} |
1690 |
|
|
1784 |
switch (exccode) { |
switch (exccode) { |
1785 |
|
|
1786 |
case EXCEPTION_INT: |
case EXCEPTION_INT: |
1787 |
debug(" cause_im=0x%02x", (int)((reg[COP0_CAUSE] & CAUSE_IP_MASK) >> CAUSE_IP_SHIFT)); |
debug(" cause_im=0x%02x", (int) |
1788 |
|
((reg[COP0_CAUSE] & CAUSE_IP_MASK) |
1789 |
|
>> CAUSE_IP_SHIFT)); |
1790 |
break; |
break; |
1791 |
|
|
1792 |
case EXCEPTION_SYS: |
case EXCEPTION_SYS: |
1876 |
|
|
1877 |
if (exc_model == EXC3K) { |
if (exc_model == EXC3K) { |
1878 |
reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK; |
reg[COP0_CONTEXT] &= ~R2K3K_CONTEXT_BADVPN_MASK; |
1879 |
reg[COP0_CONTEXT] |= ((vaddr_vpn2 << R2K3K_CONTEXT_BADVPN_SHIFT) & R2K3K_CONTEXT_BADVPN_MASK); |
reg[COP0_CONTEXT] |= ((vaddr_vpn2 << |
1880 |
|
R2K3K_CONTEXT_BADVPN_SHIFT) & |
1881 |
|
R2K3K_CONTEXT_BADVPN_MASK); |
1882 |
|
|
1883 |
reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK) |
reg[COP0_ENTRYHI] = (vaddr & R2K3K_ENTRYHI_VPN_MASK) |
1884 |
| (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT); |
| (vaddr_asid << R2K3K_ENTRYHI_ASID_SHIFT); |
1888 |
reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI]; |
reg[COP0_ENTRYHI] = (int64_t)(int32_t)reg[COP0_ENTRYHI]; |
1889 |
} else { |
} else { |
1890 |
if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) { |
if (cpu->cd.mips.cpu_type.rev == MIPS_R4100) { |
1891 |
reg[COP0_CONTEXT] &= ~CONTEXT_BADVPN2_MASK_R4100; |
reg[COP0_CONTEXT] &= |
1892 |
reg[COP0_CONTEXT] |= ((vaddr_vpn2 << CONTEXT_BADVPN2_SHIFT) & CONTEXT_BADVPN2_MASK_R4100); |
~CONTEXT_BADVPN2_MASK_R4100; |
1893 |
|
reg[COP0_CONTEXT] |= ((vaddr_vpn2 << |
1894 |
|
CONTEXT_BADVPN2_SHIFT) & |
1895 |
|
CONTEXT_BADVPN2_MASK_R4100); |
1896 |
|
|
1897 |
/* TODO: fix these */ |
/* TODO: fix these */ |
1898 |
reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK; |
reg[COP0_XCONTEXT] &= ~XCONTEXT_R_MASK; |