void schedfStyle(FontStyle *style) { schedf("Font Style: h=%f (%f), v=%f (%f), w=%f", style->fontH, style->fontHRes, style->fontV, style->fontVRes, style->fontWeight); schedf(", family=%d, style=%d / %d", style->fontFamily, style->fontStyle, style->fontStyleSub); schedf(", lang=%d, reg=%d, country=%d", style->fontLanguage, style->fontRegion, style->fontCountry); schedf(", name=%s, file=%s", style->fontName, style->fontFileName); schedf(", attr=%08x, exp=%d\n", style->fontAttributes, style->fontExpire); }
void checkDispatchCases(const char *name, void (*testfunc)(int)) { int state; dispatchCheckpoint("%s without changes:", name); testfunc(0); flushschedf(); didResched = 0; schedf("\n"); dispatchCheckpoint("%s with short dispatch suspend:", name); testfunc(1); flushschedf(); didResched = 0; schedf("\n"); dispatchCheckpoint("%s while dispatch suspended:", name); // Starting a thread apparently resumes the dispatch thread. ++ignoreResched; state = sceKernelSuspendDispatchThread(); dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state); testfunc(0); dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state)); --ignoreResched; flushschedf(); didResched = 0; schedf("\n"); dispatchCheckpoint("%s while intr suspended:", name); state = sceKernelCpuSuspendIntr(); dispatchCheckpoint("sceKernelCpuSuspendIntr: %08x", state); testfunc(1); dispatchCheckpoint("sceKernelCpuResumeIntr: %08x", sceKernelCpuResumeIntr(state)); flushschedf(); }
void testTryAllocThread(const char *title, u32 attr, u32 requestBytes, u32 initialBytes) { schedf("%s: ", title); SceUID vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, attr, 0x100, NULL); // This way we have some allocated + free. void *data; sceKernelAllocateVpl(vpl, initialBytes, &data, NULL); SceUID allocThread = sceKernelCreateThread("allocThread", &allocFunc, 0x12, 0x1000, 0, NULL); sceKernelStartThread(allocThread, sizeof(SceUID), &vpl); sceKernelDelayThread(400); int result = sceKernelTryAllocateVpl(vpl, requestBytes, &data); schedf("L2 "); sceKernelDelayThread(600); sceKernelDeleteVpl(vpl); sceKernelWaitThreadEnd(allocThread, NULL); sceKernelTerminateDeleteThread(allocThread); if (result == 0) { schedf("OK (thread=%08X)\n", schedulingResult); } else { schedf("Failed (thread=%08X, main=%08X)\n", schedulingResult, result); } }
void testCharGlyphImage(const char *title, FontHandle f, u16 charCode, GlyphImage *glyph, bool show) { if (show) { memset(glyph->buffer, 0, 80 * 20); } int result = sceFontGetCharGlyphImage(f, charCode, glyph); if (result == 0) { checkpoint("%s: OK", title); if (show) { const u8 *p = (const u8 *)glyph->buffer; for (int y = 0; y < 20; ++y) { schedf(" -> "); int linesize = 20; if (glyph->bytesPerLine > 2 && glyph->bytesPerLine <= 80) { linesize = glyph->bytesPerLine; } for (int x = 0; x < linesize; ++x) { schedf("%02x", *p++); } schedf("\n"); } } } else { checkpoint("%s: Failed (%08x)", title, result); } }
static int threadFunction(int argSize, void* argPointer) { schedf("[1]:%d:%04X\n", argSize, argPointer ? *((unsigned int*)argPointer) : 0); sceKernelWaitSemaCB(sema, 1, NULL); schedf("[2]:%d:%04X\n", argSize, argPointer ? *((unsigned int*)argPointer) : 0); return 0; }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint(NULL); schedf("%s: ", reason); // This prevents drawing to the screen, which makes the test faster. HAS_DISPLAY = 0; for (int y = 0; y < 1; ++y) { for (int x = 0; x < 1; ++x) { // For the purposes of this test, ignore alpha. schedf("%06x", buf[y * 512 + x] & 0x00FFFFFF); } schedf("\n"); flushschedf(); } HAS_DISPLAY = 1; // Reset. memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void schedfCharInfo(FontCharInfo *info) { schedf("Font Char: bitmap %dx%d, from %d,%d", info->bitmapWidth, info->bitmapHeight, info->bitmapLeft, info->bitmapTop); schedf(", metrics: %dx%d, asc=%d, desc=%d", info->sfp26Width, info->sfp26Height, info->sfp26Ascender, info->sfp26Descender); schedf(", bearH=%dx%d, bearV=%dx%d", info->sfp26BearingHX, info->sfp26BearingHY, info->sfp26BearingVX, info->sfp26BearingVY); schedf(", advanceH=%d, advanceV=%d", info->sfp26AdvanceH, info->sfp26AdvanceV); schedf(", shadowFlags=%04x, shadowId=%d\n", info->shadowFlags, info->shadowId); }
int main(int argc, char *argv[]) { reschedThread = sceKernelCreateThread("resched", &reschedFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL); checkDispatchCases("Semas", &checkSema); didResched = 0; schedf("\n\n"); checkDispatchCases("Mutexes", &checkMutex); didResched = 0; schedf("\n\n"); checkDispatchCases("LwMutexes", &checkLwMutex); didResched = 0; schedf("\n\n"); checkDispatchCases("EventFlags", &checkEventFlag); didResched = 0; schedf("\n\n"); checkDispatchCases("Io", &checkIo); didResched = 0; schedf("\n\n"); checkDispatchInterrupt(); return 0; }
void testGetCycle(const char *title, int *cyclep) { int result = sceCtrlGetSamplingCycle(cyclep); if (cyclep != NULL && cyclep != (int *) 0xDEADBEEF) { schedf("%s: %08X (%d)\n", title, result, *cyclep); } else { schedf("%s: %08X\n", title, result); } }
int main(int argc, char **argv) { int result; int check_not_update_value = 7; SceKernelSemaInfo info; sema = sceKernelCreateSema("sema1", 0, 0, 2, NULL); sceKernelReferSemaStatus(sema, &info); PRINT_SEMAPHORE(sema, info); threads[0] = sceKernelCreateThread("Thread-0", (void *)&threadFunction, 0x12, 0x10000, 0, NULL); threads[1] = sceKernelCreateThread("Thread-1", (void *)&threadFunction, 0x12, 0x10000, 0, NULL); threads[2] = sceKernelCreateThread("Thread-2", (void *)&threadFunction, 0x12, 0x10000, 0, NULL); threads[3] = sceKernelCreateThread("Thread-3", (void *)&threadFunction, 0x12, 0x10000, 0, NULL); threads[4] = sceKernelCreateThread("Thread-4", (void *)&threadFunction2, 0x12, 0x10000, 0, NULL); schedf("VALUE-INVARIANT:%d\n", check_not_update_value); sceKernelStartThread(threads[0], 1, (void*)&test[1]); sceKernelStartThread(threads[1], 2, NULL); sceKernelStartThread(threads[2], 0, (void*)&test[0]); sceKernelStartThread(threads[3], sizeof(int), (void*)&test[4]); sceKernelStartThread(threads[4], sizeof(int), &check_not_update_value); sceKernelDelayThread(10 * 1000); schedf("---\n"); sceKernelReferSemaStatus(sema, &info); PRINT_SEMAPHORE(sema, info); schedf("---\n"); sceKernelSignalSema(sema, 1); sceKernelDelayThread(10 * 1000); schedf("---\n"); sceKernelReferSemaStatus(sema, &info); PRINT_SEMAPHORE(sema, info); schedf("---\n"); sceKernelSignalSema(sema, 1); sceKernelDelayThread(10 * 1000); schedf("---\n"); sceKernelReferSemaStatus(sema, &info); PRINT_SEMAPHORE(sema, info); schedf("---\n"); result = sceKernelDeleteSema(sema); schedf("%08X\n", result); result = sceKernelDeleteSema(sema); schedf("%08X\n", result); schedf("VALUE-INVARIANT:%d\n", check_not_update_value); flushschedf(); return 0; }
static int scheduleTestFunc1(SceSize argSize, void* argPointer) { u32 bits = 0xDEADBEEF; SceUInt timeout = 5000; schedf("T1B"); int result = sceKernelWaitEventFlagCB(*(int*) argPointer, 0x00FF, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout); schedf("T1D (result=%08x, bits=%08x) ", result, (uint) bits); return 0; }
inline void testCancel(const char *title, SceUID vtimer) { int result = sceKernelCancelVTimerHandler(vtimer); if (result == 0) { checkpoint(NULL); schedf("%s: OK ", title); } else { checkpoint(NULL); schedf("%s: Failed (%08x) ", title, result); } schedfVTimer(vtimer); }
int main(int argc, char *argv[]) { sceKernelSetCompiledSdkVersion(0x2060010); schedf("Until 2.60:\n"); runReferTests(); sceKernelSetCompiledSdkVersion(0x2060011); schedf("\n\nAfter 2.60:\n"); runReferTests(); return 0; }
inline void testFree(const char *title, SceUID fpl, void *data) { int result = sceKernelFreeFpl(fpl, data); if (result == 0) { checkpoint(NULL); schedf("%s: OK ", title); schedfFpl(fpl); } else { checkpoint(NULL); schedf("%s: Failed (%08x) ", title, result); schedfFpl(fpl); } }
void *testTryAlloc(const char *title, SceUID vpl, unsigned int size, int with_data) { void *data = (void *) 0xDEADBEEF; int result = sceKernelTryAllocateVpl(vpl, size, with_data ? &data : NULL); if (result == 0) { schedf("%s: OK ", title); schedfVpl(vpl); } else { schedf("%s: Failed (%08X) ", title, result); schedfVpl(vpl); } return data; }
void *testAllocTimeout(const char *title, SceUID vpl, unsigned int size, unsigned int timeout, int with_data) { void *data = (void *) 0xDEADBEEF; int result = sceKernelAllocateVpl(vpl, size, with_data ? &data : NULL, &timeout); if (result == 0) { schedf("%s: OK (%dms left) ", title, timeout); schedfVpl(vpl); } else { schedf("%s: Failed (%08X, %dms left) ", title, result, timeout); schedfVpl(vpl); } return data; }
static int scheduleTestFunc3(SceSize argSize, void* argPointer) { int result = 0x800201A8; u32 bits = 0xDEADBEEF; SceUInt timeout; schedf("T3B"); while (result == 0x800201A8) { timeout = 5; result = sceKernelWaitEventFlagCB(*(int*) argPointer, 0xFFFF, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout); } schedf("T3D (result=%08x, bits=%08x) ", result, (uint) bits); return 0; }
inline void schedfVpl(SceUID vpl) { if (vpl > 0) { SceKernelVplInfo info; info.size = sizeof(info); int result = sceKernelReferVplStatus(vpl, &info); if (result == 0) { schedVplInfo(&info); } else { schedf("VPL: Invalid (%08X)\n", result); } } else { schedf("VPL: Failed (%08X)\n", vpl); } }
int delayFunc(SceSize argc, void *argv) { schedf("* delayFunc\n"); sceKernelDelayThread(500); return 7; }
static int lockFunc(SceSize argSize, void* argPointer) { SceUInt timeout = 1000; schedulingResult = sceKernelLockMutex(*(int*) argPointer, 1, &timeout); schedf("L1 "); sceKernelDelayThread(1000); return 0; }
void testCheckStackLayout(const char *title, int argSize, u32 attr) { char argLengthTemp[0x1000]; memset(argLengthTemp, 0xAB, sizeof(argLengthTemp)); // First create the thread to wipe the stack area, that way we can see what it'd look like clean. SceUID stackCheckThread = sceKernelCreateThread("stackCheck", &stackCheckFunc, 0x10, 0x1000, attr, NULL); stackCheckInfo.size = sizeof(stackCheckInfo); sceKernelReferThreadStatus(stackCheckThread, &stackCheckInfo); sceKernelTerminateDeleteThread(stackCheckThread); memset(stackCheckInfo.stack, 0xCC, stackCheckInfo.stackSize); stackCheckName = title; stackCheckThread = sceKernelCreateThread("stackCheck", &stackCheckFunc, 0x10, 0x1000, attr, NULL); sceKernelStartThread(stackCheckThread, argSize, argLengthTemp); sceKernelWaitThreadEnd(stackCheckThread, NULL); u32 *stack = (u32 *) stackCheckInfo.stack; stack[1] = 0xFF1337FF; sceKernelTerminateDeleteThread(stackCheckThread); if (stack[1] != 0xFF1337FF) { schedf(" %s: WARNING: stack cleared to something after delete: %08x.\n", stackCheckName, stack[1]); } checkpoint("%s", title); }
extern "C" int main(int argc, char *argv[]) { if (loadVideoModules() < 0) { return 1; } sceMpegInit(); int result = sceMpegRingbufferConstruct((SceMpegRingbuffer *) &g_ringbuffer, 512, g_ringbufferData, sceMpegRingbufferQueryMemSize(512), &testMpegCallback, (void *) 0x1234); checkpoint("Normal: %08x", sceMpegRingbufferDestruct((SceMpegRingbuffer *) &g_ringbuffer)); checkpoint("Twice: %08x", sceMpegRingbufferDestruct((SceMpegRingbuffer *) &g_ringbuffer)); checkpoint("Invalid: %08x", sceMpegRingbufferDestruct((SceMpegRingbuffer *) 0xDEADBEEF)); checkpoint("NULL: %08x", sceMpegRingbufferDestruct(NULL)); g_ringbuffer.packetsTotal = 100; g_ringbuffer.packetsAvail = 90; g_ringbuffer.packetsRead = 2; g_ringbuffer.packetsWritten = 53; sceMpegRingbufferDestruct((SceMpegRingbuffer *) &g_ringbuffer); checkpoint(NULL); schedf("After destruct: "); schedfRingbuffer(&g_ringbuffer, g_ringbufferData); unloadVideoModules(); return 0; }
int main(int argc, char *argv[]) { int result, cycle; schedulingLogPos = schedulingLog; schedf("sceCtrlGetSamplingCycle:\n"); testGetCycle("Normal", &cycle); // Crashes. //testGetCycle("NULL", NULL); //testGetCycle("Normal", (int *) 0xDEADBEEF); testSetCycle("Zero", 0); testSetCycle("1", 1); testSetCycle("Negative", -1); testSetCycle("333", 333); testSetCycle("4444", 4444); testSetCycle("5554", 5554); testSetCycle("5555", 5555); testSetCycle("5556", 5556); testSetCycle("6666", 6666); testSetCycle("19999", 19999); testSetCycle("20000", 20000); testSetCycle("20001", 20001); testSetCycle("Zero", 0); testCycleLatch(0); testCycleLatch(5555); testCycleLatch(9999); testCycleLatch(16666); testCycleLatch(20000); printf("%s", schedulingLog); return 0; }
int stackCheckFunc(SceSize argc, void *argv) { if ((int)argv & 0xf) { schedf(" %s: ERROR: arg pointer not aligned.\n", stackCheckName); } u32 *stack = (u32 *) stackCheckInfo.stack; u32 *stackEnd = stack + stackCheckInfo.stackSize / 4; if (stack[0] != sceKernelGetThreadId()) { schedf(" %s: ERROR: stack should start with thread ID.\n", stackCheckName); } if (stackEnd[-1] != 0xFFFFFFFF || stackEnd[-2] != 0xFFFFFFFF) { schedf(" %s: WARNING: k0 laid out differently?\n", stackCheckName); } if (stackEnd[-14] != (u32)stack) { schedf(" %s: WARNING: stack pointer not correct in k0.\n", stackCheckName); } if (stackEnd[-16] != sceKernelGetThreadId()) { schedf(" %s: WARNING: thread id not correct in k0.\n", stackCheckName); } SceUID uid = sceKernelAllocPartitionMemory(2, "TEST", PSP_SMEM_Low, 0x100, NULL); if (stack < (u32 *)sceKernelGetBlockHeadAddr(uid)) { schedf(" %s: WARNING: stack allocated low.\n", stackCheckName); } sceKernelFreePartitionMemory(uid); if (stack[1] != 0xFFFFFFFF) { schedf(" %s: WARNING: stack not set to FF, instead: %08x.\n", stackCheckName, stack[1]); } return 0; }
static int allocFunc(SceSize argSize, void* argPointer) { SceUInt timeout = 1000; void *data; schedulingResult = sceKernelAllocateVpl(*(SceUID *) argPointer, 0x20, &data, &timeout); schedf("L1 "); sceKernelDelayThread(1000); sceKernelFreeVpl(*(SceUID *) argPointer, data); return 0; }
void testSetCycle(const char *title, int cycle) { sceDisplayWaitVblank(); int result = sceCtrlSetSamplingCycle(cycle); schedf("%s: %08X (%d)", title, result, cycle); int verify = 0xDEADBEEF; if (result >= 0) { sceCtrlGetSamplingCycle(&verify); if (cycle == verify) { schedf(" - OK\n"); } else { schedf(" - mismatch %d vs %d\n", cycle, verify); } } else { sceCtrlGetSamplingCycle(&verify); schedf(" - still %d\n", verify); } }
int main(int argc, char **argv) { SceUID vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, 0, 0x10000, NULL); void *data; testTryAlloc("More than free", vpl, 0xFFE1, 1); testTryAlloc("0 bytes", vpl, 0, 1); testTryAlloc("1 byte", vpl, 1, 1); testTryAlloc("-1 bytes", vpl, -1, 1); testTryAlloc("16 bytes", vpl, 16, 1); testTryAlloc("8 bytes", vpl, 8, 1); // Crashes. //testTryAlloc("Into NULL", vpl, 8, 0); testTryAlloc("Most remaining", vpl, 0xFF00, 1); testTryAlloc("More than remaining", vpl, 0xA1, 1); testTryAlloc("All remaining", vpl, 0xA0, 1); testTryAlloc("All remaining - 7", vpl, 0xA0 - 7, 1); testTryAlloc("All remaining - 8", vpl, 0xA0 - 8, 1); testTryAlloc("1 byte (none left)", vpl, 1, 1); sceKernelDeleteVpl(vpl); testTryAlloc("NULL", 0, 0x100, 1); testTryAlloc("NULL with invalid", 0, 0, 0); testTryAlloc("Invalid", 0xDEADBEEF, 0x100, 1); testTryAlloc("Deleted", vpl, 0x100, 1); flushschedf(); testDiff(); u32 attrs[] = {PSP_VPL_ATTR_FIFO, PSP_VPL_ATTR_PRIORITY, PSP_VPL_ATTR_SMALLEST, PSP_VPL_ATTR_HIGHMEM}; int i; for (i = 0; i < sizeof(attrs) / sizeof(attrs[0]); ++i) { schedf("Attr %x:\n", attrs[i]); testTryAllocThread(" Alloc 0x20 of 0x00/0xE0", attrs[i], 0x20, 0xE0 - 0x08); testTryAllocThread(" Alloc 0x20 of 0x20/0xE0", attrs[i], 0x20, 0xE0 - 0x08 - (0x20 + 0x08)); testTryAllocThread(" Alloc 0x20 of 0x40/0xE0", attrs[i], 0x20, 0xE0 - 0x08 - (0x20 + 0x08) * 2); schedf("\n"); } BASIC_SCHED_TEST("Zero", result = sceKernelTryAllocateVpl(vpl1, 0, &data); );
void testRefer(const char *title, SceUID cb, SceKernelCallbackInfo *info) { int result = sceKernelReferCallbackStatus(cb, info); if (result == 0 && info != NULL) { checkpoint(NULL); schedf("%s: ", title); schedfCallback(*info); } else { checkpoint("%s: Failed (%08x)", title, result); } }
void testCreate(const char *title, const char *name, SceKernelThreadEntry entry, int prio, int stack, SceUInt attr, SceKernelThreadOptParam *opt) { SceUID result = sceKernelCreateThread(name, entry, prio, stack, attr, opt); if (result > 0) { checkpoint(NULL); schedf("%s: ", title); schedfThreadStatus(result); sceKernelDeleteThread(result); } else { checkpoint("%s: Failed (%08X)", title, result); } }
inline void createTest(const char *title, const char *name, u32 attr, int count, void *options) { SceUID mutex = sceKernelCreateMutex(name, attr, count, options); if (mutex > 0) { checkpoint(NULL); schedf("%s: ", title); schedfMutex(mutex); sceKernelDeleteMutex(mutex); } else { checkpoint("%s: Failed (%X)", title, mutex); } }