mirror of
https://github.com/isfshax/isfshax.git
synced 2024-11-06 03:35:05 +01:00
lolserial improvements
allow debug output to be suspended, drop assembly version
This commit is contained in:
parent
239a7607c8
commit
99cded2762
@ -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 */
|
|
@ -16,11 +16,12 @@
|
|||||||
#define __DEBUG_H__
|
#define __DEBUG_H__
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
#ifndef LOLSERIAL_DEBUG
|
#ifndef ENABLE_DEBUG
|
||||||
static inline void DEBUG(char *fmt, ...) {}
|
static inline void DEBUG(char *fmt, ...) {}
|
||||||
#else
|
#else
|
||||||
void DEBUG(char *fmt, ...);
|
#define DEBUG(...) printf(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
78
stage2/lolserial.c
Normal file
78
stage2/lolserial.c
Normal 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
19
stage2/lolserial.h
Normal 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__ */
|
||||||
|
|
@ -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 */
|
|
@ -31,6 +31,8 @@
|
|||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
#include "isfs/isfs.h"
|
#include "isfs/isfs.h"
|
||||||
#include "ancast.h"
|
#include "ancast.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "lolserial.h"
|
||||||
|
|
||||||
u32 load_payload_sd(void)
|
u32 load_payload_sd(void)
|
||||||
{
|
{
|
||||||
@ -108,18 +110,32 @@ error_open:
|
|||||||
u32 _main(void)
|
u32 _main(void)
|
||||||
{
|
{
|
||||||
u32 vector = 0;
|
u32 vector = 0;
|
||||||
|
|
||||||
|
lolserial_init();
|
||||||
|
DEBUG("isfshax start\n");
|
||||||
|
|
||||||
//mem_initialize();
|
//mem_initialize();
|
||||||
irq_initialize();
|
irq_initialize();
|
||||||
crypto_read_otp();
|
crypto_read_otp();
|
||||||
nand_initialize();
|
nand_initialize();
|
||||||
|
|
||||||
/* repair isfshax superblocks ecc errors, if present */
|
/* repair isfshax superblocks ecc errors, if present */
|
||||||
|
DEBUG("isfshax_refresh\n");
|
||||||
isfshax_refresh();
|
isfshax_refresh();
|
||||||
|
|
||||||
/* attempt to load the payload from SD, then NAND */
|
/* attempt to load the payload from SD, then NAND */
|
||||||
|
DEBUG("load_payload_sd\n");
|
||||||
|
lolserial_suspend();
|
||||||
vector = load_payload_sd();
|
vector = load_payload_sd();
|
||||||
if (!vector)
|
lolserial_resume();
|
||||||
|
|
||||||
|
if (!vector) {
|
||||||
|
DEBUG("load_payload_nand\n");
|
||||||
|
lolserial_suspend();
|
||||||
vector = load_payload_nand();
|
vector = load_payload_nand();
|
||||||
|
lolserial_resume();
|
||||||
|
}
|
||||||
|
DEBUG("vector: %08lX\n", vector);
|
||||||
|
|
||||||
nand_deinitialize();
|
nand_deinitialize();
|
||||||
irq_shutdown();
|
irq_shutdown();
|
||||||
|
Loading…
Reference in New Issue
Block a user