fusee-cpp: add basic structural stubs

This commit is contained in:
Michael Scire
2021-08-21 11:10:13 -07:00
committed by SciresM
parent 165c926135
commit 5f60bc7186
21 changed files with 1280 additions and 2 deletions

143
fusee_cpp/program/Makefile Normal file
View 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
#---------------------------------------------------------------------------------------

View 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))

View 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) }
}

View File

@@ -0,0 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic

View 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();
}
}

View 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();
}
}

View 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();
}

View 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

View 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();
}
}

View 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