mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
fusee-cpp: add basic structural stubs
This commit is contained in:
parent
165c926135
commit
5f60bc7186
21 changed files with 1280 additions and 2 deletions
154
fusee_cpp/loader_stub/Makefile
Normal file
154
fusee_cpp/loader_stub/Makefile
Normal file
|
@ -0,0 +1,154 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
# Define the atmosphere board and cpu
|
||||
#---------------------------------------------------------------------------------
|
||||
export ATMOSPHERE_BOARD := nx-hac-001
|
||||
export ATMOSPHERE_CPU := arm7tdmi
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# pull in common atmosphere configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/exosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(__RECURSIVE__),1)
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
|
||||
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
|
||||
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
|
||||
BINFILES :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC) program.lz4.o
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(subst -,_,$(BINFILES))))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I.
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
|
||||
|
||||
export TOPDIR := $(CURRENT_DIRECTORY)
|
||||
|
||||
OUTPUT_BASE := $(TOPDIR)/$(notdir $(TOPDIR))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ATMOSPHERE_BUILD_CONFIGS :=
|
||||
all: release
|
||||
|
||||
define ATMOSPHERE_ADD_TARGET
|
||||
|
||||
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
|
||||
|
||||
$(strip $1): check_libexo_$(strip $1) $$(ATMOSPHERE_BUILD_DIR)/$(strip $1)
|
||||
@$$(MAKE) __RECURSIVE__=1 OUTPUT=$$(OUTPUT_BASE)$(strip $2) $(3) \
|
||||
ATMOSPHERE_BUILD_TARGET_IDENTIFIER=$(strip $1) \
|
||||
ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX=$(strip $2) \
|
||||
DEPSDIR=$$(CURDIR)/$$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||
LIBEXOSPHERE_NAME=exosphere$(strip $2) \
|
||||
--no-print-directory -C $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||
-f $$(THIS_MAKEFILE)
|
||||
|
||||
check_libexo_$(strip $1):
|
||||
@$$(MAKE) --no-print-directory -C $$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere $$(ATMOSPHERE_ARCH_NAME)-$(strip $1)
|
||||
|
||||
clean-$(strip $1):
|
||||
@echo clean $(strip $1) ...
|
||||
@rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(OUTPUT_BASE)$(strip $2).bin $$(OUTPUT_BASE)$(strip $2).elf
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, , \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, _debug, \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS -DAMS_BUILD_FOR_DEBUGGING" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, _audit, \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS -DAMS_BUILD_FOR_AUDITING" \
|
||||
))
|
||||
|
||||
$(ATMOSPHERE_BUILD_DIR)/%:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean: $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),clean-$(config))
|
||||
|
||||
.PHONY: all clean $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
$(OUTPUT).bin : $(OUTPUT).elf
|
||||
$(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/lib$(LIBEXOSPHERE_NAME).a
|
||||
|
||||
program.lz4.o: program_lz4.h
|
||||
|
||||
program_lz4.h: $(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4
|
||||
@echo $(notdir $<)
|
||||
@rm -rf tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
@mkdir -p tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
@cp $(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4 tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)/program.lz4
|
||||
@bin2s -a 8 -H program_lz4.h tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)/program.lz4 | $(AS) -o program.lz4.o
|
||||
@rm -rf tmp_program_$(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
|
||||
$(TOPDIR)/../program/program$(ATMOSPHERE_BUILD_TARGET_BINARY_SUFFIX).lz4:
|
||||
@$(MAKE) __RECURSIVE__=0 --no-print-directory -C $(TOPDIR)/../program $(ATMOSPHERE_BUILD_TARGET_IDENTIFIER)
|
||||
|
||||
%.elf:
|
||||
@echo linking $(notdir $@)
|
||||
$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN) program_lz4.h
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h: %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
125
fusee_cpp/loader_stub/loader_stub.ld
Normal file
125
fusee_cpp/loader_stub/loader_stub.ld
Normal file
|
@ -0,0 +1,125 @@
|
|||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_ZN3ams6nxboot6loader5StartEv)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
NULL : ORIGIN = 0, LENGTH = 4K
|
||||
data : ORIGIN = 0x40010000, LENGTH = 0x28000
|
||||
loader_stub : ORIGIN = 0x4003D000, LENGTH = 4K
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* =========== CODE section =========== */
|
||||
|
||||
. = ORIGIN(data);
|
||||
__data_start__ = . ;
|
||||
|
||||
.crt0 :
|
||||
{
|
||||
KEEP(*(.crt0 .crt0.*))
|
||||
. = ALIGN(8);
|
||||
} >data
|
||||
|
||||
/* =========== RODATA section =========== */
|
||||
. = ALIGN(8);
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
. = ALIGN(8);
|
||||
} >data
|
||||
|
||||
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >data
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >data
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >data
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >data
|
||||
|
||||
.hash : { *(.hash) } >data
|
||||
|
||||
/* =========== DATA section =========== */
|
||||
. = ALIGN(8);
|
||||
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >data
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >data
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >data
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >data
|
||||
|
||||
.data ALIGN(8) :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
} >data
|
||||
|
||||
__bss_start__ = .;
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(16);
|
||||
} >data :NONE
|
||||
__bss_end__ = .;
|
||||
|
||||
__data_end__ = ABSOLUTE(.);
|
||||
|
||||
|
||||
.loader_stub :
|
||||
{
|
||||
. = ALIGN(32);
|
||||
PROVIDE (__loader_stub_start__ = ABSOLUTE(.));
|
||||
PROVIDE (__loader_stub_lma__ = LOADADDR(.loader_stub));
|
||||
fusee_loader_main.o(.text*)
|
||||
fusee_loader_uncompress.o(.text*)
|
||||
fusee_loader_error.o(.text*)
|
||||
fusee_loader_main.o(.rodata*)
|
||||
fusee_loader_uncompress.o(.rodata*)
|
||||
fusee_loader_error.o(.rodata*)
|
||||
fusee_loader_main.o(.data*)
|
||||
fusee_loader_uncompress.o(.data*)
|
||||
fusee_loader_error.o(.data*)
|
||||
. = ALIGN(32);
|
||||
PROVIDE (__loader_stub_end__ = ABSOLUTE(.));
|
||||
} >loader_stub AT>data
|
||||
|
||||
/* ==================
|
||||
==== Metadata ====
|
||||
================== */
|
||||
|
||||
/* Discard sections that difficult post-processing */
|
||||
/DISCARD/ : { *(.group .comment .note .interp) }
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
4
fusee_cpp/loader_stub/loader_stub.specs
Normal file
4
fusee_cpp/loader_stub/loader_stub.specs
Normal file
|
@ -0,0 +1,4 @@
|
|||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic
|
47
fusee_cpp/loader_stub/source/fusee_loader_error.cpp
Normal file
47
fusee_cpp/loader_stub/source/fusee_loader_error.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_loader_error.hpp"
|
||||
|
||||
namespace ams::diag {
|
||||
|
||||
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value, const char *format, ...) {
|
||||
AMS_UNUSED(file, line, func, expr, value, format);
|
||||
ams::nxboot::loader::ErrorStop();
|
||||
}
|
||||
|
||||
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value) {
|
||||
AMS_UNUSED(file, line, func, expr, value);
|
||||
ams::nxboot::loader::ErrorStop();
|
||||
}
|
||||
|
||||
NORETURN void AbortImpl() {
|
||||
ams::nxboot::loader::ErrorStop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ams::nxboot::loader {
|
||||
|
||||
NORETURN void ErrorStop() {
|
||||
/* Halt ourselves. */
|
||||
while (true) {
|
||||
reg::Write(secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress() + FLOW_CTLR_HALT_COP_EVENTS, FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_MODE, FLOW_MODE_STOP),
|
||||
FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_JTAG, ENABLED));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
fusee_cpp/loader_stub/source/fusee_loader_error.hpp
Normal file
23
fusee_cpp/loader_stub/source/fusee_loader_error.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot::loader {
|
||||
|
||||
NORETURN void ErrorStop();
|
||||
|
||||
}
|
61
fusee_cpp/loader_stub/source/fusee_loader_main.cpp
Normal file
61
fusee_cpp/loader_stub/source/fusee_loader_main.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_loader_uncompress.hpp"
|
||||
#include "program_lz4.h"
|
||||
|
||||
namespace ams::nxboot::loader {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr uintptr_t ProgramImageBase = 0x40001000;
|
||||
constexpr uintptr_t ProgramImageEnd = 0x4003D000;
|
||||
constexpr size_t ProgramImageSizeMax = ProgramImageEnd - ProgramImageBase;
|
||||
|
||||
void CopyBackwards(void *dst, const void *src, size_t size) {
|
||||
/* We want to copy 32-bits at a time from destination to source. */
|
||||
const size_t words = util::DivideUp(size, sizeof(u32));
|
||||
|
||||
/* Convert to 32-bit pointers. */
|
||||
u32 *dst_32 = static_cast<u32 *>(dst) + words;
|
||||
const u32 *src_32 = static_cast<const u32 *>(src) + words;
|
||||
|
||||
/* Copy data. */
|
||||
for (size_t i = 0; i < words; ++i) {
|
||||
*(--dst_32) = *(--src_32);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NORETURN void UncompressAndExecute(const void *program, size_t program_size) {
|
||||
/* Relocate the compressed binary to a place where we can safely decompress it. */
|
||||
void *relocated_program = reinterpret_cast<void *>(util::AlignDown(ProgramImageEnd - program_size, sizeof(u32)));
|
||||
if (relocated_program != program) {
|
||||
CopyBackwards(relocated_program, program, program_size);
|
||||
}
|
||||
|
||||
/* Uncompress the program image. */
|
||||
Uncompress(reinterpret_cast<void *>(ProgramImageBase), ProgramImageSizeMax, relocated_program, program_size);
|
||||
|
||||
/* Jump to the boot image. */
|
||||
reinterpret_cast<void (*)()>(ProgramImageBase)();
|
||||
|
||||
/* We will never reach this point. */
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
}
|
59
fusee_cpp/loader_stub/source/fusee_loader_start.s
Normal file
59
fusee_cpp/loader_stub/source/fusee_loader_start.s
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
.section .crt0._ZN3ams6nxboot6loader5StartEv, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot6loader5StartEv
|
||||
.type _ZN3ams6nxboot6loader5StartEv, %function
|
||||
_ZN3ams6nxboot6loader5StartEv:
|
||||
/* Switch to system mode, mask all interrupts, clear all flags */
|
||||
msr cpsr_cxsf, #0xDF
|
||||
|
||||
/* Relocate loader stub. */
|
||||
ldr r0, =_ZN3ams6nxboot6loader5StartEv
|
||||
adr r1, _ZN3ams6nxboot6loader5StartEv
|
||||
ldr r2, =__loader_stub_lma__
|
||||
sub r2, r2, r0
|
||||
add r2, r2, r1
|
||||
|
||||
ldr r3, =__loader_stub_start__
|
||||
ldr r4, =__loader_stub_end__
|
||||
sub r4, r4, r3
|
||||
0:
|
||||
ldmia r2!, {r5-r12}
|
||||
stmia r3!, {r5-r12}
|
||||
subs r4, #0x20
|
||||
bne 0b
|
||||
|
||||
/* Set the stack pointer */
|
||||
ldr sp, =0x40001000
|
||||
mov fp, #0
|
||||
|
||||
/* Generate arguments. */
|
||||
ldr r3, =program_lz4
|
||||
ldr r4, =program_lz4_end
|
||||
sub r4, r4, r3
|
||||
sub r3, r3, r0
|
||||
add r3, r3, r1
|
||||
mov r0, r3
|
||||
mov r1, r4
|
||||
|
||||
/* Jump to the loader stub. */
|
||||
ldr r3, =_ZN3ams6nxboot6loader20UncompressAndExecuteEPKvj
|
||||
bx r3
|
103
fusee_cpp/loader_stub/source/fusee_loader_uncompress.cpp
Normal file
103
fusee_cpp/loader_stub/source/fusee_loader_uncompress.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_loader_uncompress.hpp"
|
||||
|
||||
namespace ams::nxboot::loader {
|
||||
|
||||
namespace {
|
||||
|
||||
class Lz4Uncompressor {
|
||||
private:
|
||||
const u8 *src;
|
||||
size_t src_size;
|
||||
size_t src_offset;
|
||||
u8 *dst;
|
||||
size_t dst_size;
|
||||
size_t dst_offset;
|
||||
public:
|
||||
Lz4Uncompressor(void *dst, size_t dst_size, const void *src, size_t src_size) : src(static_cast<const u8 *>(src)), src_size(src_size), src_offset(0), dst(static_cast<u8 *>(dst)), dst_size(dst_size), dst_offset(0) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
void Uncompress() {
|
||||
while (true) {
|
||||
/* Read a control byte. */
|
||||
const u8 control = this->ReadByte();
|
||||
|
||||
/* Copy what it specifies we should copy. */
|
||||
this->Copy(this->GetCopySize(control >> 4));
|
||||
|
||||
/* If we've exceeded size, we're done. */
|
||||
if (this->src_offset >= this->src_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read the wide copy offset. */
|
||||
u16 wide_offset = this->ReadByte();
|
||||
AMS_ABORT_UNLESS(this->CanRead());
|
||||
wide_offset |= (this->ReadByte() << 8);
|
||||
|
||||
/* Determine the copy size. */
|
||||
const size_t wide_copy_size = this->GetCopySize(control & 0xF);
|
||||
|
||||
/* Copy bytes. */
|
||||
const size_t end_offset = this->dst_offset + wide_copy_size + 4;
|
||||
for (size_t cur_offset = this->dst_offset; cur_offset < end_offset; this->dst_offset = (++cur_offset)) {
|
||||
AMS_ABORT_UNLESS(wide_offset <= cur_offset);
|
||||
|
||||
this->dst[cur_offset] = this->dst[cur_offset - wide_offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
u8 ReadByte() {
|
||||
return this->src[this->src_offset++];
|
||||
}
|
||||
|
||||
bool CanRead() const {
|
||||
return this->src_offset < this->src_size;
|
||||
}
|
||||
|
||||
size_t GetCopySize(u8 control) {
|
||||
size_t size = control;
|
||||
|
||||
if (control >= 0xF) {
|
||||
do {
|
||||
AMS_ABORT_UNLESS(this->CanRead());
|
||||
control = this->ReadByte();
|
||||
size += control;
|
||||
} while (control == 0xFF);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void Copy(size_t size) {
|
||||
__builtin_memcpy(this->dst + this->dst_offset, this->src + this->src_offset, size);
|
||||
this->dst_offset += size;
|
||||
this->src_offset += size;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
/* Create an execute a decompressor. */
|
||||
Lz4Uncompressor(dst, dst_size, src, src_size).Uncompress();
|
||||
}
|
||||
|
||||
}
|
23
fusee_cpp/loader_stub/source/fusee_loader_uncompress.hpp
Normal file
23
fusee_cpp/loader_stub/source/fusee_loader_uncompress.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot::loader {
|
||||
|
||||
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
}
|
143
fusee_cpp/program/Makefile
Normal file
143
fusee_cpp/program/Makefile
Normal file
|
@ -0,0 +1,143 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
# Define the atmosphere board and cpu
|
||||
#---------------------------------------------------------------------------------
|
||||
export ATMOSPHERE_BOARD := nx-hac-001
|
||||
export ATMOSPHERE_CPU := arm7tdmi
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# pull in common atmosphere configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/exosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(__RECURSIVE__),1)
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
|
||||
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
|
||||
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
|
||||
BINFILES :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(subst -,_,$(BINFILES))))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I.
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
|
||||
|
||||
export TOPDIR := $(CURRENT_DIRECTORY)
|
||||
|
||||
OUTPUT_BASE := $(TOPDIR)/$(notdir $(TOPDIR))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ATMOSPHERE_BUILD_CONFIGS :=
|
||||
all: release
|
||||
|
||||
define ATMOSPHERE_ADD_TARGET
|
||||
|
||||
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
|
||||
|
||||
$(strip $1): check_libexo_$(strip $1) $$(ATMOSPHERE_BUILD_DIR)/$(strip $1)
|
||||
@$$(MAKE) __RECURSIVE__=1 OUTPUT=$$(OUTPUT_BASE)$(strip $2) $(3) \
|
||||
DEPSDIR=$$(CURDIR)/$$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||
LIBEXOSPHERE_NAME=exosphere$(strip $2) \
|
||||
--no-print-directory -C $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
|
||||
-f $$(THIS_MAKEFILE)
|
||||
|
||||
check_libexo_$(strip $1):
|
||||
@$$(MAKE) --no-print-directory -C $$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere $$(ATMOSPHERE_ARCH_NAME)-$(strip $1)
|
||||
|
||||
clean-$(strip $1):
|
||||
@echo clean $(strip $1) ...
|
||||
@rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(OUTPUT_BASE)$(strip $2).bin $$(OUTPUT_BASE)$(strip $2).elf
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, , \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, _debug, \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS -DAMS_BUILD_FOR_DEBUGGING" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, _audit, \
|
||||
ATMOSPHERE_BUILD_SETTINGS="-DAMS_FORCE_DISABLE_DETAILED_ASSERTIONS -DAMS_BUILD_FOR_AUDITING" \
|
||||
))
|
||||
|
||||
$(ATMOSPHERE_BUILD_DIR)/%:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean: $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),clean-$(config))
|
||||
|
||||
.PHONY: all clean $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
$(OUTPUT).lz4 : $(OUTPUT).bin
|
||||
@python $(TOPDIR)/lz4_compress.py $(OUTPUT).bin $(OUTPUT).lz4
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(OUTPUT).bin : $(OUTPUT).elf
|
||||
$(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/lib$(LIBEXOSPHERE_NAME).a
|
||||
|
||||
%.elf:
|
||||
@echo linking $(notdir $@)
|
||||
$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h: %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
23
fusee_cpp/program/lz4_compress.py
Normal file
23
fusee_cpp/program/lz4_compress.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
import sys, lz4
|
||||
from struct import unpack as up
|
||||
|
||||
def lz4_compress(data):
|
||||
try:
|
||||
import lz4.block as block
|
||||
except ImportError:
|
||||
block = lz4.LZ4_compress
|
||||
return block.compress(data, 'high_compression', store_size=False)
|
||||
|
||||
def main(argc, argv):
|
||||
if argc != 3:
|
||||
print('Usage: %s in out' % argv[0])
|
||||
return 1
|
||||
with open(argv[1], 'rb') as f:
|
||||
data = f.read()
|
||||
with open(argv[2], 'wb') as f:
|
||||
f.write(lz4_compress(data))
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(len(sys.argv), sys.argv))
|
184
fusee_cpp/program/program.ld
Normal file
184
fusee_cpp/program/program.ld
Normal file
|
@ -0,0 +1,184 @@
|
|||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_ZN3ams6nxboot5StartEv)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
NULL : ORIGIN = 0, LENGTH = 4K
|
||||
main : ORIGIN = 0x40001000, LENGTH = 0x2B000
|
||||
ovl : ORIGIN = 0x4002C000, LENGTH = 0x14000
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* =========== CODE section =========== */
|
||||
PROVIDE(__start__ = ORIGIN(main));
|
||||
. = __start__;
|
||||
__main_start__ = . ;
|
||||
|
||||
.crt0 :
|
||||
{
|
||||
KEEP (*(.crt0 .crt0.*))
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP( *(.init) )
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
.plt :
|
||||
{
|
||||
*(.plt)
|
||||
*(.iplt)
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP( *(.fini) )
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
|
||||
/* =========== RODATA section =========== */
|
||||
. = ALIGN(8);
|
||||
__rodata_start = . ;
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >main
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >main
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >main
|
||||
|
||||
.hash : { *(.hash) } >main
|
||||
|
||||
/* =========== DATA section =========== */
|
||||
. = ALIGN(8);
|
||||
__data_start = . ;
|
||||
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >main
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >main
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >main
|
||||
|
||||
.preinit_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} >main
|
||||
|
||||
.init_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
} >main
|
||||
|
||||
.fini_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} >main
|
||||
|
||||
.ctors ALIGN(8) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} >main
|
||||
|
||||
.dtors ALIGN(8) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
} >main
|
||||
|
||||
__got_start__ = .;
|
||||
|
||||
.got : { *(.got) *(.igot) } >main
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) } >main
|
||||
|
||||
__got_end__ = .;
|
||||
|
||||
.data ALIGN(8) :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
} >main
|
||||
|
||||
__bss_start__ = .;
|
||||
.bss ALIGN(8) :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(16);
|
||||
} >main
|
||||
__bss_end__ = .;
|
||||
|
||||
__main_end__ = ABSOLUTE(.) ;
|
||||
|
||||
/* ==================
|
||||
==== Metadata ====
|
||||
================== */
|
||||
|
||||
/* Discard sections that difficult post-processing */
|
||||
/DISCARD/ : { *(.group .comment .note .interp) }
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
4
fusee_cpp/program/program.specs
Normal file
4
fusee_cpp/program/program.specs
Normal file
|
@ -0,0 +1,4 @@
|
|||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic
|
32
fusee_cpp/program/source/fusee_crt0.cpp
Normal file
32
fusee_cpp/program/source/fusee_crt0.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
|
||||
extern "C" void __libc_init_array();
|
||||
|
||||
namespace ams::nxboot::crt0 {
|
||||
|
||||
void Initialize(uintptr_t bss_start, uintptr_t bss_end) {
|
||||
/* TODO: Collect timing information? */
|
||||
|
||||
/* Clear bss. */
|
||||
std::memset(reinterpret_cast<void *>(bss_start), 0, bss_end - bss_start);
|
||||
|
||||
/* Call init array. */
|
||||
__libc_init_array();
|
||||
}
|
||||
|
||||
}
|
52
fusee_cpp/program/source/fusee_exception_handler.cpp
Normal file
52
fusee_cpp/program/source/fusee_exception_handler.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_exception_handler.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
NORETURN void ErrorStop() {
|
||||
/* Halt ourselves. */
|
||||
while (true) {
|
||||
reg::Write(secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress() + FLOW_CTLR_HALT_COP_EVENTS, FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_MODE, FLOW_MODE_STOP),
|
||||
FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_JTAG, ENABLED));
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN void ExceptionHandlerImpl(s32 which, u32 lr, u32 svc_lr) {
|
||||
/* TODO */
|
||||
ErrorStop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ams::diag {
|
||||
|
||||
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value, const char *format, ...) {
|
||||
AMS_UNUSED(file, line, func, expr, value, format);
|
||||
ams::nxboot::ErrorStop();
|
||||
}
|
||||
|
||||
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value) {
|
||||
AMS_UNUSED(file, line, func, expr, value);
|
||||
ams::nxboot::ErrorStop();
|
||||
}
|
||||
|
||||
NORETURN void AbortImpl() {
|
||||
ams::nxboot::ErrorStop();
|
||||
}
|
||||
|
||||
}
|
32
fusee_cpp/program/source/fusee_exception_handler.hpp
Normal file
32
fusee_cpp/program/source/fusee_exception_handler.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot::loader {
|
||||
|
||||
NORETURN void ExceptionHandler();
|
||||
|
||||
NORETURN void ExceptionHandler0();
|
||||
NORETURN void ExceptionHandler1();
|
||||
NORETURN void ExceptionHandler2();
|
||||
NORETURN void ExceptionHandler3();
|
||||
NORETURN void ExceptionHandler4();
|
||||
NORETURN void ExceptionHandler5();
|
||||
NORETURN void ExceptionHandler6();
|
||||
NORETURN void ExceptionHandler7();
|
||||
|
||||
}
|
114
fusee_cpp/program/source/fusee_exception_handler_asm.s
Normal file
114
fusee_cpp/program/source/fusee_exception_handler_asm.s
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandlerNEl, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
.type _ZN3ams6nxboot17ExceptionHandlerNEl, %function
|
||||
_ZN3ams6nxboot17ExceptionHandlerNEl:
|
||||
/* Get the normal return address. */
|
||||
mov r1, lr
|
||||
|
||||
/* Get the SVC return address. */
|
||||
msr cpsr_cf, #0xD3
|
||||
mov r2, lr
|
||||
|
||||
/* Invoke the exception handler in abort mode. */
|
||||
msr cpsr_cf, #0xD7
|
||||
b _ZN3ams6nxboot20ExceptionHandlerImplElmm
|
||||
|
||||
|
||||
.section .text._ZN3ams6nxboot16ExceptionHandlerEv, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot16ExceptionHandlerEv
|
||||
.type _ZN3ams6nxboot16ExceptionHandlerEv, %function
|
||||
_ZN3ams6nxboot16ExceptionHandlerEv:
|
||||
mov r0, #-1
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler0Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler0Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler0Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler0Ev:
|
||||
mov r0, #0
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler1Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler1Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler1Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler1Ev:
|
||||
mov r0, #1
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler2Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler2Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler2Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler2Ev:
|
||||
mov r0, #2
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler3Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler3Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler3Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler3Ev:
|
||||
mov r0, #3
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler4Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler4Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler4Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler4Ev:
|
||||
mov r0, #4
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler5Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler5Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler5Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler5Ev:
|
||||
mov r0, #5
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler6Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler6Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler6Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler6Ev:
|
||||
mov r0, #6
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler7Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler7Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler7Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler7Ev:
|
||||
mov r0, #7
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
25
fusee_cpp/program/source/fusee_main.cpp
Normal file
25
fusee_cpp/program/source/fusee_main.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void Main() {
|
||||
/* TODO */
|
||||
AMS_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
}
|
70
fusee_cpp/program/source/fusee_start.s
Normal file
70
fusee_cpp/program/source/fusee_start.s
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.section .crt0._ZN3ams6nxboot5StartEv, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot5StartEv
|
||||
.type _ZN3ams6nxboot5StartEv, %function
|
||||
_ZN3ams6nxboot5StartEv:
|
||||
/* Setup all registers as = 0. */
|
||||
msr cpsr_f, #0xC0
|
||||
mov r0, #0
|
||||
mov r1, #0
|
||||
mov r2, #0
|
||||
mov r3, #0
|
||||
mov r4, #0
|
||||
mov r5, #0
|
||||
mov r6, #0
|
||||
mov r7, #0
|
||||
mov r8, #0
|
||||
mov r9, #0
|
||||
mov r10, #0
|
||||
mov r11, #0
|
||||
mov r12, #0
|
||||
|
||||
/* Setup all modes as pointing to our exception handler. */
|
||||
msr cpsr_cf, #0xDF
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD2
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD1
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD7
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xDB
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD3
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
/* Perform runtime initialization. */
|
||||
ldr r0, =__bss_start__
|
||||
ldr r1, =__bss_end__
|
||||
bl _ZN3ams6nxboot4crt010InitializeEjj
|
||||
|
||||
/* Perform nx boot procedure. */
|
||||
bl _ZN3ams6nxboot4MainEv
|
|
@ -17,7 +17,7 @@ CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
|||
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
|
||||
else ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm)
|
||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
|
||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions \
|
||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -Werror -fno-non-call-exceptions \
|
||||
-Wno-array-bounds \
|
||||
-Wno-stringop-overflow \
|
||||
-Wno-stringop-overread
|
||||
|
|
|
@ -16,7 +16,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
|
|||
#---------------------------------------------------------------------------------
|
||||
|
||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
|
||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions \
|
||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -Wextra -Werror -flto -fno-non-call-exceptions \
|
||||
-Wno-array-bounds \
|
||||
-Wno-stringop-overflow \
|
||||
-Wno-stringop-overread
|
||||
|
|
Loading…
Reference in a new issue