Adapt changes from b9s/next

This commit is contained in:
TuxSH 2017-05-23 13:33:32 +02:00
parent 53209b9be0
commit dd21a3930d
16 changed files with 113 additions and 53 deletions

View File

@ -23,7 +23,7 @@ dir_out := out
ASFLAGS := -mcpu=arm946e-s ASFLAGS := -mcpu=arm946e-s
CFLAGS := -Wall -Wextra $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math CFLAGS := -Wall -Wextra $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
LDFLAGS := -nostartfiles LDFLAGS := -nostartfiles -Wl,--nmagic
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \

View File

@ -13,8 +13,8 @@ dir_build := build
dir_out := ../$(dir_build) dir_out := ../$(dir_build)
ASFLAGS := -mcpu=mpcore ASFLAGS := -mcpu=mpcore
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
LDFLAGS := -nostdlib -Wl,--nmagic LDFLAGS := -nostartfiles -Wl,--nmagic
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \

View File

@ -4,11 +4,12 @@ OUTPUT_ARCH(arm)
ENTRY(_start) ENTRY(_start)
SECTIONS SECTIONS
{ {
. = 0x1FFFE000; . = 0x1FF80000;
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); } .text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); } .rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); } .data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
__stack_top__ = 0x1FFFF000;
. = ALIGN(4); . = ALIGN(4);
} }

View File

@ -27,7 +27,10 @@
#include "types.h" #include "types.h"
#include "memory.h" #include "memory.h"
static volatile Arm11Operation *operation = (volatile Arm11Operation *)0x1FFFFFF0; void prepareForFirmlaunch(void);
extern u32 prepareForFirmlaunchSize;
extern volatile Arm11Operation operation;
static void initScreensSequence(u32 brightnessLevel) static void initScreensSequence(u32 brightnessLevel)
{ {
@ -160,23 +163,16 @@ static void deinitScreens(void)
*(vu32 *)0x10202014 = 0; *(vu32 *)0x10202014 = 0;
} }
static void prepareForFirmlaunch(void)
{
*ARM11_CORE0_MAILBOX_ENTRYPOINT = 0;
while(*ARM11_CORE0_MAILBOX_ENTRYPOINT == 0);
((void (*)(void))*ARM11_CORE0_MAILBOX_ENTRYPOINT)();
}
void main(void) void main(void)
{ {
*operation = NO_ARM11_OPERATION; operation = ARM11_READY;
while(true) while(true)
{ {
switch(*operation) switch(operation)
{ {
case NO_ARM11_OPERATION: case ARM11_READY:
break; continue;
case INIT_SCREENS_SEQUENCE: case INIT_SCREENS_SEQUENCE:
initScreensSequence(*(vu32 *)ARM11_PARAMETERS_ADDRESS); initScreensSequence(*(vu32 *)ARM11_PARAMETERS_ADDRESS);
break; break;
@ -196,12 +192,13 @@ void main(void)
deinitScreens(); deinitScreens();
break; break;
case PREPARE_ARM11_FOR_FIRMLAUNCH: case PREPARE_ARM11_FOR_FIRMLAUNCH:
memcpy((void *)0x1FFFFC00, (void *)prepareForFirmlaunch, 0x2C); memcpy((void *)0x1FFFFC00, (void *)prepareForFirmlaunch, prepareForFirmlaunchSize);
*operation = NO_ARM11_OPERATION; *(vu32 *)0x1FFFFFFC = 0;
operation = ARM11_READY;
((void (*)(void))0x1FFFFC00)(); ((void (*)(void))0x1FFFFC00)();
break; break;
} }
*operation = NO_ARM11_OPERATION; operation = ARM11_READY;
} }
} }

View File

