-hopefully the last change now for wii game booting

This commit is contained in:
fix94.1 2014-03-31 18:14:46 +00:00
parent 92b17333ef
commit d4ce44ebec
9 changed files with 529 additions and 175 deletions

View File

@ -19,7 +19,7 @@ TARGET_LINKED = boot.elf
TARGET = extldr.bin TARGET = extldr.bin
CFILES = string.c ios.c utils.c cache.c usbgecko.c main.c CFILES = string.c ios.c utils.c cache.c usbgecko.c main.c
OBJS = crt0.o string.o ios.o utils.o cache.o usbgecko.o main.o OBJS = crt0.o memory.o string.o ios.o utils.o cache.o usbgecko.o main.o
DEPDIR = .deps DEPDIR = .deps

View File

@ -9,19 +9,117 @@
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29; .set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29;
.set r30,30; .set r31,31; .set r30,30; .set r31,31;
.extern _main #include "hw.h"
.globl _start .globl _start
_start: _start:
# Disable interrupts
mfmsr r3 mfmsr r3
rlwinm r3,r3,0,17,15 rlwinm r4,r3,0,17,15 # MSR_EE
mtmsr r3 rlwinm r4,r4,0,26,24 # MSR_IP
mtmsr r4
isync isync
lis r3,_setup@h
ori r3,r3,_setup@l
clrlwi r3,r3,2
mtsrr0 r3
mfmsr r3
li r4,MSR_IR|MSR_DR
andc r3,r3,r4
mtsrr1 r3
rfi
# Reset our registers #0001 0001 0000 1100 0110 0100
#BHT,BTIC,DCFA,DCFI,ICFI,NHR,DPM
_setup:
lis r3,0x11
ori r3,r3,0xC64 #0x110C64
mtspr rHID0,r3
isync
li r4,MSR_FP
mtmsr r4
ori r3,r3,HID0_ICE|HID0_DCE
mtspr rHID0,r3
isync
li r0,0
mtibatu 0,r0
mtibatu 1,r0
mtibatu 2,r0
mtibatu 3,r0
mtdbatu 0,r0
mtdbatu 1,r0
mtdbatu 2,r0
mtdbatu 3,r0
#mtibatl 0,r0
mtspr 560,r0
mtspr 562,r0
mtspr 564,r0
mtspr 566,r0
mtspr 568,r0
mtspr 570,r0
mtspr 572,r0
mtspr 574,r0
isync
lis r0,0x8000
mtsr 0,r0
mtsr 1,r0
mtsr 2,r0
mtsr 3,r0
mtsr 4,r0
mtsr 5,r0
mtsr 6,r0
mtsr 7,r0
mtsr 8,r0
mtsr 9,r0
mtsr 10,r0
mtsr 11,r0
mtsr 12,r0
mtsr 13,r0
mtsr 14,r0
mtsr 15,r0
isync
li r3,2 #0x00000000|PP=2
lis r4,0x8000
ori r4,r4,0x1FFF #0x80000000|256Mbytes|VS|VP
mtibatl 0,r3
mtibatu 0,r4
mtdbatl 0,r3
mtdbatu 0,r4
isync
addis r3,r3,0x1000 #0x10000000|PP=2
addis r4,r4,0x1000 #0x90000000|256Mbytes|VS|VP
mtspr 561,r3
mtspr 560,r4
mtspr 569,r3
mtspr 568,r4
isync
li r3,0x2A #0x00000000|I|G|PP=2
lis r4,0xC000
ori r4,r4,0x1FFF #0xC0000000|256Mbytes|VS|VP
mtdbatu 1,r3
mtdbatu 1,r4
isync
addis r3,r3,0x1000 #0x10000000|I|G|PP=2
addis r4,r4,0x1000 #0xD0000000|256Mbytes|VS|VP
mtspr 571,r3
mtspr 570,r4
isync
lis r3,0x8200
mtspr 1011,r3
lis r3,_init@h
ori r3,r3,_init@l
mtsrr0 r3
mfmsr r3
ori r3,r3,MSR_DR|MSR_IR
mtsrr1 r3
rfi
.extern _main
#TODO - fixup memset
_init:
bl __init_registers bl __init_registers
bl __init_memory
# Clear BSS. bl __init_syscall
bl __init_sprs
lis r3,__bss_start@h lis r3,__bss_start@h
ori r3,r3,__bss_start@l ori r3,r3,__bss_start@l
li r4,0 li r4,0
@ -29,11 +127,17 @@ _start:
ori r5,r5,__bss_end@l ori r5,r5,__bss_end@l
subf r5,r3,r5 subf r5,r3,r5
bl _memset bl _memset
lis r3,__stack_end@h
# Go! ori r3,r3,__stack_end@l
li r4,0
lis r5,__stack_top@h
ori r5,r5,__stack_top@l
subf r5,r3,r5
bl _memset
bl _main bl _main
0:
b 0b
#thanks to megazig for that
__init_registers: __init_registers:
li r0,0 li r0,0
li r3,0 li r3,0
@ -74,3 +178,79 @@ __init_registers:
lis r13,0 lis r13,0
ori r13,r13,0x8000 ori r13,r13,0x8000
blr blr
_memset:
clrlwi. r6,r5,29
rlwinm r5,r5,30,2,31
addi r3,r3,-4
mtctr r5
0:
stwu r4,4(r3)
bdnz+ 0b
cmplwi r6,0
beq- 2f
1:
stbu r4,1(r3)
addic. r6,r6,-1
bne+ 1b
2:
blr
__init_memory:
mflr r0
stw r0, 0x04(r1)
stwu r1,-0x10(r1)
stw r31,0x0C(r1)
mfspr r3,rHID0
rlwinm r0,r3,0,16,16 #HID0[ICE]
cmplwi r0,0
bne- 0f
bl ICacheEnable
0:
mfspr r3,rHID0
rlwinm r0,r3,0,17,17 #HID0[DCE]
cmplwi r0,0
bne- 1f
bl DCacheEnable
1:
mfl2cr r3
rlwinm r0,r3,0,0,0 #L2CR[L2E]
cmplwi r0,0
bne- 2f
bl L2_Init
bl L2_Enable
2:
lwz r0, 0x14(r1)
lwz r31,0x0C(r1)
addi r1,r1,0x10
mtlr r0
blr
__init_sprs:
mflr r0
stw r0, 0x04(r1)
stwu r1,-0x18(r1)
stw r31,0x14(r1)
stw r30,0x10(r1)
stw r29,0x0C(r1)
li r3,0
mtmmcr0 r3
mtmmcr1 r3
mtpmc1 r3
mtpmc2 r3
mtpmc3 r3
mtpmc4 r3
mfspr r3,rHID0
ori r3,r3,HID0_SPD #HID0[SPD]
mtspr rHID0,r3
mfspr r3,rHID2
rlwinm r3,r3,0,2,0 #HID2[WPE]
mtspr rHID2,r3
lwz r0, 0x1C(r1)
lwz r31,0x14(r1)
lwz r30,0x10(r1)
lwz r29,0x0C(r1)
addi r1,r1,0x18
mtlr r0
blr

