From 99cded27624d9f2f7395ab5ccfed07b258de5fd4 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Tue, 1 Jun 2021 13:19:23 +0200 Subject: [PATCH] lolserial improvements allow debug output to be suspended, drop assembly version --- stage2/debug.c | 15 ------ stage2/debug.h | 5 +- stage2/lolserial.c | 78 +++++++++++++++++++++++++++++++ stage2/lolserial.h | 19 ++++++++ stage2/lolserial_asm.S | 103 ----------------------------------------- stage2/main.c | 18 ++++++- 6 files changed, 117 insertions(+), 121 deletions(-) delete mode 100644 stage2/debug.c create mode 100644 stage2/lolserial.c create mode 100644 stage2/lolserial.h delete mode 100644 stage2/lolserial_asm.S diff --git a/stage2/debug.c b/stage2/debug.c deleted file mode 100644 index 4b5994f..0000000 --- a/stage2/debug.c +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef LOLSERIAL_DEBUG - -extern void lolserial_lprint(char *str, int len); - -void DEBUG(char *fmt, ...) -{ - char str[256]; - va_list va; - va_start(va, fmt); - vsnprintf(str, sizeof(str), fmt, va); - lolserial_lprint(str, sizeof(str)); - va_end(va); -} - -#endif /* LOLSERIAL_DEBUG */ diff --git a/stage2/debug.h b/stage2/debug.h index 1989413..3a45fda 100644 --- a/stage2/debug.h +++ b/stage2/debug.h @@ -16,11 +16,12 @@ #define __DEBUG_H__ #include "types.h" +#include "stdio.h" -#ifndef LOLSERIAL_DEBUG +#ifndef ENABLE_DEBUG static inline void DEBUG(char *fmt, ...) {} #else -void DEBUG(char *fmt, ...); +#define DEBUG(...) printf(__VA_ARGS__) #endif diff --git a/stage2/lolserial.c b/stage2/lolserial.c new file mode 100644 index 0000000..0b6e671 --- /dev/null +++ b/stage2/lolserial.c @@ -0,0 +1,78 @@ +#ifdef LOLSERIAL_DEBUG + +#include "lolserial.h" +#include "gpio.h" +#include "utils.h" +#include "latte.h" +#include +#include + +#define LOLSERIAL_WAIT_TICKS 200 + +static int enable = 1; +static char suspend_buf[4096]; +static int suspend_len = 0; + +/* lolserial string output, now not in assembly... */ +static void lolserial_lprint(const char *str, int len) +{ + /* setup output pin */ + clear32(LT_GPIO_OWNER, GP_SENSORBAR); + set32(LT_GPIO_ENABLE, GP_SENSORBAR); + set32(LT_GPIO_DIR, GP_SENSORBAR); + set32(LT_GPIO_OUT, GP_SENSORBAR); + + /* loop until null terminator or string end */ + for (const char *end = str + len; *str && (str != end); str++) { + for (u32 bits = 0x200 | (*str << 1); bits; bits >>= 1) { + /* set bit value */ + mask32(LT_GPIO_OUT, GP_SENSORBAR, (bits & 1) ? GP_SENSORBAR : 0); + + /* wait ticks for bit */ + u32 now = read32(LT_TIMER), then = now + LOLSERIAL_WAIT_TICKS; + for (; then < now; now = read32(LT_TIMER)); /* wait overflow */ + for (; now < then; now = read32(LT_TIMER)); /* wait */ + } + } +} + +/* lolserial is slow, for timing critical tasks it might change + * the outcome; as a workaround, output can be suspended and + * printed out at a later point in time */ +void lolserial_suspend(void) +{ + memset(suspend_buf, 0, sizeof(suspend_buf)); + suspend_len = 0; + enable = 0; +} + +void lolserial_resume(void) +{ + enable = 1; + lolserial_lprint(suspend_buf, suspend_len); +} + +/* devoptab output function */ +static ssize_t lolserial_write(struct _reent *r, void *fd, const char *ptr, size_t len) +{ + if (enable) { + lolserial_lprint(ptr, len); + } else { + for(size_t i = 0; (i < len) && (suspend_len < sizeof(suspend_buf)); i++) + suspend_buf[suspend_len++] = ptr[i]; + } + + return len; +} + +/* register lolserial devoptab */ +void lolserial_init() { + static devoptab_t lolserial_dotab = { + .name = "lolserial", + .write_r = &lolserial_write, + }; + devoptab_list[STD_OUT] = &lolserial_dotab; + devoptab_list[STD_ERR] = &lolserial_dotab; +} + +#endif /* LOLSERIAL_DEBUG */ diff --git a/stage2/lolserial.h b/stage2/lolserial.h new file mode 100644 index 0000000..72d5c10 --- /dev/null +++ b/stage2/lolserial.h @@ -0,0 +1,19 @@ +#ifndef __LOLSERIAL_H__ +#define __LOLSERIAL_H__ + +#ifdef LOLSERIAL_DEBUG + +void lolserial_init(); +void lolserial_suspend(void); +void lolserial_resume(void); + +#else + +#define lolserial_init() +#define lolserial_suspend() +#define lolserial_resume() + +#endif /* LOLSERIAL_DEBUG */ + +#endif /* __LOLSERIAL_H__ */ + diff --git a/stage2/lolserial_asm.S b/stage2/lolserial_asm.S deleted file mode 100644 index 05e4416..0000000 --- a/stage2/lolserial_asm.S +++ /dev/null @@ -1,103 +0,0 @@ -/* - * minute - a port of the "mini" IOS replacement for the Wii U. - * -* Copyright (C) 2021 Roberto Van Eeden - * - * This code is licensed to you under the terms of the GNU GPL, version 2; - * see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt - */ - -#ifdef LOLSERIAL_DEBUG - -#include "latte.h" - -.arm - -.globl lolserial_print -.globl lolserial_lprint - -.section .text - -/* - * the number of timer ticks to wait - * each bit; might need manual adjustment - * for particoular serial adapters, usually - * the stable value is in the +5/-5 range - */ - -.equ LOLSERIAL_WAIT_TICKS, 200 -.equ GP_SENSORBAR, 0x00000100 - -@ arg:r0 string address -lolserial_print: - mov r1, #-1 - -@ arg:r0 string address -@ arg:r1 max length -lolserial_lprint: - push {r4-r5} - add r1, r0 @ end address in r1 - ldr r5, =LT_REG_BASE @ latte registers base in r5 - - @ clear32(LT_GPIO_OWNER, GP_SENSORBAR) - ldr r2, [r5, #0x0FC] - bic r2, r2, #GP_SENSORBAR - str r2, [r5, #0x0FC] - - @ set32(LT_GPIO_ENABLE, GP_SENSORBAR) - ldr r2, [r5, #0x0DC] - orr r2, r2, #GP_SENSORBAR - str r2, [r5, #0x0DC] - - @ set32(LT_GPIO_DIR, GP_SENSORBAR) - ldr r2, [r5, #0x0E4] - orr r2, r2, #GP_SENSORBAR - str r2, [r5, #0x0E4] - - @ set32(LT_GPIO_OUT, GP_SENSORBAR) - ldr r2, [r5, #0x0E0] - orr r2, r2, #GP_SENSORBAR - str r2, [r5, #0x0E0] - - lolserial_send_string_loop: - cmp r0, r1 @ ensure end address was not reached - ldrneb r3, [r0], #1 @ load cur char in r3, increment r0 string ptr - cmpne r3, #0 @ check for string null termination - beq lolserial_send_string_end - - @ r3: bits to send (serial end bit, data byte, serial start bit) - @ r3 = (1 << 9) | (r3:chr << 1) | (0 << 0) - lsl r3, #1 - orr r3, #0x200 - - @ loop over bits to send - lolserial_send_char_loop: - @ mask32(LT_GPIO_OUT, GP_SENSORBAR, bit ? GP_SENSORBAR : 0) - tst r3, #1 - ldr r2, [r5, #0x0E0] - biceq r2, #GP_SENSORBAR - orrne r2, #GP_SENSORBAR - str r2, [r5, #0x0E0] - - @ wait for LOLSERIAL_WAIT_TICKS timer ticks - ldr r2, [r5, #0x010] @ r2: current ticks - adds r4, r2, #LOLSERIAL_WAIT_TICKS @ r4: wait time end - timer_wait_overflow_loop: - cmp r4, r2 - ldr r2, [r5, #0x010] - blo timer_wait_overflow_loop - timer_wait_loop: - cmp r4, r2 - ldr r2, [r5, #0x010] - bhi timer_wait_loop - - lsrs r3, #1 @ go to next bit - bne lolserial_send_char_loop @ unless r3 is 0 (end bit sent) - - b lolserial_send_string_loop - lolserial_send_string_end: - - pop {r4-r5} - bx lr - -#endif /* LOLSERIAL_DEBUG */ diff --git a/stage2/main.c b/stage2/main.c index 7cc9241..923506b 100644 --- a/stage2/main.c +++ b/stage2/main.c @@ -31,6 +31,8 @@ #include "nand.h" #include "isfs/isfs.h" #include "ancast.h" +#include "debug.h" +#include "lolserial.h" u32 load_payload_sd(void) { @@ -108,18 +110,32 @@ error_open: u32 _main(void) { u32 vector = 0; + + lolserial_init(); + DEBUG("isfshax start\n"); + //mem_initialize(); irq_initialize(); crypto_read_otp(); nand_initialize(); /* repair isfshax superblocks ecc errors, if present */ + DEBUG("isfshax_refresh\n"); isfshax_refresh(); /* attempt to load the payload from SD, then NAND */ + DEBUG("load_payload_sd\n"); + lolserial_suspend(); vector = load_payload_sd(); - if (!vector) + lolserial_resume(); + + if (!vector) { + DEBUG("load_payload_nand\n"); + lolserial_suspend(); vector = load_payload_nand(); + lolserial_resume(); + } + DEBUG("vector: %08lX\n", vector); nand_deinitialize(); irq_shutdown();