/* SPDX-License-Identifier: GPL-3.0-or-later */ #define SDL_MAIN_HANDLED #include #include "firmware_gate.h" #include #include #ifndef CHIMERA_GFX_PS5_ALLOWED_FIRMWARE #define CHIMERA_GFX_PS5_ALLOWED_FIRMWARE "NONE" #endif #define CHIMERA_GFX_PHASE1_WIDTH 1920 #define CHIMERA_GFX_PHASE1_HEIGHT 1080 #define CHIMERA_GFX_PHASE1_HOLD_MS 1000u static void log_stage(const char *stage, int success) { (void)fprintf(stdout, "{\"stage\":\"%s\",\"success\":%s}\n", stage, success != 0 ? "true" : "false"); } int main(int argc, char **argv) { SDL_Window *window = NULL; SDL_Surface *surface = NULL; Uint32 color; int result = 1; if (argc != 4 || strcmp(argv[1], "--firmware") != 0 || strcmp(argv[3], "--acknowledge-phase1-videoout-clear") != 0) { (void)fprintf( stderr, "refusing: exact firmware and acknowledgement required\n"); return 64; } if (!chimera_gfx_firmware_gate_allows(CHIMERA_GFX_PS5_ALLOWED_FIRMWARE, argv[2])) { (void)fprintf(stderr, "refusing: firmware is not allowlisted\n"); return 77; } log_stage("firmware_gate", 1); SDL_SetMainReady(); if (SDL_Init(SDL_INIT_VIDEO) != 0) { log_stage("video_init", 0); goto cleanup; } log_stage("video_init", 1); window = SDL_CreateWindow("chimera-gfx controlled clear", 0, 0, CHIMERA_GFX_PHASE1_WIDTH, CHIMERA_GFX_PHASE1_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { log_stage("window_create", 0); goto cleanup; } log_stage("window_create", 1); surface = SDL_GetWindowSurface(window); if (surface == NULL) { log_stage("surface_acquire", 0); goto cleanup; } log_stage("surface_acquire", 1); color = SDL_MapRGBA(surface->format, 0x18u, 0x2au, 0x41u, 0xffu); if (SDL_FillRect(surface, NULL, color) != 0) { log_stage("cpu_fill", 0); goto cleanup; } log_stage("cpu_fill", 1); /* This is the only requested display mutation and the hardware gate. */ if (SDL_UpdateWindowSurface(window) != 0) { log_stage("single_present", 0); goto cleanup; } log_stage("single_present", 1); SDL_Delay(CHIMERA_GFX_PHASE1_HOLD_MS); result = 0; cleanup: if (window != NULL) { SDL_DestroyWindow(window); } SDL_Quit(); log_stage("cleanup", 1); return result; }