Fix definition of OSCoroutine structure and context switch logic.

This commit is contained in:
Andrew Church
2016-07-07 00:04:46 +09:00
parent e4379ee431
commit ad8f744747
2 changed files with 17 additions and 14 deletions

View File

@@ -22,30 +22,32 @@ OSSwitchCoroutine(OSCoroutine *from, OSCoroutine *to)
kernel::saveContext(&thread->context);
from->nia = thread->context.lr;
from->cr = thread->context.cr;
from->gpr5 = thread->context.gpr[5];
from->gqr1 = thread->context.gqr[1];
from->gpr1 = thread->context.gpr[1];
from->gpr2 = thread->context.gpr[2];
for (int i = 13; i < 32; i++) {
thread->context.gpr[i] = to->gpr13_31[i-13];
}
from->gpr13_31[0] = thread->context.gpr[13];
for (int i = 14; i < 32; i++) {
thread->context.fpr[i] = to->fpr14_31[i-14];
from->gpr13_31[i-13] = thread->context.gpr[i];
from->fpr14_31[i-14] = thread->context.fpr[i];
from->ps14_31[i-14][0] = static_cast<float>(thread->context.fpr[i]);
from->ps14_31[i-14][1] = static_cast<float>(thread->context.psf[i]);
}
// Switch to new coroutine state
thread->context.lr = to->nia;
thread->context.cr = to->cr;
thread->context.gqr[1] = to->gqr1;
thread->context.gpr[0] = from->nia; // Probably just coincidence
thread->context.gpr[1] = to->gpr1;
thread->context.gpr[2] = to->gpr2;
thread->context.gpr[3] = 1;
thread->context.gpr[4] = 1;
thread->context.gpr[5] = to->gpr5;
for (int i = 13; i < 32; i++) {
thread->context.gpr[i] = to->gpr13_31[i-13];
}
thread->context.gpr[3] = 1; // Possibly an argument?
thread->context.gpr[4] = 1; // Possibly an argument?
thread->context.gpr[5] = to->gqr1; // Probably just coincidence
thread->context.gpr[13] = to->gpr13_31[0];
for (int i = 14; i < 32; i++) {
thread->context.gpr[i] = to->gpr13_31[i-13];
thread->context.fpr[i] = to->fpr14_31[i-14];
thread->context.psf[i] = static_cast<double>(to->ps14_31[i-14][1]);
}
kernel::restoreContext(&thread->context);
}

View File

@@ -10,20 +10,21 @@ struct OSCoroutine
{
be_val<uint32_t> nia;
be_val<uint32_t> cr;
be_val<uint32_t> gpr5;
be_val<uint32_t> gqr1;
be_val<uint32_t> gpr1;
be_val<uint32_t> gpr2;
be_val<uint32_t> gpr13_31[19];
be_val<double> fpr14_31[18];
UNKNOWN(0x90);
be_val<float> ps14_31[18][2];
};
CHECK_OFFSET(OSCoroutine, 0x000, nia);
CHECK_OFFSET(OSCoroutine, 0x004, cr);
CHECK_OFFSET(OSCoroutine, 0x008, gpr5);
CHECK_OFFSET(OSCoroutine, 0x008, gqr1);
CHECK_OFFSET(OSCoroutine, 0x00C, gpr1);
CHECK_OFFSET(OSCoroutine, 0x010, gpr2);
CHECK_OFFSET(OSCoroutine, 0x014, gpr13_31);
CHECK_OFFSET(OSCoroutine, 0x060, fpr14_31);
CHECK_OFFSET(OSCoroutine, 0x0F0, ps14_31);
CHECK_SIZE(OSCoroutine, 0x180);
} // namespace coreinit