void listener_thread(void *unused) { struct sockaddr_in sa; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(ftp_port); sa.sin_addr.s_addr = htonl(INADDR_ANY); int list_s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(bind(list_s, (struct sockaddr *)&sa, sizeof(sa)) == -1 || listen(list_s, OFTP_LISTEN_BACKLOG) == -1) { appstate = 1; } int conn_s; sys_ppu_thread_t id; while(appstate != 1) { if((conn_s = accept(list_s, NULL, NULL)) > 0) { sysThreadCreate(&id, client_thread, (void *)&conn_s, 1337, 0x2000, THREAD_JOINABLE, "client"); sysThreadYield(); } else sysUsleep(250000); } closesocket(list_s); sysThreadExit(0); }
void listener_thread(void *unused) { sys_ppu_thread_t id; struct sockaddr_in sa; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(2002); sa.sin_addr.s_addr = htonl(INADDR_ANY); int list_s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // only 1 socket connection is allowed at once if(bind(list_s, (struct sockaddr *)&sa, sizeof(sa)) == -1 || listen(list_s, 1) == -1) { sysThreadExit(0); } int conn_s; while (!user_requested_exit()) { if((conn_s = accept(list_s, NULL, NULL)) > 0) { sysThreadCreate(&id, client_thread, (void *)&conn_s, 1337, 0x2000, 0, "client"); sysThreadYield(); } } closesocket(list_s); sysThreadExit(0); }
int ftp_init() { if(ftp_initialized) return 1; netInitialize(); netCtlInit(); union net_ctl_info info; if(netCtlGetInfo(NET_CTL_INFO_IP_ADDRESS, &info) == 0) { // start server thread appstate = 0; sprintf(ftp_ip_str, "FTP active (%s:%i)", info.ip_address, 21); sysThreadCreate(&thread_id, listener_thread, NULL, 1500, 0x400, 0, "listener"); //s32 fd; //u64 read = 0; /* if(sysLv2FsOpen(OFTP_PASSWORD_FILE, SYS_O_RDONLY | SYS_O_CREAT, &fd, 0660, NULL, 0) == 0) { sysLv2FsRead(fd, passwd, 63, &read); } passwd[read] = '\0'; sysLv2FsClose(fd); // prevent multiline passwords strreplace(passwd, '\r', '\0'); strreplace(passwd, '\n', '\0'); */ char dlgmsg[256]; sprintf(dlgmsg, "OpenPS3FTP %s by jjolano (Twitter: @jjolano)\nWebsite: http://jjolano.dashhacks.com\nDonations: http://bit.ly/gB8CJo\nStatus: FTP Server Active (%s port 21)\n\nPress OK to exit this program.", OFTP_VERSION, info.ip_address); //msgDialogOpen2(mt_ok, dlgmsg, dialog_handler, NULL, NULL); ftp_initialized = 1; return 0; } else { //msgDialogOpen2(mt_ok, OFTP_ERRMSG_NETWORK, dialog_handler, NULL, NULL); ftp_initialized = 0; netDeinitialize(); } return -1; }
int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { sys_ppu_thread_t id; size_t stack_size = 0x4000; u64 priority = 1500; /* Create the thread and go! */ int s = sysThreadCreate(&id, RunThread, args, priority, stack_size, THREAD_JOINABLE, "SDL"); thread->handle = id; if ( s != 0) { SDL_SetError("Not enough resources to create thread"); return (-1); } //resume_thread(thread->handle); return (0); }
int main(int argc,char *argv[]) { u64 retval; s32 i,ret,running; sys_ppu_thread_t id; u64 prio = 1500; padInfo padinfo; padData paddata; size_t stacksize = 0x1000; char *threadname = "myThread"; void *threadarg = (void*)0x1337; ioPadInit(7); ret = sysThreadCreate(&id,thread_start,threadarg,prio,stacksize,THREAD_JOINABLE,threadname); printf("sysThreadCreate: %d\n",ret); ret = sysThreadJoin(id,&retval); printf("sysThreadJoin: %d - %llX\n",ret,(unsigned long long int)retval); running = 1; while(running) { ioPadGetInfo(&padinfo); for(i=0; i<MAX_PADS; i++){ if(padinfo.status[i]){ ioPadGetData(i, &paddata); if(paddata.BTN_CROSS){ running = 0; break; } } } } printf("Exiting thread test\n"); return 0; }
int main(int argc, char *argv[]) { int ret, server_mode; void *host_addr = memalign(1024 * 1024, HOST_SIZE); msgType dialog_type; sys_ppu_thread_t id; // start server thread load_modules(); init_logging(); netInitialize(); netCtlInit(); // Initialize SPUs LOG(lm_main, LOG_DEBUG, ("Initializing SPUs\n")); ret = sysSpuInitialize(MAX_PHYSICAL_SPU, MAX_RAW_SPU); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sysSpuInitialize failed: %d\n", ret)); goto quit; } init_screen(host_addr, HOST_SIZE); ioPadInit(7); ret = initialize_exit_handlers(); if (ret != 0) goto quit; show_version(); if (user_requested_exit()) goto quit; u64 CEX=0x4345580000000000ULL; u64 DEX=0x4445580000000000ULL; u64 DEH=0x4445480000000000ULL; if(lv2peek(0x80000000002E79C8ULL)==DEX) {dex_mode=2; c_firmware=3.41f;} else if(lv2peek(0x80000000002CFF98ULL)==CEX) {dex_mode=0; c_firmware=3.41f;} else if(lv2peek(0x80000000002EFE20ULL)==DEX) {dex_mode=2; c_firmware=3.55f;} else if(lv2peek(0x80000000002D83D0ULL)==CEX) {dex_mode=0; c_firmware=3.55f;} else if(lv2peek(0x8000000000302D88ULL)==DEX) {dex_mode=2; c_firmware=4.21f;} else if(lv2peek(0x80000000002E8610ULL)==CEX) {dex_mode=0; c_firmware=4.21f;} else if(lv2peek(0x80000000002E9F08ULL)==CEX) {dex_mode=0; c_firmware=4.30f;} else if(lv2peek(0x8000000000304630ULL)==DEX) {dex_mode=2; c_firmware=4.30f;} else if(lv2peek(0x80000000002E9F18ULL)==CEX) {dex_mode=0; c_firmware=4.31f;} else if(lv2peek(0x80000000002EA488ULL)==CEX) {dex_mode=0; c_firmware=4.40f;} else if(lv2peek(0x80000000002EA498ULL)==CEX) {dex_mode=0; c_firmware=4.41f;} else if(lv2peek(0x8000000000304EF0ULL)==DEX) {dex_mode=2; c_firmware=4.41f;} else if(lv2peek(0x80000000002EA9B8ULL)==CEX) {dex_mode=0; c_firmware=4.46f;} else if(lv2peek(0x8000000000305410ULL)==DEX) {dex_mode=2; c_firmware=4.46f;} else if(lv2peek(0x80000000002E9BE0ULL)==CEX) {dex_mode=0; c_firmware=4.50f;} else if(lv2peek(0x8000000000309698ULL)==DEX) {dex_mode=2; c_firmware=4.50f;} else if(lv2peek(0x80000000002E9D70ULL)==CEX) {dex_mode=0; c_firmware=4.53f;} else if(lv2peek(0x80000000002EC5E0ULL)==CEX) {dex_mode=0; c_firmware=4.55f;} else if(lv2peek(0x80000000002ED850ULL)==CEX) {dex_mode=0; c_firmware=4.60f;} else if(lv2peek(0x80000000002ED860ULL)==CEX) {dex_mode=0; c_firmware=4.65f;} else if(lv2peek(0x800000000030F1A8ULL)==DEX) {dex_mode=2; c_firmware=4.65f;} else if(lv2peek(0x80000000002ED778ULL)==CEX) {dex_mode=0; c_firmware=4.70f;} else if(lv2peek(0x800000000030F240ULL)==DEX) {dex_mode=2; c_firmware=4.70f;} else if(lv2peek(0x80000000002ED818ULL)==CEX) {dex_mode=0; c_firmware=4.75f;} else if(lv2peek(0x800000000030F2D0ULL)==DEX) {dex_mode=2; c_firmware=4.75f;} else if(lv2peek(0x80000000002ED808ULL)==CEX) {dex_mode=0; c_firmware=4.80f;} else if(lv2peek(0x800000000030F3A0ULL)==DEX) {dex_mode=2; c_firmware=4.80f;} else if(lv2peek(0x800000000030F3B0ULL)==DEX) {dex_mode=2; c_firmware=4.81f;} else if(lv2peek(0x800000000032EB60ULL)==DEH) {deh_mode=2; c_firmware=4.81f;} else c_firmware=0.00f; if(c_firmware==3.55f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_355D; } else if(c_firmware==3.55f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_355; } else if(c_firmware==4.21f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_421; } else if(c_firmware==4.30f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_430; } else if(c_firmware==4.30f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_430D; } else if(c_firmware==4.31f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_431; } else if(c_firmware==4.40f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_440; } else if(c_firmware==4.41f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_441; } else if(c_firmware==4.41f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_441D; } else if(c_firmware==4.46f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_446; } else if(c_firmware==4.50f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_450; } else if(c_firmware==4.53f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_453; } else if(c_firmware==4.55f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_455; } else if(c_firmware==4.60f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_460; } else if(c_firmware==4.65f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_465; } else if(c_firmware==4.65f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_465D; } else if(c_firmware==4.70f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_470; } else if(c_firmware==4.70f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_470D; } else if(c_firmware==4.75f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_475; } else if(c_firmware==4.80f && !dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_480; } else if(c_firmware==4.80f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_480D; } else if(c_firmware==4.75f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_475D; } else if(c_firmware==4.81f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_481D; } else if(c_firmware==4.46f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_446D; } else if(c_firmware==4.50f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_450D; } else if(c_firmware==4.21f && dex_mode) { SYSCALL_TABLE = SYSCALL_TABLE_421D; } else if(c_firmware==3.41f) { SYSCALL_TABLE = SYSCALL_TABLE_341; } else if(c_firmware==4.81f && deh_mode) { SYSCALL_TABLE = SYSCALL_TABLE_481H; } /* if(c_firmware>=4.20f && SYSCALL_TABLE) { // add and enable lv2 peek/poke + lv1 peek/poke lv2poke(0x800000000000171CULL, 0x7C0802A6F8010010ULL); lv2poke(0x800000000000171CULL + 8, 0x396000B644000022ULL); lv2poke(0x800000000000171CULL + 16, 0x7C832378E8010010ULL); lv2poke(0x800000000000171CULL + 24, 0x7C0803A64E800020ULL); lv2poke(0x800000000000171CULL + 32, 0x7C0802A6F8010010ULL); lv2poke(0x800000000000171CULL + 40, 0x396000B744000022ULL); lv2poke(0x800000000000171CULL + 48, 0x38600000E8010010ULL); lv2poke(0x800000000000171CULL + 56, 0x7C0803A64E800020ULL); lv2poke(0x800000000000171CULL + 64, 0x7C0802A6F8010010ULL); lv2poke(0x800000000000171CULL + 72, 0x7D4B537844000022ULL); lv2poke(0x800000000000171CULL + 80, 0xE80100107C0803A6ULL); lv2poke(0x800000000000171CULL + 88, 0x4E80002080000000ULL); lv2poke(0x800000000000171CULL + 96, 0x0000170C80000000ULL); lv2poke(0x800000000000171CULL + 104, 0x0000171480000000ULL); lv2poke(0x800000000000171CULL + 112, 0x0000171C80000000ULL); lv2poke(0x800000000000171CULL + 120, 0x0000173C80000000ULL); lv2poke(0x800000000000171CULL + 128, 0x0000175C00000000ULL); lv2poke(SYSCALL_PTR( 6), 0x8000000000001778ULL); //sc6 lv2poke(SYSCALL_PTR( 7), 0x8000000000001780ULL); //sc7 lv2poke(SYSCALL_PTR( 8), 0x8000000000001788ULL); //sc8 lv2poke(SYSCALL_PTR( 9), 0x8000000000001790ULL); //sc9 lv2poke(SYSCALL_PTR(10), 0x8000000000001798ULL); //sc10 }*/ // remove patch protection if(c_firmware==3.55f) remove_protection(); if(c_firmware==0.00f) ret = -1; else ret = patch_lv1_ss_services(); if (ret < 0) { dialog_type = (MSG_DIALOG_NORMAL | MSG_DIALOG_BTN_TYPE_OK | MSG_DIALOG_DISABLE_CANCEL_ON); msgDialogOpen2(dialog_type, "ERROR: Couldn't patch lv1 services, returning to the XMB.\nMake sure you are running a firmware which allows patching!", dialog_handler, NULL, NULL); dialog_action = 0; while (!dialog_action && !user_requested_exit()) { sysUtilCheckCallback(); flip(); } msgDialogAbort(); goto quit; } // patch syscall 864 to allow drive re-init if(c_firmware==0.0f) ret = -1; else ret = patch_syscall_864(); if (ret < 0) { dialog_type = (MSG_DIALOG_NORMAL | MSG_DIALOG_BTN_TYPE_OK | MSG_DIALOG_DISABLE_CANCEL_ON); msgDialogOpen2(dialog_type, "ERROR: Couldn't patch syscall 864, returning to the XMB.\nMake sure you are running a firmware which allows patching!", dialog_handler, NULL, NULL); dialog_action = 0; while (!dialog_action && !user_requested_exit()) { sysUtilCheckCallback(); flip(); } msgDialogAbort(); goto quit; } // install the necessary modules ret = install_modules(); if (ret < 0) { dialog_type = (MSG_DIALOG_NORMAL | MSG_DIALOG_BTN_TYPE_OK | MSG_DIALOG_DISABLE_CANCEL_ON); msgDialogOpen2(dialog_type, "Installation was aborted, returning to the XMB.", dialog_handler, NULL, NULL); dialog_action = 0; while (!dialog_action && !user_requested_exit()) { sysUtilCheckCallback(); flip(); } msgDialogAbort(); goto quit; } if (user_requested_exit()) goto quit; // reset & re-authenticate the BD drive sys_storage_reset_bd(); sys_storage_authenticate_bd(); // eject current disc { int fd; ret = sys_storage_open(BD_DEVICE, &fd); if (ret == 0) { ioctl_eject(fd); sys_storage_close(fd); } } ret = sysDiscRegisterDiscChangeCallback(&bd_eject_disc_callback, &bd_insert_disc_callback); // poll for an output_device poll_output_devices(); server_mode = user_select_server_mode(); if (user_requested_exit()) goto quit; if (server_mode) { #ifdef ENABLE_LOGGING if (output_device) { char file_path[100]; sprintf(file_path, "%s/daemon_log.txt", output_device); set_log_file(file_path); } #endif sysThreadCreate(&id, listener_thread, NULL, 1500, 0x400, 0, "listener"); while (1) { // server loop server_loop(); // break out of the loop when requested if (user_requested_exit()) break; } } else { while (1) { // main loop main_loop(); // break out of the loop when requested if (user_requested_exit()) break; } } ret = sysDiscUnregisterDiscChangeCallback(); quit: unpatch_lv1_ss_services(); destroy_logging(); netDeinitialize(); unload_modules(); free(host_addr); return 0; }
int main(s32 argc, char* argv[]) { atexit(_unload); // Initialize graphics GFX = new NoRSX(); MsgDialog MSG(GFX); // Release message MSG.Dialog(MSG_OK, "This build of OpenPS3FTP has not been tested by the author. As such, you use this software at your own risk. Please report any issues found to the OpenPS3FTP GitHub repository or send a tweet to @jjolano. See README.txt for more details."); // Initialize required libraries: net, netctl, io netInitialize(); netCtlInit(); ioPadInit(7); // Verify connection state s32 state; netCtlGetState(&state); if(state != NET_CTL_STATE_IPObtained) { // not connected to network - terminate program MSG.Dialog(MSG_OK, "Could not verify connection status. OpenPS3FTP will now exit."); exit(EXIT_FAILURE); } // Set application running state GFX->AppStart(); // Create thread for server sys_ppu_thread_t id; sysThreadCreate(&id, ftp_main, GFX, 1001, 0x1000, THREAD_JOINABLE, const_cast<char*>("opf_ftp_main")); // Set up graphics Font F1(LATIN2, GFX); Background BG(GFX); Bitmap BM(GFX); NoRSX_Bitmap PCL; BM.GenerateBitmap(&PCL); BG.MonoBitmap(COLOR_BLACK, &PCL); // Retrieve detailed connection information (ip address) net_ctl_info info; netCtlGetInfo(NET_CTL_INFO_IP_ADDRESS, &info); // Draw bitmap layer // Not sure how this will actually look. F1.PrintfToBitmap(50, 50, &PCL, COLOR_WHITE, "OpenPS3FTP version %s", OFTP_VERSION); F1.PrintfToBitmap(50, 100, &PCL, COLOR_WHITE, "Written by John Olano (twitter: @jjolano)"); F1.PrintfToBitmap(50, 200, &PCL, COLOR_WHITE, "IP Address: %s (port 21)", info.ip_address); F1.PrintfToBitmap(50, 300, &PCL, COLOR_WHITE, "SELECT: Execute dev_blind"); F1.PrintfToBitmap(50, 350, &PCL, COLOR_WHITE, "START: Exit OpenPS3FTP"); // Pad IO variables padInfo padinfo; padData paddata; padData paddata_old[MAX_PADS]; // Main thread loop while(GFX->GetAppStatus() != APP_EXIT) { // Get Pad Status ioPadGetInfo(&padinfo); for(unsigned int i = 0; i < MAX_PADS; i++) { if(padinfo.status[i]) { // Get Pad Data ioPadGetData(i, &paddata); // Parse Pad Data if(Pad_onPress(paddata, paddata_old[i], BTN_SELECT)) { // dev_blind stuff sysFSStat stat; s32 ret = sysFsStat("/dev_blind", &stat); if(ret == 0) { // dev_blind exists - ask to unmount MSG.Dialog(MSG_YESNO, "Do you want to unmount dev_blind?"); if(MSG.GetResponse(MSG_DIALOG_BTN_YES) == 1) { // syscall unmount lv2syscall1(838, (u64)"/dev_blind"); // display success MSG.Dialog(MSG_OK, "dev_blind was successfully unmounted."); } } else { // dev_blind does not exist - ask to mount MSG.Dialog(MSG_YESNO, "Do you want to mount dev_blind?"); if(MSG.GetResponse(MSG_DIALOG_BTN_YES) == 1) { // syscall mount lv2syscall8(837, (u64)"CELL_FS_IOS:BUILTIN_FLSH1", (u64)"CELL_FS_FAT", (u64)"/dev_blind", 0, 0 /* readonly */, 0, 0, 0); // display success with info MSG.Dialog(MSG_OK, "dev_blind was successfully mounted. Please note that dev_blind will not automatically unmount upon exiting OpenPS3FTP."); } } } if(Pad_onPress(paddata, paddata_old[i], BTN_START)) { // Exit application GFX->AppExit(); } paddata_old[i] = paddata; } } // Draw bitmap->screenbuffer BM.DrawBitmap(&PCL); GFX->Flip(); } BM.ClearBitmap(&PCL); // Wait for server thread to complete u64 retval; sysThreadJoin(id, &retval); // Parse thread return value if application is not exiting if(GFX->ExitSignalStatus() == NO_SIGNAL && retval != 0) { // Error - see ftp.cpp MSG.ErrorDialog((u32)retval); exit(EXIT_FAILURE); } return 0; }
int create_sac_accessor(void) { sys_cond_attr_t cond_attr; sys_mutex_attr_t mutex_attr; #ifndef USE_ISOSELF uint32_t entry; #endif int ret; if (sa != NULL) { return -1; } sa = calloc(sizeof(sac_accessor_t), 1); if (sa == NULL) { LOG(lm_main, LOG_ERROR, ("sac_accessor_t malloc failed\n")); return -1; } sa->id = -1; sa->buffer = (uint8_t *) memalign(128, DMA_BUFFER_SIZE); memset(sa->buffer, 0, DMA_BUFFER_SIZE); sa->read_buffer = (uint8_t *) malloc(DMA_BUFFER_SIZE); sa->write_buffer = (uint8_t *) malloc(DMA_BUFFER_SIZE); #ifdef USE_ISOSELF ret = file_alloc_load(SAC_MODULE_LOCATION, &sa->module_buffer, &sa->module_size); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("cannot load file: " SAC_MODULE_LOCATION "0x%x\n", ret)); return 0; } ret = sys_isoself_spu_create(&sa->id, sa->module_buffer); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_create : 0x%x\n", ret)); return 0; } #else ret = sysSpuRawCreate(&sa->id, NULL); if (ret) { LOG(lm_main, LOG_ERROR, ("sysSpuRawCreate failed %d\n", ret)); return ret; } LOG(lm_main, LOG_DEBUG, ("succeeded. raw_spu number is %d\n", sa->id)); // Reset all pending interrupts before starting. sysSpuRawSetIntStat(sa->id, 2, 0xfUL); sysSpuRawSetIntStat(sa->id, 0, 0xfUL); ret = sysSpuRawLoad(sa->id, SAC_MODULE_LOCATION, &entry); if (ret) { LOG(lm_main, LOG_ERROR, ("sysSpuRawLoad failed [" SAC_MODULE_LOCATION "]%d\n", ret)); return ret; } LOG(lm_main, LOG_DEBUG, ("succeeded. entry %x\n", entry)); #endif #ifdef USE_ISOSELF ret = sys_isoself_spu_set_int_mask(sa->id, SPU_INTR_CLASS_2, INTR_PPU_MB_MASK | INTR_STOP_MASK | INTR_HALT_MASK); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_set_int_mask : 0x%x\n", ret)); return 0; } #else ret = sysSpuRawSetIntMask(sa->id, SPU_INTR_CLASS_2, INTR_PPU_MB_MASK | INTR_STOP_MASK | INTR_HALT_MASK); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_raw_spu_set_int_mask : 0x%x\n", ret)); return ret; } #endif memset(&cond_attr, 0, sizeof(sys_cond_attr_t)); cond_attr.attr_pshared = SYS_COND_ATTR_PSHARED; memset(&mutex_attr, 0, sizeof(sys_mutex_attr_t)); mutex_attr.attr_protocol = SYS_MUTEX_PROTOCOL_PRIO; mutex_attr.attr_recursive = SYS_MUTEX_ATTR_NOT_RECURSIVE; mutex_attr.attr_pshared = SYS_MUTEX_ATTR_PSHARED; mutex_attr.attr_adaptive = SYS_MUTEX_ATTR_NOT_ADAPTIVE; if (sysMutexCreate(&sa->mmio_mutex, &mutex_attr) != 0) { LOG(lm_main, LOG_ERROR, ("create mmio_mutex failed.\n")); return -1; } if (sysCondCreate(&sa->mmio_cond, sa->mmio_mutex, &cond_attr) != 0) { LOG(lm_main, LOG_ERROR, ("create mmio_cond failed.\n")); return -1; } if ((ret = sysThreadCreate(&sa->handler, handle_interrupt, 0, PRIMARY_PPU_THREAD_PRIO, PRIMARY_PPU_STACK_SIZE, THREAD_INTERRUPT, (char *) "SEL Interrupt PPU Thread")) != 0) { LOG(lm_main, LOG_ERROR, ("ppu_thread_create returned %d\n", ret)); return ret; } #ifdef USE_ISOSELF ret = sys_isoself_spu_create_interrupt_tag(sa->id, SPU_INTR_CLASS_2, SYS_HW_THREAD_ANY, &sa->intrtag); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_create_interrupt_tag : 0x%x\n", ret)); return 0; } #else ret = sysSpuRawCreateInterrupTag(sa->id, SPU_INTR_CLASS_2, SYS_HW_THREAD_ANY, &sa->intrtag); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_raw_spu_create_interrupt_tag : 0x%x\n", ret)); return ret; } #endif // Establishing the interrupt tag on the interrupt PPU thread. LOG(lm_main, LOG_DEBUG, ("Establishing the interrupt tag on the interrupt PPU thread.\n")); if ((ret = sysInterruptThreadEstablish(&sa->ih, sa->intrtag, sa->handler, sa->id)) != 0) { LOG(lm_main, LOG_ERROR, ("sys_interrupt_thread_establish returned %d\n", ret)); return ret; } #ifdef USE_ISOSELF ret = sys_isoself_spu_set_int_mask(sa->id, SPU_INTR_CLASS_2, INTR_PPU_MB_MASK); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_set_int_mask : 0x%x\n", ret)); return 0; } ret = sys_isoself_spu_start(sa->id); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_start : 0x%x\n", ret)); return 0; } #else ret = sysSpuRawSetIntMask(sa->id, SPU_INTR_CLASS_2, INTR_PPU_MB_MASK); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_raw_spu_set_int_mask : 0x%x\n", ret)); return ret; } // Run the Raw SPU sysSpuRawWriteProblemStorage(sa->id, SPU_NextPC, entry); sysSpuRawWriteProblemStorage(sa->id, SPU_RunCtrl, 0x1); EIEIO; #endif sysSpuRawWriteProblemStorage(sa->id, SPU_In_MBox, (uint64_t) sa->buffer); EIEIO; return 0; }
pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle* ppte_osThreadHandle) { char threadName[28]; static int threadNum = 1; int psl1ghtAttr; void *pTls; sys_ppu_thread_t threadId; pte_osResult result; psl1ghtThreadData *pThreadData; sys_sem_attr_t sem_attr; s32 ret; if (threadNum++ > MAX_PSL1GHT_UID) { threadNum = 0; } /* Make sure that the stack we're going to allocate is big enough */ if (stackSize < DEFAULT_STACK_SIZE_BYTES) { stackSize = DEFAULT_STACK_SIZE_BYTES; } /* Allocate TLS structure for this thread. */ pTls = pteTlsThreadInit(); if (pTls == NULL) { PSL1GHT_DEBUG("pteTlsThreadInit: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Allocate some memory for our per-thread control data. We use this for: * 1. Entry point and parameters for the user thread's main function. * 2. Semaphore used for thread cancellation. */ pThreadData = (psl1ghtThreadData *) malloc(sizeof(psl1ghtThreadData)); if (pThreadData == NULL) { pteTlsThreadDestroy(pTls); PSL1GHT_DEBUG("malloc(psl1ghtThreadData): PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; goto FAIL0; } /* Save a pointer to our per-thread control data as a TLS value */ pteTlsSetValue(pTls, threadDataKey, pThreadData); pThreadData->entryPoint = entryPoint; pThreadData->argv = argv; /* Create a semaphore used to cancel threads */ sem_attr.attr_protocol = SYS_SEM_ATTR_PROTOCOL; sem_attr.attr_pshared = SYS_SEM_ATTR_PSHARED; sem_attr.key = 0; sem_attr.flags = 0; snprintf(sem_attr.name, sizeof(sem_attr.name), "cncl%04d", threadNum); ret = sysSemCreate(&pThreadData->cancelSem, &sem_attr, 0, 255); if (ret == 0) { /* In order to emulate TLS functionality, we append the address of the TLS structure that we * allocated above to the thread's name. To set or get TLS values for this thread, the user * needs to get the name of the thread from the OS and then parse the name to extract * a pointer to the TLS structure. */ snprintf(threadName, sizeof(threadName), "pthread%04d__%x", threadNum, (unsigned int) ((u64)pTls)); // FIXME: joinable or not ? psl1ghtAttr = 0; pThreadData->priority = initialPriority; pThreadData->ended = 0; // printf("%s %p %d %d %d\n",threadName, psl1ghtStubThreadEntry, initialPriority, stackSize, psl1ghtAttr); ret = sysThreadCreate(&threadId, psl1ghtStubThreadEntry, pThreadData, OS_MAX_PRIO, stackSize, psl1ghtAttr, threadName); } if (ret == 0x80010004) { free(pThreadData); pteTlsThreadDestroy(pTls); PSL1GHT_DEBUG("sceKernelCreateThread: PTE_OS_NO_RESOURCES\n"); result = PTE_OS_NO_RESOURCES; } else if (ret != 0) { free(pThreadData); pteTlsThreadDestroy(pTls); PSL1GHT_DEBUG("sceKernelCreateThread: PTE_OS_GENERAL_FAILURE\n"); result = PTE_OS_GENERAL_FAILURE; } else { *ppte_osThreadHandle = threadId; result = PTE_OS_OK; } FAIL0: return result; }
int main(s32 argc, const char* argv[]) { //Mutex. sys_mutex_attr_t attr; memset(&attr, 0, sizeof(attr)); attr.attr_protocol = SYS_MUTEX_PROTOCOL_FIFO; attr.attr_recursive = SYS_MUTEX_ATTR_NOT_RECURSIVE; attr.attr_pshared = SYS_MUTEX_ATTR_PSHARED; attr.attr_adaptive = SYS_MUTEX_ATTR_NOT_ADAPTIVE; strcpy(attr.name, "mutex"); sysMutexCreate(&thread_mutex, &attr); //Threads. THREADS_RUNNING = 2; sys_ppu_thread_t pad_id, program_id; sysThreadCreate(&pad_id, pad_thread, (void*) &GLOBAL_EXIT, 1500, 0x400, 0, "pad"); sysThreadCreate(&program_id, program_thread, (void*) &GLOBAL_EXIT, 1337, 0x400, 0, "program"); //Create buffers. gcmContextData *context; void *host_addr = NULL; rsxBuffer buffers[MAX_BUFFERS]; int currentBuffer = 0; //Allocate a 1Mb buffer, alligned to a 1Mb boundary to be our shared IO memory with the RSX. host_addr = memalign(1024*1024, HOST_SIZE); context = initScreen(host_addr, HOST_SIZE); //Get resolution. u16 width, height; getResolution(&width, &height); //Create buffers. int i; for(i = 0; i < MAX_BUFFERS; i++) { makeBuffer(&buffers[i], width, height, i); } flip(context, MAX_BUFFERS - 1); //Main loop. while(THREADS_RUNNING > 0) { //Prepare buffer. setRenderTarget(context, &buffers[currentBuffer]); waitFlip(); //Flip buffer onto screen. flip(context, buffers[currentBuffer].id); //Change buffer. currentBuffer++; if(currentBuffer >= MAX_BUFFERS) { currentBuffer = 0; } } //Free buffers. gcmSetWaitFlip(context); for(i = 0; i < MAX_BUFFERS; i++) { rsxFree(buffers[i].ptr); } rsxFinish(context, 1); free(host_addr); //Mutex destroy. sysMutexDestroy(thread_mutex); return 0; }