@ -17,11 +17,35 @@
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified @ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal @ reasonable legal notices or author attributions in that material or in the Appropriate Legal
@ Notices displayed by works containing it. @ Notices displayed by works containing it.
.section .text.start .section .text.start
.align 4 .align 4
.global _start .global _start
.type _start, %function
_start: _start:
b start
.global operation
operation:
.word 0
start:
cpsid aif cpsid aif
ldr sp, =0x1FFFE000 ldr sp, =__stack_top__
b main b main
.global prepareForFirmlaunch
.type prepareForFirmlaunch, %function
prepareForFirmlaunch:
mov r0, #0x20000000
_wait_for_core0_entrypoint_loop:
ldr r1, [r0, #-4] @ check if core0's entrypoint is 0
cmp r1, #0
beq _wait_for_core0_entrypoint_loop
bx r1 @ jump to core0's entrypoint
prepareForFirmlaunchEnd:
.global prepareForFirmlaunchSize
prepareForFirmlaunchSize: .word prepareForFirmlaunchEnd - prepareForFirmlaunch

View File

@ -40,8 +40,7 @@ typedef volatile u64 vu64;
#define SCREEN_HEIGHT 240 #define SCREEN_HEIGHT 240
#define SCREEN_TOP_FBSIZE (3 * SCREEN_TOP_WIDTH * SCREEN_HEIGHT) #define SCREEN_TOP_FBSIZE (3 * SCREEN_TOP_WIDTH * SCREEN_HEIGHT)
#define SCREEN_BOTTOM_FBSIZE (3 * SCREEN_BOTTOM_WIDTH * SCREEN_HEIGHT) #define SCREEN_BOTTOM_FBSIZE (3 * SCREEN_BOTTOM_WIDTH * SCREEN_HEIGHT)
#define ARM11_CORE0_MAILBOX_ENTRYPOINT ((vu32 *)0x1FFFFFFC) #define ARM11_PARAMETERS_ADDRESS 0x1FFFF000
#define ARM11_PARAMETERS_ADDRESS 0x1FFFC000
struct fb { struct fb {
u8 *top_left; u8 *top_left;
@ -51,12 +50,12 @@ struct fb {
typedef enum typedef enum
{ {
NO_ARM11_OPERATION = 0, INIT_SCREENS_SEQUENCE = 0,
INIT_SCREENS_SEQUENCE,
SETUP_FRAMEBUFFERS, SETUP_FRAMEBUFFERS,
CLEAR_SCREENS, CLEAR_SCREENS,
SWAP_FRAMEBUFFERS, SWAP_FRAMEBUFFERS,
UPDATE_BRIGHTNESS, UPDATE_BRIGHTNESS,
DEINIT_SCREENS, DEINIT_SCREENS,
PREPARE_ARM11_FOR_FIRMLAUNCH, PREPARE_ARM11_FOR_FIRMLAUNCH,
ARM11_READY,
} Arm11Operation; } Arm11Operation;

View File

@ -13,8 +13,8 @@ dir_build := build
dir_out := ../$(dir_build) dir_out := ../$(dir_build)
ASFLAGS := -mcpu=arm946e-s ASFLAGS := -mcpu=arm946e-s
CFLAGS := -Wall -Wextra -mthumb $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math CFLAGS := -Wall -Wextra -marm $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
LDFLAGS := -nostdlib LDFLAGS := -nostartfiles -Wl,--nmagic
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \

View File

@ -24,20 +24,15 @@
#include "memory.h" #include "memory.h"
#include "cache.h" #include "cache.h"
void disableMpuAndJumpToEntrypoints(int argc, char **argv, void *arm11Entry, void *arm9Entry);
void launchFirm(Firm *firm, int argc, char **argv) void launchFirm(Firm *firm, int argc, char **argv)
{ {
//Copy FIRM sections to respective memory locations //Copy FIRM sections to respective memory locations
for(u32 sectionNum = 0; sectionNum < 4 && firm->section[sectionNum].size != 0; sectionNum++) for(u32 sectionNum = 0; sectionNum < 4 && firm->section[sectionNum].size != 0; sectionNum++)
memcpy(firm->section[sectionNum].address, (u8 *)firm + firm->section[sectionNum].offset, firm->section[sectionNum].size); memcpy(firm->section[sectionNum].address, (u8 *)firm + firm->section[sectionNum].offset, firm->section[sectionNum].size);
//Ensure that all memory transfers have completed and that the caches have been flushed disableMpuAndJumpToEntrypoints(argc, argv, firm->arm9Entry, firm->arm11Entry);
flushCaches();
//Set ARM11 entrypoint
*(vu32 *)0x1FFFFFFC = (u32)firm->arm11Entry;
//Jump to ARM9 entrypoint. Also give it additional arguments it can dismiss
((void (*)(int, char**, u32))firm->arm9Entry)(argc, argv, 0x0000BEEF);
__builtin_unreachable(); __builtin_unreachable();
} }

View File

@ -24,17 +24,25 @@
#include "cache.h" #include "cache.h"
#include "firm.h" #include "firm.h"
void main(int argc __attribute__((unused)), char **argv) void main(int argc, char **argv)
{ {
Firm *firm = (Firm *)0x24000000; Firm *firm = (Firm *)0x20001000;
struct fb fbs[2];
char absPath[24 + 255]; char absPath[24 + 255];
if(argc == 2)
{
struct fb *fbsrc = (struct fb *)argv[1];
fbs[0] = fbsrc[0];
fbs[1] = fbsrc[1];
}
u32 i; u32 i;
for(i = 0; i < sizeof(absPath) - 1 && argv[0][i] != 0; i++) for(i = 0; i < sizeof(absPath) - 1 && argv[0][i] != 0; i++)
absPath[i] = argv[0][i]; absPath[i] = argv[0][i];
absPath[i] = 0; absPath[i] = 0;
char *argvPassed[1] = {absPath}; char *argvPassed[2] = {absPath, (char *)&fbs};
launchFirm(firm, 1, argvPassed); launchFirm(firm, argc, argvPassed);
} }

View File

@ -18,9 +18,40 @@
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal @ reasonable legal notices or author attributions in that material or in the Appropriate Legal
@ Notices displayed by works containing it. @ Notices displayed by works containing it.
.arm
.section .text.start .section .text.start
.align 4 .align 4
.global _start .global _start
_start: _start:
ldr sp, =0x27ffe000 ldr sp, =0x27ffe000
b main b main
.text
.balign 4
.global disableMpuAndJumpToEntrypoints
.type disableMpuAndJumpToEntrypoints, %function
disableMpuAndJumpToEntrypoints:
mov r4, r0
mov r5, r1
mov r6, r2
mov r7, r3
bl flushCaches
@ Disable caches / MPU
mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r0, #(1<<12) @ - instruction cache disable
bic r0, #(1<<2) @ - data cache disable
bic r0, #(1<<0) @ - mpu disable
mcr p15, 0, r0, c1, c0, 0 @ write control register
@ Set the ARM11 entrypoint
mov r0, #0x20000000
str r7, [r0, #-4]
@ Jump to the ARM9 entrypoint
mov r0, r4
mov r1, r5
ldr r2, =0xBEEF
bx r6

View File

@ -32,4 +32,10 @@ typedef uint64_t u64;
typedef volatile u8 vu8; typedef volatile u8 vu8;
typedef volatile u16 vu16; typedef volatile u16 vu16;
typedef volatile u32 vu32; typedef volatile u32 vu32;
typedef volatile u64 vu64; typedef volatile u64 vu64;
struct fb {
u8 *top_left;
u8 *top_right;
u8 *bottom;
} __attribute__((packed));

View File

@ -7,7 +7,7 @@ fname_addr equ 0x27FFDF80
low_tid_addr equ 0x27FFDFE0 low_tid_addr equ 0x27FFDFE0
copy_launch_stub_addr equ 0x27FFE000 copy_launch_stub_addr equ 0x27FFE000
firm_addr equ 0x24000000 firm_addr equ 0x20001000
firm_maxsize equ (copy_launch_stub_addr - 0x1000 - firm_addr) firm_maxsize equ (copy_launch_stub_addr - 0x1000 - firm_addr)
arm11_entrypoint_addr equ 0x1FFFFFFC arm11_entrypoint_addr equ 0x1FFFFFFC

View File

@ -443,6 +443,7 @@ bool checkFirmPayload(void)
(section->address + section->size < section->address) || //Overflow check (section->address + section->size < section->address) || //Overflow check
((u32)section->address & 3) || (section->offset & 0x1FF) || (section->size & 0x1FF) || //Alignment check ((u32)section->address & 3) || (section->offset & 0x1FF) || (section->size & 0x1FF) || //Alignment check
(overlaps((u32)section->address, (u32)section->address + section->size, 0x27FFE000 - 0x1000, 0x28000000)) || (overlaps((u32)section->address, (u32)section->address + section->size, 0x27FFE000 - 0x1000, 0x28000000)) ||
(overlaps((u32)section->address, (u32)section->address + section->size, 0x1FFFFC00, 0x20000000)) ||
(overlaps((u32)section->address, (u32)section->address + section->size, (u32)firm + section->offset, (u32)firm + size))) (overlaps((u32)section->address, (u32)section->address + section->size, (u32)firm + section->offset, (u32)firm + size)))
return false; return false;

View File

@ -170,12 +170,10 @@ void loadPayload(u32 pressed, const char *payloadPath)
else else
sprintf(absPath, "sdmc:/luma/%s", path); sprintf(absPath, "sdmc:/luma/%s", path);
char *argv[1] = {absPath}; char *argv[2] = {absPath, (char *)fbs};
initScreens(); initScreens();
if((u8 *)firm + payloadSize < (u8 *)0x23FFFE00) launchFirm((firm->reserved2[0] & 1) ? 2 : 1, argv);
memcpy((void *)0x23FFFE00, fbs, sizeof(fbs));
launchFirm(1, argv);
} }
void payloadMenu(void) void payloadMenu(void)

View File

@ -50,9 +50,9 @@ struct fb fbs[2];
static void invokeArm11Function(Arm11Operation op) static void invokeArm11Function(Arm11Operation op)
{ {
while(*operation != NO_ARM11_OPERATION); while(*operation != ARM11_READY);
*operation = op; *operation = op;
while(*operation != NO_ARM11_OPERATION); while(*operation != ARM11_READY);
} }
void prepareArm11ForFirmlaunch(void) void prepareArm11ForFirmlaunch(void)
@ -125,5 +125,6 @@ void initScreens(void)
} }
clearScreens(false); clearScreens(false);
clearScreens(true);
swapFramebuffers(false); swapFramebuffers(false);
} }

