| 154 | } |
| 155 | |
| 156 | Result gspInit(void) |
| 157 | { |
| 158 | Result ret=0; |
| 159 | if (AtomicPostIncrement(&gspRefCount)) return 0; |
| 160 | |
| 161 | // Initialize events |
| 162 | for (int i = 0; i < GSPGPU_EVENT_MAX; i ++) |
| 163 | LightEvent_Init(&gspEvents[i], RESET_STICKY); |
| 164 | |
| 165 | // Retrieve a GSP service session handle |
| 166 | ret = srvGetServiceHandle(&gspGpuHandle, "gsp::Gpu"); |
| 167 | if (R_FAILED(ret)) goto _fail0; |
| 168 | |
| 169 | // Acquire GPU rights |
| 170 | ret = GSPGPU_AcquireRight(0); |
| 171 | if (R_FAILED(ret)) goto _fail1; |
| 172 | |
| 173 | // Register ourselves as a user of graphics hardware |
| 174 | svcCreateEvent(&gspEvent, RESET_ONESHOT); |
| 175 | ret = GSPGPU_RegisterInterruptRelayQueue(gspEvent, 0x1, &gspSharedMemHandle, &gspThreadId); |
| 176 | if (R_FAILED(ret)) |
| 177 | goto _fail2; |
| 178 | |
| 179 | // Initialize the hardware if we are the first process to register |
| 180 | if (ret == 0x2A07) |
| 181 | gspHardwareInit(); |
| 182 | |
| 183 | // Map GSP shared memory |
| 184 | gspSharedMem = mappableAlloc(0x1000); |
| 185 | svcMapMemoryBlock(gspSharedMemHandle, (u32)gspSharedMem, MEMPERM_READWRITE, MEMPERM_DONTCARE); |
| 186 | |
| 187 | // Initialize interrupt queue header |
| 188 | s32* sharedGspCmdBuf = (s32*)((u8*)gspSharedMem + 0x800 + gspThreadId*0x200); |
| 189 | do { |
| 190 | __ldrex(sharedGspCmdBuf); |
| 191 | } while (__strex(sharedGspCmdBuf, 0)); |
| 192 | |
| 193 | // Start event handling thread |
| 194 | gspRunEvents = true; |
| 195 | gspLastEvent = -1; |
| 196 | gspEventThread = threadCreate(gspEventThreadMain, 0x0, GSP_EVENT_STACK_SIZE, 0x1A, -2, true); |
| 197 | return 0; |
| 198 | |
| 199 | _fail2: |
| 200 | GSPGPU_ReleaseRight(); |
| 201 | _fail1: |
| 202 | svcCloseHandle(gspGpuHandle); |
| 203 | _fail0: |
| 204 | AtomicDecrement(&gspRefCount); |
| 205 | return ret; |
| 206 | } |
| 207 | |
| 208 | void gspExit(void) |
| 209 | { |
no test coverage detected