From 49d0a51d6b2c7b96e0c7c25501893a3d5ca40038 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 23 Aug 2021 07:11:28 -0700 Subject: [PATCH] fusee_cpp: implement sd card init --- fusee_cpp/program/program.ld | 3 + .../source/fusee_exception_handler.cpp | 19 ++++ fusee_cpp/program/source/fusee_main.cpp | 18 ++++ fusee_cpp/program/source/fusee_sd_card.cpp | 98 +++++++++++++++++++ fusee_cpp/program/source/fusee_sd_card.hpp | 26 +++++ .../vapours/sdmmc/sdmmc_build_config.hpp | 6 +- 6 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 fusee_cpp/program/source/fusee_sd_card.cpp create mode 100644 fusee_cpp/program/source/fusee_sd_card.hpp diff --git a/fusee_cpp/program/program.ld b/fusee_cpp/program/program.ld index 89bd75227..c84da359f 100644 --- a/fusee_cpp/program/program.ld +++ b/fusee_cpp/program/program.ld @@ -114,8 +114,11 @@ SECTIONS .data : { + FILL(0x00000000) *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) + . = ALIGN(64) - 1; + BYTE(0x00); } >main AT>glob __bss_start__ = .; diff --git a/fusee_cpp/program/source/fusee_exception_handler.cpp b/fusee_cpp/program/source/fusee_exception_handler.cpp index d9cc0810c..3863f6890 100644 --- a/fusee_cpp/program/source/fusee_exception_handler.cpp +++ b/fusee_cpp/program/source/fusee_exception_handler.cpp @@ -19,6 +19,10 @@ namespace ams::nxboot { NORETURN void ErrorStop() { + /* ABORT? */ + *reinterpret_cast(0x40038000) = 0xDEADDEAD; + *reinterpret_cast(0x7000E400) = 0x10; + /* 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), @@ -37,15 +41,30 @@ 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); + { + u32 lr; + __asm__ __volatile__("mov %0, lr" : "=r"(lr) :: "memory"); + *reinterpret_cast(0x40038004) = lr; + } 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); + { + u32 lr; + __asm__ __volatile__("mov %0, lr" : "=r"(lr) :: "memory"); + *reinterpret_cast(0x40038004) = lr; + } ams::nxboot::ErrorStop(); } NORETURN void AbortImpl() { + { + u32 lr; + __asm__ __volatile__("mov %0, lr" : "=r"(lr) :: "memory"); + *reinterpret_cast(0x40038004) = lr; + } ams::nxboot::ErrorStop(); } diff --git a/fusee_cpp/program/source/fusee_main.cpp b/fusee_cpp/program/source/fusee_main.cpp index c51a67253..28c863344 100644 --- a/fusee_cpp/program/source/fusee_main.cpp +++ b/fusee_cpp/program/source/fusee_main.cpp @@ -16,6 +16,7 @@ #include #include "fusee_secure_initialize.hpp" #include "fusee_sdram.hpp" +#include "fusee_sd_card.hpp" namespace ams::nxboot { @@ -26,6 +27,23 @@ namespace ams::nxboot { /* Initialize Sdram. */ InitializeSdram(); + /* Initialize SD card. */ + Result result = InitializeSdCard(); + + /* DEBUG: Check SD card connection. */ + { + *reinterpret_cast(0x40038000) = 0xAAAAAAAA; + *reinterpret_cast(0x40038004) = result.GetValue(); + if (R_SUCCEEDED(result)) { + sdmmc::SpeedMode sm; + sdmmc::BusWidth bw; + *reinterpret_cast(0x40038008) = CheckSdCardConnection(std::addressof(sm), std::addressof(bw)).GetValue(); + *reinterpret_cast(0x4003800C) = static_cast(sm); + *reinterpret_cast(0x40038010) = static_cast(bw); + } + *reinterpret_cast(0x7000E400) = 0x10; + } + /* TODO */ AMS_INFINITE_LOOP(); } diff --git a/fusee_cpp/program/source/fusee_sd_card.cpp b/fusee_cpp/program/source/fusee_sd_card.cpp new file mode 100644 index 000000000..061511b16 --- /dev/null +++ b/fusee_cpp/program/source/fusee_sd_card.cpp @@ -0,0 +1,98 @@ +/* + * 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 . + */ +#include +#include "fusee_sd_card.hpp" + +namespace ams::nxboot { + + namespace { + + constexpr inline auto SdCardPort = sdmmc::Port_SdCard0; + + constexpr inline const uintptr_t APB = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress(); + + alignas(0x10) constinit u8 g_sd_work_buffer[sdmmc::SdCardWorkBufferSize]; + + void ConfigureInitialSdCardPinmux() { + /* Normally, these pints get configured by boot sysmodule during initial pinmux config. */ + /* However, they're required to access the SD card, so we must do them ahead of time. */ + reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_CLK, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_DOWN), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CLK_PM, SDMMC1)); + + reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_CMD, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CMD_PM, SDMMC1)); + + reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT3, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT3_PM, SDMMC1)); + + reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT2, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT2_PM, SDMMC1)); + + reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT1, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT1_PM, SDMMC1)); + + reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT0, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, SDMMC1)); + + reg::ReadWrite(APB + PINMUX_AUX_DMIC3_CLK, PINMUX_REG_BITS_ENUM(AUX_E_OD, DISABLE), + PINMUX_REG_BITS_ENUM(AUX_E_INPUT, DISABLE), + PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH), + PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, RSVD2)); + } + + } + + Result InitializeSdCard() { + /* Perform initial pinmux config to enable sd card access. */ + ConfigureInitialSdCardPinmux(); + + /* Initialize the SD card. */ + sdmmc::Initialize(SdCardPort); + + /* Set the SD card work buffer. */ + sdmmc::SetSdCardWorkBuffer(SdCardPort, g_sd_work_buffer, sizeof(g_sd_work_buffer)); + + /* Activate the SD card. */ + return sdmmc::Activate(SdCardPort); + } + + Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) { + return sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort); + } + + Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) { + /* TODO */ + return ResultSuccess(); + } + + Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) { + /* TODO */ + return ResultSuccess(); + } + +} \ No newline at end of file diff --git a/fusee_cpp/program/source/fusee_sd_card.hpp b/fusee_cpp/program/source/fusee_sd_card.hpp new file mode 100644 index 000000000..7b20f6796 --- /dev/null +++ b/fusee_cpp/program/source/fusee_sd_card.hpp @@ -0,0 +1,26 @@ +/* + * 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 . + */ +#include +#pragma once + +namespace ams::nxboot { + + Result InitializeSdCard(); + Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw); + Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count); + Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size); + +} \ No newline at end of file diff --git a/libraries/libvapours/include/vapours/sdmmc/sdmmc_build_config.hpp b/libraries/libvapours/include/vapours/sdmmc/sdmmc_build_config.hpp index 97d6560c1..480dbc895 100644 --- a/libraries/libvapours/include/vapours/sdmmc/sdmmc_build_config.hpp +++ b/libraries/libvapours/include/vapours/sdmmc/sdmmc_build_config.hpp @@ -32,9 +32,9 @@ //#define AMS_SDMMC_USE_OS_EVENTS //#define AMS_SDMMC_USE_OS_TIMER #define AMS_SDMMC_USE_UTIL_TIMER - //#define AMS_SDMMC_ENABLE_MMC_HS400 - //#define AMS_SDMMC_ENABLE_SD_UHS_I - //#define AMS_SDMMC_SET_PLLC4_BASE + #define AMS_SDMMC_ENABLE_MMC_HS400 + #define AMS_SDMMC_ENABLE_SD_UHS_I + #define AMS_SDMMC_SET_PLLC4_BASE //#define AMS_SDMMC_USE_SD_CARD_DETECTOR #elif defined(ATMOSPHERE_IS_MESOSPHERE)