107
resources/extldr/hw.h Normal file
View File

@ -0,0 +1,107 @@
#ifndef __HW_H__
#define __HW_H__
#define MSR_POW (1<<18)
#define MSR_ILE (1<<16)
#define MSR_EE (1<<15)
#define MSR_PR (1<<14)
#define MSR_FP (1<<13)
#define MSR_ME (1<<12)
#define MSR_FE0 (1<<11)
#define MSR_SE (1<<10)
#define MSR_BE (1<< 9)
#define MSR_FE1 (1<< 8)
#define MSR_IP (1<< 6)
#define MSR_IR (1<< 5)
#define MSR_DR (1<< 4)
#define MSR_RI (1<< 1)
#define MSR_LE (1<< 0)
#define HID0_EMCP (1<<31)
#define HID0_DBP (1<<30)
#define HID0_EBA (1<<29)
#define HID0_EBD (1<<28)
#define HID0_BCLK (1<<27)
#define HID0_ECLK (1<<25)
#define HID0_PAR (1<<24)
#define HID0_DOZE (1<<23)
#define HID0_NAP (1<<22)
#define HID0_SLEEP (1<<21)
#define HID0_DPM (1<<20)
#define HID0_NHR (1<<16)
#define HID0_ICE (1<<15)
#define HID0_DCE (1<<14)
#define HID0_ILOCK (1<<13)
#define HID0_DLOCK (1<<12)
#define HID0_ICFI (1<<11)
#define HID0_DCFI (1<<10)
#define HID0_SPD (1<< 9)
#define HID0_IFEM (1<< 8)
#define HID0_SGE (1<< 7)
#define HID0_DCFA (1<< 6)
#define HID0_BTIC (1<< 5)
#define HID0_ABE (1<< 3)
#define HID0_BHT (1<< 2)
#define HID0_NOOPTI (1<< 0)
#define HID2_LSQE (1<<31)
#define HID2_WPE (1<<30)
#define HID2_PSE (1<<29)
#define HID2_LCE (1<<28)
#define L2CR_L2E (1<<31)
#define L2CR_L2CE (1<<30)
#define L2CR_L2DO (1<<22)
#define L2CR_L2I (1<<21)
#define L2CR_L2WT (1<<19)
#define L2CR_L2TS (1<<18)
#define L2CR_L2IP (1<< 0)
#define DMAU_MEM_ADDR_MASK 0xFFFFFFE0
#define DMAU_LENU(x) (x & 0x1F)
#define DMAL_LC_ADDR_MASK 0xFFFFFFE0
#define DMAL_LD (1<< 4)
#define DMAL_LENL(x) (x & 0xC)
#define DMAL_T (1<< 1)
#define DMAL_F (1<< 0)
#define BATU_BEPI_MASK 0xFFFC0000
#define BATU_BL(x) (x & 0x00001FFC)
#define BATU_VS (1<< 1)
#define BATU_VP (1<< 0)
#define BATL_BRPN_MASK 0xFFFC0000
#define BATL_WIMG_MASK 0x78
#define BATL_PP (1<< 0)
// BATU - 0x80001FFF == 256Mbytes
// 1000 0000 000x xxx0 0001 1111 1111 11xx
// 0x80000000|256Mbytes|VS|VP
// BATL - 0x00000002
// 0000 0000 0000 000x xxxx xxxx x000 0x10
// PP=b10
//
// BATU - 0xC0001FFF == 256Mbytes
// BATL - 0x0000002a
// 0000 0000 0000 000x xxxx xxxx x010 1x10
// WIMG=b0101|PP=b10
//
#define rHID2 920
#define rDMAU 922
#define rDMAL 923
#define rHID0 1008
#define rHID1 1009
#define rHID4 1011
/*
* Upper PTE
* 0|1-24|25|26-31
* V|VSID|H |API
*
* Lower PTE
* 0-19|20-22|23|24|25-28|29|30-31
* RPN |000 |R |C |WIMG |0 |PP
*/
#endif

