mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-05 19:25:12 +01:00
Inital version of a ARM side geckoloader.
This commit is contained in:
parent
1c137199ac
commit
1f9aa5b566
119
gecko.c
119
gecko.c
@ -1,9 +1,12 @@
|
||||
#include "types.h"
|
||||
#include "irq.h"
|
||||
#include "start.h"
|
||||
#include "vsprintf.h"
|
||||
#include "string.h"
|
||||
#include "utils.h"
|
||||
#include "hollywood.h"
|
||||
#include "powerpc.h"
|
||||
#include "powerpc_elf.h"
|
||||
#include "gecko.h"
|
||||
|
||||
static u8 gecko_console_enabled = 0;
|
||||
@ -34,7 +37,7 @@ static u32 _gecko_command(u32 command)
|
||||
return i;
|
||||
}
|
||||
|
||||
static u32 _gecko_sendbyte(char sendbyte)
|
||||
static u32 _gecko_sendbyte(u8 sendbyte)
|
||||
{
|
||||
u32 i = 0;
|
||||
i = _gecko_command(0xB0000000 | (sendbyte<<20));
|
||||
@ -43,8 +46,7 @@ static u32 _gecko_sendbyte(char sendbyte)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static u32 _gecko_recvbyte(char *recvbyte)
|
||||
static u32 _gecko_recvbyte(u8 *recvbyte)
|
||||
{
|
||||
u32 i = 0;
|
||||
*recvbyte = 0;
|
||||
@ -57,6 +59,7 @@ static u32 _gecko_recvbyte(char *recvbyte)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static u32 _gecko_checksend(void)
|
||||
{
|
||||
u32 i = 0;
|
||||
@ -65,6 +68,7 @@ static u32 _gecko_checksend(void)
|
||||
return 1; // Return 1 if safe to send
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 _gecko_checkrecv(void)
|
||||
{
|
||||
@ -74,7 +78,6 @@ static u32 _gecko_checkrecv(void)
|
||||
return 1; // Return 1 if safe to recv
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gecko_isalive(void)
|
||||
{
|
||||
@ -207,3 +210,111 @@ int gecko_printf(const char *fmt, ...)
|
||||
|
||||
return gecko_sendbuffer(buffer, i);
|
||||
}
|
||||
|
||||
// irq context
|
||||
|
||||
#define GECKO_STATE_NONE 0
|
||||
#define GECKO_STATE_RECEIVE_ELF_SIZE 1
|
||||
#define GECKO_STATE_RECEIVE_ELF 2
|
||||
|
||||
static u32 _gecko_cmd = 0;
|
||||
static u32 _gecko_cmd_start_time = 0;
|
||||
static u32 _gecko_state = GECKO_STATE_NONE;
|
||||
static u32 _gecko_receive_left = 0;
|
||||
static u32 _gecko_receive_len = 0;
|
||||
static u8 *_gecko_receive_buffer = NULL;
|
||||
|
||||
void gecko_timer_initialize(void)
|
||||
{
|
||||
if (!gecko_isalive())
|
||||
return;
|
||||
|
||||
irq_set_alarm(100, 1);
|
||||
}
|
||||
|
||||
void gecko_timer(void) {
|
||||
u8 b;
|
||||
|
||||
if (_gecko_cmd_start_time && read32(HW_TIMER) >
|
||||
(_gecko_cmd_start_time + IRQ_ALARM_MS2REG(5000))) {
|
||||
// time's over, bitch
|
||||
irq_set_alarm(100, 0);
|
||||
_gecko_cmd = 0;
|
||||
_gecko_cmd_start_time = 0;
|
||||
_gecko_state = GECKO_STATE_NONE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_gecko_state) {
|
||||
case GECKO_STATE_NONE:
|
||||
if (!_gecko_checkrecv() || !_gecko_recvbyte(&b))
|
||||
return;
|
||||
|
||||
_gecko_cmd <<= 8;
|
||||
_gecko_cmd |= b;
|
||||
|
||||
switch (_gecko_cmd) {
|
||||
// upload powerpc ELF
|
||||
case 0x43524150:
|
||||
_gecko_state = GECKO_STATE_RECEIVE_ELF_SIZE;
|
||||
_gecko_receive_len = 0;
|
||||
_gecko_receive_left = 4;
|
||||
|
||||
irq_set_alarm(1, 0);
|
||||
_gecko_cmd_start_time = read32(HW_TIMER);
|
||||
|
||||
gecko_console_enabled = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case GECKO_STATE_RECEIVE_ELF_SIZE:
|
||||
if (!_gecko_checkrecv() || !_gecko_recvbyte(&b))
|
||||
return;
|
||||
|
||||
_gecko_receive_len <<= 8;
|
||||
_gecko_receive_len |= b;
|
||||
_gecko_receive_left--;
|
||||
|
||||
if (!_gecko_receive_left) {
|
||||
_gecko_state = GECKO_STATE_RECEIVE_ELF;
|
||||
_gecko_receive_buffer = (u8 *) 0x10100000;
|
||||
_gecko_receive_left = _gecko_receive_len;
|
||||
|
||||
powerpc_hang();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case GECKO_STATE_RECEIVE_ELF:
|
||||
while (_gecko_receive_left) {
|
||||
if (!_gecko_checkrecv() || !_gecko_recvbyte(_gecko_receive_buffer))
|
||||
return;
|
||||
|
||||
_gecko_receive_buffer++;
|
||||
_gecko_receive_left--;
|
||||
}
|
||||
|
||||
if (!_gecko_receive_left) {
|
||||
irq_set_alarm(100, 0);
|
||||
_gecko_cmd = 0;
|
||||
_gecko_cmd_start_time = 0;
|
||||
_gecko_state = GECKO_STATE_NONE;
|
||||
|
||||
gecko_console_enabled = 1;
|
||||
|
||||
if (powerpc_boot_mem((u8 *) 0x10100000, _gecko_receive_len))
|
||||
gecko_printf("GECKOTIMER: elflolwtf?\n");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
gecko_printf("GECKOTIMER: statelolwtf?\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
2
gecko.h
2
gecko.h
@ -6,5 +6,7 @@
|
||||
void gecko_init(void);
|
||||
u8 gecko_enable_console(const u8 enable);
|
||||
int gecko_printf(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
void gecko_timer_initialize(void);
|
||||
void gecko_timer(void);
|
||||
|
||||
#endif
|
||||
|
22
irq.c
22
irq.c
@ -6,6 +6,8 @@
|
||||
#include "crypto.h"
|
||||
#include "nand.h"
|
||||
|
||||
static u32 _alarm_frequency = 0;
|
||||
|
||||
void irq_setup_stack(void);
|
||||
|
||||
void irq_initialize(void)
|
||||
@ -18,6 +20,8 @@ void irq_initialize(void)
|
||||
//???
|
||||
write32(HW_ARMIRQMASK+0x04, 0);
|
||||
write32(HW_ARMIRQMASK+0x20, 0);
|
||||
|
||||
write32(HW_ALARM, 0);
|
||||
}
|
||||
|
||||
void irq_shutdown(void)
|
||||
@ -37,10 +41,11 @@ void irq_handler(void)
|
||||
flags = flags & enabled;
|
||||
|
||||
if(flags & IRQF_TIMER) {
|
||||
gecko_printf("IRQ: timer\n");
|
||||
gecko_printf("Timer: %08x\n", read32(HW_TIMER));
|
||||
gecko_printf("Alarm: %08x\n", read32(HW_ALARM));
|
||||
write32(HW_ALARM, 0); // shut it up
|
||||
if (_alarm_frequency) {
|
||||
// currently we use the alarm timer only for lame usbgecko polling
|
||||
gecko_timer();
|
||||
write32(HW_ALARM, read32(HW_TIMER) + _alarm_frequency);
|
||||
}
|
||||
write32(HW_ARMIRQFLAG, IRQF_TIMER);
|
||||
}
|
||||
if(flags & IRQF_NAND) {
|
||||
@ -88,3 +93,12 @@ void irq_disable(u32 irq)
|
||||
{
|
||||
clear32(HW_ARMIRQMASK, 1<<irq);
|
||||
}
|
||||
|
||||
void irq_set_alarm(u32 ms, u8 enable)
|
||||
{
|
||||
_alarm_frequency = IRQ_ALARM_MS2REG(ms);
|
||||
|
||||
if (enable)
|
||||
write32(HW_ALARM, read32(HW_TIMER) + _alarm_frequency);
|
||||
}
|
||||
|
||||
|
5
irq.h
5
irq.h
@ -33,8 +33,11 @@
|
||||
#define CPSR_FIQDIS 0x40
|
||||
|
||||
#ifndef _LANGUAGE_ASSEMBLY
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define IRQ_ALARM_MS2REG(x) (1898 * x)
|
||||
|
||||
void irq_initialize(void);
|
||||
void irq_shutdown(void);
|
||||
|
||||
@ -50,6 +53,8 @@ static inline void irq_wait(void)
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c7, c0, 4" : : "r" (data) );
|
||||
}
|
||||
|
||||
void irq_set_alarm(u32 ms, u8 enable);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user