int main(int argc, char **argv)
{
   OSMessage msg;
   int i;

   OSInitMessageQueue(&sQueue, sMessages, NumMessages);

   OSCreateThread(&sThread, msgThreadEntry, 0, NULL, sThreadStack + StackSize, StackSize, 20, 0);
   OSResumeThread(&sThread);

   // Make sure other thread gets to a blocking read
   OSSleepTicks(OSMillisecondsToTicks(10));

   // Sending message into empty queue should succeed.
   for (i = 0; i < NumMessages; ++i) {
      msg.message = (void *)1;
      msg.args[0] = 2 + i;
      msg.args[1] = 3;
      msg.args[2] = 4;
      test_eq(OSSendMessage(&sQueue, &msg, 0), TRUE);
   }

   // Make sure other thread gets a chance to read all messages.
   OSSleepTicks(OSMillisecondsToTicks(10));
   test_eq(sMessagesRead, NumMessages);

   return 0;
}
示例#2
0
/* Start of our code */
void _start()
{
  /* Load a good stack */
  asm(
      "lis %r1, 0x1ab5 ;"
      "ori %r1, %r1, 0xd138 ;"
  );
 
  /* Get a handle to coreinit.rpl */
  unsigned int coreinit_handle;
  OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);

  /* OS memory allocation functions */
  void* (*OSAllocFromSystem)(uint32_t size, int align);

  /* OS thread functions */
  bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint16_t attr);
  int32_t (*OSResumeThread)(void *thread);

  /* Exit function */
  void (*_Exit)();

  /* Read the addresses of the functions */
  OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
  OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
  OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
  OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);

  /* Create a string argument */
  char *str = OSAllocFromSystem(6, 1);
  str[0] = 'H';
  str[1] = 'e';
  str[2] = 'l';
  str[3] = 'l';
  str[4] = 'o';
  str[5] = 0;

  /* Allocate a stack for the thread */
  uint32_t stack = (uint32_t) OSAllocFromSystem(0x1000, 0x10);
  stack += 0x1000;

  /* Create the thread */
  void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8);
  bool ret = OSCreateThread(thread, OSFatal, (int)str, null, stack, 0x1000, 0, 1);
  if (ret == false)
  {
	  OSFatal("Failed to create thread");
  }

  /* Schedule it for execution */
  OSResumeThread(thread);

  /* Infinite loop */
  while(1);
}
示例#3
0
void
startAlarmCallbackThreads()
{
   for (auto i = 0u; i < CoreCount; ++i) {
      auto &thread = sAlarmCallbackThread[i];
      auto stackSize = 16 * 1024;
      auto stack = reinterpret_cast<uint8_t*>(coreinit::internal::sysAlloc(stackSize, 8));
      auto name = coreinit::internal::sysStrDup(fmt::format("Alarm Thread {}", i));

      OSCreateThread(thread, sAlarmCallbackThreadEntryPoint, i, nullptr,
         reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, -1,
         static_cast<OSThreadAttributes>(1 << i));
      OSSetThreadName(thread, name);
      OSResumeThread(thread);
   }
}
示例#4
0
void
GameLoaderRun()
{
   auto appModule = gLoader.loadRPL(gGameRpx.c_str());

   if (!appModule) {
      gLog->error("Could not load {}", gGameRpx);
      return;
   }

   gSystem.setUserModule(appModule);
   gDebugControl.preLaunch();
   gLog->debug("Succesfully loaded {}", gGameRpx);

   // Call the RPX __preinit_user if it is defined
   auto userPreinit = appModule->findFuncExport<void, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*>("__preinit_user");

   if (userPreinit) {
      struct HeapHandles
      {
         be_ptr<CommonHeap> mem1Heap;
         be_ptr<CommonHeap> fgHeap;
         be_ptr<CommonHeap> mem2Heap;
      };

      HeapHandles *wiiHandles = OSAllocFromSystem<HeapHandles>();
      wiiHandles->mem1Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM1);
      wiiHandles->fgHeap = MEMGetBaseHeapHandle(BaseHeapType::FG);
      wiiHandles->mem2Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2);

      userPreinit(&wiiHandles->mem1Heap, &wiiHandles->fgHeap, &wiiHandles->mem2Heap);

      MEMSetBaseHeapHandle(BaseHeapType::MEM1, wiiHandles->mem1Heap);
      MEMSetBaseHeapHandle(BaseHeapType::FG, wiiHandles->fgHeap);
      MEMSetBaseHeapHandle(BaseHeapType::MEM2, wiiHandles->mem2Heap);
      OSFreeToSystem(wiiHandles);
   }

   // Create default threads
   for (auto i = 0u; i < CoreCount; ++i) {
      auto thread = OSAllocFromSystem<OSThread>();
      auto stackSize = appModule->defaultStackSize;
      auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8));
      auto name = OSSprintfFromSystem("Default Thread %d", i);

      OSCreateThread(thread, 0u, 0, nullptr,
                     reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, 16,
                     static_cast<OSThreadAttributes::Flags>(1 << i));
      OSSetDefaultThread(i, thread);
      OSSetThreadName(thread, name);
   }

   // Create interrupt threads
   for (auto i = 0u; i < CoreCount; ++i) {
      auto thread = OSAllocFromSystem<OSThread>();
      auto stackSize = 16 * 1024;
      auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8));
      auto name = OSSprintfFromSystem("Interrupt Thread %d", i);

      OSCreateThread(thread, InterruptThreadEntryPoint, i, nullptr,
                     reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, -1,
                     static_cast<OSThreadAttributes::Flags>(1 << i));
      OSSetInterruptThread(i, thread);
      OSSetThreadName(thread, name);
      OSResumeThread(thread);
   }

   // Run thread 1
   OSRunThread(OSGetDefaultThread(1), appModule->entryPoint, 0, nullptr);
}
示例#5
0
void _start()
{
	asm(
		"lis %r1, 0x1ab5 ;"
		"ori %r1, %r1, 0xd138 ;"
	);
	unsigned int coreinit_handle, gx2_handle;
	OSDynLoad_Acquire("coreinit", &coreinit_handle);
	OSDynLoad_Acquire("gx2", &gx2_handle);
	//OS Memory functions
	void*(*memset)(void * dest, unsigned int value, unsigned int bytes);
	void*(*OSAllocFromSystem)(unsigned int size, int align);
	void(*OSFreeToSystem)(void *ptr);
	//IM functions
	int(*IM_Open)();
	int(*IM_Close)(int fd);
	int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b);

	//OS Memory functions
	OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem);
	//IM functions
	OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open);
	OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close);
	OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState);
	//Restart system to get lib access
	int fd = IM_Open();
	void *mem = OSAllocFromSystem(0x100, 64);
	memset(mem, 0, 0x100);
	//set restart flag to force quit browser
	IM_SetDeviceState(fd, mem, 3, 0, 0); 
	IM_Close(fd);
	OSFreeToSystem(mem);
	//wait a bit for browser end
	unsigned int t1 = 0x1FFFFFFF;
	while(t1--) ;

	/* Get the framebuffer of the TV or DRC */
	void(*GX2SwapScanBuffers)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers);
	unsigned char *abuseFunc = (unsigned char*)GX2SwapScanBuffers;
	unsigned short f_hi = *(unsigned short*)(abuseFunc+0x12);
	unsigned short f_lo = *(unsigned short*)(abuseFunc+0x16);
	unsigned int gx2settingBase = (((f_lo & 0x8000) ? (f_hi-1) : f_hi) << 16) | f_lo;
	unsigned int args[2];
	args[0] = *((unsigned int*)(gx2settingBase + 0x304));
	args[1] = *((unsigned int*)(gx2settingBase + 0x304 + 0x20));
	int(*OSGetCoreId)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId);
	void(*OSTestThreadCancel)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSTestThreadCancel", &OSTestThreadCancel);
	void(*GX2Shutdown)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown);
	int(*GX2GetMainCoreId)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId);

	/* Prepare for our own death */
	void*(*OSGetCurrentThread)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCurrentThread", &OSGetCurrentThread);
	void *myBorkedThread = OSGetCurrentThread();
	int (*OSSuspendThread)(void *thread);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSSuspendThread", &OSSuspendThread);

	/* Prepare for thread startups */
	int (*OSCreateThread)(void *thread, void *entry, int argc, void *args, unsigned int stack, unsigned int stack_size, int priority, unsigned short attr);
	int (*OSResumeThread)(void *thread);
	int (*OSIsThreadTerminated)(void *thread);

	OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated);

	/* Allocate a stack for the thread */
	unsigned int stack = (unsigned int) OSAllocFromSystem(0x1000, 0x10);
	stack += 0x1000;
	/* Create the thread */
	void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8);
	
	if(OSGetCoreId() != GX2GetMainCoreId()) //needed for access without crashing
	{
		int ret = OSCreateThread(thread, GX2Shutdown, 0, (void*)0, stack, 0x1000, 0, 0x10 | (1<<GX2GetMainCoreId()));
		if (ret == 0)
			OSFatal("Failed to create thread");
		/* Schedule it for execution */
		OSResumeThread(thread);
		while(OSIsThreadTerminated(thread) == 0) ;
	}
	else //same core, easy
		GX2Shutdown();

	//current thread is broken, switch to a working one in core 1
	int ret = OSCreateThread(thread, myGXthread, 2, args, stack, 0x1000, 0, 0xA);
	if (ret == 0)
		OSFatal("Failed to create thread");

	/* Schedule it for execution */
	OSResumeThread(thread);
	/* SO UGLY but it works magically */
	while(1) ;
	//would be better but again, crashes 5.3.2
	//OSSuspendThread(myBorkedThread);
	//OSFatal("I am still not dead!");
}