lolserial improvements

allow debug output to be suspended, drop assembly version
This commit is contained in:
rw-r-r-0644 2021-06-01 13:19:23 +02:00
parent 239a7607c8
commit 99cded2762
6 changed files with 117 additions and 121 deletions

View File

@ -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 */

View File

@ -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

78
stage2/lolserial.c Normal file
View File

@ -0,0 +1,78 @@
#ifdef LOLSERIAL_DEBUG
#include "lolserial.h"
#include "gpio.h"
#include "utils.h"
#include "latte.h"
#include <sys/iosupport.h>
#include <string.h>
#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 */

19
stage2/lolserial.h Normal file
View File

@ -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__ */

View File

@ -1,103 +0,0 @@
/*
* minute - a port of the "mini" IOS replacement for the Wii U.
*
* Copyright (C) 2021 Roberto Van Eeden <rwrr0644@gmail.com>
*
* 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 */

View File

@ -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();