From: chaoskagami Date: Sat, 6 Aug 2016 14:42:00 +0000 (-0400) Subject: Merge branch 'master' into wip/malloc X-Git-Tag: v0.3.0~66 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=121c6c10e920b0283ea5cfe6aeec6aea75be6dfe;p=corbenik%2Fcorbenik.git Merge branch 'master' into wip/malloc --- 121c6c10e920b0283ea5cfe6aeec6aea75be6dfe diff --cc include/std/draw.h index ea6ed75,98c91e2..2533685 --- a/include/std/draw.h +++ b/include/std/draw.h @@@ -25,15 -25,12 +25,13 @@@ enum scree screen_bottom }; - struct framebuffers -_UNUSED static volatile struct framebuffers --{ ++struct framebuffers { uint8_t *top_left; uint8_t *top_right; uint8_t *bottom; -} *framebuffers = (struct framebuffers *)0x23FFFE00; +}; + - _UNUSED static struct framebuffers *framebuffers_cakehax = (struct framebuffers *)0x23FFFE00; +extern struct framebuffers *framebuffers; // This is marked unused since it occurs in all files. #define TOP_FB framebuffers->top_left diff --cc source/option.c index 628a9e0,7d2edf8..2ff53a0 --- a/source/option.c +++ b/source/option.c @@@ -105,14 -101,12 +105,12 @@@ save_config( f_unlink(PATH_CONFIG); if (!(conf_handle = fopen(PATH_CONFIG, "w"))) - abort("Failed to open config for write?\n"); + while(1); - config.options[OPTION_RECONFIGURED] = 0; // This should not persist to disk. + config->options[OPTION_RECONFIGURED] = 0; // This should not persist to disk. - fwrite(&config, 1, sizeof(config), conf_handle); + fwrite(config, 1, sizeof(struct config_file), conf_handle); fclose(conf_handle); - config.options[OPTION_RECONFIGURED] = 1; // Save caches on boot. + config->options[OPTION_RECONFIGURED] = 1; // Save caches on boot. - - fprintf(stderr, "Saved config successfully.\n"); } diff --cc source/screeninit.c index 4bda651,167c079..5be8d08 --- a/source/screeninit.c +++ b/source/screeninit.c @@@ -1,187 -33,222 +33,231 @@@ #include #include #include + #include #include - #define PDN_GPU_CNT (*(volatile uint8_t *)0x10141200) - - static volatile uint32_t *const a11_entry = (volatile uint32_t *)0x1FFFFFF8; - - struct framebuffers* framebuffers = NULL; - - #define FB_FMT(col, plx, screen) ((col & 0b111) | ((plx & 1) << 5) | ((screen & 1) << 6) | 0b10000000001100000000) - - #define RGBA8 0 - #define BGR8 1 - #define RGB565_OES 2 - #define RGB5_A1_OES 3 - #define RGBA4_OES 4 - - #define INIT_FULL 0 - #define INIT_PARAMS 1 - #define INIT_DEINIT 2 - - uint32_t do_init = 0; - uint32_t brightnessLevel = 0; - uint32_t init_mode = 0; - - void __attribute__((naked)) screen11(void) { - // FIXME - We could use some serious macros here... - - uint32_t yaw, init_top, init_bottom; - switch(init_mode) { - case RGBA8: - yaw = 240 * 4; - break; - case BGR8: - case RGB565_OES: - case RGB5_A1_OES: - case RGBA4_OES: - yaw = 240 * 3; - break; - } - - init_top = FB_FMT(init_mode, 0, 1); - init_bottom = FB_FMT(init_mode, 0, 0); - - volatile uint32_t *const arm11 = (uint32_t *)0x1FFFFFF8; - - if (do_init == INIT_FULL) { - *(volatile uint32_t *)0x10141200 = 0x1007F; - *(volatile uint32_t *)0x10202014 = 0x00000001; - *(volatile uint32_t *)0x1020200C &= 0xFFFEFFFE; - } - - *(volatile uint32_t *)0x10202240 = brightnessLevel; // Alteration; directly read brightness. - *(volatile uint32_t *)0x10202A40 = brightnessLevel; - - if (do_init == INIT_FULL) { - *(volatile uint32_t *)0x10202244 = 0x1023E; - *(volatile uint32_t *)0x10202A44 = 0x1023E; - } - - // Top screen - *(volatile uint32_t *)0x10400400 = 0x000001c2; - *(volatile uint32_t *)0x10400404 = 0x000000d1; - *(volatile uint32_t *)0x10400408 = 0x000001c1; - *(volatile uint32_t *)0x1040040c = 0x000001c1; - *(volatile uint32_t *)0x10400410 = 0x00000000; - *(volatile uint32_t *)0x10400414 = 0x000000cf; - *(volatile uint32_t *)0x10400418 = 0x000000d1; - *(volatile uint32_t *)0x1040041c = 0x01c501c1; - *(volatile uint32_t *)0x10400420 = 0x00010000; - *(volatile uint32_t *)0x10400424 = 0x0000019d; - *(volatile uint32_t *)0x10400428 = 0x00000002; - *(volatile uint32_t *)0x1040042c = 0x00000192; - *(volatile uint32_t *)0x10400430 = 0x00000192; - *(volatile uint32_t *)0x10400434 = 0x00000192; - *(volatile uint32_t *)0x10400438 = 0x00000001; - *(volatile uint32_t *)0x1040043c = 0x00000002; - *(volatile uint32_t *)0x10400440 = 0x01960192; - *(volatile uint32_t *)0x10400444 = 0x00000000; - *(volatile uint32_t *)0x10400448 = 0x00000000; - - *(volatile uint32_t *)0x1040045C = 0x00f00190; - *(volatile uint32_t *)0x10400460 = 0x01c100d1; - *(volatile uint32_t *)0x10400464 = 0x01920002; - *(volatile uint32_t *)0x10400468 = 0x18300000; - *(volatile uint32_t *)0x10400470 = init_top; // Format - *(volatile uint32_t *)0x10400474 = 0x00010501; - *(volatile uint32_t *)0x10400478 = 0; - *(volatile uint32_t *)0x10400490 = yaw; - *(volatile uint32_t *)0x1040049C = 0x00000000; - - // Disco register - for(uint32_t i = 0; i < 256; i++) - *(volatile uint32_t *)0x10400484 = 0x10101 * i; - - // Bottom screen - *(volatile uint32_t *)0x10400500 = 0x000001c2; - *(volatile uint32_t *)0x10400504 = 0x000000d1; - *(volatile uint32_t *)0x10400508 = 0x000001c1; - *(volatile uint32_t *)0x1040050c = 0x000001c1; - *(volatile uint32_t *)0x10400510 = 0x000000cd; - *(volatile uint32_t *)0x10400514 = 0x000000cf; - *(volatile uint32_t *)0x10400518 = 0x000000d1; - *(volatile uint32_t *)0x1040051c = 0x01c501c1; - *(volatile uint32_t *)0x10400520 = 0x00010000; - *(volatile uint32_t *)0x10400524 = 0x0000019d; - *(volatile uint32_t *)0x10400528 = 0x00000052; - *(volatile uint32_t *)0x1040052c = 0x00000192; - *(volatile uint32_t *)0x10400530 = 0x00000192; - *(volatile uint32_t *)0x10400534 = 0x0000004f; - *(volatile uint32_t *)0x10400538 = 0x00000050; - *(volatile uint32_t *)0x1040053c = 0x00000052; - *(volatile uint32_t *)0x10400540 = 0x01980194; - *(volatile uint32_t *)0x10400544 = 0x00000000; - *(volatile uint32_t *)0x10400548 = 0x00000011; - *(volatile uint32_t *)0x1040055C = 0x00f00140; - *(volatile uint32_t *)0x10400560 = 0x01c100d1; - *(volatile uint32_t *)0x10400564 = 0x01920052; - *(volatile uint32_t *)0x10400568 = 0x18300000 + (yaw * 400); - *(volatile uint32_t *)0x10400570 = init_bottom; // Format - *(volatile uint32_t *)0x10400574 = 0x00010501; - *(volatile uint32_t *)0x10400578 = 0; - *(volatile uint32_t *)0x10400590 = yaw; - *(volatile uint32_t *)0x1040059C = 0x00000000; - - // Disco register - for(uint32_t i = 0; i < 256; i++) - *(volatile uint32_t *)0x10400584 = 0x10101 * i; - - *(volatile uint32_t *)0x10400468 = 0x18300000; - *(volatile uint32_t *)0x1040046c = 0x18300000; - *(volatile uint32_t *)0x10400494 = 0x18300000; - *(volatile uint32_t *)0x10400498 = 0x18300000; - *(volatile uint32_t *)0x10400568 = 0x18300000 + (yaw * 400); - *(volatile uint32_t *)0x1040056c = 0x18300000 + (yaw * 400); - - //Set CakeBrah framebuffers - *((volatile uint32_t *)0x23FFFE00) = 0x18300000; - *((volatile uint32_t *)0x23FFFE04) = 0x18300000; - *((volatile uint32_t *)0x23FFFE08) = 0x18300000 + (yaw * 400); - - //Clear ARM11 entry offset - *arm11 = 0; - - //Wait for the entry to be set - while(!*arm11); - - //Jump to it - ((void (*)())*arm11)(); ++struct framebuffers *framebuffers; ++ + volatile uint32_t *const arm11Entry = (volatile uint32_t *)0x1FFFFFF8; + static const uint32_t brightness[4] = {0x26, 0x39, 0x4C, 0x5F}; + + void __attribute__((naked)) arm11Stub(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + //Wait for the entry to be set + while(*arm11Entry == ARM11_STUB_ADDRESS); + + //Jump to it + ((void (*)())*arm11Entry)(); } - void - screen_mode(uint32_t mode) + static void invokeArm11Function(void (*func)()) { - // FIXME - At the moment, this seems mandatory to do full screeninit. + static int hasCopiedStub = false; + if(!hasCopiedStub) + { + memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x30); + ctr_cache_clean_and_flush_all(); + hasCopiedStub = true; + } - // I get very fucked up results from just changing the framebuffer offsets - // and display color mode. Until I figure out WHY a full screeninit has to - // be performed, I have to do a full screeninit. + *arm11Entry = (uint32_t)func; + while(*arm11Entry); + *arm11Entry = ARM11_STUB_ADDRESS; + } - // And no, 3dbrew didn't help. Partial init seems to be a superset of what - // I was attempting. + void deinitScreens(void) + { + void __attribute__((naked)) ARM11(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); - do_init = 1; // Do a partial init. + //Shutdown LCDs + *(volatile uint32_t *)0x10202A44 = 0; + *(volatile uint32_t *)0x10202244 = 0; + *(volatile uint32_t *)0x10202014 = 0; - if (PDN_GPU_CNT == 1) - do_init = 0; // Do a full init. + WAIT_FOR_ARM9(); + } - // FIXME - God awful syntactical hack. - brightnessLevel = ("\x40\x8F\xC0\xFF")[config->options[OPTION_BRIGHTNESS]]; + if(PDN_GPU_CNT != 1) invokeArm11Function(ARM11); + } - init_mode = mode; // Mode + void updateBrightness(uint32_t brightnessIndex) + { + static uint32_t brightnessLevel; + brightnessLevel = brightness[brightnessIndex]; - *a11_entry = (uint32_t)screen11; + void __attribute__((naked)) ARM11(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); - while (*a11_entry); + //Change brightness + *(volatile uint32_t *)0x10202240 = brightnessLevel; + *(volatile uint32_t *)0x10202A40 = brightnessLevel; + WAIT_FOR_ARM9(); + } + + ctr_cache_clean_and_flush_all(); + invokeArm11Function(ARM11); + } + + void clearScreens(void) { + void __attribute__((naked)) ARM11(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + //Setting up two simultaneous memory fills using the GPU + volatile uint32_t *REGs_PSC0 = (volatile uint32_t *)0x10400010; + + REGs_PSC0[0] = (uint32_t)framebuffers->top_left >> 3; //Start address + REGs_PSC0[1] = (uint32_t)(framebuffers->top_left + (400 * 240 * 4)) >> 3; //End address + REGs_PSC0[2] = 0; //Fill value + REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start + + volatile uint32_t *REGs_PSC1 = (volatile uint32_t *)0x10400020; + + REGs_PSC1[0] = (uint32_t)framebuffers->bottom >> 3; //Start address + REGs_PSC1[1] = (uint32_t)(framebuffers->bottom + (320 * 240 * 4)) >> 3; //End address + REGs_PSC1[2] = 0; //Fill value + REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start + + while(!((REGs_PSC0[3] & 2) && (REGs_PSC1[3] & 2))); + + WAIT_FOR_ARM9(); + } + + ctr_cache_clean_and_flush_all(); + invokeArm11Function(ARM11); + } + + void screen_mode(uint32_t mode) { + static uint32_t stride, init_top, init_bottom, bright; + - bright = brightness[config.options[OPTION_BRIGHTNESS]]; ++ bright = brightness[config->options[OPTION_BRIGHTNESS]]; + + stride = 240 * 3; + if (mode == RGBA8) + stride = 240 * 4; + + init_top = MAKE_FRAMEBUFFER_PIXFMT(mode, 0, 1); + init_bottom = MAKE_FRAMEBUFFER_PIXFMT(mode, 0, 0); + ++ // We literally just discard the previous state - for sanity's sake. + if (!framebuffers) { + framebuffers = malloc(sizeof(struct framebuffers)); - memcpy(framebuffers, framebuffers_cakehax, sizeof(struct framebuffers)); + } + + void __attribute__((naked)) ARM11(void) { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + PDN_GPU_CNT = 0x1007F; //bit0: Enable GPU regs 0x10400000+, bit16 turn on LCD backlight? + LCD_REG(0x14) = 0x00000001; //UNKNOWN register, maybe LCD related? 0x10202000 + LCD_REG(0xC) &= 0xFFFEFFFE; //UNKNOWN register, maybe LCD related? + + LCD_TOP_CONF_BRIGHTNESS = bright; + LCD_BOT_CONF_BRIGHTNESS = bright; + LCD_TOP_CONF_REG(0x44) = 0x1023E; //unknown + LCD_BOT_CONF_REG(0x44) = 0x1023E; //unknown + + // Top screen + PDC0_FRAMEBUFFER_SETUP_REG(0x00) = 0x000001c2; //unknown + PDC0_FRAMEBUFFER_SETUP_REG(0x04) = 0x000000d1; //unknown + PDC0_FRAMEBUFFER_SETUP_REG(0x08) = 0x000001c1; + PDC0_FRAMEBUFFER_SETUP_REG(0x0c) = 0x000001c1; + PDC0_FRAMEBUFFER_SETUP_REG(0x10) = 0x00000000; + PDC0_FRAMEBUFFER_SETUP_REG(0x14) = 0x000000cf; + PDC0_FRAMEBUFFER_SETUP_REG(0x18) = 0x000000d1; + PDC0_FRAMEBUFFER_SETUP_REG(0x1c) = 0x01c501c1; + PDC0_FRAMEBUFFER_SETUP_REG(0x20) = 0x00010000; + PDC0_FRAMEBUFFER_SETUP_REG(0x24) = 0x0000019d; + PDC0_FRAMEBUFFER_SETUP_REG(0x28) = 0x00000002; + PDC0_FRAMEBUFFER_SETUP_REG(0x2c) = 0x00000192; + PDC0_FRAMEBUFFER_SETUP_REG(0x30) = 0x00000192; + PDC0_FRAMEBUFFER_SETUP_REG(0x34) = 0x00000192; + PDC0_FRAMEBUFFER_SETUP_REG(0x38) = 0x00000001; + PDC0_FRAMEBUFFER_SETUP_REG(0x3c) = 0x00000002; + PDC0_FRAMEBUFFER_SETUP_REG(0x40) = 0x01960192; + PDC0_FRAMEBUFFER_SETUP_REG(0x44) = 0x00000000; + PDC0_FRAMEBUFFER_SETUP_REG(0x48) = 0x00000000; + PDC0_FRAMEBUFFER_SETUP_DIMS = (240u << 16) | (400u); + PDC0_FRAMEBUFFER_SETUP_REG(0x60) = 0x01c100d1; + PDC0_FRAMEBUFFER_SETUP_REG(0x64) = 0x01920002; + PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FB_FORMAT = init_top; + PDC0_FRAMEBUFFER_SETUP_REG(0x74) = 0x00010501; + PDC0_FRAMEBUFFER_SETUP_FB_SELECT = 0; + PDC0_FRAMEBUFFER_SETUP_FB_STRIDE = stride; + PDC0_FRAMEBUFFER_SETUP_REG(0x9C) = 0x00000000; + + // Disco register + for(volatile uint32_t i = 0; i < 256; i++) + PDC0_FRAMEBUFFER_SETUP_DISCO = 0x10101 * i; + + // Bottom screen + PDC1_FRAMEBUFFER_SETUP_REG(0x00) = 0x000001c2; + PDC1_FRAMEBUFFER_SETUP_REG(0x04) = 0x000000d1; + PDC1_FRAMEBUFFER_SETUP_REG(0x08) = 0x000001c1; + PDC1_FRAMEBUFFER_SETUP_REG(0x0c) = 0x000001c1; + PDC1_FRAMEBUFFER_SETUP_REG(0x10) = 0x000000cd; + PDC1_FRAMEBUFFER_SETUP_REG(0x14) = 0x000000cf; + PDC1_FRAMEBUFFER_SETUP_REG(0x18) = 0x000000d1; + PDC1_FRAMEBUFFER_SETUP_REG(0x1c) = 0x01c501c1; + PDC1_FRAMEBUFFER_SETUP_REG(0x20) = 0x00010000; + PDC1_FRAMEBUFFER_SETUP_REG(0x24) = 0x0000019d; + PDC1_FRAMEBUFFER_SETUP_REG(0x28) = 0x00000052; + PDC1_FRAMEBUFFER_SETUP_REG(0x2c) = 0x00000192; + PDC1_FRAMEBUFFER_SETUP_REG(0x30) = 0x00000192; + PDC1_FRAMEBUFFER_SETUP_REG(0x34) = 0x0000004f; + PDC1_FRAMEBUFFER_SETUP_REG(0x38) = 0x00000050; + PDC1_FRAMEBUFFER_SETUP_REG(0x3c) = 0x00000052; + PDC1_FRAMEBUFFER_SETUP_REG(0x40) = 0x01980194; + PDC1_FRAMEBUFFER_SETUP_REG(0x44) = 0x00000000; + PDC1_FRAMEBUFFER_SETUP_REG(0x48) = 0x00000011; + PDC1_FRAMEBUFFER_SETUP_DIMS = (240u << 16) | 320u; + PDC1_FRAMEBUFFER_SETUP_REG(0x60) = 0x01c100d1; + PDC1_FRAMEBUFFER_SETUP_REG(0x64) = 0x01920052; + PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x1835dc00; + PDC1_FRAMEBUFFER_SETUP_FB_FORMAT = init_bottom; + PDC1_FRAMEBUFFER_SETUP_REG(0x74) = 0x00010501; + PDC1_FRAMEBUFFER_SETUP_FB_SELECT = 0; + PDC1_FRAMEBUFFER_SETUP_FB_STRIDE = stride; + PDC1_FRAMEBUFFER_SETUP_REG(0x9C) = 0x00000000; + + // Disco register + for(volatile uint32_t i = 0; i < 256; i++) + PDC1_FRAMEBUFFER_SETUP_DISCO = 0x10101 * i; + + PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_2 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FBB_ADDR_1 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FBB_ADDR_2 = 0x18300000; + + PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x1835dc00; + PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_2 = 0x1835dc00; + + //Set CakeBrah framebuffers + framebuffers->top_left = (uint8_t *)0x18300000; + framebuffers->top_right = (uint8_t *)0x18300000; + framebuffers->bottom = (uint8_t *)0x1835dc00; + + WAIT_FOR_ARM9(); + } + + ctr_cache_clean_and_flush_all(); + invokeArm11Function(ARM11); + + clearScreens(); + + // Turn on backlight - i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1); ++// i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1); + //Turn on backlight + i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); }