View File

@ -84,15 +84,6 @@ static void ipc_wait_reply(void)
ios_delay(); ios_delay();
} }
static u32 ipc_wait(void)
{
u32 ret;
while(!((ret = ipc_read(1)) & 0x6))
;
ios_delay();
return ret;
}
// Mid-level IPC access. // Mid-level IPC access.
struct ipc { struct ipc {
@ -118,27 +109,6 @@ static void ipc_send_request(void)
ipc_bell(2); ipc_bell(2);
} }
static int ipc_send_twoack(void)
{
sync_after_write(&ipc, 0x40);
ios_delay();
ipc_write(0, (u32)virt_to_phys(&ipc));
ipc_bell(1);
if(ipc_wait() & 4)
return 0;
ipc_bell(2);
if(ipc_wait() & 4)
return 0;
ipc_bell(2);
ipc_bell(8);
return 1;
}
static void ipc_recv_reply(void) static void ipc_recv_reply(void)
{ {
for (;;) for (;;)
@ -162,49 +132,6 @@ static void ipc_recv_reply(void)
// High-level IPC access. // High-level IPC access.
void ios_cleanup()
{
int loops = 0xA;
do
{
if ((ipc_read(1) & 0x22) == 0x22)
{
ipc_write(1, (ipc_read(1)&~0x30) | 2);
}
if ((ipc_read(1) & 0x14) == 0x14)
{
ipc_read(2);
ipc_write(1, (ipc_read(1)&~0x30) | 4);
ipc_write(12, 0x4000);
ipc_write(1, (ipc_read(1)&~0x30) | 8);
}
ipc_write(12, 0x4000);
usleep(1000);
loops--;
} while(loops != 0);
int fd;
for (fd = 0; fd != 31; fd++)
{
ios_close(fd);
}
}
int ios_open(const char *filename, u32 mode)
{
sync_after_write((void*)filename, 0x20);
ipc.cmd = 1;
ipc.fd = 0;
ipc.arg[0] = (u32)virt_to_phys(filename);
ipc.arg[1] = mode;
ipc_send_request();
ipc_recv_reply();
return ipc.result;
}
int ios_close(int fd) int ios_close(int fd)
{ {
ipc.cmd = 2; ipc.cmd = 2;
@ -216,77 +143,11 @@ int ios_close(int fd)
return ipc.result; return ipc.result;
} }
static void ios_std(int fd, int cmd) void ios_cleanup()
{ {
ipc.cmd = cmd; int fd;
ipc.fd = fd; for (fd = 0; fd != 31; fd++)
ipc_send_request();
ipc_recv_reply();
}
int ios_read(int fd, void *buf, u32 size)
{
ipc.arg[0] = (u32)virt_to_phys(buf);
ipc.arg[1] = size;
ios_std(fd, 3);
sync_before_read(buf, size);
return ipc.result;
}
int _ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec, int reboot)
{
u32 i;
for (i = 0; i < in_count + out_count; i++)
{ {
if (vec[i].data) ios_close(fd);
{
sync_after_write(vec[i].data, vec[i].len);
vec[i].data = (void *)virt_to_phys(vec[i].data);
} }
}
sync_after_write(vec, (in_count + out_count) * sizeof *vec);
ipc.cmd = 7;
ipc.fd = fd;
ipc.arg[0] = n;
ipc.arg[1] = in_count;
ipc.arg[2] = out_count;
ipc.arg[3] = (u32)virt_to_phys(vec);
if(reboot)
{
if(ipc_send_twoack())
return 0;
}
else
ipc_send_request();
ipc_recv_reply();
for(i = in_count; i < in_count + out_count; i++)
{
if (vec[i].data)
{
vec[i].data = phys_to_virt((u32)vec[i].data);
sync_before_read(vec[i].data, vec[i].len);
}
}
if(reboot && (ipc.result >= 0))
return -100;
return ipc.result;
}
int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec)
{
return _ios_ioctlv(fd, n, in_count, out_count, vec, 0);
}
int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec)
{
return _ios_ioctlv(fd, n, in_count, out_count, vec, 1);
} }

