mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-24 12:19:21 +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 "types.h"
|
||||||
|
#include "irq.h"
|
||||||
#include "start.h"
|
#include "start.h"
|
||||||
#include "vsprintf.h"
|
#include "vsprintf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "hollywood.h"
|
#include "hollywood.h"
|
||||||
|
#include "powerpc.h"
|
||||||
|
#include "powerpc_elf.h"
|
||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
|
|
||||||
static u8 gecko_console_enabled = 0;
|
static u8 gecko_console_enabled = 0;
|
||||||
@ -34,7 +37,7 @@ static u32 _gecko_command(u32 command)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 _gecko_sendbyte(char sendbyte)
|
static u32 _gecko_sendbyte(u8 sendbyte)
|
||||||
{
|
{
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
i = _gecko_command(0xB0000000 | (sendbyte<<20));
|
i = _gecko_command(0xB0000000 | (sendbyte<<20));
|
||||||
@ -43,8 +46,7 @@ static u32 _gecko_sendbyte(char sendbyte)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
static u32 _gecko_recvbyte(u8 *recvbyte)
|
||||||
static u32 _gecko_recvbyte(char *recvbyte)
|
|
||||||
{
|
{
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
*recvbyte = 0;
|
*recvbyte = 0;
|
||||||
@ -57,6 +59,7 @@ static u32 _gecko_recvbyte(char *recvbyte)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static u32 _gecko_checksend(void)
|
static u32 _gecko_checksend(void)
|
||||||
{
|
{
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
@ -65,6 +68,7 @@ static u32 _gecko_checksend(void)
|
|||||||
return 1; // Return 1 if safe to send
|
return 1; // Return 1 if safe to send
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static u32 _gecko_checkrecv(void)
|
static u32 _gecko_checkrecv(void)
|
||||||
{
|
{
|
||||||
@ -74,7 +78,6 @@ static u32 _gecko_checkrecv(void)
|
|||||||
return 1; // Return 1 if safe to recv
|
return 1; // Return 1 if safe to recv
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int gecko_isalive(void)
|
static int gecko_isalive(void)
|
||||||
{
|
{
|
||||||
@ -207,3 +210,111 @@ int gecko_printf(const char *fmt, ...)
|
|||||||
|
|
||||||
return gecko_sendbuffer(buffer, i);
|
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);
|
void gecko_init(void);
|
||||||
u8 gecko_enable_console(const u8 enable);
|
u8 gecko_enable_console(const u8 enable);
|
||||||
int gecko_printf(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
int gecko_printf(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||||
|
void gecko_timer_initialize(void);
|
||||||
|
void gecko_timer(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
22
irq.c
22
irq.c
@ -6,6 +6,8 @@
|
|||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
|
|
||||||
|
static u32 _alarm_frequency = 0;
|
||||||
|
|
||||||
void irq_setup_stack(void);
|
void irq_setup_stack(void);
|
||||||
|
|
||||||
void irq_initialize(void)
|
void irq_initialize(void)
|
||||||
@ -18,6 +20,8 @@ void irq_initialize(void)
|
|||||||
//???
|
//???
|
||||||
write32(HW_ARMIRQMASK+0x04, 0);
|
write32(HW_ARMIRQMASK+0x04, 0);
|
||||||
write32(HW_ARMIRQMASK+0x20, 0);
|
write32(HW_ARMIRQMASK+0x20, 0);
|
||||||
|
|
||||||
|
write32(HW_ALARM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_shutdown(void)
|
void irq_shutdown(void)
|
||||||
@ -37,10 +41,11 @@ void irq_handler(void)
|
|||||||
flags = flags & enabled;
|
flags = flags & enabled;
|
||||||
|
|
||||||
if(flags & IRQF_TIMER) {
|
if(flags & IRQF_TIMER) {
|
||||||
gecko_printf("IRQ: timer\n");
|
if (_alarm_frequency) {
|
||||||
gecko_printf("Timer: %08x\n", read32(HW_TIMER));
|
// currently we use the alarm timer only for lame usbgecko polling
|
||||||
gecko_printf("Alarm: %08x\n", read32(HW_ALARM));
|
gecko_timer();
|
||||||
write32(HW_ALARM, 0); // shut it up
|
write32(HW_ALARM, read32(HW_TIMER) + _alarm_frequency);
|
||||||
|
}
|
||||||
write32(HW_ARMIRQFLAG, IRQF_TIMER);
|
write32(HW_ARMIRQFLAG, IRQF_TIMER);
|
||||||
}
|
}
|
||||||
if(flags & IRQF_NAND) {
|
if(flags & IRQF_NAND) {
|
||||||
@ -88,3 +93,12 @@ void irq_disable(u32 irq)
|
|||||||
{
|
{
|
||||||
clear32(HW_ARMIRQMASK, 1<<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
|
#define CPSR_FIQDIS 0x40
|
||||||
|
|
||||||
#ifndef _LANGUAGE_ASSEMBLY
|
#ifndef _LANGUAGE_ASSEMBLY
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#define IRQ_ALARM_MS2REG(x) (1898 * x)
|
||||||
|
|
||||||
void irq_initialize(void);
|
void irq_initialize(void);
|
||||||
void irq_shutdown(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) );
|
__asm__ volatile ( "mcr\tp15, 0, %0, c7, c0, 4" : : "r" (data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void irq_set_alarm(u32 ms, u8 enable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1
main.c
1
main.c
@ -190,6 +190,7 @@ void *_main(void *base)
|
|||||||
irq_enable(IRQ_GPIO1B);
|
irq_enable(IRQ_GPIO1B);
|
||||||
irq_enable(IRQ_GPIO1);
|
irq_enable(IRQ_GPIO1);
|
||||||
irq_enable(IRQ_RESET);
|
irq_enable(IRQ_RESET);
|
||||||
|
gecko_timer_initialize();
|
||||||
gecko_printf("Interrupts initialized\n");
|
gecko_printf("Interrupts initialized\n");
|
||||||
|
|
||||||
crypto_initialize();
|
crypto_initialize();
|
||||||
|
Loading…
Reference in New Issue
Block a user