Tlb fixes (#10)

* tlb fixes

* more

* more

* more

* more

* back

* clean
This commit is contained in:
Logan McNaughton
2023-10-06 13:37:43 -06:00
committed by GitHub
parent a9bff5c568
commit c193b03771
3 changed files with 66 additions and 27 deletions
+1
View File
@@ -43,6 +43,7 @@ pub const COP0_STATUS_CU1: u64 = 1 << 29;
pub const COP0_STATUS_CU2: u64 = 1 << 30;
//pub const COP0_CAUSE_EXCCODE_INTR: u64 = 0 << 2;
pub const COP0_CAUSE_EXCCODE_MOD: u64 = 1 << 2;
pub const COP0_CAUSE_EXCCODE_TLBL: u64 = 2 << 2;
pub const COP0_CAUSE_EXCCODE_TLBS: u64 = 3 << 2;
//pub const COP0_CAUSE_EXCCODE_ADEL: u64 = 4 << 2;
+26 -16
View File
@@ -246,11 +246,12 @@ pub fn ldl(device: &mut device::Device, opcode: u32) {
let shift = 8 * n;
let mask = bits_below_mask(8 * n);
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !7, device::memory::AccessType::Read);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Read);
if err {
return;
}
phys_address &= !7;
let mut w = [0; 2];
w[0] = device::memory::data_read(
@@ -280,11 +281,12 @@ pub fn ldr(device: &mut device::Device, opcode: u32) {
mask = bits_above_mask(8 * (n + 1))
}
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !7, device::memory::AccessType::Read);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Read);
if err {
return;
}
phys_address &= !7;
let mut w = [0; 2];
w[0] = device::memory::data_read(
@@ -349,11 +351,12 @@ pub fn lwl(device: &mut device::Device, opcode: u32) {
let shift = 8 * n;
let mask = bits_below_mask(8 * n) as u32;
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !3, device::memory::AccessType::Read);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Read);
if err {
return;
}
phys_address &= !3;
device.cpu.gpr[rt(opcode) as usize] = se32(
((device.cpu.gpr[rt(opcode) as usize] as u32) & mask
@@ -433,11 +436,12 @@ pub fn lwr(device: &mut device::Device, opcode: u32) {
mask = bits_above_mask(8 * (n + 1))
}
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !3, device::memory::AccessType::Read);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Read);
if err {
return;
}
phys_address &= !3;
device.cpu.gpr[rt(opcode) as usize] = se32(
((device.cpu.gpr[rt(opcode) as usize] as u32) & (mask as u32)
@@ -522,11 +526,13 @@ pub fn swl(device: &mut device::Device, opcode: u32) {
mask = bits_below_mask(8 * (4 - n)) as u32
}
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !3, device::memory::AccessType::Write);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Write);
if err {
return;
}
phys_address &= !3;
device::memory::data_write(
device,
phys_address,
@@ -567,11 +573,12 @@ pub fn sdl(device: &mut device::Device, opcode: u32) {
mask = bits_below_mask(8 * (8 - n))
}
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !7, device::memory::AccessType::Write);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Write);
if err {
return;
}
phys_address &= !7;
let value = device.cpu.gpr[rt(opcode) as usize] >> shift;
device::memory::data_write(
@@ -591,11 +598,12 @@ pub fn sdr(device: &mut device::Device, opcode: u32) {
let mask = bits_above_mask(8 * (7 - n));
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !7, device::memory::AccessType::Write);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Write);
if err {
return;
}
phys_address &= !7;
let value = device.cpu.gpr[rt(opcode) as usize] << shift;
device::memory::data_write(
@@ -615,11 +623,13 @@ pub fn swr(device: &mut device::Device, opcode: u32) {
let mask = bits_above_mask(8 * (3 - n)) as u32;
let (phys_address, cached, err) =
device::memory::translate_address(device, addr & !3, device::memory::AccessType::Write);
let (mut phys_address, cached, err) =
device::memory::translate_address(device, addr, device::memory::AccessType::Write);
if err {
return;
}
phys_address &= !3;
device::memory::data_write(
device,
phys_address,
+39 -11
View File
@@ -20,49 +20,49 @@ pub fn check_pending_interrupts(device: &mut device::Device) {
return;
}
exception_general(device);
exception_general(device, 0x180);
}
pub fn floating_point_exception(device: &mut device::Device) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_FPE;
exception_general(device)
exception_general(device, 0x180)
}
pub fn trap_exception(device: &mut device::Device) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_TR;
exception_general(device)
exception_general(device, 0x180)
}
pub fn syscall_exception(device: &mut device::Device) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_SYS;
exception_general(device)
exception_general(device, 0x180)
}
pub fn break_exception(device: &mut device::Device) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_BP;
exception_general(device)
exception_general(device, 0x180)
}
pub fn reserved_exception(device: &mut device::Device, cop: u64) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_RI | cop;
exception_general(device)
exception_general(device, 0x180)
}
pub fn cop_unusable_exception(device: &mut device::Device, cop: u64) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_CPU | cop;
exception_general(device)
exception_general(device, 0x180)
}
pub fn tlb_miss_exception(
@@ -94,17 +94,46 @@ pub fn tlb_miss_exception(
address >> 31,
device::cop0::COP0_XCONTEXT_REGION_MASK,
);
device::memory::masked_write_64(
&mut device.cpu.cop0.regs[device::cop0::COP0_ENTRYHI_REG as usize],
address,
0xFFFFE000,
);
let mut vector_offset = 0x180;
let mut valid = true;
for i in device.cpu.cop0.tlb_entries {
if address & !3 >= i.start_even && address & !3 <= i.end_even {
valid = i.v_even != 0;
if valid && access_type == device::memory::AccessType::Write && i.d_even == 0 {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_MOD;
valid = false;
}
break;
}
if address & !3 >= i.start_odd && address & !3 <= i.start_odd {
valid = i.v_odd != 0;
if valid && access_type == device::memory::AccessType::Write && i.d_odd == 0 {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] =
device::cop0::COP0_CAUSE_EXCCODE_MOD;
valid = false;
}
break;
}
}
if device.cpu.cop0.regs[device::cop0::COP0_STATUS_REG as usize] & device::cop0::COP0_STATUS_EXL
== 0
&& valid
{
device.cpu.pc -= 0x180
vector_offset = 0;
}
exception_general(device)
exception_general(device, vector_offset)
}
pub fn exception_general(device: &mut device::Device) {
pub fn exception_general(device: &mut device::Device, vector_offset: u32) {
if device.cpu.cop0.regs[device::cop0::COP0_STATUS_REG as usize] & device::cop0::COP0_STATUS_EXL
== 0
{
@@ -121,7 +150,6 @@ pub fn exception_general(device: &mut device::Device) {
device.cpu.cop0.regs[device::cop0::COP0_STATUS_REG as usize] |= device::cop0::COP0_STATUS_EXL;
let vector_offset: u32 = 0x180;
if device.cpu.cop0.regs[device::cop0::COP0_STATUS_REG as usize] & device::cop0::COP0_STATUS_BEV
== 0
{