View File

@ -10,19 +10,7 @@
// Copyright 2008-2009 Hector Martin <marcan@marcansoft.com> // Copyright 2008-2009 Hector Martin <marcan@marcansoft.com>
#include "types.h"
struct ioctlv {
void *data;
u32 len;
};
void ios_cleanup(void); void ios_cleanup(void);
int ios_open(const char *filename, u32 mode);
int ios_close(int fd);
int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec);
int ios_ioctlvreboot(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec);
int ios_read(int fd, void *buf, u32 size);
#endif #endif

View File

@ -20,6 +20,7 @@ SECTIONS {
__bss_end = .; __bss_end = .;
. = ALIGN(0x40); . = ALIGN(0x40);
__stack_end = .;
.stack : { .stack : {
. += 0x8000; . += 0x8000;
__stack_top = .; __stack_top = .;

View File

@ -3,14 +3,13 @@
#include "cache.h" #include "cache.h"
#include "ios.h" #include "ios.h"
#include "usbgecko.h" #include "usbgecko.h"
u8 *start = (u8*)0x80A80000;
u8 *buffer = (u8*)0x90110000;
void _main(void) void _main(void)
{ {
usbgecko_init(); usbgecko_init();
ios_cleanup(); //hopefully that wont disable any features ios_cleanup(); //hopefully that wont disable any features
gprintf("Copying External Booter...\n"); gprintf("Copying External Booter...\n");
_memcpy(start, buffer, 0xF0000); //960kb safe copying of booter u8 *start = (u8*)0x80A80000;
_memcpy(start, (u8*)0x90110000, 0xF0000); //960kb safe copying of booter
sync_after_write(start, 0xF0000); sync_after_write(start, 0xF0000);
gprintf("Done! Jumping to Entrypoint...\n"); gprintf("Done! Jumping to Entrypoint...\n");
asm volatile ( asm volatile (
@ -21,3 +20,20 @@ void _main(void)
"blr\n" "blr\n"
); );
} }
#include "memory.h"
#define SYSCALL_VECTOR ((u8*)0x80000C00)
void __init_syscall()
{
u8* sc_vector = SYSCALL_VECTOR;
u32 bytes = (u32)DCFlashInvalidate - (u32)__temp_abe;
u8* from = (u8*)__temp_abe;
for ( ; bytes != 0 ; --bytes )
{
*sc_vector = *from;
sc_vector++;
from++;
}
sync_after_write(SYSCALL_VECTOR, 0x100);
ICInvalidateRange(SYSCALL_VECTOR, 0x100);
}

192
resources/extldr/memory.S Normal file
View File

@ -0,0 +1,192 @@
.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4;
.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9;
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14;
.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19;
.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24;
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29;
.set r30,30; .set r31,31;
#include "hw.h"
.global __temp_abe
__temp_abe:
mfspr r3,rHID0
ori r4,r3,HID0_ABE #HID0[ABE]
mtspr rHID0,r4
isync
sync
mtspr rHID0,r3
rfi
.global DCFlashInvalidate
DCFlashInvalidate:
nop
mfspr r3,rHID0
ori r3,r3,HID0_DCFI #HID0[DCFI]
mtspr rHID0,r3
blr
.global DCacheEnable
DCacheEnable:
sync
mfspr r3,rHID0
ori r3,r3,HID0_DCE #HID0[DCE]
mtspr rHID0,r3
blr
.global DCBlockInvalidate
DCBlockInvalidate:
cmplwi r4,0
blelr
clrlwi. r5,r3,27
beq- 0f
addi r4,r4,0x20
0:
addi r4,r4,0x1F
rlwinm r4,r4,27,5,31
mtctr r4
1:
dcbi r0,r3
addi r3,r3,0x20
bdnz+ 1b
blr
DCBlockFlushSc:
cmplwi r4,0
blelr
clrlwi. r5,r3,27
beq- 0f
addi r4,r4,0x20
0:
addi r4,r4,0x1F
rlwinm r4,r4,27,5,31
mtctr r4
1:
dcbf r0,r3
addi r3,r3,0x20
bdnz+ 1b
sc
blr
DCBlockFlush:
cmplwi r4,0
blelr
clrlwi. r5,r3,27
beq- 0f
addi r4,r4,0x20
0:
addi r4,r4,0x1F
rlwinm r4,r4,27,5,31
mtctr r4
1:
dcbf r0,r3
addi r3,r3,0x20
bdnz+ 1b
blr
.global ICInvalidateRange
ICInvalidateRange:
cmplwi r4,0
blelr
clrlwi. r5,r3,27
beq- 0f
addi r4,r4,0x20
0:
addi r4,r4,0x1F
rlwinm r4,r4,27,5,31
mtctr r4
1:
icbi r0,r3
addi r3,r3,0x20
bdnz+ 1b
sync
isync
blr
ICFlashInvalidate:
mfspr r3,rHID0
ori r3,r3,HID0_ICFI #HID0[ICFI]
mtspr rHID0,r3
blr
.global ICacheEnable
ICacheEnable:
isync
mfspr r3,rHID0
ori r3,r3,HID0_ICE #HID0[ICE]
mtspr rHID0,r3
blr
ICacheDisable:
isync
mfspr r3,rHID0
rlwinm r3,r3,0,17,15 #HID0[ICE]
mtspr rHID0,r3
blr
ISync:
isync
blr
.global L2_Init
L2_Init:
mflr r0
stw r0, 0x04(r1)
stwu r1,-0x10(r1)
stw r31,0x0C(r1)
mfmsr r3
mr r31,r3
sync
li r3,MSR_IR|MSR_DR #MSR[IR|DR]
mtmsr r3
sync
bl L2_Disable
bl L2_Invalidate
mr r3,r31
mtmsr r3
lwz r0, 0x14(r1)
lwz r31,0x0C(r1)
mtlr r0
blr
.global L2_Enable
L2_Enable:
mfl2cr r3
oris r0,r3,0x8000 #L2CR[L2E]
rlwinm r3,r0,0,11,9 #L2CR[L2I]
mtl2cr r3
blr
L2_Disable:
sync
mfl2cr r3
clrlwi r3,r3,1 #L2CR[L2E]
mtl2cr r3
sync
blr
L2_Invalidate:
mflr r0
stw r0, 0x04(r1)
stwu r1,-0x08(r1)
bl L2_Disable
mfl2cr r3
oris r3,r3,0x200 #L2CR[L2I]
mtl2cr r3
0:
mfl2cr r3
clrlwi r0,r3,31 #L2CR[L2IP]
cmplwi r0,0
bne+ 0b
mfl2cr r3
rlwinm r3,r3,0,11,9 #L2CR[L2I]
mtl2cr r3
1:
mfl2cr r3
clrlwi r0,r3,31 #L2CR[L2IP]
cmplwi r0,0
bne+ 1b
lwz r0,0x0C(r1)
addi r1,r1,0x08
mtlr r0
blr

View File

@ -0,0 +1,9 @@
#ifndef __MEMORY_H__
#define __MEMORY_H__
void __temp_abe(void);
void ICInvalidateRange(void *, int);
void DCFlashInvalidate(void *, int);
#endif