View File

@ -33,7 +33,7 @@
#define ARESCREENSINITIALIZED (PDN_GPU_CNT != 1) #define ARESCREENSINITIALIZED (PDN_GPU_CNT != 1)
#define ARM11_PARAMETERS_ADDRESS 0x1FFFC000 #define ARM11_PARAMETERS_ADDRESS 0x1FFFF000
#define SCREEN_TOP_WIDTH 400 #define SCREEN_TOP_WIDTH 400
#define SCREEN_BOTTOM_WIDTH 320 #define SCREEN_BOTTOM_WIDTH 320
@ -45,22 +45,21 @@ struct fb {
u8 *top_left; u8 *top_left;
u8 *top_right; u8 *top_right;
u8 *bottom; u8 *bottom;
} __attribute__((packed)); //*const fbs = (volatile struct fb *)0x23FFFE00; } __attribute__((packed));
extern struct fb fbs[2];
typedef enum typedef enum
{ {
NO_ARM11_OPERATION = 0, INIT_SCREENS_SEQUENCE = 0,
INIT_SCREENS_SEQUENCE,
SETUP_FRAMEBUFFERS, SETUP_FRAMEBUFFERS,
CLEAR_SCREENS, CLEAR_SCREENS,
SWAP_FRAMEBUFFERS, SWAP_FRAMEBUFFERS,
UPDATE_BRIGHTNESS, UPDATE_BRIGHTNESS,
DEINIT_SCREENS, DEINIT_SCREENS,
PREPARE_ARM11_FOR_FIRMLAUNCH, PREPARE_ARM11_FOR_FIRMLAUNCH,
ARM11_READY,
} Arm11Operation; } Arm11Operation;
extern struct fb fbs[2];
extern CfgData configData; extern CfgData configData;
void prepareArm11ForFirmlaunch(void); void prepareArm11ForFirmlaunch(void);