Compare commits

...

39 Commits

Author SHA1 Message Date
Michael Scire
e6bddf8782 i2c: correct missing destruction 2020-11-14 03:37:17 -08:00
Michael Scire
d8bd3d16bb ams.mitm: provide different boot0-protection for custom public key 2020-11-10 23:25:24 -08:00
Michael Scire
80f567d46a wec: whoops 2020-11-10 18:32:21 -08:00
Michael Scire
b6580b3170 updater: don't overwrite custom-public-key BCTs 2020-11-10 16:53:19 -08:00
Michael Scire
df8ceb9b06 pinmux: whoops 2020-11-10 16:30:36 -08:00
Michael Scire
c5656d39d2 boot/powctl/i2c: more miscellaneous fixes 2020-11-10 05:50:13 -08:00
Michael Scire
62ff502979 boot: various bugfixes (b/w logo displays now) 2020-11-10 05:02:41 -08:00
Michael Scire
f135ee74f8 powctl: implement max17050 driver 2020-11-10 02:23:05 -08:00
Michael Scire
8c3e536e94 powctl: add battery driver logic (missing impl) 2020-11-10 01:27:35 -08:00
Michael Scire
35573c4d85 powctl: implement max17050 custom parameter init 2020-11-09 23:14:31 -08:00
Michael Scire
e6ef753bb6 powctl: implement full bq24193 driver 2020-11-09 21:50:41 -08:00
Michael Scire
eade15b34e i2c: add register acccessor helpers 2020-11-09 17:34:47 -08:00
Michael Scire
b9c5dab18a powctl: add ChargerDriver body (needs impl) 2020-11-09 17:09:25 -08:00
Michael Scire
d0a45b8f21 pinmux: implement updated initial config api 2020-11-09 02:01:29 -08:00
Michael Scire
e0ce035323 boot: update/refactor display management to support hw type 5/display 0x1040/0x2050 2020-11-08 17:56:49 -08:00
Michael Scire
2562700f34 dd: implement DeviceAddressSpaceType api 2020-11-08 15:27:55 -08:00
Michael Scire
e93c3cbf58 boot: refactor battery checking to use new powctl apis 2020-11-08 04:16:50 -08:00
Michael Scire
cd7d7894f1 powctl: implement client api (needs board-specific impl) 2020-11-02 18:13:36 -08:00
Michael Scire
aa63b1eab7 pwm: implement driver for boot sysmodule 2020-11-01 23:04:19 -08:00
Michael Scire
4cc4f5fdb0 gpio: add missing driver functions for boot 2020-11-01 23:04:01 -08:00
Michael Scire
22ae1d5bd3 i2c: implement remaining required driver logic 2020-11-01 00:52:02 -07:00
Michael Scire
43f7b10c0f i2c: command list format, get boot down to linker errors 2020-10-31 22:52:43 -07:00
Michael Scire
48784da42a i2c/gpio: hook up open session for sf interface 2020-10-31 21:50:21 -07:00
Michael Scire
f27d6f2fd8 i2c: implement driver init api 2020-10-31 20:14:41 -07:00
Michael Scire
6f7502dfef i2c: finish I2cBusAccessor 2020-10-31 19:14:43 -07:00
Michael Scire
2d2b11a2d2 i2c: implement BusAccessor::WriteHeader 2020-10-31 18:24:26 -07:00
Michael Scire
2744a614de i2c: implement BusAccessor except Send/Receive/WriteHeader 2020-10-31 17:58:38 -07:00
Michael Scire
27be1a548c boot: add rgltr/clkrst overrides, skel I2cBusAccessor 2020-10-31 16:34:06 -07:00
Michael Scire
91b2a233c4 i2c: add auto-generated bus/device map 2020-10-31 14:20:01 -07:00
Michael Scire
7636dd2d44 i2c: begin skeleton device driver framework 2020-10-31 04:55:11 -07:00
Michael Scire
c867975eb8 gpio: remove copy-pasted unused file 2020-10-31 03:23:30 -07:00
Michael Scire
5bc4abb92f gpio: implement more of server library for boot sysmodule client usage 2020-10-31 03:22:01 -07:00
Michael Scire
e1dccef7d1 wec: implement wec driver components for boot sysmodule 2020-10-31 00:47:45 -07:00
Michael Scire
17fa05a789 gpio: add (most of) driver framework for boot sysmodule usage 2020-10-30 23:57:21 -07:00
Michael Scire
5b617f4d2f ddsf: implement namespace 2020-10-30 15:36:11 -07:00
Michael Scire
d2e530c2aa libstrat: fix precompiled-header dependency detection 2020-10-30 11:56:12 -07:00
SciresM
166318ba77 sdmmc: implement driver suitable for fs + bootloader
* sdmmc: begin skeletoning sdmmc driver

* sdmmc: add most of SdHostStandardController

* sdmmc: implement most of SdmmcController

* sdmmc: Sdmmc2Controller

* sdmmc: skeleton implementation of Sdmmc1Controller

* sdmmc: complete abstract logic for Sdmmc1 power controller

* sdmmc: implement gpio handling for sdmmc1-register-control

* sdmmc: implement pinmux handling for sdmmc1-register-control

* sdmmc: fix building for arm32 and in stratosphere context

* sdmmc: implement voltage enable/set for sdmmc1-register-control

* util: move T(V)SNPrintf from kernel to util

* sdmmc: implement BaseDeviceAccessor

* sdmmc: implement MmcDeviceAccessor

* sdmmc: implement clock reset controller for register api

* sdmmc: fix bug in WaitWhileCommandInhibit, add mmc accessors

* exo: add sdmmc test program

* sdmmc: fix speed mode extension, add CheckMmcConnection for debug

* sdmmc: add DeviceDetector, gpio: implement client api

* gpio: modernize client api instead of doing it the lazy way

* sdmmc: SdCardDeviceAccessor impl

* sdmmc: update test program to read first two sectors of sd card

* sdmmc: fix vref sel

* sdmmc: finish outward-facing api (untested)

* ams: changes for libvapours including tegra register defs

* sdmmc: remove hwinit
2020-10-30 11:54:30 -07:00
SciresM
ac04e02a08 Meso build targets (#1196)
* meso: commit wip (thanks fincs) rewrite to support build targets

* meso: commit mostly-working build system

* meso: correct .o dependencies in kernel/kldr

* libstratosphere: fix building after PCH related build changes

Co-authored-by: fincs <fincs@devkitpro.org>
2020-10-27 13:55:19 -07:00
Michael Scire
1c71d12d9d ams.mitm: avoid inadvertently breaking ftpd/file listers 2020-10-27 10:28:51 -07:00
463 changed files with 36853 additions and 8991 deletions

View File

@@ -648,7 +648,7 @@ namespace ams::secmon {
reg::Read (MC + MC_SMMU_TLB_CONFIG); reg::Read (MC + MC_SMMU_TLB_CONFIG);
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */ /* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
reg::Write(MC + MC_SMMU_PTC_FLUSH, 0); reg::Write(MC + MC_SMMU_PTC_FLUSH_0, 0);
reg::Read (MC + MC_SMMU_TLB_CONFIG); reg::Read (MC + MC_SMMU_TLB_CONFIG);
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */ /* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */
@@ -907,7 +907,7 @@ namespace ams::secmon {
reg::Write(MC + MC_SMMU_PPCS1_ASID, MC_REG_BITS_ENUM(SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE, ENABLE), MC_REG_BITS_VALUE(SMMU_PPCS1_ASID_PPCS1_ASID, BpmpAsid)); reg::Write(MC + MC_SMMU_PPCS1_ASID, MC_REG_BITS_ENUM(SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE, ENABLE), MC_REG_BITS_VALUE(SMMU_PPCS1_ASID_PPCS1_ASID, BpmpAsid));
/* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */ /* Flush the entire page table cache, and read TLB_CONFIG to ensure the flush takes. */
reg::Write(MC + MC_SMMU_PTC_FLUSH, 0); reg::Write(MC + MC_SMMU_PTC_FLUSH_0, 0);
reg::Read (MC + MC_SMMU_TLB_CONFIG); reg::Read (MC + MC_SMMU_TLB_CONFIG);
/* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */ /* Flush the entire translation lookaside buffer, and read TLB_CONFIG to ensure the flush takes. */

View File

@@ -22,7 +22,7 @@ SetRegisterAllowed(MC_SMMU_CONFIG); /* 0x010 */
SetRegisterAllowed(MC_SMMU_PTB_ASID); /* 0x01C */ SetRegisterAllowed(MC_SMMU_PTB_ASID); /* 0x01C */
SetRegisterAllowed(MC_SMMU_PTB_DATA); /* 0x020 */ SetRegisterAllowed(MC_SMMU_PTB_DATA); /* 0x020 */
SetRegisterAllowed(MC_SMMU_TLB_FLUSH); /* 0x030 */ SetRegisterAllowed(MC_SMMU_TLB_FLUSH); /* 0x030 */
SetRegisterAllowed(MC_SMMU_PTC_FLUSH); /* 0x034 */ SetRegisterAllowed(MC_SMMU_PTC_FLUSH_0); /* 0x034 */
SetRegisterAllowed(MC_EMEM_CFG); /* 0x050 */ SetRegisterAllowed(MC_EMEM_CFG); /* 0x050 */
SetRegisterAllowed(MC_EMEM_ADR_CFG); /* 0x054 */ SetRegisterAllowed(MC_EMEM_ADR_CFG); /* 0x054 */
SetRegisterAllowed(MC_EMEM_ARB_CFG); /* 0x090 */ SetRegisterAllowed(MC_EMEM_ARB_CFG); /* 0x090 */
@@ -53,7 +53,7 @@ SetRegisterAllowed(MC_SMMU_DCB_ASID); /* 0x244 */
SetRegisterAllowed(MC_SMMU_HC_ASID); /* 0x250 */ SetRegisterAllowed(MC_SMMU_HC_ASID); /* 0x250 */
SetRegisterAllowed(MC_SMMU_HDA_ASID); /* 0x254 */ SetRegisterAllowed(MC_SMMU_HDA_ASID); /* 0x254 */
SetRegisterAllowed(MC_SMMU_ISP2_ASID); /* 0x258 */ SetRegisterAllowed(MC_SMMU_ISP2_ASID); /* 0x258 */
SetRegisterAllowed(MC_SMMU_NVENC_ASID); /* 0x264 */ SetRegisterAllowed(MC_SMMU_MSENC_NVENC_ASID); /* 0x264 */
SetRegisterAllowed(MC_SMMU_NV_ASID); /* 0x268 */ SetRegisterAllowed(MC_SMMU_NV_ASID); /* 0x268 */
SetRegisterAllowed(MC_SMMU_NV2_ASID); /* 0x26C */ SetRegisterAllowed(MC_SMMU_NV2_ASID); /* 0x26C */
SetRegisterAllowed(MC_SMMU_PPCS_ASID); /* 0x270 */ SetRegisterAllowed(MC_SMMU_PPCS_ASID); /* 0x270 */

View File

@@ -0,0 +1,108 @@
#---------------------------------------------------------------------------------
# Define the atmosphere board and cpu
#---------------------------------------------------------------------------------
export ATMOSPHERE_BOARD := nx-hac-001
export ATMOSPHERE_CPU := arm7tdmi
#---------------------------------------------------------------------------------
# pull in common atmosphere configuration
#---------------------------------------------------------------------------------
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 ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(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)
#---------------------------------------------------------------------------------
# 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)/lib -L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD) check_libexo
$(BUILD): check_libexo
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
check_libexo:
@$(MAKE) --no-print-directory -C ../../libraries/libexosphere arm
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).bin $(OUTPUT).elf *.lz4
#---------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all : $(OUTPUT).bin
$(OUTPUT).bin : $(OUTPUT).elf
$(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@
@echo built ... $(notdir $@)
$(OUTPUT).elf : $(OFILES) ../../../libraries/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.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,194 @@
OUTPUT_ARCH(arm)
ENTRY(_ZN3ams10sdmmc_test5StartEv)
MEMORY
{
NULL : ORIGIN = 0, LENGTH = 4K
test_fw : ORIGIN = 0x40010000, LENGTH = 32K
}
SECTIONS
{
/* =========== CODE section =========== */
PROVIDE(__start__ = ORIGIN(test_fw));
. = __start__;
__code_start = . ;
.crt0 :
{
KEEP (*(.crt0 .crt0.*))
. = ALIGN(8);
} >test_fw
.vectors :
{
KEEP (*(.vectors .vectors.*))
. = ALIGN(8);
} >test_fw
.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);
} >test_fw
.init :
{
KEEP( *(.init) )
. = ALIGN(8);
} >test_fw
.plt :
{
*(.plt)
*(.iplt)
. = ALIGN(8);
} >test_fw
.fini :
{
KEEP( *(.fini) )
. = ALIGN(8);
} >test_fw
/* =========== RODATA section =========== */
. = ALIGN(8);
__rodata_start = . ;
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(8);
} >test_fw
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >test_fw
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >test_fw
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >test_fw
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >test_fw
.hash : { *(.hash) } >test_fw
/* =========== DATA section =========== */
. = ALIGN(8);
__data_start = . ;
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >test_fw
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >test_fw
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >test_fw
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >test_fw
.preinit_array ALIGN(8) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} >test_fw
.init_array ALIGN(8) :
{
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
} >test_fw
.fini_array ALIGN(8) :
{
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
} >test_fw
.ctors ALIGN(8) :
{
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >test_fw
.dtors ALIGN(8) :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >test_fw
__got_start__ = .;
.got : { *(.got) *(.igot) } >test_fw
.got.plt : { *(.got.plt) *(.igot.plt) } >test_fw
__got_end__ = .;
.data ALIGN(8) :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} >test_fw
__bss_start__ = .;
.bss ALIGN(8) :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(16);
} >test_fw
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
__total_size__ = (__end__ - __start__);
__stack_top__ = 0x40031000;
__stack_bottom__ = 0x40030000;
/* ==================
==== 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,7 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic -nostdlib -nostartfiles
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -0,0 +1,146 @@
/*
* 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::sdmmc_test {
namespace {
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
constexpr inline auto Port = sdmmc::Port_SdCard0;
alignas(8) constinit u8 g_sd_work_buffer[sdmmc::SdCardWorkBufferSize];
constexpr inline u32 SectorIndex = 0;
constexpr inline u32 SectorCount = 2;
NORETURN void PmcMainReboot() {
/* Write enable to MAIN_RESET. */
reg::Write(PMC + APBDEV_PMC_CNTRL, PMC_REG_BITS_ENUM(CNTRL_MAIN_RESET, ENABLE));
/* Wait forever until we're reset. */
AMS_INFINITE_LOOP();
}
void CheckResult(const Result result) {
volatile u32 * const DEBUG = reinterpret_cast<volatile u32 *>(0x4003C000);
if (R_FAILED(result)) {
DEBUG[1] = result.GetValue();
PmcMainReboot();
}
}
}
void Main() {
/* Perform butchered hwinit. */
/* TODO: replace with simpler, non-C logic. */
/* nx_hwinit(); */
/* Clear output buffer for debug. */
std::memset((void *)0x40038000, 0xAA, 0x400);
/* Normally, these pins get configured by boot sysmodule during initial pinmux config. */
/* However, they're required to access the SD card. */
{
const uintptr_t apb_misc = dd::QueryIoMapping(0x70000000, 0x4000);
reg::ReadWrite(apb_misc + 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_misc + 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_misc + 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_misc + 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_misc + 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_misc + 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_misc + 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));
}
/* Debug signaler. */
volatile u32 * const DEBUG = reinterpret_cast<volatile u32 *>(0x4003C000);
DEBUG[0] = 0;
DEBUG[1] = 0xAAAAAAAA;
/* Initialize sdmmc library. */
sdmmc::Initialize(Port);
DEBUG[0] = 1;
sdmmc::SetSdCardWorkBuffer(Port, g_sd_work_buffer, sizeof(g_sd_work_buffer));
DEBUG[0] = 2;
Result result = sdmmc::Activate(Port);
DEBUG[0] = 3;
CheckResult(result);
/* Read the first two sectors from disk. */
void * const sector_dst = reinterpret_cast<void *>(0x40038000);
result = sdmmc::Read(sector_dst, SectorCount * sdmmc::SectorSize, Port, SectorIndex, SectorCount);
DEBUG[0] = 4;
CheckResult(result);
/* Get the connection status. */
sdmmc::SpeedMode speed_mode;
sdmmc::BusWidth bus_width;
result = sdmmc::CheckSdCardConnection(std::addressof(speed_mode), std::addressof(bus_width), Port);
/* Save status for debug. */
DEBUG[0] = 5;
DEBUG[1] = result.GetValue();
DEBUG[2] = static_cast<u32>(speed_mode);
DEBUG[3] = static_cast<u32>(bus_width);
/* Perform a reboot. */
PmcMainReboot();
}
NORETURN void ExceptionHandler() {
PmcMainReboot();
}
}
namespace ams::diag {
void AbortImpl() {
sdmmc_test::ExceptionHandler();
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.text._ZN3ams10sdmmc_test5StartEv, "ax", %progbits
.align 3
.global _ZN3ams10sdmmc_test5StartEv
_ZN3ams10sdmmc_test5StartEv:
/* Switch to system mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
/* Set the stack pointer. */
ldr sp, =__stack_top__
/* Set our link register to the exception handler. */
ldr lr, =_ZN3ams10sdmmc_test16ExceptionHandlerEv
/* Call init array functions. */
bl __libc_init_array
/* Invoke main. */
b _ZN3ams10sdmmc_test4MainEv
/* Infinite loop. */
2: b 2b

View File

@@ -30,7 +30,7 @@ _ZN3ams8warmboot5StartEv:
/* Invoke main. */ /* Invoke main. */
ldr r0, =_metadata ldr r0, =_metadata
bl _ZN3ams8warmboot4MainEPKNS0_8MetadataE b _ZN3ams8warmboot4MainEPKNS0_8MetadataE
/* Infinite loop. */ /* Infinite loop. */
1: b 1b 1: b 1b

View File

@@ -15,8 +15,10 @@ endif
endif endif
ATMOSPHERE_BUILD_SETTINGS ?=
export ATMOSPHERE_DEFINES := -DATMOSPHERE export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \ export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \ -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation -Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
@@ -132,10 +134,15 @@ FIND_SOURCE_FILES=$(foreach dir,$1,$(filter-out $(notdir $(wildcard $(dir)/*.arc
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),os,$(ATMOSPHERE_OS_NAME),$2)) \ $(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES,$(dir),os,$(ATMOSPHERE_OS_NAME),$2)) \
$(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES_EX,$(dir),cpu,$(ATMOSPHERE_CPU_NAME) $(ATMOSPHERE_CPU_EXTENSIONS),$2)) $(foreach dir,$1,$(call FIND_SPECIFIC_SOURCE_FILES_EX,$(dir),cpu,$(ATMOSPHERE_CPU_NAME) $(ATMOSPHERE_CPU_EXTENSIONS),$2))
ATMOSPHERE_GCH_IDENTIFIER ?= ams_placeholder_gch_identifier
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# Rules for compiling pre-compiled headers # Rules for compiling pre-compiled headers
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%.gch: %.hpp %.hpp.gch/$(ATMOSPHERE_GCH_IDENTIFIER): %.hpp | %.hpp.gch
@echo $< @echo Precompiling $(notdir $<) for $(ATMOSPHERE_GCH_IDENTIFIER)
$(CXX) -w -x c++-header -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) $(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
@cp $@ $(<).gch
%.hpp.gch: %.hpp
@echo Precompiling $(notdir $<)
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)

View File

@@ -29,7 +29,7 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_ZSt20__throw_length_errorPKc \ -Wl,--wrap,_ZSt20__throw_length_errorPKc \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc -Wl,--wrap,_ZNSt11logic_errorC2EPKc
export LIBS := -lmesosphere export LIBS := -l$(LIBMESOSPHERE_NAME)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing

View File

@@ -112,6 +112,7 @@ $(OFILES) : $(GCH_FILES)
$(OFILES_SRC) : $(HFILES_BIN) $(OFILES_SRC) : $(HFILES_BIN)
libc.o: CFLAGS += -fno-builtin -fno-lto libc.o: CFLAGS += -fno-builtin -fno-lto
libgcc_division.arch.arm.o: CFLAGS += -fno-builtin -fno-lto
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin %_bin.h %.bin.o : %.bin

View File

@@ -17,7 +17,6 @@
#include <vapours.hpp> #include <vapours.hpp>
#include <exosphere/common.hpp> #include <exosphere/common.hpp>
#include <exosphere/reg.hpp>
#include <exosphere/hw.hpp> #include <exosphere/hw.hpp>
#include <exosphere/util.hpp> #include <exosphere/util.hpp>
#include <exosphere/mmu.hpp> #include <exosphere/mmu.hpp>
@@ -41,4 +40,3 @@
#include <exosphere/actmon.hpp> #include <exosphere/actmon.hpp>
#include <exosphere/pmc.hpp> #include <exosphere/pmc.hpp>
#include <exosphere/secmon.hpp> #include <exosphere/secmon.hpp>
#include <exosphere/tegra.hpp>

View File

@@ -1,34 +0,0 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <exosphere/tegra/tegra_ahb_arbc.hpp>
#include <exosphere/tegra/tegra_apb_misc.hpp>
#include <exosphere/tegra/tegra_avp_cache.hpp>
#include <exosphere/tegra/tegra_clkrst.hpp>
#include <exosphere/tegra/tegra_emc.hpp>
#include <exosphere/tegra/tegra_evp.hpp>
#include <exosphere/tegra/tegra_flow_ctlr.hpp>
#include <exosphere/tegra/tegra_ictlr.hpp>
#include <exosphere/tegra/tegra_mc.hpp>
#include <exosphere/tegra/tegra_mselect.hpp>
#include <exosphere/tegra/tegra_pinmux.hpp>
#include <exosphere/tegra/tegra_pg_up.hpp>
#include <exosphere/tegra/tegra_pmc.hpp>
#include <exosphere/tegra/tegra_sb.hpp>
#include <exosphere/tegra/tegra_sysctr0.hpp>
#include <exosphere/tegra/tegra_timer.hpp>

View File

@@ -20,14 +20,6 @@ namespace ams::util {
void SetRegisterAddress(uintptr_t address); void SetRegisterAddress(uintptr_t address);
u32 GetMicroSeconds();
void WaitMicroSeconds(int us);
void ClearMemory(void *ptr, size_t size); void ClearMemory(void *ptr, size_t size);
template<typename T, typename U> requires std::integral<T> && std::integral<U>
constexpr T DivideUp(T x, U y) {
return (x + (y - 1)) / y;
}
} }

View File

@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <exosphere.hpp> #include <exosphere.hpp>
#include "i2c_registers.hpp"
namespace ams::i2c { namespace ams::i2c {

View File

@@ -1,77 +0,0 @@
/*
* 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::i2c {
#define I2C_I2C_CNFG (0x000)
#define I2C_I2C_CMD_ADDR0 (0x004)
#define I2C_I2C_CMD_DATA1 (0x00C)
#define I2C_I2C_STATUS (0x01C)
#define I2C_INTERRUPT_STATUS_REGISTER (0x068)
#define I2C_CLK_DIVISOR_REGISTER (0x06C)
#define I2C_BUS_CLEAR_CONFIG (0x084)
#define I2C_BUS_CLEAR_STATUS (0x088)
#define I2C_CONFIG_LOAD (0x08C)
#define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
#define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
#define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
#define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
#define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
#define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
#define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
#define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
#define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
/* I2C_CNFG */
DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
/* I2C_CMD_ADDR0 */
DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
/* I2C_STATUS */
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
/* INTERRUPT_STATUS_REGISTER */
DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
/* CLK_DIVISOR_REGISTER */
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
/* BUS_CLEAR_CONFIG */
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
/* CONFIG_LOAD */
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
}

View File

@@ -0,0 +1,27 @@
/*
* 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>
#ifdef __cplusplus
extern "C" {
#endif
/* cxx implementation details to be stubbed here, as needed. */
void __cxa_pure_virtual() { AMS_ABORT("pure virtual function call"); }
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@@ -0,0 +1,160 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
/*
* Form ABI specifications:
* int __aeabi_idiv(int numerator, int denominator);
* unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
*
* typedef struct { int quot; int rem; } idiv_return;
* typedef struct { unsigned quot; unsigned rem; } uidiv_return;
*
* __value_in_regs idiv_return __aeabi_idivmod(int numerator,
* int *denominator);
* __value_in_regs uidiv_return __aeabi_uidivmod(unsigned *numerator,
* unsigned denominator);
*/
#ifdef __cplusplus
extern "C" {
#endif
/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
struct qr {
unsigned q; /* computed quotient */
unsigned r; /* computed remainder */
unsigned q_n; /* specficies if quotient shall be negative */
unsigned r_n; /* specficies if remainder shall be negative */
};
static void uint_div_qr(unsigned numerator, unsigned denominator,
struct qr *qr);
/* returns in R0 and R1 by tail calling an asm function */
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator);
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
/* returns in R0 and R1 by tail calling an asm function */
signed __aeabi_idivmod(signed numerator, signed denominator);
signed __aeabi_idiv(signed numerator, signed denominator);
/*
* __ste_idivmod_ret_t __aeabi_idivmod(signed numerator, signed denominator)
* Numerator and Denominator are received in R0 and R1.
* Where __ste_idivmod_ret_t is returned in R0 and R1.
*
* __ste_uidivmod_ret_t __aeabi_uidivmod(unsigned numerator,
* unsigned denominator)
* Numerator and Denominator are received in R0 and R1.
* Where __ste_uidivmod_ret_t is returned in R0 and R1.
*/
#ifdef __GNUC__
signed ret_idivmod_values(signed quotient, signed remainder);
unsigned ret_uidivmod_values(unsigned quotient, unsigned remainder);
#else
#error "Compiler not supported"
#endif
static void division_qr(unsigned n, unsigned p, struct qr *qr)
{
unsigned i = 1, q = 0;
if (p == 0) {
qr->r = 0xFFFFFFFF; /* division by 0 */
return;
}
while ((p >> 31) == 0) {
i = i << 1; /* count the max division steps */
p = p << 1; /* increase p until it has maximum size*/
}
while (i > 0) {
q = q << 1; /* write bit in q at index (size-1) */
if (n >= p)
{
n -= p;
q++;
}
p = p >> 1; /* decrease p */
i = i >> 1; /* decrease remaining size in q */
}
qr->r = n;
qr->q = q;
}
static void uint_div_qr(unsigned numerator, unsigned denominator, struct qr *qr)
{
division_qr(numerator, denominator, qr);
/* negate quotient and/or remainder according to requester */
if (qr->q_n)
qr->q = -qr->q;
if (qr->r_n)
qr->r = -qr->r;
}
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
uint_div_qr(numerator, denominator, &qr);
return qr.q;
}
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
uint_div_qr(numerator, denominator, &qr);
return ret_uidivmod_values(qr.q, qr.r);
}
signed __aeabi_idiv(signed numerator, signed denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
if (((numerator < 0) && (denominator > 0)) ||
((numerator > 0) && (denominator < 0)))
qr.q_n = 1; /* quotient shall be negate */
if (numerator < 0) {
numerator = -numerator;
qr.r_n = 1; /* remainder shall be negate */
}
if (denominator < 0)
denominator = -denominator;
uint_div_qr(numerator, denominator, &qr);
return qr.q;
}
signed __aeabi_idivmod(signed numerator, signed denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
if (((numerator < 0) && (denominator > 0)) ||
((numerator > 0) && (denominator < 0)))
qr.q_n = 1; /* quotient shall be negate */
if (numerator < 0) {
numerator = -numerator;
qr.r_n = 1; /* remainder shall be negate */
}
if (denominator < 0)
denominator = -denominator;
uint_div_qr(numerator, denominator, &qr);
return ret_idivmod_values(qr.q, qr.r);
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
/*
* signed ret_idivmod_values(signed quot, signed rem);
* return quotient and remaining the EABI way (regs r0,r1)
*/
.section .text.ret_idivmod_values, "ax", %progbits
.globl ret_idivmod_values
.align 0
.syntax unified
ret_idivmod_values:
bx lr
.type ret_idivmod_values, %function
.size ret_idivmod_values, .-ret_idivmod_values
/*
* unsigned ret_uidivmod_values(unsigned quot, unsigned rem);
* return quotient and remaining the EABI way (regs r0,r1)
*/
.section .text.ret_uidivmod_values, "ax", %progbits
.globl ret_uidivmod_values
.align 0
.syntax unified
ret_uidivmod_values:
bx lr
.type ret_uidivmod_values, %function
.size ret_uidivmod_values, .-ret_uidivmod_values

View File

@@ -0,0 +1,35 @@
/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that 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.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
.section .text.__gnu_thumb1_case_uqi, "ax", %progbits
.globl __gnu_thumb1_case_uqi
.align 0
.thumb_func
.syntax unified
__gnu_thumb1_case_uqi:
push {r1}
mov r1, lr
lsrs r1, r1, #1
lsls r1, r1, #1
ldrb r1, [r1, r0]
lsls r1, r1, #1
add lr, lr, r1
pop {r1}
bx lr
.type __gnu_thumb1_case_uqi, %function
.size __gnu_thumb1_case_uqi, .-__gnu_thumb1_case_uqi

View File

@@ -1,12 +1,14 @@
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# pull in common atmosphere configuration # pull in common atmosphere configuration
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
include $(CURRENT_DIRECTORY)/../config/common.mk
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/mesosphere.hpp PRECOMPILED_HEADERS := include/mesosphere.hpp
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
@@ -28,7 +30,7 @@ LIBDIRS := $(ATMOSPHERE_LIBRARIES_DIR)/libvapours
# no real need to edit anything past this point unless you need to add additional # no real need to edit anything past this point unless you need to add additional
# rules for different file extensions # rules for different file extensions
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR))) ifneq ($(__RECURSIVE__),1)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \
@@ -54,7 +56,7 @@ endif
export OFILES_BIN := $(addsuffix .o,$(BINFILES)) export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.gch),$(notdir $(hdr))) export GCH_DIRS := $(PRECOMPILED_HEADERS:.hpp=.hpp.gch)
export OFILES := $(OFILES_BIN) $(OFILES_SRC) export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
@@ -62,41 +64,70 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I. -I.
.PHONY: clean all #---------------------------------------------------------------------------------
ATMOSPHERE_BUILD_CONFIGS :=
all: release
define ATMOSPHERE_ADD_TARGET
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
$(strip $1): $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
$$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2) : $$(ATMOSPHERE_LIBRARY_DIR) $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(SOURCES) $$(INCLUDES) $$(GCH_DIRS)
@$$(MAKE) __RECURSIVE__=1 OUTPUT=$$(CURDIR)/$$@ $(3) \
ATMOSPHERE_GCH_IDENTIFIER="$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1)" \
DEPSDIR=$$(CURDIR)/$$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
--no-print-directory -C $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) \
-f $$(THIS_MAKEFILE)
clean-$(strip $1):
@echo clean $(strip $1) ...
@rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
ATMOSPHERE_BUILD_SETTINGS="" \
))
$(eval $(call ATMOSPHERE_ADD_TARGET, debug, $(TARGET)_debug.a, \
ATMOSPHERE_BUILD_SETTINGS="-DMESOSPHERE_BUILD_FOR_DEBUGGING" \
))
$(eval $(call ATMOSPHERE_ADD_TARGET, audit, $(TARGET)_audit.a, \
ATMOSPHERE_BUILD_SETTINGS="-DMESOSPHERE_BUILD_FOR_AUDITING" \
))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
all: lib/$(TARGET).a
lib: -include $(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME).mk
ALL_GCH_IDENTIFIERS := $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)_$(config))
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@ @[ -d $@ ] || mkdir -p $@
release: $(ATMOSPHERE_BUILD_DIR)/%:
@[ -d $@ ] || mkdir -p $@ @[ -d $@ ] || mkdir -p $@
lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \
-f $(CURDIR)/Makefile
dist-bin: all
@tar --exclude=*~ -cjf $(TARGET).tar.bz2 include lib
dist-src:
@tar --exclude=*~ -cjf $(TARGET)-src.tar.bz2 include source Makefile
dist: dist-src dist-bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
@echo clean ... @echo clean ...
@rm -fr release lib *.bz2 @rm -fr $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARY_DIR) *.bz2 $(ALL_GCH_FILES)
@for i in $(GCH_DIRS); do [ -d $$i ] && rmdir --ignore-fail-on-non-empty $$i || true; done
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
else else
DEPENDS := $(OFILES:.o=.d) $(GCH_FILES:.gch=.d) GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(CURRENT_DIRECTORY)/$(hdr)/$(ATMOSPHERE_GCH_IDENTIFIER))
DEPENDS := $(OFILES:.o=.d) $(foreach hdr,$(GCH_FILES),$(notdir $(patsubst %.hpp.gch/,%.d,$(dir $(hdr)))))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets

View File

@@ -1,20 +0,0 @@
/*
* 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/>.
*/
#pragma once
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304

View File

@@ -1,21 +0,0 @@
/*
* 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/>.
*/
#pragma once
#define FLOW_CTLR_HALT_COP_EVENTS 0x004
#define FLOW_CTLR_CC4_HVC_CONTROL 0x060
#define FLOW_CTLR_CC4_RETENTION_CONTROL 0x064
#define FLOW_CTLR_CC4_HVC_RETRY 0x08C

View File

@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <mesosphere.hpp> #include <mesosphere.hpp>
#include "kern_mc_registers.hpp"
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING) || defined(MESOSPHERE_BUILD_FOR_AUDITING) #if defined(MESOSPHERE_BUILD_FOR_DEBUGGING) || defined(MESOSPHERE_BUILD_FOR_AUDITING)
#define MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT #define MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT

View File

@@ -78,13 +78,11 @@ namespace ams::kern::board::nintendo::nx {
void WaitOtherCpuPowerOff() { void WaitOtherCpuPowerOff() {
constexpr u64 PmcPhysicalAddress = 0x7000E400; constexpr u64 PmcPhysicalAddress = 0x7000E400;
constexpr u64 APBDEV_PMC_PWRGATE_STATUS = PmcPhysicalAddress + 0x38;
constexpr u32 PWRGATE_STATUS_CE123_MASK = ((1u << 3) - 1) << 9; constexpr u32 PWRGATE_STATUS_CE123_MASK = ((1u << 3) - 1) << 9;
u32 value; u32 value;
do { do {
bool res = smc::ReadWriteRegister(std::addressof(value), APBDEV_PMC_PWRGATE_STATUS, 0, 0); bool res = smc::ReadWriteRegister(std::addressof(value), PmcPhysicalAddress + APBDEV_PMC_PWRGATE_STATUS, 0, 0);
MESOSPHERE_ASSERT(res); MESOSPHERE_ASSERT(res);
} while ((value & PWRGATE_STATUS_CE123_MASK) != 0); } while ((value & PWRGATE_STATUS_CE123_MASK) != 0);
} }

View File

@@ -19,11 +19,7 @@
#include "kern_bpmp_api.hpp" #include "kern_bpmp_api.hpp"
#include "kern_atomics_registers.hpp" #include "kern_atomics_registers.hpp"
#include "kern_clkrst_registers.hpp"
#include "kern_evp_registers.hpp"
#include "kern_flow_registers.hpp"
#include "kern_ictlr_registers.hpp" #include "kern_ictlr_registers.hpp"
#include "kern_pmc_registers.hpp"
#include "kern_sema_registers.hpp" #include "kern_sema_registers.hpp"
namespace ams::kern::board::nintendo::nx::lps { namespace ams::kern::board::nintendo::nx::lps {

View File

@@ -1,526 +0,0 @@
/*
* 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/>.
*/
#pragma once
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH_0 0x34
#define MC_SMMU_PTC_FLUSH_1 0x9b8
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_ASID_SECURITY_1 0x3c
#define MC_SMMU_ASID_SECURITY_2 0x9e0
#define MC_SMMU_ASID_SECURITY_3 0x9e4
#define MC_SMMU_ASID_SECURITY_4 0x9e8
#define MC_SMMU_ASID_SECURITY_5 0x9ec
#define MC_SMMU_ASID_SECURITY_6 0x9f0
#define MC_SMMU_ASID_SECURITY_7 0x9f4
#define MC_SMMU_AFI_ASID 0x238
#define MC_SMMU_AVPC_ASID 0x23c
#define MC_SMMU_DC_ASID 0x240
#define MC_SMMU_DCB_ASID 0x244
#define MC_SMMU_HC_ASID 0x250
#define MC_SMMU_HDA_ASID 0x254
#define MC_SMMU_ISP2_ASID 0x258
#define MC_SMMU_MSENC_NVENC_ASID 0x264
#define MC_SMMU_NV_ASID 0x268
#define MC_SMMU_NV2_ASID 0x26c
#define MC_SMMU_PPCS_ASID 0x270
#define MC_SMMU_SATA_ASID 0x274
#define MC_SMMU_VDE_ASID 0x27c
#define MC_SMMU_VI_ASID 0x280
#define MC_SMMU_VIC_ASID 0x284
#define MC_SMMU_XUSB_HOST_ASID 0x288
#define MC_SMMU_XUSB_DEV_ASID 0x28c
#define MC_SMMU_TSEC_ASID 0x294
#define MC_SMMU_PPCS1_ASID 0x298
#define MC_SMMU_DC1_ASID 0xa88
#define MC_SMMU_SDMMC1A_ASID 0xa94
#define MC_SMMU_SDMMC2A_ASID 0xa98
#define MC_SMMU_SDMMC3A_ASID 0xa9c
#define MC_SMMU_SDMMC4A_ASID 0xaa0
#define MC_SMMU_ISP2B_ASID 0xaa4
#define MC_SMMU_GPU_ASID 0xaa8
#define MC_SMMU_GPUB_ASID 0xaac
#define MC_SMMU_PPCS2_ASID 0xab0
#define MC_SMMU_NVDEC_ASID 0xab4
#define MC_SMMU_APE_ASID 0xab8
#define MC_SMMU_SE_ASID 0xabc
#define MC_SMMU_NVJPG_ASID 0xac0
#define MC_SMMU_HC1_ASID 0xac4
#define MC_SMMU_SE1_ASID 0xac8
#define MC_SMMU_AXIAP_ASID 0xacc
#define MC_SMMU_ETR_ASID 0xad0
#define MC_SMMU_TSECB_ASID 0xad4
#define MC_SMMU_TSEC1_ASID 0xad8
#define MC_SMMU_TSECB1_ASID 0xadc
#define MC_SMMU_NVDEC1_ASID 0xae0
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
#define MC_EMEM_CFG 0x50
#define MC_EMEM_ADR_CFG 0x54
#define MC_EMEM_ADR_CFG_DEV0 0x58
#define MC_EMEM_ADR_CFG_DEV1 0x5c
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
#define MC_SECURITY_CFG0 0x70
#define MC_SECURITY_CFG1 0x74
#define MC_SECURITY_CFG3 0x9bc
#define MC_SECURITY_RSV 0x7c
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
#define MC_EMEM_ARB_TIMING_RAS 0xa4
#define MC_EMEM_ARB_TIMING_FAW 0xa8
#define MC_EMEM_ARB_TIMING_RRD 0xac
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
#define MC_EMEM_ARB_TIMING_R2R 0xb8
#define MC_EMEM_ARB_TIMING_W2W 0xbc
#define MC_EMEM_ARB_TIMING_R2W 0xc0
#define MC_EMEM_ARB_TIMING_W2R 0xc4
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
#define MC_EMEM_ARB_DA_TURNS 0xd0
#define MC_EMEM_ARB_DA_COVERS 0xd4
#define MC_EMEM_ARB_MISC0 0xd8
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_MISC2 0xc8
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
#define MC_EMEM_ARB_OVERRIDE 0xe8
#define MC_EMEM_ARB_RSV 0xec
#define MC_CLKEN_OVERRIDE 0xf4
#define MC_TIMING_CONTROL_DBG 0xf8
#define MC_TIMING_CONTROL 0xfc
#define MC_STAT_CONTROL 0x100
#define MC_STAT_STATUS 0x104
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
#define MC_STAT_EMC_CLOCKS 0x110
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
#define MC_STAT_EMC_SET0_COUNT 0x138
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
#define MC_STAT_EMC_SET1_COUNT 0x178
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
#define MC_CLIENT_HOTRESET_CTRL 0x200
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
#define MC_CLIENT_HOTRESET_STATUS 0x204
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
#define MC_RESERVED_RSV 0x3fc
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
#define MC_VIDEO_PROTECT_BOM 0x648
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
#define MC_ERR_VPR_STATUS 0x654
#define MC_ERR_VPR_ADR 0x658
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
#define MC_IRAM_BOM 0x65c
#define MC_IRAM_TOM 0x660
#define MC_IRAM_ADR_HI 0x980
#define MC_IRAM_REG_CTRL 0x964
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
#define MC_TZ_SECURITY_CTRL 0x668
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
#define MC_SEC_CARVEOUT_BOM 0x670
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
#define MC_ERR_SEC_STATUS 0x67c
#define MC_ERR_SEC_ADR 0x680
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
#define MC_STUTTER_CONTROL 0x688
#define MC_RESERVED_RSV_1 0x958
#define MC_DVFS_PIPE_SELECT 0x95c
#define MC_AHB_PTSA_MIN 0x4e0
#define MC_AUD_PTSA_MIN 0x54c
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
#define MC_RING2_PTSA_RATE 0x440
#define MC_USBD_PTSA_RATE 0x530
#define MC_USBX_PTSA_MIN 0x528
#define MC_USBD_PTSA_MIN 0x534
#define MC_APB_PTSA_MAX 0x4f0
#define MC_JPG_PTSA_RATE 0x584
#define MC_DIS_PTSA_MIN 0x420
#define MC_AVP_PTSA_MAX 0x4fc
#define MC_AVP_PTSA_RATE 0x4f4
#define MC_RING1_PTSA_MIN 0x480
#define MC_DIS_PTSA_MAX 0x424
#define MC_SD_PTSA_MAX 0x4d8
#define MC_MSE_PTSA_RATE 0x4c4
#define MC_VICPC_PTSA_MIN 0x558
#define MC_PCX_PTSA_MAX 0x4b4
#define MC_ISP_PTSA_RATE 0x4a0
#define MC_A9AVPPC_PTSA_MIN 0x48c
#define MC_RING2_PTSA_MAX 0x448
#define MC_AUD_PTSA_RATE 0x548
#define MC_HOST_PTSA_MIN 0x51c
#define MC_MLL_MPCORER_PTSA_MAX 0x454
#define MC_SD_PTSA_MIN 0x4d4
#define MC_RING1_PTSA_RATE 0x47c
#define MC_JPG_PTSA_MIN 0x588
#define MC_HDAPC_PTSA_MIN 0x62c
#define MC_AVP_PTSA_MIN 0x4f8
#define MC_JPG_PTSA_MAX 0x58c
#define MC_VE_PTSA_MAX 0x43c
#define MC_DFD_PTSA_MAX 0x63c
#define MC_VICPC_PTSA_RATE 0x554
#define MC_GK_PTSA_MAX 0x544
#define MC_VICPC_PTSA_MAX 0x55c
#define MC_SDM_PTSA_MAX 0x624
#define MC_SAX_PTSA_RATE 0x4b8
#define MC_PCX_PTSA_MIN 0x4b0
#define MC_APB_PTSA_MIN 0x4ec
#define MC_GK2_PTSA_MIN 0x614
#define MC_PCX_PTSA_RATE 0x4ac
#define MC_RING1_PTSA_MAX 0x484
#define MC_HDAPC_PTSA_RATE 0x628
#define MC_MLL_MPCORER_PTSA_MIN 0x450
#define MC_GK2_PTSA_MAX 0x618
#define MC_AUD_PTSA_MAX 0x550
#define MC_GK2_PTSA_RATE 0x610
#define MC_ISP_PTSA_MAX 0x4a8
#define MC_DISB_PTSA_RATE 0x428
#define MC_VE2_PTSA_MAX 0x49c
#define MC_DFD_PTSA_MIN 0x638
#define MC_FTOP_PTSA_RATE 0x50c
#define MC_A9AVPPC_PTSA_RATE 0x488
#define MC_VE2_PTSA_MIN 0x498
#define MC_USBX_PTSA_MAX 0x52c
#define MC_DIS_PTSA_RATE 0x41c
#define MC_USBD_PTSA_MAX 0x538
#define MC_A9AVPPC_PTSA_MAX 0x490
#define MC_USBX_PTSA_RATE 0x524
#define MC_FTOP_PTSA_MAX 0x514
#define MC_HDAPC_PTSA_MAX 0x630
#define MC_SD_PTSA_RATE 0x4d0
#define MC_DFD_PTSA_RATE 0x634
#define MC_FTOP_PTSA_MIN 0x510
#define MC_SDM_PTSA_RATE 0x61c
#define MC_AHB_PTSA_RATE 0x4dc
#define MC_SMMU_SMMU_PTSA_MAX 0x460
#define MC_RING2_PTSA_MIN 0x444
#define MC_SDM_PTSA_MIN 0x620
#define MC_APB_PTSA_RATE 0x4e8
#define MC_MSE_PTSA_MIN 0x4c8
#define MC_HOST_PTSA_RATE 0x518
#define MC_VE_PTSA_RATE 0x434
#define MC_AHB_PTSA_MAX 0x4e4
#define MC_SAX_PTSA_MIN 0x4bc
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
#define MC_ISP_PTSA_MIN 0x4a4
#define MC_HOST_PTSA_MAX 0x520
#define MC_SAX_PTSA_MAX 0x4c0
#define MC_VE_PTSA_MIN 0x438
#define MC_GK_PTSA_MIN 0x540
#define MC_MSE_PTSA_MAX 0x4cc
#define MC_DISB_PTSA_MAX 0x430
#define MC_DISB_PTSA_MIN 0x42c
#define MC_SMMU_SMMU_PTSA_RATE 0x458
#define MC_VE2_PTSA_RATE 0x494
#define MC_GK_PTSA_RATE 0x53c
#define MC_PTSA_GRANT_DECREMENT 0x960
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
#define MC_MIN_LENGTH_APE_0 0xb34
#define MC_MIN_LENGTH_DCB_2 0x8a8
#define MC_MIN_LENGTH_A9AVP_0 0x950
#define MC_MIN_LENGTH_TSEC_0 0x93c
#define MC_MIN_LENGTH_DC_1 0x898
#define MC_MIN_LENGTH_AXIAP_0 0x94c
#define MC_MIN_LENGTH_ISP2B_0 0x930
#define MC_MIN_LENGTH_VI2_0 0x944
#define MC_MIN_LENGTH_DCB_0 0x8a0
#define MC_MIN_LENGTH_DCB_1 0x8a4
#define MC_MIN_LENGTH_PPCS_1 0x8f4
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
#define MC_MIN_LENGTH_HDA_0 0x8c4
#define MC_MIN_LENGTH_NVENC_0 0x8d4
#define MC_MIN_LENGTH_SDMMC_0 0xb18
#define MC_MIN_LENGTH_ISP2B_1 0x934
#define MC_MIN_LENGTH_HC_1 0x8c0
#define MC_MIN_LENGTH_DC_3 0xb20
#define MC_MIN_LENGTH_AVPC_0 0x890
#define MC_MIN_LENGTH_VIC_0 0x940
#define MC_MIN_LENGTH_ISP2_0 0x91c
#define MC_MIN_LENGTH_HC_0 0x8bc
#define MC_MIN_LENGTH_SE_0 0xb38
#define MC_MIN_LENGTH_NVDEC_0 0xb30
#define MC_MIN_LENGTH_SATA_0 0x8fc
#define MC_MIN_LENGTH_DC_0 0x894
#define MC_MIN_LENGTH_XUSB_1 0x92c
#define MC_MIN_LENGTH_DC_2 0x89c
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
#define MC_MIN_LENGTH_GPU_0 0xb04
#define MC_MIN_LENGTH_ETR_0 0xb44
#define MC_MIN_LENGTH_AFI_0 0x88c
#define MC_MIN_LENGTH_PPCS_0 0x8f0
#define MC_MIN_LENGTH_ISP2_1 0x920
#define MC_MIN_LENGTH_XUSB_0 0x928
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
#define MC_MIN_LENGTH_TSECB_0 0xb48
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
#define MC_MIN_LENGTH_GPU2_0 0xb40
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
#define MC_MIN_LENGTH_PTC_0 0x8f8
#define MC_EMEM_ARB_OVERRIDE_1 0x968
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
#define MC_EMEM_ARB_STATS_0 0x990
#define MC_EMEM_ARB_STATS_1 0x994
#define MC_MTS_CARVEOUT_BOM 0x9a0
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
#define MC_ERR_MTS_STATUS 0x9b0
#define MC_ERR_MTS_ADR 0x9b4
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
#define MC_DA_CONFIG0 0x9dc

View File

@@ -1,21 +0,0 @@
/*
* 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/>.
*/
#pragma once
#define APBDEV_PMC_DPD_ENABLE 0x024
#define APBDEV_PMC_SCRATCH0 0x050
#define APBDEV_PMC_SCRATCH4 0x060
#define APBDEV_PMC_SCRATCH39 0x138

View File

@@ -17,386 +17,9 @@
#include "kern_debug_log_impl.hpp" #include "kern_debug_log_impl.hpp"
namespace ams::kern { namespace ams::kern {
#pragma GCC push_options
#pragma GCC optimize ("-Os")
namespace { namespace {
/* Useful definitions for our VSNPrintf implementation. */
enum FormatSpecifierFlag : u32 {
FormatSpecifierFlag_None = 0,
FormatSpecifierFlag_EmptySign = (1 << 0),
FormatSpecifierFlag_ForceSign = (1 << 1),
FormatSpecifierFlag_Hash = (1 << 2),
FormatSpecifierFlag_LeftJustify = (1 << 3),
FormatSpecifierFlag_ZeroPad = (1 << 4),
FormatSpecifierFlag_Char = (1 << 5),
FormatSpecifierFlag_Short = (1 << 6),
FormatSpecifierFlag_Long = (1 << 7),
FormatSpecifierFlag_LongLong = (1 << 8),
FormatSpecifierFlag_Uppercase = (1 << 9),
FormatSpecifierFlag_HasPrecision = (1 << 10),
};
using FormatSpecifierFlagStorage = std::underlying_type<FormatSpecifierFlag>::type;
constexpr ALWAYS_INLINE bool IsDigit(char c) {
return '0' <= c && c <= '9';
}
constexpr ALWAYS_INLINE u32 ParseU32(const char *&str) {
u32 value = 0;
do {
value = (value * 10) + static_cast<u32>(*(str++) - '0');
} while (IsDigit(*str));
return value;
}
constexpr ALWAYS_INLINE size_t Strnlen(const char *str, size_t max) {
const char *cur = str;
while (*cur && max--) {
cur++;
}
return static_cast<size_t>(cur - str);
}
ALWAYS_INLINE void VSNPrintfImpl(char * const dst, const size_t dst_size, const char *format, ::std::va_list vl) {
size_t dst_index = 0;
auto WriteCharacter = [dst, dst_size, &dst_index](char c) ALWAYS_INLINE_LAMBDA {
if (dst_index < dst_size) {
dst[dst_index++] = c;
}
};
/* Loop over every character in the string, looking for format specifiers. */
while (*format) {
if (const char c = *(format++); c != '%') {
WriteCharacter(c);
continue;
}
/* We have to parse a format specifier. */
/* Start by parsing flags. */
FormatSpecifierFlagStorage flags = FormatSpecifierFlag_None;
auto SetFlag = [&flags](FormatSpecifierFlag f) ALWAYS_INLINE_LAMBDA { flags |= f; };
auto ClearFlag = [&flags](FormatSpecifierFlag f) ALWAYS_INLINE_LAMBDA { flags &= ~f; };
auto HasFlag = [&flags](FormatSpecifierFlag f) ALWAYS_INLINE_LAMBDA { return (flags & f) != 0; };
{
bool parsed_flags = false;
while (!parsed_flags) {
switch (*format) {
case ' ': SetFlag(FormatSpecifierFlag_EmptySign); format++; break;
case '+': SetFlag(FormatSpecifierFlag_ForceSign); format++; break;
case '#': SetFlag(FormatSpecifierFlag_Hash); format++; break;
case '-': SetFlag(FormatSpecifierFlag_LeftJustify); format++; break;
case '0': SetFlag(FormatSpecifierFlag_ZeroPad); format++; break;
default:
parsed_flags = true;
break;
}
}
}
/* Next, parse width. */
u32 width = 0;
if (IsDigit(*format)) {
/* Integer width. */
width = ParseU32(format);
} else if (*format == '*') {
/* Dynamic width. */
const int _width = va_arg(vl, int);
if (_width >= 0) {
width = static_cast<u32>(_width);
} else {
SetFlag(FormatSpecifierFlag_LeftJustify);
width = static_cast<u32>(-_width);
}
format++;
}
/* Next, parse precision if present. */
u32 precision = 0;
if (*format == '.') {
SetFlag(FormatSpecifierFlag_HasPrecision);
format++;
if (IsDigit(*format)) {
/* Integer precision. */
precision = ParseU32(format);
} else if (*format == '*') {
/* Dynamic precision. */
const int _precision = va_arg(vl, int);
if (_precision > 0) {
precision = static_cast<u32>(_precision);
}
format++;
}
}
/* Parse length. */
constexpr bool SizeIsLong = sizeof(size_t) == sizeof(long);
constexpr bool IntMaxIsLong = sizeof(intmax_t) == sizeof(long);
constexpr bool PtrDiffIsLong = sizeof(ptrdiff_t) == sizeof(long);
switch (*format) {
case 'z':
SetFlag(SizeIsLong ? FormatSpecifierFlag_Long : FormatSpecifierFlag_LongLong);
format++;
break;
case 'j':
SetFlag(IntMaxIsLong ? FormatSpecifierFlag_Long : FormatSpecifierFlag_LongLong);
format++;
break;
case 't':
SetFlag(PtrDiffIsLong ? FormatSpecifierFlag_Long : FormatSpecifierFlag_LongLong);
format++;
break;
case 'h':
SetFlag(FormatSpecifierFlag_Short);
format++;
if (*format == 'h') {
SetFlag(FormatSpecifierFlag_Char);
format++;
}
break;
case 'l':
SetFlag(FormatSpecifierFlag_Long);
format++;
if (*format == 'l') {
SetFlag(FormatSpecifierFlag_LongLong);
format++;
}
break;
default:
break;
}
const char specifier = *(format++);
switch (specifier) {
case 'p':
if constexpr (sizeof(uintptr_t) == sizeof(long long)) {
SetFlag(FormatSpecifierFlag_LongLong);
} else {
SetFlag(FormatSpecifierFlag_Long);
}
SetFlag(FormatSpecifierFlag_Hash);
[[fallthrough]];
case 'd':
case 'i':
case 'u':
case 'b':
case 'o':
case 'x':
case 'X':
{
/* Determine the base to print with. */
u32 base;
switch (specifier) {
case 'b':
base = 2;
break;
case 'o':
base = 8;
break;
case 'X':
SetFlag(FormatSpecifierFlag_Uppercase);
[[fallthrough]];
case 'p':
case 'x':
base = 16;
break;
default:
base = 10;
ClearFlag(FormatSpecifierFlag_Hash);
break;
}
/* Precision implies no zero-padding. */
if (HasFlag(FormatSpecifierFlag_HasPrecision)) {
ClearFlag(FormatSpecifierFlag_ZeroPad);
}
/* Unsigned types don't get signs. */
const bool is_unsigned = base != 10 || specifier == 'u';
if (is_unsigned) {
ClearFlag(FormatSpecifierFlag_EmptySign);
ClearFlag(FormatSpecifierFlag_ForceSign);
}
auto PrintInteger = [&](bool negative, uintmax_t value) {
constexpr size_t BufferSize = 64; /* Binary digits for 64-bit numbers may use 64 digits. */
char buf[BufferSize];
size_t len = 0;
/* No hash flag for zero. */
if (value == 0) {
ClearFlag(FormatSpecifierFlag_Hash);
}
if (!HasFlag(FormatSpecifierFlag_HasPrecision) || value != 0) {
do {
const char digit = static_cast<char>(value % base);
buf[len++] = (digit < 10) ? ('0' + digit) : ((HasFlag(FormatSpecifierFlag_Uppercase) ? 'A' : 'a') + digit - 10);
value /= base;
} while (value);
}
/* Determine our prefix length. */
size_t prefix_len = 0;
const bool has_sign = negative || HasFlag(FormatSpecifierFlag_ForceSign) || HasFlag(FormatSpecifierFlag_EmptySign);
if (has_sign) {
prefix_len++;
}
if (HasFlag(FormatSpecifierFlag_Hash)) {
prefix_len += (base != 8) ? 2 : 1;
}
/* Determine zero-padding count. */
size_t num_zeroes = (len < precision) ? precision - len : 0;
if (!HasFlag(FormatSpecifierFlag_LeftJustify) && HasFlag(FormatSpecifierFlag_ZeroPad)) {
num_zeroes = (len + prefix_len < width) ? width - len - prefix_len : 0;
}
/* Print out left padding. */
if (!HasFlag(FormatSpecifierFlag_LeftJustify)) {
for (size_t i = len + prefix_len + num_zeroes; i < static_cast<size_t>(width); i++) {
WriteCharacter(' ');
}
}
/* Print out sign. */
if (negative) {
WriteCharacter('-');
} else if (HasFlag(FormatSpecifierFlag_ForceSign)) {
WriteCharacter('+');
} else if (HasFlag(FormatSpecifierFlag_EmptySign)) {
WriteCharacter(' ');
}
/* Print out base prefix. */
if (HasFlag(FormatSpecifierFlag_Hash)) {
WriteCharacter('0');
if (base == 2) {
WriteCharacter('b');
} else if (base == 16) {
WriteCharacter('x');
}
}
/* Print out zeroes. */
for (size_t i = 0; i < num_zeroes; i++) {
WriteCharacter('0');
}
/* Print out digits. */
for (size_t i = 0; i < len; i++) {
WriteCharacter(buf[len - 1 - i]);
}
/* Print out right padding. */
if (HasFlag(FormatSpecifierFlag_LeftJustify)) {
for (size_t i = len + prefix_len + num_zeroes; i < static_cast<size_t>(width); i++) {
WriteCharacter(' ');
}
}
};
/* Output the integer. */
if (is_unsigned) {
uintmax_t n = 0;
if (HasFlag(FormatSpecifierFlag_LongLong)) {
n = static_cast<unsigned long long>(va_arg(vl, unsigned long long));
} else if (HasFlag(FormatSpecifierFlag_Long)) {
n = static_cast<unsigned long>(va_arg(vl, unsigned long));
} else if (HasFlag(FormatSpecifierFlag_Char)) {
n = static_cast<unsigned char>(va_arg(vl, unsigned int));
} else if (HasFlag(FormatSpecifierFlag_Short)) {
n = static_cast<unsigned short>(va_arg(vl, unsigned int));
} else {
n = static_cast<unsigned int>(va_arg(vl, unsigned int));
}
if (specifier == 'p' && n == 0) {
WriteCharacter('(');
WriteCharacter('n');
WriteCharacter('i');
WriteCharacter('l');
WriteCharacter(')');
} else {
PrintInteger(false, n);
}
} else {
intmax_t n = 0;
if (HasFlag(FormatSpecifierFlag_LongLong)) {
n = static_cast<signed long long>(va_arg(vl, signed long long));
} else if (HasFlag(FormatSpecifierFlag_Long)) {
n = static_cast<signed long>(va_arg(vl, signed long));
} else if (HasFlag(FormatSpecifierFlag_Char)) {
n = static_cast<signed char>(va_arg(vl, signed int));
} else if (HasFlag(FormatSpecifierFlag_Short)) {
n = static_cast<signed short>(va_arg(vl, signed int));
} else {
n = static_cast<signed int>(va_arg(vl, signed int));
}
const bool negative = n < 0;
const uintmax_t u = (negative) ? static_cast<uintmax_t>(-n) : static_cast<uintmax_t>(n);
PrintInteger(negative, u);
}
}
break;
case 'c':
{
size_t len = 1;
if (!HasFlag(FormatSpecifierFlag_LeftJustify)) {
while (len++ < width) {
WriteCharacter(' ');
}
}
WriteCharacter(static_cast<char>(va_arg(vl, int)));
if (HasFlag(FormatSpecifierFlag_LeftJustify)) {
while (len++ < width) {
WriteCharacter(' ');
}
}
}
break;
case 's':
{
const char *str = va_arg(vl, char *);
if (str == nullptr) {
str = "(null)";
}
size_t len = Strnlen(str, precision > 0 ? precision : std::numeric_limits<size_t>::max());
if (HasFlag(FormatSpecifierFlag_HasPrecision)) {
len = (len < precision) ? len : precision;
}
if (!HasFlag(FormatSpecifierFlag_LeftJustify)) {
while (len++ < width) {
WriteCharacter(' ');
}
}
while (*str && (!HasFlag(FormatSpecifierFlag_HasPrecision) || (precision--) != 0)) {
WriteCharacter(*(str++));
}
if (HasFlag(FormatSpecifierFlag_LeftJustify)) {
while (len++ < width) {
WriteCharacter(' ');
}
}
}
break;
case '%':
default:
WriteCharacter(specifier);
break;
}
}
/* Ensure null termination. */
WriteCharacter('\0');
dst[dst_size - 1] = '\0';
}
KSpinLock g_debug_log_lock; KSpinLock g_debug_log_lock;
bool g_initialized_impl; bool g_initialized_impl;
@@ -452,9 +75,6 @@ namespace ams::kern {
} }
#pragma GCC pop_options
void KDebugLog::Initialize() { void KDebugLog::Initialize() {
if (KTargetSystem::IsDebugLoggingEnabled()) { if (KTargetSystem::IsDebugLoggingEnabled()) {
KScopedInterruptDisable di; KScopedInterruptDisable di;
@@ -486,7 +106,7 @@ namespace ams::kern {
} }
void KDebugLog::VSNPrintf(char *dst, const size_t dst_size, const char *format, ::std::va_list vl) { void KDebugLog::VSNPrintf(char *dst, const size_t dst_size, const char *format, ::std::va_list vl) {
VSNPrintfImpl(dst, dst_size, format, vl); ::ams::util::TVSNPrintf(dst, dst_size, format, vl);
} }
Result KDebugLog::PrintUserString(ams::kern::svc::KUserPointer<const char *> user_str, size_t len) { Result KDebugLog::PrintUserString(ams::kern::svc::KUserPointer<const char *> user_str, size_t len) {

View File

@@ -1,7 +1,9 @@
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# pull in common atmosphere configuration # pull in common atmosphere configuration
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
include $(CURRENT_DIRECTORY)/../config/common.mk
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# pull in switch rules # pull in switch rules
@@ -15,7 +17,7 @@ include $(DEVKITPRO)/libnx/switch_rules
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
PRECOMPILED_HEADERS := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/include/stratosphere.hpp PRECOMPILED_HEADERS := $(CURRENT_DIRECTORY)/include/stratosphere.hpp
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_STRATOSPHERE -D_GNU_SOURCE
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 SETTINGS := $(ATMOSPHERE_SETTINGS) -O2
@@ -66,7 +68,7 @@ endif
export OFILES_BIN := $(addsuffix .o,$(BINFILES)) export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.gch),$(notdir $(hdr))) export GCH_FILES := $(PRECOMPILED_HEADERS:.hpp=.hpp.gch)
export OFILES := $(OFILES_BIN) $(OFILES_SRC) export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
@@ -103,12 +105,12 @@ dist: dist-src dist-bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
@echo clean ... @echo clean ...
@rm -fr release lib *.bz2 include/stratosphere.hpp.gch @rm -fr release lib *.bz2 $(GCH_FILES)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
else else
DEPENDS := $(OFILES:.o=.d) $(GCH_FILES:.gch=.d) DEPENDS := $(OFILES:.o=.d) $(foreach hdr,$(GCH_FILES:.hpp.gch=.d),$(notdir $(hdr)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets

View File

@@ -41,14 +41,19 @@
/* At this point, just include the rest alphabetically. */ /* At this point, just include the rest alphabetically. */
/* TODO: Figure out optimal order. */ /* TODO: Figure out optimal order. */
#include <stratosphere/boot2.hpp> #include <stratosphere/boot2.hpp>
#include <stratosphere/cal.hpp>
#include <stratosphere/capsrv.hpp> #include <stratosphere/capsrv.hpp>
#include <stratosphere/cfg.hpp> #include <stratosphere/cfg.hpp>
#include <stratosphere/clkrst.hpp>
#include <stratosphere/ddsf.hpp>
#include <stratosphere/dmnt.hpp> #include <stratosphere/dmnt.hpp>
#include <stratosphere/erpt.hpp> #include <stratosphere/erpt.hpp>
#include <stratosphere/err.hpp> #include <stratosphere/err.hpp>
#include <stratosphere/fatal.hpp> #include <stratosphere/fatal.hpp>
#include <stratosphere/gpio.hpp>
#include <stratosphere/hid.hpp> #include <stratosphere/hid.hpp>
#include <stratosphere/hos.hpp> #include <stratosphere/hos.hpp>
#include <stratosphere/i2c.hpp>
#include <stratosphere/kvdb.hpp> #include <stratosphere/kvdb.hpp>
#include <stratosphere/ldr.hpp> #include <stratosphere/ldr.hpp>
#include <stratosphere/lr.hpp> #include <stratosphere/lr.hpp>
@@ -57,10 +62,14 @@
#include <stratosphere/nim.hpp> #include <stratosphere/nim.hpp>
#include <stratosphere/ns.hpp> #include <stratosphere/ns.hpp>
#include <stratosphere/patcher.hpp> #include <stratosphere/patcher.hpp>
#include <stratosphere/pcv.hpp>
#include <stratosphere/pgl.hpp> #include <stratosphere/pgl.hpp>
#include <stratosphere/pinmux.hpp>
#include <stratosphere/powctl.hpp>
#include <stratosphere/psc.hpp> #include <stratosphere/psc.hpp>
#include <stratosphere/pm.hpp> #include <stratosphere/pm.hpp>
#include <stratosphere/reg.hpp> #include <stratosphere/pwm.hpp>
#include <stratosphere/regulator.hpp>
#include <stratosphere/ro.hpp> #include <stratosphere/ro.hpp>
#include <stratosphere/settings.hpp> #include <stratosphere/settings.hpp>
#include <stratosphere/sf.hpp> #include <stratosphere/sf.hpp>
@@ -68,6 +77,7 @@
#include <stratosphere/spl.hpp> #include <stratosphere/spl.hpp>
#include <stratosphere/time.hpp> #include <stratosphere/time.hpp>
#include <stratosphere/updater.hpp> #include <stratosphere/updater.hpp>
#include <stratosphere/wec.hpp>
/* Include FS last. */ /* Include FS last. */
#include <stratosphere/fs.hpp> #include <stratosphere/fs.hpp>

View File

@@ -39,19 +39,21 @@ namespace ams::impl {
AMS_DEFINE_SYSTEM_THREAD(21, pm, Main); AMS_DEFINE_SYSTEM_THREAD(21, pm, Main);
AMS_DEFINE_SYSTEM_THREAD(21, pm, ProcessTrack); AMS_DEFINE_SYSTEM_THREAD(21, pm, ProcessTrack);
/* NCM. */ /* NCM. */
AMS_DEFINE_SYSTEM_THREAD(21, ncm, MainWaitThreads); AMS_DEFINE_SYSTEM_THREAD(21, ncm, MainWaitThreads);
AMS_DEFINE_SYSTEM_THREAD(21, ncm, ContentManagerServerIpcSession); AMS_DEFINE_SYSTEM_THREAD(21, ncm, ContentManagerServerIpcSession);
AMS_DEFINE_SYSTEM_THREAD(21, ncm, LocationResolverServerIpcSession); AMS_DEFINE_SYSTEM_THREAD(21, ncm, LocationResolverServerIpcSession);
/* FS. */ /* FS. */
AMS_DEFINE_SYSTEM_THREAD(16, fs, WorkerThreadPool); AMS_DEFINE_SYSTEM_THREAD(11, sdmmc, DeviceDetector);
AMS_DEFINE_SYSTEM_THREAD(17, fs, Main); AMS_DEFINE_SYSTEM_THREAD(16, fs, WorkerThreadPool);
AMS_DEFINE_SYSTEM_THREAD(17, fs, WorkerRealTimeAccess); AMS_DEFINE_SYSTEM_THREAD(17, fs, Main);
AMS_DEFINE_SYSTEM_THREAD(18, fs, WorkerNormalPriorityAccess); AMS_DEFINE_SYSTEM_THREAD(17, fs, WorkerRealTimeAccess);
AMS_DEFINE_SYSTEM_THREAD(19, fs, WorkerLowPriorityAccess); AMS_DEFINE_SYSTEM_THREAD(18, fs, WorkerNormalPriorityAccess);
AMS_DEFINE_SYSTEM_THREAD(30, fs, WorkerBackgroundAccess); AMS_DEFINE_SYSTEM_THREAD(19, fs, WorkerLowPriorityAccess);
AMS_DEFINE_SYSTEM_THREAD(30, fs, PatrolReader); AMS_DEFINE_SYSTEM_THREAD(30, fs, WorkerBackgroundAccess);
AMS_DEFINE_SYSTEM_THREAD(30, fs, PatrolReader);
/* Boot. */ /* Boot. */
AMS_DEFINE_SYSTEM_THREAD(-1, boot, Main); AMS_DEFINE_SYSTEM_THREAD(-1, boot, Main);
@@ -87,9 +89,15 @@ namespace ams::impl {
/* ro. */ /* ro. */
AMS_DEFINE_SYSTEM_THREAD(16, ro, Main); AMS_DEFINE_SYSTEM_THREAD(16, ro, Main);
/* gpio. */
AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler);
/* bpc. */ /* bpc. */
AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer); AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer);
/* powctl. */
AMS_DEFINE_SYSTEM_THREAD(9, powctl, InterruptHandler);
/* hid. */ /* hid. */
AMS_DEFINE_SYSTEM_THREAD(-10, hid, IpcServer); AMS_DEFINE_SYSTEM_THREAD(-10, hid, IpcServer);

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2018-2020 Atmosphère-NX * Copyright (c) 2018-2020 Atmosphère-NX
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License * under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation. * version 2, as published by the Free Software Foundation.
* *
* This program is distributed in the hope it will be useful, but WITHOUT * This program is distributed in the hope it will be useful, but WITHOUT
@@ -13,6 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#define EVP_COP_RESET_VECTOR 0x200 #include <stratosphere/cal/cal_battery_api.hpp>

View File

@@ -0,0 +1,24 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::cal {
Result GetBatteryVersion(u8 *out);
Result GetBatteryVendor(size_t *out_vendor_size, void *dst, size_t dst_size);
}

View File

@@ -0,0 +1,21 @@
/*
* 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/>.
*/
#pragma once
#include <stratosphere/clkrst/clkrst_types.hpp>
#include <stratosphere/clkrst/clkrst_api.hpp>
#include <stratosphere/clkrst/clkrst_session_api.hpp>

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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/clkrst/clkrst_types.hpp>
namespace ams::clkrst {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,36 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/clkrst/clkrst_types.hpp>
namespace ams::clkrst {
struct ClkRstSession {
void *_session;
};
Result OpenSession(ClkRstSession *out, DeviceCode device_code);
void CloseSession(ClkRstSession *session);
void SetResetAsserted(ClkRstSession *session);
void SetResetDeasserted(ClkRstSession *session);
void SetClockRate(ClkRstSession *session, u32 hz);
void SetClockDisabled(ClkRstSession *session);
}

View 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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::clkrst {
/* ... */
}

View File

@@ -16,5 +16,7 @@
#pragma once #pragma once
#include "dd/dd_io_mappings.hpp" #include <stratosphere/dd/dd_types.hpp>
#include "dd/dd_process_handle.hpp" #include <stratosphere/dd/dd_device_address_space.hpp>
#include <stratosphere/dd/dd_io_mappings.hpp>
#include <stratosphere/dd/dd_process_handle.hpp>

View File

@@ -0,0 +1,21 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/dd/dd_device_address_space_common.hpp>
#include <stratosphere/dd/dd_device_address_space_types.hpp>
#include <stratosphere/dd/dd_device_address_space_api.hpp>

View File

@@ -0,0 +1,48 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/dd/dd_types.hpp>
#include <stratosphere/dd/dd_device_address_space_common.hpp>
#include <stratosphere/dd/dd_device_address_space_types.hpp>
namespace ams::dd {
Result CreateDeviceAddressSpace(DeviceAddressSpaceType *das, u64 address, u64 size);
Result CreateDeviceAddressSpace(DeviceAddressSpaceType *das, u64 size);
void DestroyDeviceAddressSpace(DeviceAddressSpaceType *das);
void AttachDeviceAddressSpaceHandle(DeviceAddressSpaceType *das, Handle handle, bool managed);
Handle GetDeviceAddressSpaceHandle(DeviceAddressSpaceType *das);
Result MapDeviceAddressSpaceAligned(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
Result MapDeviceAddressSpaceNotAligned(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
void UnmapDeviceAddressSpace(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address);
void InitializeDeviceAddressSpaceMapInfo(DeviceAddressSpaceMapInfo *info, DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
Result MapNextDeviceAddressSpaceRegion(size_t *out_mapped_size, DeviceAddressSpaceMapInfo *info);
void UnmapDeviceAddressSpaceRegion(DeviceAddressSpaceMapInfo *info);
u64 GetMappedProcessAddress(DeviceAddressSpaceMapInfo *info);
DeviceVirtualAddress GetMappedDeviceVirtualAddress(DeviceAddressSpaceMapInfo *info);
size_t GetMappedSize(DeviceAddressSpaceMapInfo *info);
Result AttachDeviceAddressSpace(DeviceAddressSpaceType *das, DeviceName device_name);
void DetachDeviceAddressSpace(DeviceAddressSpaceType *das, DeviceName device_name);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
using DeviceName = ::ams::svc::DeviceName;
constexpr inline u64 DeviceAddressSpaceMemoryRegionAlignment = 4_KB;
}

View File

@@ -0,0 +1,49 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
using DeviceVirtualAddress = u64;
using DeviceAddressSpaceHandle = ::Handle;
struct DeviceAddressSpaceType {
enum State {
State_NotInitialized = 0,
State_Initialized = 1,
};
DeviceAddressSpaceHandle device_handle;
u8 state;
bool is_handle_managed;
};
static_assert(std::is_trivial<DeviceAddressSpaceType>::value);
struct DeviceAddressSpaceMapInfo {
size_t last_mapped_size;
size_t size;
u64 process_address;
DeviceVirtualAddress device_start_address;
DeviceVirtualAddress device_end_address;
ProcessHandle process_handle;
MemoryPermission device_permission;
DeviceAddressSpaceType *device_address_space;
};
static_assert(std::is_trivial<DeviceAddressSpaceMapInfo>::value);
}

View File

@@ -19,16 +19,9 @@
namespace ams::dd { namespace ams::dd {
uintptr_t QueryIoMapping(uintptr_t phys_addr, size_t size);
u32 ReadRegister(uintptr_t phys_addr);
void WriteRegister(uintptr_t phys_addr, u32 value);
u32 ReadWriteRegister(uintptr_t phys_addr, u32 value, u32 mask);
/* Convenience Helper. */ /* Convenience Helper. */
inline uintptr_t GetIoMapping(dd::PhysicalAddress phys_addr, size_t size) {
inline uintptr_t GetIoMapping(uintptr_t phys_addr, size_t size) { const uintptr_t io_mapping = dd::QueryIoMapping(phys_addr, size);
const uintptr_t io_mapping = QueryIoMapping(phys_addr, size);
AMS_ABORT_UNLESS(io_mapping); AMS_ABORT_UNLESS(io_mapping);
return io_mapping; return io_mapping;
} }

View File

@@ -13,12 +13,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include <vapours.hpp> #include <vapours.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd { namespace ams::dd {
::Handle GetCurrentProcessHandle(); ProcessHandle GetCurrentProcessHandle();
} }

View File

@@ -0,0 +1,33 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
using ProcessHandle = ::Handle;
enum MemoryPermission {
MemoryPermission_None = 0,
MemoryPermission_ReadOnly = (1u << 0),
MemoryPermission_WriteOnly = (1u << 1),
MemoryPermission_ReadWrite = MemoryPermission_ReadOnly | MemoryPermission_WriteOnly,
};
}

View File

@@ -0,0 +1,27 @@
/*
* 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/>.
*/
#pragma once
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
#include <stratosphere/ddsf/ddsf_i_session.hpp>
#include <stratosphere/ddsf/ddsf_i_device.hpp>
#include <stratosphere/ddsf/ddsf_i_driver.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry_manager.hpp>
#include <stratosphere/ddsf/ddsf_i_event_handler.hpp>
#include <stratosphere/ddsf/ddsf_event_handler_manager.hpp>
#include <stratosphere/ddsf/ddsf_memory_api.hpp>

View File

@@ -0,0 +1,110 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ddsf {
class IDevice;
class DeviceCodeEntry {
NON_COPYABLE(DeviceCodeEntry);
NON_MOVEABLE(DeviceCodeEntry);
private:
ams::DeviceCode device_code = ams::InvalidDeviceCode;
IDevice *device = nullptr;
public:
constexpr DeviceCodeEntry(ams::DeviceCode dc, IDevice *dev) : device_code(dc), device(dev) {
AMS_ASSERT(dev != nullptr);
}
constexpr ams::DeviceCode GetDeviceCode() const {
return this->device_code;
}
constexpr IDevice &GetDevice() {
return *this->device;
}
constexpr const IDevice &GetDevice() const {
return *this->device;
}
};
class DeviceCodeEntryHolder {
NON_COPYABLE(DeviceCodeEntryHolder);
NON_MOVEABLE(DeviceCodeEntryHolder);
private:
util::IntrusiveListNode list_node;
TYPED_STORAGE(DeviceCodeEntry) entry_storage;
bool is_constructed;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<DeviceCodeEntryHolder, util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::list_node>>;
public:
DeviceCodeEntryHolder() : list_node(), entry_storage(), is_constructed(false) {
/* ... */
}
~DeviceCodeEntryHolder() {
if (this->IsConstructed()) {
this->Destroy();
}
}
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
DeviceCodeEntry &Construct(DeviceCode dc, IDevice *dev) {
AMS_ASSERT(!this->IsConstructed());
DeviceCodeEntry *entry = new (GetPointer(this->entry_storage)) DeviceCodeEntry(dc, dev);
this->is_constructed = true;
return *entry;
}
bool IsConstructed() const {
return this->is_constructed;
}
void Destroy() {
AMS_ASSERT(this->IsConstructed());
GetReference(this->entry_storage).~DeviceCodeEntry();
this->is_constructed = false;
}
DeviceCodeEntry &Get() {
AMS_ASSERT(this->IsConstructed());
return GetReference(this->entry_storage);
}
const DeviceCodeEntry &Get() const {
AMS_ASSERT(this->IsConstructed());
return GetReference(this->entry_storage);
}
};
static_assert(DeviceCodeEntryHolder::ListTraits::IsValid());
}

View File

@@ -0,0 +1,84 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
namespace ams::ddsf {
class IDevice;
class DeviceCodeEntryManager {
private:
ams::MemoryResource *memory_resource;
ddsf::DeviceCodeEntryHolder::List entry_list;
mutable os::SdkMutex entry_list_lock;
private:
void DestroyAllEntries() {
auto it = this->entry_list.begin();
while (it != this->entry_list.end()) {
ddsf::DeviceCodeEntryHolder *entry = std::addressof(*it);
it = this->entry_list.erase(it);
AMS_ASSERT(entry->IsConstructed());
if (entry->IsConstructed()) {
entry->Destroy();
}
this->memory_resource->Deallocate(entry, sizeof(*entry));
}
}
public:
DeviceCodeEntryManager(ams::MemoryResource *mr) : memory_resource(mr), entry_list(), entry_list_lock() { /* ... */ }
~DeviceCodeEntryManager() {
this->DestroyAllEntries();
}
void Reset() {
std::scoped_lock lk(this->entry_list_lock);
this->DestroyAllEntries();
}
Result Add(DeviceCode device_code, IDevice *device);
bool Remove(DeviceCode device_code);
Result FindDeviceCodeEntry(DeviceCodeEntry **out, DeviceCode device_code);
Result FindDeviceCodeEntry(const DeviceCodeEntry **out, DeviceCode device_code) const;
Result FindDevice(IDevice **out, DeviceCode device_code);
Result FindDevice(const IDevice **out, DeviceCode device_code) const;
template<typename F>
int ForEachEntry(F f) {
return impl::ForEach(this->entry_list_lock, this->entry_list, [&](DeviceCodeEntryHolder &holder) -> bool {
AMS_ASSERT(holder.IsConstructed());
return f(holder.Get());
});
}
template<typename F>
int ForEachEntry(F f) const {
return impl::ForEach(this->entry_list_lock, this->entry_list, [&](const DeviceCodeEntryHolder &holder) -> bool {
AMS_ASSERT(holder.IsConstructed());
return f(holder.Get());
});
}
};
}

View File

@@ -0,0 +1,80 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/os.hpp>
#include <stratosphere/ddsf/ddsf_i_event_handler.hpp>
namespace ams::ddsf {
class EventHandlerManager;
class EventHandlerManager {
NON_COPYABLE(EventHandlerManager);
NON_MOVEABLE(EventHandlerManager);
private:
struct LoopControlCommandParameters;
private:
bool is_initialized;
bool is_looping;
os::SdkConditionVariable is_looping_cv;
os::WaitableManagerType waitable_manager;
os::ThreadType *loop_thread;
os::Event loop_control_event;
os::WaitableHolderType loop_control_event_holder;
LoopControlCommandParameters *loop_control_command_params;
os::Event loop_control_command_done_event; /* TODO: os::LightEvent, requires mesosphere for < 4.0.0 compat. */
os::SdkMutex loop_control_lock;
private:
void ProcessControlCommand(LoopControlCommandParameters *params);
void ProcessControlCommandImpl(LoopControlCommandParameters *params);
public:
EventHandlerManager()
: is_initialized(false), is_looping(false), is_looping_cv(), waitable_manager(),
loop_thread(), loop_control_event(os::EventClearMode_AutoClear), loop_control_event_holder(),
loop_control_command_params(), loop_control_command_done_event(os::EventClearMode_AutoClear),
loop_control_lock()
{
this->Initialize();
}
~EventHandlerManager() {
if (this->is_looping) {
AMS_ASSERT(!this->IsRunningOnLoopThread());
this->RequestStop();
}
if (this->is_initialized) {
this->Finalize();
}
}
bool IsRunningOnLoopThread() const { return this->loop_thread == os::GetCurrentThread(); }
bool IsLooping() const { return this->is_looping; }
void Initialize();
void Finalize();
void RegisterHandler(IEventHandler *handler);
void UnregisterHandler(IEventHandler *handler);
void WaitLoopEnter();
void WaitLoopExit();
void RequestStop();
void LoopAuto();
};
}

View File

@@ -0,0 +1,88 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_type_tag.hpp>
namespace ams::ddsf {
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING)
#define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \
static_assert(std::convertible_to<__CLASS__ *, __BASE__ *>); \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__, __BASE__::s_ams_ddsf_castable_type_tag}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#else
#define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \
static_assert(std::convertible_to<__CLASS__ *, __BASE__ *>); \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{__BASE__::s_ams_ddsf_castable_type_tag}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#endif
class ICastable {
private:
constexpr virtual const impl::TypeTag &GetTypeTag() const = 0;
template<typename T>
constexpr ALWAYS_INLINE void AssertCastableTo() const {
AMS_ASSERT(this->IsCastableTo<T>());
}
public:
template<typename T>
constexpr bool IsCastableTo() const {
return this->GetTypeTag().DerivesFrom(T::s_ams_ddsf_castable_type_tag);
}
template<typename T>
constexpr T &SafeCastTo() {
this->AssertCastableTo<T>();
return static_cast<T &>(*this);
}
template<typename T>
constexpr const T &SafeCastTo() const {
this->AssertCastableTo<T>();
return static_cast<const T &>(*this);
}
template<typename T>
constexpr T *SafeCastToPointer() {
this->AssertCastableTo<T>();
return static_cast<T *>(this);
}
template<typename T>
constexpr const T *SafeCastToPointer() const {
this->AssertCastableTo<T>();
return static_cast<const T *>(this);
}
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
constexpr const char *GetClassName() const {
return this->GetTypeTag().GetClassName();
}
#endif
};
}

View File

@@ -0,0 +1,140 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
#include <stratosphere/ddsf/ddsf_i_session.hpp>
namespace ams::ddsf {
class IDriver;
class IDevice : public ICastable {
friend Result OpenSession(IDevice *device, ISession *session, AccessMode mode);
friend void CloseSession(ISession *session);
friend class IDriver;
public:
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDevice);
private:
util::IntrusiveListNode list_node;
IDriver *driver;
ISession::List session_list;
mutable os::SdkMutex session_list_lock;
bool is_exclusive_write;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<IDevice, util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::list_node>>;
private:
Result AttachSession(ISession *session) {
AMS_ASSERT(session != nullptr);
std::scoped_lock lk(this->session_list_lock);
/* Check if we're allowed to attach the session. */
if (this->is_exclusive_write && session->CheckExclusiveWrite()) {
for (const auto &attached : this->session_list) {
R_UNLESS(!attached.CheckAccess(AccessMode_Write), ddsf::ResultAccessModeDenied());
}
}
/* Attach the session. */
this->session_list.push_back(*session);
return ResultSuccess();
}
void DetachSession(ISession *session) {
AMS_ASSERT(session != nullptr);
std::scoped_lock lk(this->session_list_lock);
this->session_list.erase(this->session_list.iterator_to(*session));
}
void AttachDriver(IDriver *drv) {
AMS_ASSERT(drv != nullptr);
AMS_ASSERT(!this->IsDriverAttached());
this->driver = drv;
AMS_ASSERT(this->IsDriverAttached());
}
void DetachDriver() {
AMS_ASSERT(this->IsDriverAttached());
this->driver = nullptr;
AMS_ASSERT(!this->IsDriverAttached());
}
public:
IDevice(bool exclusive_write) : list_node(), driver(nullptr), session_list(), session_list_lock(), is_exclusive_write(exclusive_write) {
this->session_list.clear();
}
protected:
~IDevice() {
this->session_list.clear();
}
public:
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
IDriver &GetDriver() {
AMS_ASSERT(this->IsDriverAttached());
return *this->driver;
}
const IDriver &GetDriver() const {
AMS_ASSERT(this->IsDriverAttached());
return *this->driver;
}
bool IsDriverAttached() const {
return this->driver != nullptr;
}
template<typename F>
Result ForEachSession(F f, bool return_on_fail) {
return impl::ForEach(this->session_list_lock, this->session_list, f, return_on_fail);
}
template<typename F>
Result ForEachSession(F f, bool return_on_fail) const {
return impl::ForEach(this->session_list_lock, this->session_list, f, return_on_fail);
}
template<typename F>
int ForEachSession(F f) {
return impl::ForEach(this->session_list_lock, this->session_list, f);
}
template<typename F>
int ForEachSession(F f) const {
return impl::ForEach(this->session_list_lock, this->session_list, f);
}
bool HasAnyOpenSession() const {
return !this->session_list.empty();
}
};
static_assert(IDevice::ListTraits::IsValid());
}

View File

@@ -0,0 +1,99 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
#include <stratosphere/ddsf/ddsf_i_device.hpp>
namespace ams::ddsf {
class IDriver : public ICastable {
public:
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDriver);
private:
util::IntrusiveListNode list_node;
IDevice::List device_list;
mutable os::SdkMutex device_list_lock;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<IDriver, util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::list_node>>;
private:
public:
IDriver() : list_node(), device_list(), device_list_lock() {
this->device_list.clear();
}
protected:
~IDriver() {
this->device_list.clear();
}
public:
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
bool HasAnyDevice() const {
return !this->device_list.empty();
}
void RegisterDevice(IDevice *dev) {
AMS_ASSERT(dev != nullptr);
std::scoped_lock lk(this->device_list_lock);
dev->AttachDriver(this);
this->device_list.push_back(*dev);
}
void UnregisterDevice(IDevice *dev) {
AMS_ASSERT(dev != nullptr);
std::scoped_lock lk(this->device_list_lock);
this->device_list.erase(this->device_list.iterator_to(*dev));
dev->DetachDriver();
}
template<typename F>
Result ForEachDevice(F f, bool return_on_fail) {
return impl::ForEach(this->device_list_lock, this->device_list, f, return_on_fail);
}
template<typename F>
Result ForEachDevice(F f, bool return_on_fail) const {
return impl::ForEach(this->device_list_lock, this->device_list, f, return_on_fail);
}
template<typename F>
int ForEachDevice(F f) {
return impl::ForEach(this->device_list_lock, this->device_list, f);
}
template<typename F>
int ForEachDevice(F f) const {
return impl::ForEach(this->device_list_lock, this->device_list, f);
}
};
static_assert(IDriver::ListTraits::IsValid());
}

View File

@@ -0,0 +1,92 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/os.hpp>
namespace ams::ddsf {
class EventHandlerManager;
class IEventHandler {
NON_COPYABLE(IEventHandler);
NON_MOVEABLE(IEventHandler);
friend class EventHandlerManager;
private:
os::WaitableHolderType holder;
uintptr_t user_data;
bool is_initialized;
bool is_registered;
private:
void Link(os::WaitableManagerType *manager) {
AMS_ASSERT(this->IsInitialized());
AMS_ASSERT(!this->IsRegistered());
AMS_ASSERT(manager != nullptr);
os::LinkWaitableHolder(manager, std::addressof(this->holder));
}
void Unlink() {
AMS_ASSERT(this->IsInitialized());
AMS_ASSERT(this->IsRegistered());
os::UnlinkWaitableHolder(std::addressof(this->holder));
}
static IEventHandler &ToEventHandler(os::WaitableHolderType *holder) {
AMS_ASSERT(holder != nullptr);
auto &event_handler = *reinterpret_cast<IEventHandler *>(os::GetWaitableHolderUserData(holder));
AMS_ASSERT(event_handler.IsInitialized());
return event_handler;
}
public:
IEventHandler() : holder(), user_data(0), is_initialized(false), is_registered(false) { /* ... */ }
~IEventHandler() {
if (this->IsRegistered()) {
this->Unlink();
}
if (this->IsInitialized()) {
this->Finalize();
}
}
bool IsInitialized() const { return this->is_initialized; }
bool IsRegistered() const { return this->is_registered; }
uintptr_t GetUserData() const { return this->user_data; }
void SetUserData(uintptr_t d) { this->user_data = d; }
template<typename T>
void Initialize(T *object) {
AMS_ASSERT(object != nullptr);
AMS_ASSERT(!this->IsInitialized());
os::InitializeWaitableHolder(std::addressof(this->holder), object);
os::SetWaitableHolderUserData(std::addressof(this->holder), reinterpret_cast<uintptr_t>(this));
this->is_initialized = true;
this->is_registered = false;
}
void Finalize() {
AMS_ASSERT(this->IsInitialized());
AMS_ASSERT(!this->IsRegistered());
os::FinalizeWaitableHolder(std::addressof(this->holder));
this->is_initialized = false;
this->is_registered = false;
}
protected:
virtual void HandleEvent() = 0;
};
}

View File

@@ -0,0 +1,100 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
namespace ams::ddsf {
class ISession;
class IDevice;
Result OpenSession(IDevice *device, ISession *session, AccessMode access_mode);
void CloseSession(ISession *session);
class ISession : public ICastable {
friend Result OpenSession(IDevice *device, ISession *session, AccessMode mode);
friend void CloseSession(ISession *session);
public:
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDevice);
private:
util::IntrusiveListNode list_node;
IDevice *device;
AccessMode access_mode;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&ISession::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<ISession, util::IntrusiveListMemberTraitsDeferredAssert<&ISession::list_node>>;
private:
void AttachDevice(IDevice *dev, AccessMode mode) {
AMS_ASSERT(dev != nullptr);
AMS_ASSERT(!this->IsOpen());
this->device = dev;
this->access_mode = mode;
AMS_ASSERT(this->IsOpen());
}
void DetachDevice() {
AMS_ASSERT(this->IsOpen());
this->device = nullptr;
this->access_mode = AccessMode_None;
AMS_ASSERT(!this->IsOpen());
}
public:
ISession() : list_node(), device(nullptr), access_mode() { /* ... */ }
protected:
~ISession() { this->DetachDevice(); AMS_ASSERT(!this->IsOpen()); }
public:
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
IDevice &GetDevice() {
AMS_ASSERT(this->IsOpen());
return *this->device;
}
const IDevice &GetDevice() const {
AMS_ASSERT(this->IsOpen());
return *this->device;
}
bool IsOpen() const {
return this->device != nullptr;
}
bool CheckAccess(AccessMode mode) const {
AMS_ASSERT(this->IsOpen());
return ((~this->access_mode) & mode) == 0;
}
bool CheckExclusiveWrite() const {
return this->CheckAccess(AccessMode_Write) && !this->CheckAccess(AccessMode_Shared);
}
};
static_assert(ISession::ListTraits::IsValid());
}

View File

@@ -0,0 +1,31 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
namespace ams::ddsf {
void SetMemoryResource(ams::MemoryResource *mr);
ams::MemoryResource *GetMemoryResource();
static constexpr size_t DeviceCodeEntryHolderSize = sizeof(DeviceCodeEntryHolder);
void SetDeviceCodeEntryHolderMemoryResource(ams::MemoryResource *mr);
ams::MemoryResource *GetDeviceCodeEntryHolderMemoryResource();
}

View File

@@ -0,0 +1,33 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ddsf {
enum AccessMode {
AccessMode_None = (0u << 0),
AccessMode_Read = (1u << 0),
AccessMode_Write = (1u << 1),
AccessMode_Shared = (1u << 2),
AccessMode_ReadWrite = AccessMode_Read | AccessMode_Write,
AccessMode_WriteShared = AccessMode_Write | AccessMode_Shared,
AccessMode_ReadWriteShared = AccessMode_Read | AccessMode_WriteShared,
};
}

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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ddsf::impl {
template<typename Lock, typename List, typename F>
inline Result ForEach(Lock &lock, List &list, F f, bool return_on_fail) {
std::scoped_lock lk(lock);
Result result = ResultSuccess();
for (auto && it : list) {
if (const auto cur_result = f(std::addressof(it)); R_FAILED(cur_result)) {
if (return_on_fail) {
return cur_result;
} else if (R_SUCCEEDED(result)) {
result = cur_result;
}
}
}
return result;
}
template<typename List, typename F, typename Lock>
inline int ForEach(Lock &lock, List &list, F f) {
std::scoped_lock lk(lock);
int success_count = 0;
for (auto && it : list) {
if (!f(it)) {
return success_count;
}
++success_count;
}
return success_count;
}
}

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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
namespace ams::ddsf::impl {
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING)
#define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#else
#define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#endif
class TypeTag {
private:
const char * const class_name;
const TypeTag * const base;
public:
#if !(defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING))
constexpr TypeTag() : class_name(nullptr), base(nullptr) { /* ... */}
constexpr TypeTag(const TypeTag &b) : class_name(nullptr), base(std::addressof(b)) { AMS_ASSERT(this != this->base); }
constexpr TypeTag(const char *c) : class_name(nullptr), base(nullptr) { AMS_UNUSED(c); }
constexpr TypeTag(const char *c, const TypeTag &b) : class_name(nullptr), base(std::addressof(b)) { AMS_UNUSED(c); AMS_ASSERT(this != this->base); }
#else
constexpr TypeTag(const char *c) : class_name(c), base(nullptr) { /* ... */ }
constexpr TypeTag(const char *c, const TypeTag &b) : class_name(c), base(std::addressof(b)) { AMS_ASSERT(this != this->base); }
#endif
constexpr const char * GetClassName() const { return this->class_name; }
constexpr bool Is(const TypeTag &rhs) const { return this == std::addressof(rhs); }
constexpr bool DerivesFrom(const TypeTag &rhs) const {
const TypeTag * cur = this;
while (cur != nullptr) {
if (cur == std::addressof(rhs)) {
return true;
}
cur = cur->base;
}
return false;
}
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
#include <stratosphere/gpio/gpio_api.hpp>
#include <stratosphere/gpio/gpio_pad_api.hpp>
#include <stratosphere/gpio/driver/gpio_select_driver_api.hpp>
#include <stratosphere/gpio/driver/gpio_pad_accessor.hpp>
#include <stratosphere/gpio/driver/impl/gpio_pad_session_impl.hpp>
#include <stratosphere/gpio/server/gpio_server_api.hpp>

View File

@@ -0,0 +1,28 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
namespace ams::gpio::driver::board::nintendo_nx {
void Initialize(bool enable_interrupt_handlers);
void SetInitialGpioConfig();
void SetInitialWakePinConfig();
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
namespace ams::gpio::driver {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,35 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
namespace ams::gpio::driver {
void RegisterDriver(IGpioDriver *driver);
void UnregisterDriver(IGpioDriver *driver);
Result RegisterDeviceCode(DeviceCode device_code, Pad *pad);
bool UnregisterDeviceCode(DeviceCode device_code);
void RegisterInterruptHandler(ddsf::IEventHandler *handler);
void UnregisterInterruptHandler(ddsf::IEventHandler *handler);
void SetInitialGpioConfig();
void SetInitialWakePinConfig();
}

View File

@@ -0,0 +1,75 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::gpio::driver {
class Pad;
class IGpioDriver : public ::ams::ddsf::IDriver {
NON_COPYABLE(IGpioDriver);
NON_MOVEABLE(IGpioDriver);
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::IGpioDriver, ::ams::ddsf::IDriver);
public:
IGpioDriver() : IDriver() { /* ... */ }
virtual ~IGpioDriver() { /* ... */ }
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
virtual Result InitializePad(Pad *pad) = 0;
virtual void FinalizePad(Pad *pad) = 0;
virtual Result GetDirection(Direction *out, Pad *pad) const = 0;
virtual Result SetDirection(Pad *pad, Direction direction) = 0;
virtual Result GetValue(GpioValue *out, Pad *pad) const = 0;
virtual Result SetValue(Pad *pad, GpioValue value) = 0;
virtual Result GetInterruptMode(InterruptMode *out, Pad *pad) const = 0;
virtual Result SetInterruptMode(Pad *pad, InterruptMode mode) = 0;
virtual Result SetInterruptEnabled(Pad *pad, bool en) = 0;
virtual Result GetInterruptStatus(InterruptStatus *out, Pad *pad) = 0;
virtual Result ClearInterruptStatus(Pad *pad) = 0;
virtual os::SdkMutex &GetInterruptControlMutex(const Pad &pad) const = 0;
virtual Result GetDebounceEnabled(bool *out, Pad *pad) const = 0;
virtual Result SetDebounceEnabled(Pad *pad, bool en) = 0;
virtual Result GetDebounceTime(s32 *out_ms, Pad *pad) const = 0;
virtual Result SetDebounceTime(Pad *pad, s32 ms) = 0;
virtual Result GetUnknown22(u32 *out) = 0;
virtual void Unknown23();
virtual Result SetValueForSleepState(Pad *pad, GpioValue value) = 0;
virtual Result IsWakeEventActive(bool *out, Pad *pad) const = 0;
virtual Result SetWakeEventActiveFlagSetForDebug(Pad *pad, bool en) = 0;
virtual Result SetWakePinDebugMode(WakePinDebugMode mode) = 0;
virtual Result Suspend() = 0;
virtual Result SuspendLow() = 0;
virtual Result Resume() = 0;
virtual Result ResumeLow() = 0;
};
}

View 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::gpio::driver {
class Pad : public ::ams::ddsf::IDevice {
NON_COPYABLE(Pad);
NON_MOVEABLE(Pad);
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::Pad, ::ams::ddsf::IDevice);
private:
int pad_number;
bool is_interrupt_enabled;
public:
explicit Pad(int pad) : IDevice(true), pad_number(pad), is_interrupt_enabled(false) { /* ... */ }
Pad() : Pad(0) { /* ... */ }
virtual ~Pad() { /* ... */ }
int GetPadNumber() const {
return this->pad_number;
}
void SetPadNumber(int p) {
this->pad_number = p;
}
bool IsInterruptEnabled() const {
return this->is_interrupt_enabled;
}
void SetInterruptEnabled(bool en) {
this->is_interrupt_enabled = en;
}
bool IsInterruptRequiredForDriver() const {
return this->IsInterruptEnabled() && this->IsAnySessionBoundToInterrupt();
}
bool IsAnySessionBoundToInterrupt() const;
void SignalInterruptBoundEvent();
};
}

View File

@@ -0,0 +1,45 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
namespace ams::gpio::driver {
namespace impl {
constexpr inline size_t GpioPadSessionSize = 0x60;
constexpr inline size_t GpioPadSessionAlign = 8;
struct alignas(GpioPadSessionAlign) GpioPadSessionImplPadded;
}
struct GpioPadSession {
util::TypedStorage<impl::GpioPadSessionImplPadded, impl::GpioPadSessionSize, impl::GpioPadSessionAlign> _impl;
};
Result OpenSession(GpioPadSession *out, DeviceCode device_code, ddsf::AccessMode access_mode);
void CloseSession(GpioPadSession *session);
Result SetDirection(GpioPadSession *session, gpio::Direction direction);
Result GetDirection(gpio::Direction *out, GpioPadSession *session);
Result SetValue(GpioPadSession *session, gpio::GpioValue value);
Result GetValue(gpio::GpioValue *out, GpioPadSession *session);
/* TODO */
}

View File

@@ -0,0 +1,38 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
#include <stratosphere/gpio/driver/gpio_driver_service_api.hpp>
#include <stratosphere/gpio/driver/gpio_driver_client_api.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp>
namespace ams::gpio::driver::board {
using namespace ams::gpio::driver::board::nintendo_nx;
}
#else
#error "Unknown board for ams::gpio::driver::"
#endif

View File

@@ -0,0 +1,49 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/os.hpp>
namespace ams::gpio::driver::impl {
class EventHolder {
NON_COPYABLE(EventHolder);
NON_MOVEABLE(EventHolder);
private:
os::SystemEventType *event;
public:
constexpr EventHolder() : event(nullptr) { /* ... */ }
void AttachEvent(os::SystemEventType *event) {
this->event = event;
}
os::SystemEventType *DetachEvent() {
auto ev = this->event;
this->event = nullptr;
return ev;
}
os::SystemEventType *GetSystemEvent() {
return this->event;
}
bool IsBound() const {
return this->event != nullptr;
}
};
}

View File

@@ -0,0 +1,90 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_pad_accessor.hpp>
#include <stratosphere/gpio/driver/impl/gpio_event_holder.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::gpio::driver {
class Pad;
}
namespace ams::gpio::driver::impl {
class PadSessionImpl : public ::ams::ddsf::ISession {
NON_COPYABLE(PadSessionImpl);
NON_MOVEABLE(PadSessionImpl);
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::impl::PadSessionImpl, ::ams::ddsf::ISession);
private:
EventHolder event_holder;
private:
Result UpdateDriverInterruptEnabled();
public:
PadSessionImpl() : event_holder() { /* ... */ }
~PadSessionImpl() {
this->Close();
}
bool IsInterruptBound() const {
return this->event_holder.IsBound();
}
Result Open(Pad *pad, ddsf::AccessMode access_mode);
void Close();
Result BindInterrupt(os::SystemEventType *event);
void UnbindInterrupt();
Result GetInterruptEnabled(bool *out) const;
Result SetInterruptEnabled(bool en);
void SignalInterruptBoundEvent();
};
static_assert( sizeof(PadSessionImpl) <= GpioPadSessionSize);
static_assert(alignof(PadSessionImpl) <= GpioPadSessionAlign);
struct alignas(GpioPadSessionAlign) GpioPadSessionImplPadded {
PadSessionImpl _impl;
u8 _padding[GpioPadSessionSize - sizeof(PadSessionImpl)];
};
static_assert( sizeof(GpioPadSessionImplPadded) == GpioPadSessionSize);
static_assert(alignof(GpioPadSessionImplPadded) == GpioPadSessionAlign);
ALWAYS_INLINE PadSessionImpl &GetPadSessionImpl(GpioPadSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE const PadSessionImpl &GetPadSessionImpl(const GpioPadSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE PadSessionImpl &GetOpenPadSessionImpl(GpioPadSession &session) {
auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
ALWAYS_INLINE const PadSessionImpl &GetOpenPadSessionImpl(const GpioPadSession &session) {
const auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
}

View File

@@ -13,16 +13,16 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include <switch.h> #include <vapours.hpp>
#include <stratosphere.hpp> #include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
namespace ams::gpio { namespace ams::gpio {
/* GPIO Utilities. */ void Initialize();
u32 Configure(u32 gpio_pad_name); void Finalize();
u32 SetDirection(u32 gpio_pad_name, GpioDirection dir);
u32 SetValue(u32 gpio_pad_name, GpioValue val); void InitializeWith(std::shared_ptr<gpio::sf::IManager> &&sp);
} }

View 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/gpio_select_pad_name.hpp>
#include <stratosphere/gpio/driver/gpio_pad.hpp>
namespace ams::gpio {
struct GpioPadSession {
void *_session;
os::SystemEventType *_event;
};
Result OpenSession(GpioPadSession *out_session, ams::DeviceCode device_code);
void CloseSession(GpioPadSession *session);
Direction GetDirection(GpioPadSession *session);
void SetDirection(GpioPadSession *session, Direction direction);
GpioValue GetValue(GpioPadSession *session);
void SetValue(GpioPadSession *session, GpioValue value);
InterruptMode GetInterruptMode(GpioPadSession *session);
void SetInterruptMode(GpioPadSession *session, InterruptMode mode);
bool GetInterruptEnable(GpioPadSession *session);
void SetInterruptEnable(GpioPadSession *session, bool en);
InterruptStatus GetInterruptStatus(GpioPadSession *session);
void ClearInterruptStatus(GpioPadSession *session);
int GetDebounceTime(GpioPadSession *session);
void SetDebounceTime(GpioPadSession *session, int ms);
bool GetDebounceEnabled(GpioPadSession *session);
void SetDebounceEnabled(GpioPadSession *session, bool en);
Result BindInterrupt(os::SystemEventType *event, GpioPadSession *session);
void UnbindInterrupt(GpioPadSession *session);
Result IsWakeEventActive(bool *out_is_active, ams::DeviceCode device_code);
}

View File

@@ -0,0 +1,416 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
namespace ams::gpio {
enum GpioPadName : u32 {
GpioPadName_CodecLdoEnTemp = 1,
GpioPadName_PowSdEn = 2,
GpioPadName_BtRst = 3,
GpioPadName_RamCode3 = 4,
GpioPadName_GameCardReset = 5,
GpioPadName_CodecAlert = 6,
GpioPadName_PowGc = 7,
GpioPadName_DebugControllerDet = 8,
GpioPadName_BattChgStatus = 9,
GpioPadName_BattChgEnableN = 10,
GpioPadName_FanTach = 11,
GpioPadName_ExtconDetS = 12,
GpioPadName_Vdd50AEn = 13,
GpioPadName_SdevCoaxSel1 = 14,
GpioPadName_GameCardCd = 15,
GpioPadName_ProdType0 = 16,
GpioPadName_ProdType1 = 17,
GpioPadName_ProdType2 = 18,
GpioPadName_ProdType3 = 19,
GpioPadName_TempAlert = 20,
GpioPadName_CodecHpDetIrq = 21,
GpioPadName_MotionInt = 22,
GpioPadName_TpIrq = 23,
GpioPadName_ButtonSleep2 = 24,
GpioPadName_ButtonVolUp = 25,
GpioPadName_ButtonVolDn = 26,
GpioPadName_BattMgicIrq = 27,
GpioPadName_RecoveryKey = 28,
GpioPadName_PowLcdBlEn = 29,
GpioPadName_LcdReset = 30,
GpioPadName_PdVconnEn = 31,
GpioPadName_PdRstN = 32,
GpioPadName_Bq24190Irq = 33,
GpioPadName_SdevCoaxSel0 = 34,
GpioPadName_SdWp = 35,
GpioPadName_TpReset = 36,
GpioPadName_BtGpio2 = 37,
GpioPadName_BtGpio3 = 38,
GpioPadName_BtGpio4 = 39,
GpioPadName_CradleIrq = 40,
GpioPadName_PowVcpuInt = 41,
GpioPadName_Max77621GpuInt = 42,
GpioPadName_ExtconChgU = 43,
GpioPadName_ExtconChgS = 44,
GpioPadName_WifiRfDisable = 45,
GpioPadName_WifiReset = 46,
GpioPadName_ApWakeBt = 47,
GpioPadName_BtWakeAp = 48,
GpioPadName_BtGpio5 = 49,
GpioPadName_PowLcdVddPEn = 50,
GpioPadName_PowLcdVddNEn = 51,
GpioPadName_ExtconDetU = 52,
GpioPadName_RamCode2 = 53,
GpioPadName_Vdd50BEn = 54,
GpioPadName_WifiWakeHost = 55,
GpioPadName_SdCd = 56,
GpioPadName_OtgFet1ForSdev = 57,
GpioPadName_OtgFet2ForSdev = 58,
GpioPadName_ExtConWakeU = 59,
GpioPadName_ExtConWakeS = 60,
GpioPadName_PmuIrq = 61,
GpioPadName_ExtUart2Cts = 62,
GpioPadName_ExtUart3Cts = 63,
GpioPadName_5VStepDownEn = 64,
GpioPadName_UsbSwitchB2Oc = 65,
GpioPadName_5VStepDownPg = 66,
GpioPadName_UsbSwitchAEn = 67,
GpioPadName_UsbSwitchAFlag = 68,
GpioPadName_UsbSwitchB3Oc = 69,
GpioPadName_UsbSwitchB3En = 70,
GpioPadName_UsbSwitchB2En = 71,
GpioPadName_Hdmi5VEn = 72,
GpioPadName_UsbSwitchB1En = 73,
GpioPadName_HdmiPdTrEn = 74,
GpioPadName_FanEn = 75,
GpioPadName_UsbSwitchB1Oc = 76,
GpioPadName_PwmFan = 77,
GpioPadName_HdmiHpd = 78,
GpioPadName_Max77812Irq = 79,
GpioPadName_Debug0 = 80,
GpioPadName_Debug1 = 81,
GpioPadName_Debug2 = 82,
GpioPadName_Debug3 = 83,
GpioPadName_NfcIrq = 84,
GpioPadName_NfcRst = 85,
GpioPadName_McuIrq = 86,
GpioPadName_McuBoot = 87,
GpioPadName_McuRst = 88,
GpioPadName_Vdd5V3En = 89,
GpioPadName_McuPor = 90,
GpioPadName_LcdGpio1 = 91,
GpioPadName_NfcEn = 92,
};
/* TODO: Better place for this? */
constexpr inline const DeviceCode DeviceCode_CodecLdoEnTemp = 0x33000002;
constexpr inline const DeviceCode DeviceCode_PowSdEn = 0x3C000001;
constexpr inline const DeviceCode DeviceCode_BtRst = 0x37000002;
constexpr inline const DeviceCode DeviceCode_RamCode3 = 0xC9000402;
constexpr inline const DeviceCode DeviceCode_GameCardReset = 0x3C000402;
constexpr inline const DeviceCode DeviceCode_CodecAlert = 0x33000003;
constexpr inline const DeviceCode DeviceCode_PowGc = 0x3C000401;
constexpr inline const DeviceCode DeviceCode_DebugControllerDet = 0x350000CA;
constexpr inline const DeviceCode DeviceCode_BattChgStatus = 0x39000407;
constexpr inline const DeviceCode DeviceCode_BattChgEnableN = 0x39000003;
constexpr inline const DeviceCode DeviceCode_FanTach = 0x3D000002;
constexpr inline const DeviceCode DeviceCode_ExtconDetS = 0x3500040B;
constexpr inline const DeviceCode DeviceCode_Vdd50AEn = 0x39000401;
constexpr inline const DeviceCode DeviceCode_SdevCoaxSel1 = 0xCA000402;
constexpr inline const DeviceCode DeviceCode_GameCardCd = 0x3C000403;
constexpr inline const DeviceCode DeviceCode_ProdType0 = 0xC900040B;
constexpr inline const DeviceCode DeviceCode_ProdType1 = 0xC900040C;
constexpr inline const DeviceCode DeviceCode_ProdType2 = 0xC900040D;
constexpr inline const DeviceCode DeviceCode_ProdType3 = 0xC900040E;
constexpr inline const DeviceCode DeviceCode_TempAlert = 0x3E000002;
constexpr inline const DeviceCode DeviceCode_CodecHpDetIrq = 0x33000004;
constexpr inline const DeviceCode DeviceCode_MotionInt = 0x35000041;
constexpr inline const DeviceCode DeviceCode_TpIrq = 0x35000036;
constexpr inline const DeviceCode DeviceCode_ButtonSleep2 = 0x35000001;
constexpr inline const DeviceCode DeviceCode_ButtonVolUp = 0x35000002;
constexpr inline const DeviceCode DeviceCode_ButtonVolDn = 0x35000003;
constexpr inline const DeviceCode DeviceCode_BattMgicIrq = 0x39000034;
constexpr inline const DeviceCode DeviceCode_RecoveryKey = 0x35000004;
constexpr inline const DeviceCode DeviceCode_PowLcdBlEn = 0x3400003E;
constexpr inline const DeviceCode DeviceCode_LcdReset = 0x34000033;
constexpr inline const DeviceCode DeviceCode_PdVconnEn = 0x040000CC;
constexpr inline const DeviceCode DeviceCode_PdRstN = 0x040000CA;
constexpr inline const DeviceCode DeviceCode_Bq24190Irq = 0x39000002;
constexpr inline const DeviceCode DeviceCode_SdevCoaxSel0 = 0xCA000401;
constexpr inline const DeviceCode DeviceCode_SdWp = 0x3C000003;
constexpr inline const DeviceCode DeviceCode_TpReset = 0x35000035;
constexpr inline const DeviceCode DeviceCode_BtGpio2 = 0x37000401;
constexpr inline const DeviceCode DeviceCode_BtGpio3 = 0x37000402;
constexpr inline const DeviceCode DeviceCode_BtGpio4 = 0x37000403;
constexpr inline const DeviceCode DeviceCode_CradleIrq = 0x040000CB;
constexpr inline const DeviceCode DeviceCode_PowVcpuInt = 0x3E000003;
constexpr inline const DeviceCode DeviceCode_Max77621GpuInt = 0x3E000004;
constexpr inline const DeviceCode DeviceCode_ExtconChgU = 0x35000402;
constexpr inline const DeviceCode DeviceCode_ExtconChgS = 0x3500040C;
constexpr inline const DeviceCode DeviceCode_WifiRfDisable = 0x38000003;
constexpr inline const DeviceCode DeviceCode_WifiReset = 0x38000002;
constexpr inline const DeviceCode DeviceCode_ApWakeBt = 0x37000003;
constexpr inline const DeviceCode DeviceCode_BtWakeAp = 0x37000004;
constexpr inline const DeviceCode DeviceCode_BtGpio5 = 0x37000404;
constexpr inline const DeviceCode DeviceCode_PowLcdVddPEn = 0x34000034;
constexpr inline const DeviceCode DeviceCode_PowLcdVddNEn = 0x34000035;
constexpr inline const DeviceCode DeviceCode_ExtconDetU = 0x35000401;
constexpr inline const DeviceCode DeviceCode_RamCode2 = 0xC9000401;
constexpr inline const DeviceCode DeviceCode_Vdd50BEn = 0x39000402;
constexpr inline const DeviceCode DeviceCode_WifiWakeHost = 0x38000004;
constexpr inline const DeviceCode DeviceCode_SdCd = 0x3C000002;
constexpr inline const DeviceCode DeviceCode_OtgFet1ForSdev = 0x39000404;
constexpr inline const DeviceCode DeviceCode_OtgFet2ForSdev = 0x39000405;
constexpr inline const DeviceCode DeviceCode_ExtConWakeU = 0x35000403;
constexpr inline const DeviceCode DeviceCode_ExtConWakeS = 0x3500040D;
constexpr inline const DeviceCode DeviceCode_PmuIrq = 0x39000406;
constexpr inline const DeviceCode DeviceCode_ExtUart2Cts = 0x35000404;
constexpr inline const DeviceCode DeviceCode_ExtUart3Cts = 0x3500040E;
constexpr inline const DeviceCode DeviceCode_5VStepDownEn = 0x39000408;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB2Oc = 0x04000401;
constexpr inline const DeviceCode DeviceCode_5VStepDownPg = 0x39000409;
constexpr inline const DeviceCode DeviceCode_UsbSwitchAEn = 0x04000402;
constexpr inline const DeviceCode DeviceCode_UsbSwitchAFlag = 0x04000403;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB3Oc = 0x04000404;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB3En = 0x04000405;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB2En = 0x04000406;
constexpr inline const DeviceCode DeviceCode_Hdmi5VEn = 0x34000004;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB1En = 0x04000407;
constexpr inline const DeviceCode DeviceCode_HdmiPdTrEn = 0x34000005;
constexpr inline const DeviceCode DeviceCode_FanEn = 0x3D000003;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB1Oc = 0x04000408;
constexpr inline const DeviceCode DeviceCode_PwmFan = 0x3D000001;
constexpr inline const DeviceCode DeviceCode_HdmiHpd = 0x34000006;
constexpr inline const DeviceCode DeviceCode_Max77812Irq = 0x3E000003;
constexpr inline const DeviceCode DeviceCode_Debug0 = 0xCA000001;
constexpr inline const DeviceCode DeviceCode_Debug1 = 0xCA000002;
constexpr inline const DeviceCode DeviceCode_Debug2 = 0xCA000003;
constexpr inline const DeviceCode DeviceCode_Debug3 = 0xCA000004;
constexpr inline const DeviceCode DeviceCode_NfcIrq = 0x36000004;
constexpr inline const DeviceCode DeviceCode_NfcRst = 0x36000003;
constexpr inline const DeviceCode DeviceCode_McuIrq = 0x35000415;
constexpr inline const DeviceCode DeviceCode_McuBoot = 0x35000416;
constexpr inline const DeviceCode DeviceCode_McuRst = 0x35000417;
constexpr inline const DeviceCode DeviceCode_Vdd5V3En = 0x39000403;
constexpr inline const DeviceCode DeviceCode_McuPor = 0x35000418;
constexpr inline const DeviceCode DeviceCode_LcdGpio1 = 0x35000005;
constexpr inline const DeviceCode DeviceCode_NfcEn = 0x36000002;
constexpr inline const DeviceCode DeviceCode_ExtUart2Rts = 0x35000406;
constexpr inline const DeviceCode DeviceCode_ExtUart3Rts = 0x35000410;
constexpr inline const DeviceCode DeviceCode_GpioPortC7 = 0x3500041B;
constexpr inline const DeviceCode DeviceCode_GpioPortD0 = 0x3500041C;
constexpr inline const DeviceCode DeviceCode_GpioPortC5 = 0x3500041D;
constexpr inline const DeviceCode DeviceCode_GpioPortC6 = 0x3500041E;
constexpr inline const DeviceCode DeviceCode_GpioPortY7 = 0x35000065;
constexpr inline const DeviceCode DeviceCode_GpioPortF1 = 0x04000409;
constexpr inline const DeviceCode DeviceCode_GpioPortH0 = 0x34000401;
constexpr inline GpioPadName ConvertToGpioPadName(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_CodecLdoEnTemp .GetInternalValue(): return GpioPadName_CodecLdoEnTemp;
case DeviceCode_PowSdEn .GetInternalValue(): return GpioPadName_PowSdEn;
case DeviceCode_BtRst .GetInternalValue(): return GpioPadName_BtRst;
case DeviceCode_RamCode3 .GetInternalValue(): return GpioPadName_RamCode3;
case DeviceCode_GameCardReset .GetInternalValue(): return GpioPadName_GameCardReset;
case DeviceCode_CodecAlert .GetInternalValue(): return GpioPadName_CodecAlert;
case DeviceCode_PowGc .GetInternalValue(): return GpioPadName_PowGc;
case DeviceCode_DebugControllerDet.GetInternalValue(): return GpioPadName_DebugControllerDet;
case DeviceCode_BattChgStatus .GetInternalValue(): return GpioPadName_BattChgStatus;
case DeviceCode_BattChgEnableN .GetInternalValue(): return GpioPadName_BattChgEnableN;
case DeviceCode_FanTach .GetInternalValue(): return GpioPadName_FanTach;
case DeviceCode_ExtconDetS .GetInternalValue(): return GpioPadName_ExtconDetS;
case DeviceCode_Vdd50AEn .GetInternalValue(): return GpioPadName_Vdd50AEn;
case DeviceCode_SdevCoaxSel1 .GetInternalValue(): return GpioPadName_SdevCoaxSel1;
case DeviceCode_GameCardCd .GetInternalValue(): return GpioPadName_GameCardCd;
case DeviceCode_ProdType0 .GetInternalValue(): return GpioPadName_ProdType0;
case DeviceCode_ProdType1 .GetInternalValue(): return GpioPadName_ProdType1;
case DeviceCode_ProdType2 .GetInternalValue(): return GpioPadName_ProdType2;
case DeviceCode_ProdType3 .GetInternalValue(): return GpioPadName_ProdType3;
case DeviceCode_TempAlert .GetInternalValue(): return GpioPadName_TempAlert;
case DeviceCode_CodecHpDetIrq .GetInternalValue(): return GpioPadName_CodecHpDetIrq;
case DeviceCode_MotionInt .GetInternalValue(): return GpioPadName_MotionInt;
case DeviceCode_TpIrq .GetInternalValue(): return GpioPadName_TpIrq;
case DeviceCode_ButtonSleep2 .GetInternalValue(): return GpioPadName_ButtonSleep2;
case DeviceCode_ButtonVolUp .GetInternalValue(): return GpioPadName_ButtonVolUp;
case DeviceCode_ButtonVolDn .GetInternalValue(): return GpioPadName_ButtonVolDn;
case DeviceCode_BattMgicIrq .GetInternalValue(): return GpioPadName_BattMgicIrq;
case DeviceCode_RecoveryKey .GetInternalValue(): return GpioPadName_RecoveryKey;
case DeviceCode_PowLcdBlEn .GetInternalValue(): return GpioPadName_PowLcdBlEn;
case DeviceCode_LcdReset .GetInternalValue(): return GpioPadName_LcdReset;
case DeviceCode_PdVconnEn .GetInternalValue(): return GpioPadName_PdVconnEn;
case DeviceCode_PdRstN .GetInternalValue(): return GpioPadName_PdRstN;
case DeviceCode_Bq24190Irq .GetInternalValue(): return GpioPadName_Bq24190Irq;
case DeviceCode_SdevCoaxSel0 .GetInternalValue(): return GpioPadName_SdevCoaxSel0;
case DeviceCode_SdWp .GetInternalValue(): return GpioPadName_SdWp;
case DeviceCode_TpReset .GetInternalValue(): return GpioPadName_TpReset;
case DeviceCode_BtGpio2 .GetInternalValue(): return GpioPadName_BtGpio2;
case DeviceCode_BtGpio3 .GetInternalValue(): return GpioPadName_BtGpio3;
case DeviceCode_BtGpio4 .GetInternalValue(): return GpioPadName_BtGpio4;
case DeviceCode_CradleIrq .GetInternalValue(): return GpioPadName_CradleIrq;
/* case DeviceCode_PowVcpuInt .GetInternalValue(): return GpioPadName_PowVcpuInt; */
case DeviceCode_Max77621GpuInt .GetInternalValue(): return GpioPadName_Max77621GpuInt;
case DeviceCode_ExtconChgU .GetInternalValue(): return GpioPadName_ExtconChgU;
case DeviceCode_ExtconChgS .GetInternalValue(): return GpioPadName_ExtconChgS;
case DeviceCode_WifiRfDisable .GetInternalValue(): return GpioPadName_WifiRfDisable;
case DeviceCode_WifiReset .GetInternalValue(): return GpioPadName_WifiReset;
case DeviceCode_ApWakeBt .GetInternalValue(): return GpioPadName_ApWakeBt;
case DeviceCode_BtWakeAp .GetInternalValue(): return GpioPadName_BtWakeAp;
case DeviceCode_BtGpio5 .GetInternalValue(): return GpioPadName_BtGpio5;
case DeviceCode_PowLcdVddPEn .GetInternalValue(): return GpioPadName_PowLcdVddPEn;
case DeviceCode_PowLcdVddNEn .GetInternalValue(): return GpioPadName_PowLcdVddNEn;
case DeviceCode_ExtconDetU .GetInternalValue(): return GpioPadName_ExtconDetU;
case DeviceCode_RamCode2 .GetInternalValue(): return GpioPadName_RamCode2;
case DeviceCode_Vdd50BEn .GetInternalValue(): return GpioPadName_Vdd50BEn;
case DeviceCode_WifiWakeHost .GetInternalValue(): return GpioPadName_WifiWakeHost;
case DeviceCode_SdCd .GetInternalValue(): return GpioPadName_SdCd;
case DeviceCode_OtgFet1ForSdev .GetInternalValue(): return GpioPadName_OtgFet1ForSdev;
case DeviceCode_OtgFet2ForSdev .GetInternalValue(): return GpioPadName_OtgFet2ForSdev;
case DeviceCode_ExtConWakeU .GetInternalValue(): return GpioPadName_ExtConWakeU;
case DeviceCode_ExtConWakeS .GetInternalValue(): return GpioPadName_ExtConWakeS;
case DeviceCode_PmuIrq .GetInternalValue(): return GpioPadName_PmuIrq;
case DeviceCode_ExtUart2Cts .GetInternalValue(): return GpioPadName_ExtUart2Cts;
case DeviceCode_ExtUart3Cts .GetInternalValue(): return GpioPadName_ExtUart3Cts;
case DeviceCode_5VStepDownEn .GetInternalValue(): return GpioPadName_5VStepDownEn;
case DeviceCode_UsbSwitchB2Oc .GetInternalValue(): return GpioPadName_UsbSwitchB2Oc;
case DeviceCode_5VStepDownPg .GetInternalValue(): return GpioPadName_5VStepDownPg;
case DeviceCode_UsbSwitchAEn .GetInternalValue(): return GpioPadName_UsbSwitchAEn;
case DeviceCode_UsbSwitchAFlag .GetInternalValue(): return GpioPadName_UsbSwitchAFlag;
case DeviceCode_UsbSwitchB3Oc .GetInternalValue(): return GpioPadName_UsbSwitchB3Oc;
case DeviceCode_UsbSwitchB3En .GetInternalValue(): return GpioPadName_UsbSwitchB3En;
case DeviceCode_UsbSwitchB2En .GetInternalValue(): return GpioPadName_UsbSwitchB2En;
case DeviceCode_Hdmi5VEn .GetInternalValue(): return GpioPadName_Hdmi5VEn;
case DeviceCode_UsbSwitchB1En .GetInternalValue(): return GpioPadName_UsbSwitchB1En;
case DeviceCode_HdmiPdTrEn .GetInternalValue(): return GpioPadName_HdmiPdTrEn;
case DeviceCode_FanEn .GetInternalValue(): return GpioPadName_FanEn;
case DeviceCode_UsbSwitchB1Oc .GetInternalValue(): return GpioPadName_UsbSwitchB1Oc;
case DeviceCode_PwmFan .GetInternalValue(): return GpioPadName_PwmFan;
case DeviceCode_HdmiHpd .GetInternalValue(): return GpioPadName_HdmiHpd;
case DeviceCode_Max77812Irq .GetInternalValue(): return GpioPadName_Max77812Irq;
case DeviceCode_Debug0 .GetInternalValue(): return GpioPadName_Debug0;
case DeviceCode_Debug1 .GetInternalValue(): return GpioPadName_Debug1;
case DeviceCode_Debug2 .GetInternalValue(): return GpioPadName_Debug2;
case DeviceCode_Debug3 .GetInternalValue(): return GpioPadName_Debug3;
case DeviceCode_NfcIrq .GetInternalValue(): return GpioPadName_NfcIrq;
case DeviceCode_NfcRst .GetInternalValue(): return GpioPadName_NfcRst;
case DeviceCode_McuIrq .GetInternalValue(): return GpioPadName_McuIrq;
case DeviceCode_McuBoot .GetInternalValue(): return GpioPadName_McuBoot;
case DeviceCode_McuRst .GetInternalValue(): return GpioPadName_McuRst;
case DeviceCode_Vdd5V3En .GetInternalValue(): return GpioPadName_Vdd5V3En;
case DeviceCode_McuPor .GetInternalValue(): return GpioPadName_McuPor;
case DeviceCode_LcdGpio1 .GetInternalValue(): return GpioPadName_LcdGpio1;
case DeviceCode_NfcEn .GetInternalValue(): return GpioPadName_NfcEn;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr inline DeviceCode ConvertToDeviceCode(GpioPadName gpn) {
switch (gpn) {
case GpioPadName_CodecLdoEnTemp: return DeviceCode_CodecLdoEnTemp;
case GpioPadName_PowSdEn: return DeviceCode_PowSdEn;
case GpioPadName_BtRst: return DeviceCode_BtRst;
case GpioPadName_RamCode3: return DeviceCode_RamCode3;
case GpioPadName_GameCardReset: return DeviceCode_GameCardReset;
case GpioPadName_CodecAlert: return DeviceCode_CodecAlert;
case GpioPadName_PowGc: return DeviceCode_PowGc;
case GpioPadName_DebugControllerDet: return DeviceCode_DebugControllerDet;
case GpioPadName_BattChgStatus: return DeviceCode_BattChgStatus;
case GpioPadName_BattChgEnableN: return DeviceCode_BattChgEnableN;
case GpioPadName_FanTach: return DeviceCode_FanTach;
case GpioPadName_ExtconDetS: return DeviceCode_ExtconDetS;
case GpioPadName_Vdd50AEn: return DeviceCode_Vdd50AEn;
case GpioPadName_SdevCoaxSel1: return DeviceCode_SdevCoaxSel1;
case GpioPadName_GameCardCd: return DeviceCode_GameCardCd;
case GpioPadName_ProdType0: return DeviceCode_ProdType0;
case GpioPadName_ProdType1: return DeviceCode_ProdType1;
case GpioPadName_ProdType2: return DeviceCode_ProdType2;
case GpioPadName_ProdType3: return DeviceCode_ProdType3;
case GpioPadName_TempAlert: return DeviceCode_TempAlert;
case GpioPadName_CodecHpDetIrq: return DeviceCode_CodecHpDetIrq;
case GpioPadName_MotionInt: return DeviceCode_MotionInt;
case GpioPadName_TpIrq: return DeviceCode_TpIrq;
case GpioPadName_ButtonSleep2: return DeviceCode_ButtonSleep2;
case GpioPadName_ButtonVolUp: return DeviceCode_ButtonVolUp;
case GpioPadName_ButtonVolDn: return DeviceCode_ButtonVolDn;
case GpioPadName_BattMgicIrq: return DeviceCode_BattMgicIrq;
case GpioPadName_RecoveryKey: return DeviceCode_RecoveryKey;
case GpioPadName_PowLcdBlEn: return DeviceCode_PowLcdBlEn;
case GpioPadName_LcdReset: return DeviceCode_LcdReset;
case GpioPadName_PdVconnEn: return DeviceCode_PdVconnEn;
case GpioPadName_PdRstN: return DeviceCode_PdRstN;
case GpioPadName_Bq24190Irq: return DeviceCode_Bq24190Irq;
case GpioPadName_SdevCoaxSel0: return DeviceCode_SdevCoaxSel0;
case GpioPadName_SdWp: return DeviceCode_SdWp;
case GpioPadName_TpReset: return DeviceCode_TpReset;
case GpioPadName_BtGpio2: return DeviceCode_BtGpio2;
case GpioPadName_BtGpio3: return DeviceCode_BtGpio3;
case GpioPadName_BtGpio4: return DeviceCode_BtGpio4;
case GpioPadName_CradleIrq: return DeviceCode_CradleIrq;
case GpioPadName_PowVcpuInt: return DeviceCode_PowVcpuInt;
case GpioPadName_Max77621GpuInt: return DeviceCode_Max77621GpuInt;
case GpioPadName_ExtconChgU: return DeviceCode_ExtconChgU;
case GpioPadName_ExtconChgS: return DeviceCode_ExtconChgS;
case GpioPadName_WifiRfDisable: return DeviceCode_WifiRfDisable;
case GpioPadName_WifiReset: return DeviceCode_WifiReset;
case GpioPadName_ApWakeBt: return DeviceCode_ApWakeBt;
case GpioPadName_BtWakeAp: return DeviceCode_BtWakeAp;
case GpioPadName_BtGpio5: return DeviceCode_BtGpio5;
case GpioPadName_PowLcdVddPEn: return DeviceCode_PowLcdVddPEn;
case GpioPadName_PowLcdVddNEn: return DeviceCode_PowLcdVddNEn;
case GpioPadName_ExtconDetU: return DeviceCode_ExtconDetU;
case GpioPadName_RamCode2: return DeviceCode_RamCode2;
case GpioPadName_Vdd50BEn: return DeviceCode_Vdd50BEn;
case GpioPadName_WifiWakeHost: return DeviceCode_WifiWakeHost;
case GpioPadName_SdCd: return DeviceCode_SdCd;
case GpioPadName_OtgFet1ForSdev: return DeviceCode_OtgFet1ForSdev;
case GpioPadName_OtgFet2ForSdev: return DeviceCode_OtgFet2ForSdev;
case GpioPadName_ExtConWakeU: return DeviceCode_ExtConWakeU;
case GpioPadName_ExtConWakeS: return DeviceCode_ExtConWakeS;
case GpioPadName_PmuIrq: return DeviceCode_PmuIrq;
case GpioPadName_ExtUart2Cts: return DeviceCode_ExtUart2Cts;
case GpioPadName_ExtUart3Cts: return DeviceCode_ExtUart3Cts;
case GpioPadName_5VStepDownEn: return DeviceCode_5VStepDownEn;
case GpioPadName_UsbSwitchB2Oc: return DeviceCode_UsbSwitchB2Oc;
case GpioPadName_5VStepDownPg: return DeviceCode_5VStepDownPg;
case GpioPadName_UsbSwitchAEn: return DeviceCode_UsbSwitchAEn;
case GpioPadName_UsbSwitchAFlag: return DeviceCode_UsbSwitchAFlag;
case GpioPadName_UsbSwitchB3Oc: return DeviceCode_UsbSwitchB3Oc;
case GpioPadName_UsbSwitchB3En: return DeviceCode_UsbSwitchB3En;
case GpioPadName_UsbSwitchB2En: return DeviceCode_UsbSwitchB2En;
case GpioPadName_Hdmi5VEn: return DeviceCode_Hdmi5VEn;
case GpioPadName_UsbSwitchB1En: return DeviceCode_UsbSwitchB1En;
case GpioPadName_HdmiPdTrEn: return DeviceCode_HdmiPdTrEn;
case GpioPadName_FanEn: return DeviceCode_FanEn;
case GpioPadName_UsbSwitchB1Oc: return DeviceCode_UsbSwitchB1Oc;
case GpioPadName_PwmFan: return DeviceCode_PwmFan;
case GpioPadName_HdmiHpd: return DeviceCode_HdmiHpd;
case GpioPadName_Max77812Irq: return DeviceCode_Max77812Irq;
case GpioPadName_Debug0: return DeviceCode_Debug0;
case GpioPadName_Debug1: return DeviceCode_Debug1;
case GpioPadName_Debug2: return DeviceCode_Debug2;
case GpioPadName_Debug3: return DeviceCode_Debug3;
case GpioPadName_NfcIrq: return DeviceCode_NfcIrq;
case GpioPadName_NfcRst: return DeviceCode_NfcRst;
case GpioPadName_McuIrq: return DeviceCode_McuIrq;
case GpioPadName_McuBoot: return DeviceCode_McuBoot;
case GpioPadName_McuRst: return DeviceCode_McuRst;
case GpioPadName_Vdd5V3En: return DeviceCode_Vdd5V3En;
case GpioPadName_McuPor: return DeviceCode_McuPor;
case GpioPadName_LcdGpio1: return DeviceCode_LcdGpio1;
case GpioPadName_NfcEn: return DeviceCode_NfcEn;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
}

View File

@@ -0,0 +1,24 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/gpio/gpio_pad_name.board.nintendo_nx.hpp>
#else
/* Error? */
#endif

View File

@@ -0,0 +1,51 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::gpio {
enum InterruptMode : u32 {
InterruptMode_LowLevel = 0,
InterruptMode_HighLevel = 1,
InterruptMode_RisingEdge = 2,
InterruptMode_FallingEdge = 3,
InterruptMode_AnyEdge = 4,
};
enum Direction : u32 {
Direction_Input = 0,
Direction_Output = 1,
};
enum GpioValue : u32 {
GpioValue_Low = 0,
GpioValue_High = 1,
};
enum InterruptStatus : u32 {
InterruptStatus_Inactive = 0,
InterruptStatus_Active = 1,
};
enum WakePinDebugMode {
WakePinDebugMode_AutoImmediateWake = 1,
WakePinDebugMode_NoWake = 2,
};
using WakeBitFlag = util::BitFlagSet<128>;
}

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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
namespace ams::gpio::server {
std::shared_ptr<gpio::sf::IManager> GetServiceObject();
}

View File

@@ -0,0 +1,41 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/gpio_select_pad_name.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp>
namespace ams::gpio::sf {
#define AMS_GPIO_I_MANAGER_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDev, (ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, s32 pad_descriptor) ) \
AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSession, (ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) ) \
AMS_SF_METHOD_INFO(C, H, 2, Result, OpenSessionForTest, (ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) ) \
AMS_SF_METHOD_INFO(C, H, 3, Result, IsWakeEventActive, (ams::sf::Out<bool> out, gpio::GpioPadName pad_name), hos::Version_Min, hos::Version_6_2_0) \
AMS_SF_METHOD_INFO(C, H, 4, Result, GetWakeEventActiveFlagSet, (ams::sf::Out<gpio::WakeBitFlag> out), hos::Version_Min, hos::Version_6_2_0) \
AMS_SF_METHOD_INFO(C, H, 5, Result, SetWakeEventActiveFlagSetForDebug, (gpio::GpioPadName pad_name, bool is_enabled), hos::Version_Min, hos::Version_6_2_0) \
AMS_SF_METHOD_INFO(C, H, 6, Result, SetWakePinDebugMode, (s32 mode) ) \
AMS_SF_METHOD_INFO(C, H, 7, Result, OpenSession2, (ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode), hos::Version_5_0_0 ) \
AMS_SF_METHOD_INFO(C, H, 8, Result, IsWakeEventActive2, (ams::sf::Out<bool> out, DeviceCode device_code), hos::Version_5_0_0 ) \
AMS_SF_METHOD_INFO(C, H, 9, Result, SetWakeEventActiveFlagSetForDebug2, (DeviceCode device_code, bool is_enabled), hos::Version_5_0_0 ) \
AMS_SF_METHOD_INFO(C, H, 10, Result, SetRetryValues, (u32 arg0, u32 arg1), hos::Version_6_0_0 )
AMS_SF_DEFINE_INTERFACE(IManager, AMS_GPIO_I_MANAGER_INTERFACE_INFO)
}

View File

@@ -0,0 +1,45 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
namespace ams::gpio::sf {
#define AMS_GPIO_I_PAD_SESSION_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, SetDirection, (gpio::Direction direction) ) \
AMS_SF_METHOD_INFO(C, H, 1, Result, GetDirection, (ams::sf::Out<gpio::Direction> out) ) \
AMS_SF_METHOD_INFO(C, H, 2, Result, SetInterruptMode, (gpio::InterruptMode mode) ) \
AMS_SF_METHOD_INFO(C, H, 3, Result, GetInterruptMode, (ams::sf::Out<gpio::InterruptMode> out) ) \
AMS_SF_METHOD_INFO(C, H, 4, Result, SetInterruptEnable, (bool enable) ) \
AMS_SF_METHOD_INFO(C, H, 5, Result, GetInterruptEnable, (ams::sf::Out<bool> out) ) \
AMS_SF_METHOD_INFO(C, H, 6, Result, GetInterruptStatus, (ams::sf::Out<gpio::InterruptStatus> out) ) \
AMS_SF_METHOD_INFO(C, H, 7, Result, ClearInterruptStatus, () ) \
AMS_SF_METHOD_INFO(C, H, 8, Result, SetValue, (gpio::GpioValue value) ) \
AMS_SF_METHOD_INFO(C, H, 9, Result, GetValue, (ams::sf::Out<gpio::GpioValue> out) ) \
AMS_SF_METHOD_INFO(C, H, 10, Result, BindInterrupt, (ams::sf::OutCopyHandle out) ) \
AMS_SF_METHOD_INFO(C, H, 11, Result, UnbindInterrupt, () ) \
AMS_SF_METHOD_INFO(C, H, 12, Result, SetDebounceEnabled, (bool enable) ) \
AMS_SF_METHOD_INFO(C, H, 13, Result, GetDebounceEnabled, (ams::sf::Out<bool> out) ) \
AMS_SF_METHOD_INFO(C, H, 14, Result, SetDebounceTime, (s32 ms) ) \
AMS_SF_METHOD_INFO(C, H, 15, Result, GetDebounceTime, (ams::sf::Out<s32> out) ) \
AMS_SF_METHOD_INFO(C, H, 16, Result, SetValueForSleepState, (gpio::GpioValue value), hos::Version_4_0_0) \
AMS_SF_METHOD_INFO(C, H, 16, Result, GetValueForSleepState, (ams::sf::Out<gpio::GpioValue> out), hos::Version_6_0_0)
AMS_SF_DEFINE_INTERFACE(IPadSession, AMS_GPIO_I_PAD_SESSION_INTERFACE_INFO)
}

View File

@@ -0,0 +1,31 @@
/*
* 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/>.
*/
#pragma once
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/i2c_select_device_name.hpp>
#include <stratosphere/i2c/i2c_command_list_formatter.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_session.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_manager.hpp>
#include <stratosphere/i2c/server/i2c_server_api.hpp>
#include <stratosphere/i2c/driver/i2c_select_driver_api.hpp>
#include <stratosphere/i2c/driver/i2c_driver_service_api.hpp>
#include <stratosphere/i2c/driver/i2c_driver_client_api.hpp>
#include <stratosphere/i2c/driver/i2c_bus_api.hpp>
#include <stratosphere/i2c/driver/impl/i2c_i2c_session_impl.hpp>
#include <stratosphere/i2c/i2c_api.hpp>
#include <stratosphere/i2c/i2c_bus_api.hpp>
#include <stratosphere/i2c/i2c_register_accessor.hpp>

View File

@@ -0,0 +1,24 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::driver::board::nintendo_nx {
void Initialize();
}

View File

@@ -0,0 +1,45 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::driver {
namespace impl {
constexpr inline size_t I2cSessionSize = 0x60;
constexpr inline size_t I2cSessionAlign = 8;
struct alignas(I2cSessionAlign) I2cSessionImplPadded;
}
struct I2cSession {
util::TypedStorage<impl::I2cSessionImplPadded, impl::I2cSessionSize, impl::I2cSessionAlign> _impl;
};
Result OpenSession(I2cSession *out, DeviceCode device_code);
void CloseSession(I2cSession &session);
Result Send(I2cSession &session, const void *src, size_t src_size, TransactionOption option);
Result Receive(void *dst, size_t dst_size, I2cSession &session, TransactionOption option);
Result ExecuteCommandList(void *dst, size_t dst_size, I2cSession &session, const void *src, size_t src_size);
Result SetRetryPolicy(I2cSession &session, int max_retry_count, int retry_interval_us);
}

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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::driver {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,30 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/driver/i2c_i2c_device_property.hpp>
#include <stratosphere/i2c/driver/i2c_i_i2c_driver.hpp>
namespace ams::i2c::driver {
void RegisterDriver(II2cDriver *driver);
void UnregisterDriver(II2cDriver *driver);
Result RegisterDeviceCode(DeviceCode device_code, I2cDeviceProperty *device);
bool UnregisterDeviceCode(DeviceCode device_code);
}

View File

@@ -0,0 +1,50 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::i2c::driver {
class I2cDeviceProperty : public ::ams::ddsf::IDevice {
NON_COPYABLE(I2cDeviceProperty);
NON_MOVEABLE(I2cDeviceProperty);
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::I2cDeviceProperty, ::ams::ddsf::IDevice);
private:
u16 address;
AddressingMode addressing_mode;
util::IntrusiveListNode device_property_list_node;
public:
using DevicePropertyListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cDeviceProperty::device_property_list_node>;
using DevicePropertyList = typename DevicePropertyListTraits::ListType;
friend class util::IntrusiveList<I2cDeviceProperty, util::IntrusiveListMemberTraitsDeferredAssert<&I2cDeviceProperty::device_property_list_node>>;
public:
I2cDeviceProperty() : IDevice(false), address(0), addressing_mode(AddressingMode_SevenBit), device_property_list_node() { /* ... */ }
I2cDeviceProperty(u16 addr, AddressingMode m) : IDevice(false), address(addr), addressing_mode(m), device_property_list_node() { /* ... */ }
virtual ~I2cDeviceProperty() { /* ... */ }
u16 GetAddress() const {
return this->address;
}
AddressingMode GetAddressingMode() const {
return this->addressing_mode;
}
};
}

View File

@@ -0,0 +1,53 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::i2c::driver {
class I2cDeviceProperty;
class II2cDriver : public ::ams::ddsf::IDriver {
NON_COPYABLE(II2cDriver);
NON_MOVEABLE(II2cDriver);
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::II2cDriver, ::ams::ddsf::IDriver);
public:
II2cDriver() : IDriver() { /* ... */ }
virtual ~II2cDriver() { /* ... */ }
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
virtual Result InitializeDevice(I2cDeviceProperty *device) = 0;
virtual void FinalizeDevice(I2cDeviceProperty *device) = 0;
virtual Result Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) = 0;
virtual Result Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) = 0;
virtual os::SdkMutex &GetTransactionOrderMutex() = 0;
virtual void SuspendBus() = 0;
virtual void SuspendPowerBus() = 0;
virtual void ResumeBus() = 0;
virtual void ResumePowerBus() = 0;
virtual const DeviceCode &GetDeviceCode() const = 0;
};
}

View File

@@ -0,0 +1,37 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/driver/i2c_i_i2c_driver.hpp>
#include <stratosphere/i2c/driver/i2c_i2c_device_property.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/i2c/driver/board/nintendo_nx/i2c_driver_api.hpp>
namespace ams::i2c::driver::board {
using namespace ams::i2c::driver::board::nintendo_nx;
}
#else
#error "Unknown board for ams::i2c::driver::"
#endif

View File

@@ -0,0 +1,93 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/driver/i2c_bus_api.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::i2c::driver {
class I2cDeviceProperty;
}
namespace ams::i2c::driver::impl {
class I2cSessionImpl : public ::ams::ddsf::ISession {
NON_COPYABLE(I2cSessionImpl);
NON_MOVEABLE(I2cSessionImpl);
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::impl::I2cSessionImpl, ::ams::ddsf::ISession);
private:
enum class Command {
Send = 0,
Receive = 1,
};
private:
TimeSpan retry_interval;
int max_retry_count;
private:
Result SendHandler(const u8 **cur_cmd, u8 **cur_dst);
Result ReceiveHandler(const u8 **cur_cmd, u8 **cur_dst);
Result ExtensionHandler(const u8 **cur_cmd, u8 **cur_dst);
Result ExecuteTransactionWithRetry(void *dst, Command command, const void *src, size_t size, TransactionOption option);
public:
I2cSessionImpl(int mr, TimeSpan rt) : retry_interval(rt), max_retry_count(mr) { /* ... */ }
~I2cSessionImpl() {
this->Close();
}
Result Open(I2cDeviceProperty *device, ddsf::AccessMode access_mode);
void Close();
Result Send(const void *src, size_t src_size, TransactionOption option);
Result Receive(void *dst, size_t dst_size, TransactionOption option);
Result ExecuteCommandList(void *dst, size_t dst_size, const void *src, size_t src_size);
Result SetRetryPolicy(int mr, int interval_us);
};
static_assert( sizeof(I2cSessionImpl) <= I2cSessionSize);
static_assert(alignof(I2cSessionImpl) <= I2cSessionAlign);
struct alignas(I2cSessionAlign) I2cSessionImplPadded {
I2cSessionImpl _impl;
u8 _padding[I2cSessionSize - sizeof(I2cSessionImpl)];
};
static_assert( sizeof(I2cSessionImplPadded) == I2cSessionSize);
static_assert(alignof(I2cSessionImplPadded) == I2cSessionAlign);
ALWAYS_INLINE I2cSessionImpl &GetI2cSessionImpl(I2cSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE const I2cSessionImpl &GetI2cSessionImpl(const I2cSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE I2cSessionImpl &GetOpenI2cSessionImpl(I2cSession &session) {
auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
ALWAYS_INLINE const I2cSessionImpl &GetOpenI2cSessionImpl(const I2cSession &session) {
const auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_manager.hpp>
namespace ams::i2c {
void InitializeWith(std::shared_ptr<i2c::sf::IManager> &&sp, std::shared_ptr<i2c::sf::IManager> &&sp_pcv);
void InitializeEmpty();
void Finalize();
}

View File

@@ -0,0 +1,36 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c {
struct I2cSession {
void *_session;
};
Result OpenSession(I2cSession *out, DeviceCode device_code);
void CloseSession(I2cSession &session);
Result Send(const I2cSession &session, const void *src, size_t src_size, TransactionOption option);
Result Receive(void *dst, size_t dst_size, const I2cSession &session, TransactionOption option);
Result ExecuteCommandList(void *dst, size_t dst_size, const I2cSession &session, const void *src, size_t src_size);
void SetRetryPolicy(const I2cSession &session, int max_retry_count, int retry_interval_us);
}

View File

@@ -0,0 +1,51 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c {
constexpr inline size_t CommandListLengthMax = 0x100;
constexpr inline size_t CommandListReceiveCommandSize = 2;
constexpr inline size_t CommandListSendCommandSize = 2;
constexpr inline size_t CommandListSleepCommandSize = 2;
class CommandListFormatter {
NON_COPYABLE(CommandListFormatter);
NON_MOVEABLE(CommandListFormatter);
private:
size_t current_index;
size_t command_list_length;
void *command_list;
private:
Result IsEnqueueAble(size_t sz) const;
public:
CommandListFormatter(void *p, size_t sz) : current_index(0), command_list_length(sz), command_list(p) {
AMS_ABORT_UNLESS(this->command_list_length <= CommandListLengthMax);
}
~CommandListFormatter() { this->command_list = nullptr; }
size_t GetCurrentLength() const { return this->current_index; }
const void *GetListHead() const { return this->command_list; }
Result EnqueueReceiveCommand(i2c::TransactionOption option, size_t size);
Result EnqueueSendCommand(i2c::TransactionOption option, const void *src, size_t size);
Result EnqueueSleepCommand(int us);
};
}

View File

@@ -0,0 +1,250 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c {
enum I2cBus {
I2cBus_I2c1 = 0,
I2cBus_I2c2 = 1,
I2cBus_I2c3 = 2,
I2cBus_I2c4 = 3,
I2cBus_I2c5 = 4,
I2cBus_I2c6 = 5,
};
constexpr inline const DeviceCode DeviceCode_I2c1 = 0x02000001;
constexpr inline const DeviceCode DeviceCode_I2c2 = 0x02000002;
constexpr inline const DeviceCode DeviceCode_I2c3 = 0x02000003;
constexpr inline const DeviceCode DeviceCode_I2c4 = 0x02000004;
constexpr inline const DeviceCode DeviceCode_I2c5 = 0x02000005;
constexpr inline const DeviceCode DeviceCode_I2c6 = 0x02000006;
constexpr inline DeviceCode ConvertToDeviceCode(I2cBus bus) {
switch (bus) {
case I2cBus_I2c1: return DeviceCode_I2c1;
case I2cBus_I2c2: return DeviceCode_I2c2;
case I2cBus_I2c3: return DeviceCode_I2c3;
case I2cBus_I2c4: return DeviceCode_I2c4;
case I2cBus_I2c5: return DeviceCode_I2c5;
case I2cBus_I2c6: return DeviceCode_I2c6;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr inline DeviceCode ConvertToI2cBus(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_I2c1.GetInternalValue(): return I2cBus_I2c1;
case DeviceCode_I2c2.GetInternalValue(): return I2cBus_I2c2;
case DeviceCode_I2c3.GetInternalValue(): return I2cBus_I2c3;
case DeviceCode_I2c4.GetInternalValue(): return I2cBus_I2c4;
case DeviceCode_I2c5.GetInternalValue(): return I2cBus_I2c5;
case DeviceCode_I2c6.GetInternalValue(): return I2cBus_I2c6;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
enum I2cDevice : u32 {
I2cDevice_ClassicController = 0,
I2cDevice_Ftm3bd56 = 1,
I2cDevice_Tmp451 = 2,
I2cDevice_Nct72 = 3,
I2cDevice_Alc5639 = 4,
I2cDevice_Max77620Rtc = 5,
I2cDevice_Max77620Pmic = 6,
I2cDevice_Max77621Cpu = 7,
I2cDevice_Max77621Gpu = 8,
I2cDevice_Bq24193 = 9,
I2cDevice_Max17050 = 10,
I2cDevice_Bm92t30mwv = 11,
I2cDevice_Ina226Vdd15v0Hb = 12,
I2cDevice_Ina226VsysCpuDs = 13,
I2cDevice_Ina226VddCpuAp = 13,
I2cDevice_Ina226VsysGpuDs = 14,
I2cDevice_Ina226VddGpuAp = 14,
I2cDevice_Ina226VsysDdrDs = 15,
I2cDevice_Ina226VddDdr1V1Pmic = 15,
I2cDevice_Ina226VsysAp = 16,
I2cDevice_Ina226VsysBlDs = 17,
I2cDevice_Bh1730 = 18,
I2cDevice_Ina226VsysCore = 19,
I2cDevice_Ina226VddCoreAp = 19,
I2cDevice_Ina226Soc1V8 = 20,
I2cDevice_Ina226VddSoc1V8 = 20,
I2cDevice_Ina226Lpddr1V8 = 21,
I2cDevice_Ina226Vdd1V8 = 21,
I2cDevice_Ina226Reg1V32 = 22,
I2cDevice_Ina226Vdd3V3Sys = 23,
I2cDevice_HdmiDdc = 24,
I2cDevice_HdmiScdc = 25,
I2cDevice_HdmiHdcp = 26,
I2cDevice_Fan53528 = 27,
I2cDevice_Max77812_3 = 28,
I2cDevice_Max77812_2 = 29,
I2cDevice_Ina226VddDdr0V6 = 30,
I2cDevice_HoagNfcIc = 31, /* TODO */
};
/* TODO: Better place for this? */
constexpr inline const DeviceCode DeviceCode_ClassicController = 0x350000C9;
constexpr inline const DeviceCode DeviceCode_Ftm3bd56 = 0x35000033;
constexpr inline const DeviceCode DeviceCode_Tmp451 = 0x3E000001;
constexpr inline const DeviceCode DeviceCode_Nct72 = 0x3E000001;
constexpr inline const DeviceCode DeviceCode_Alc5639 = 0x33000001;
constexpr inline const DeviceCode DeviceCode_Max77620Rtc = 0x3B000001;
constexpr inline const DeviceCode DeviceCode_Max77620Pmic = 0x3A000001;
constexpr inline const DeviceCode DeviceCode_Max77621Cpu = 0x3A000003;
constexpr inline const DeviceCode DeviceCode_Max77621Gpu = 0x3A000004;
constexpr inline const DeviceCode DeviceCode_Bq24193 = 0x39000001;
constexpr inline const DeviceCode DeviceCode_Max17050 = 0x39000033;
constexpr inline const DeviceCode DeviceCode_Bm92t30mwv = 0x040000C9;
constexpr inline const DeviceCode DeviceCode_Ina226Vdd15v0Hb = 0x3F000401;
constexpr inline const DeviceCode DeviceCode_Ina226VsysCpuDs = 0x3F000001;
constexpr inline const DeviceCode DeviceCode_Ina226VddCpuAp = 0x3F000001;
constexpr inline const DeviceCode DeviceCode_Ina226VsysGpuDs = 0x3F000002;
constexpr inline const DeviceCode DeviceCode_Ina226VddGpuAp = 0x3F000002;
constexpr inline const DeviceCode DeviceCode_Ina226VsysDdrDs = 0x3F000003;
constexpr inline const DeviceCode DeviceCode_Ina226VddDdr1V1Pmi = 0x3F000003;
constexpr inline const DeviceCode DeviceCode_Ina226VsysAp = 0x3F000402;
constexpr inline const DeviceCode DeviceCode_Ina226VsysBlDs = 0x3F000403;
constexpr inline const DeviceCode DeviceCode_Bh1730 = 0x35000047;
constexpr inline const DeviceCode DeviceCode_Ina226VsysCore = 0x3F000404;
constexpr inline const DeviceCode DeviceCode_Ina226VddCoreAp = 0x3F000404;
constexpr inline const DeviceCode DeviceCode_Ina226Soc1V8 = 0x3F000405;
constexpr inline const DeviceCode DeviceCode_Ina226VddSoc1V8 = 0x3F000405;
constexpr inline const DeviceCode DeviceCode_Ina226Lpddr1V8 = 0x3F000406;
constexpr inline const DeviceCode DeviceCode_Ina226Vdd1V8 = 0x3F000406;
constexpr inline const DeviceCode DeviceCode_Ina226Reg1V32 = 0x3F000407;
constexpr inline const DeviceCode DeviceCode_Ina226Vdd3V3Sys = 0x3F000408;
constexpr inline const DeviceCode DeviceCode_HdmiDdc = 0x34000001;
constexpr inline const DeviceCode DeviceCode_HdmiScdc = 0x34000002;
constexpr inline const DeviceCode DeviceCode_HdmiHdcp = 0x34000003;
constexpr inline const DeviceCode DeviceCode_Fan53528 = 0x3A000005;
constexpr inline const DeviceCode DeviceCode_Max77812_3 = 0x3A000002;
constexpr inline const DeviceCode DeviceCode_Max77812_2 = 0x3A000006;
constexpr inline const DeviceCode DeviceCode_Ina226VddDdr0V6 = 0x3F000409;
constexpr inline const DeviceCode DeviceCode_HoagNfcIc = 0x36000001;
constexpr inline DeviceCode ConvertToDeviceCode(I2cDevice dv) {
switch (dv) {
case I2cDevice_ClassicController: return DeviceCode_ClassicController;
case I2cDevice_Ftm3bd56: return DeviceCode_Ftm3bd56;
case I2cDevice_Tmp451: return DeviceCode_Tmp451;
case I2cDevice_Nct72: return DeviceCode_Nct72;
case I2cDevice_Alc5639: return DeviceCode_Alc5639;
case I2cDevice_Max77620Rtc: return DeviceCode_Max77620Rtc;
case I2cDevice_Max77620Pmic: return DeviceCode_Max77620Pmic;
case I2cDevice_Max77621Cpu: return DeviceCode_Max77621Cpu;
case I2cDevice_Max77621Gpu: return DeviceCode_Max77621Gpu;
case I2cDevice_Bq24193: return DeviceCode_Bq24193;
case I2cDevice_Max17050: return DeviceCode_Max17050;
case I2cDevice_Bm92t30mwv: return DeviceCode_Bm92t30mwv;
case I2cDevice_Ina226Vdd15v0Hb: return DeviceCode_Ina226Vdd15v0Hb;
case I2cDevice_Ina226VsysCpuDs: return DeviceCode_Ina226VsysCpuDs;
case I2cDevice_Ina226VsysGpuDs: return DeviceCode_Ina226VsysGpuDs;
case I2cDevice_Ina226VsysDdrDs: return DeviceCode_Ina226VsysDdrDs;
case I2cDevice_Ina226VsysAp: return DeviceCode_Ina226VsysAp;
case I2cDevice_Ina226VsysBlDs: return DeviceCode_Ina226VsysBlDs;
case I2cDevice_Bh1730: return DeviceCode_Bh1730;
case I2cDevice_Ina226VsysCore: return DeviceCode_Ina226VsysCore;
case I2cDevice_Ina226Soc1V8: return DeviceCode_Ina226Soc1V8;
case I2cDevice_Ina226Lpddr1V8: return DeviceCode_Ina226Lpddr1V8;
case I2cDevice_Ina226Reg1V32: return DeviceCode_Ina226Reg1V32;
case I2cDevice_Ina226Vdd3V3Sys: return DeviceCode_Ina226Vdd3V3Sys;
case I2cDevice_HdmiDdc: return DeviceCode_HdmiDdc;
case I2cDevice_HdmiScdc: return DeviceCode_HdmiScdc;
case I2cDevice_HdmiHdcp: return DeviceCode_HdmiHdcp;
case I2cDevice_Fan53528: return DeviceCode_Fan53528;
case I2cDevice_Max77812_3: return DeviceCode_Max77812_3;
case I2cDevice_Max77812_2: return DeviceCode_Max77812_2;
case I2cDevice_Ina226VddDdr0V6: return DeviceCode_Ina226VddDdr0V6;
case I2cDevice_HoagNfcIc: return DeviceCode_HoagNfcIc;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr inline I2cDevice ConvertToI2cDevice(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_ClassicController.GetInternalValue(): return I2cDevice_ClassicController;
case DeviceCode_Ftm3bd56 .GetInternalValue(): return I2cDevice_Ftm3bd56;
case DeviceCode_Tmp451 .GetInternalValue(): return I2cDevice_Tmp451;
/* case DeviceCode_Nct72 .GetInternalValue(): return I2cDevice_Nct72; */
case DeviceCode_Alc5639 .GetInternalValue(): return I2cDevice_Alc5639;
case DeviceCode_Max77620Rtc .GetInternalValue(): return I2cDevice_Max77620Rtc;
case DeviceCode_Max77620Pmic .GetInternalValue(): return I2cDevice_Max77620Pmic;
case DeviceCode_Max77621Cpu .GetInternalValue(): return I2cDevice_Max77621Cpu;
case DeviceCode_Max77621Gpu .GetInternalValue(): return I2cDevice_Max77621Gpu;
case DeviceCode_Bq24193 .GetInternalValue(): return I2cDevice_Bq24193;
case DeviceCode_Max17050 .GetInternalValue(): return I2cDevice_Max17050;
case DeviceCode_Bm92t30mwv .GetInternalValue(): return I2cDevice_Bm92t30mwv;
case DeviceCode_Ina226Vdd15v0Hb .GetInternalValue(): return I2cDevice_Ina226Vdd15v0Hb;
case DeviceCode_Ina226VsysCpuDs .GetInternalValue(): return I2cDevice_Ina226VsysCpuDs;
case DeviceCode_Ina226VsysGpuDs .GetInternalValue(): return I2cDevice_Ina226VsysGpuDs;
case DeviceCode_Ina226VsysDdrDs .GetInternalValue(): return I2cDevice_Ina226VsysDdrDs;
case DeviceCode_Ina226VsysAp .GetInternalValue(): return I2cDevice_Ina226VsysAp;
case DeviceCode_Ina226VsysBlDs .GetInternalValue(): return I2cDevice_Ina226VsysBlDs;
case DeviceCode_Bh1730 .GetInternalValue(): return I2cDevice_Bh1730;
case DeviceCode_Ina226VsysCore .GetInternalValue(): return I2cDevice_Ina226VsysCore;
case DeviceCode_Ina226Soc1V8 .GetInternalValue(): return I2cDevice_Ina226Soc1V8;
case DeviceCode_Ina226Lpddr1V8 .GetInternalValue(): return I2cDevice_Ina226Lpddr1V8;
case DeviceCode_Ina226Reg1V32 .GetInternalValue(): return I2cDevice_Ina226Reg1V32;
case DeviceCode_Ina226Vdd3V3Sys .GetInternalValue(): return I2cDevice_Ina226Vdd3V3Sys;
case DeviceCode_HdmiDdc .GetInternalValue(): return I2cDevice_HdmiDdc;
case DeviceCode_HdmiScdc .GetInternalValue(): return I2cDevice_HdmiScdc;
case DeviceCode_HdmiHdcp .GetInternalValue(): return I2cDevice_HdmiHdcp;
case DeviceCode_Fan53528 .GetInternalValue(): return I2cDevice_Fan53528;
case DeviceCode_Max77812_3 .GetInternalValue(): return I2cDevice_Max77812_3;
case DeviceCode_Max77812_2 .GetInternalValue(): return I2cDevice_Max77812_2;
case DeviceCode_Ina226VddDdr0V6 .GetInternalValue(): return I2cDevice_Ina226VddDdr0V6;
case DeviceCode_HoagNfcIc .GetInternalValue(): return I2cDevice_HoagNfcIc;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr bool IsPowerBusDeviceCode(DeviceCode device_code) {
switch (device_code.GetInternalValue()) {
case DeviceCode_Max77620Pmic.GetInternalValue():
case DeviceCode_Max77812_3 .GetInternalValue():
case DeviceCode_Max77621Cpu .GetInternalValue():
case DeviceCode_Max77621Gpu .GetInternalValue():
case DeviceCode_Fan53528 .GetInternalValue():
case DeviceCode_Max77812_2 .GetInternalValue():
case DeviceCode_Max77620Rtc .GetInternalValue():
return true;
default:
return false;
}
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/i2c_command_list_formatter.hpp>
#include <stratosphere/i2c/i2c_bus_api.hpp>
namespace ams::i2c {
template<typename RegType> requires std::unsigned_integral<RegType>
Result ReadSingleRegister(const I2cSession &session, u8 address, RegType *out) {
/* Check pre-conditions. */
AMS_ABORT_UNLESS(out != nullptr);
constexpr i2c::TransactionOption StartOption = i2c::TransactionOption_StartCondition;
constexpr i2c::TransactionOption StopOption = static_cast<i2c::TransactionOption>(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition);
u8 cmd_list[CommandListLengthMax];
i2c::CommandListFormatter formatter(cmd_list, sizeof(cmd_list));
R_TRY(formatter.EnqueueSendCommand(StartOption, std::addressof(address), sizeof(address)));
R_TRY(formatter.EnqueueReceiveCommand(StopOption, sizeof(*out)));
R_TRY(i2c::ExecuteCommandList(out, sizeof(*out), session, cmd_list, formatter.GetCurrentLength()));
return ResultSuccess();
}
template<typename RegType> requires std::unsigned_integral<RegType>
Result WriteSingleRegister(const I2cSession &session, u8 address, RegType value) {
/* Prepare buffer. */
u8 buf[sizeof(address) + sizeof(value)];
std::memcpy(buf + 0, std::addressof(address), sizeof(address));
std::memcpy(buf + sizeof(address), std::addressof(value), sizeof(value));
constexpr i2c::TransactionOption StopOption = static_cast<i2c::TransactionOption>(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition);
R_TRY(i2c::Send(session, buf, sizeof(buf), StopOption));
return ResultSuccess();
}
}

View File

@@ -0,0 +1,24 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/i2c/i2c_device_name.board.nintendo_nx.hpp>
#else
/* Error? */
#endif

View File

@@ -0,0 +1,40 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::i2c {
enum TransactionOption : u32 {
TransactionOption_StartCondition = (1u << 0),
TransactionOption_StopCondition = (1u << 1),
TransactionOption_MaxBits = (1u << 30),
};
enum AddressingMode : u32 {
AddressingMode_SevenBit = 0,
};
enum SpeedMode : u32 {
SpeedMode_Standard = 100000,
SpeedMode_Fast = 400000,
SpeedMode_FastPlus = 1000000,
SpeedMode_HighSpeed = 3400000,
};
using I2cCommand = u8;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_manager.hpp>
namespace ams::i2c::server {
std::shared_ptr<i2c::sf::IManager> GetServiceObject();
std::shared_ptr<i2c::sf::IManager> GetServiceObjectPowerBus();
}

View File

@@ -0,0 +1,34 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/i2c/i2c_select_device_name.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_session.hpp>
namespace ams::i2c::sf {
#define AMS_I2C_I_MANAGER_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDev, (ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode) ) \
AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSession, (ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, i2c::I2cDevice device) ) \
AMS_SF_METHOD_INFO(C, H, 2, Result, HasDevice, (ams::sf::Out<bool> out, i2c::I2cDevice device), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 3, Result, HasDeviceForDev, (ams::sf::Out<bool> out, i2c::I2cDevice device), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 4, Result, OpenSession2, (ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, DeviceCode device_code), hos::Version_6_0_0 )
AMS_SF_DEFINE_INTERFACE(IManager, AMS_I2C_I_MANAGER_INTERFACE_INFO)
}

View File

@@ -0,0 +1,34 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::sf {
#define AMS_I2C_I_SESSION_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, SendOld, (const ams::sf::InBuffer &in_data, i2c::TransactionOption option), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 1, Result, ReceiveOld, (const ams::sf::OutBuffer &out_data, i2c::TransactionOption option), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 2, Result, ExecuteCommandListOld, (const ams::sf::OutBuffer &rcv_buf, const ams::sf::InPointerArray<i2c::I2cCommand> &command_list), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, Send, (const ams::sf::InAutoSelectBuffer &in_data, i2c::TransactionOption option) ) \
AMS_SF_METHOD_INFO(C, H, 11, Result, Receive, (const ams::sf::OutAutoSelectBuffer &out_data, i2c::TransactionOption option) ) \
AMS_SF_METHOD_INFO(C, H, 12, Result, ExecuteCommandList, (const ams::sf::OutAutoSelectBuffer &rcv_buf, const ams::sf::InPointerArray<i2c::I2cCommand> &command_list) ) \
AMS_SF_METHOD_INFO(C, H, 13, Result, SetRetryPolicy, (s32 max_retry_count, s32 retry_interval_us), hos::Version_6_0_0 )
AMS_SF_DEFINE_INTERFACE(ISession, AMS_I2C_I_SESSION_INTERFACE_INFO)
}

View File

@@ -28,6 +28,7 @@
#include <stratosphere/os/os_mutex.hpp> #include <stratosphere/os/os_mutex.hpp>
#include <stratosphere/os/os_condition_variable.hpp> #include <stratosphere/os/os_condition_variable.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp> #include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/os/os_sdk_condition_variable.hpp>
#include <stratosphere/os/os_rw_lock.hpp> #include <stratosphere/os/os_rw_lock.hpp>
#include <stratosphere/os/os_transfer_memory.hpp> #include <stratosphere/os/os_transfer_memory.hpp>
#include <stratosphere/os/os_semaphore.hpp> #include <stratosphere/os/os_semaphore.hpp>

View File

@@ -0,0 +1,74 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/os/impl/os_internal_condition_variable.hpp>
namespace ams::os {
struct SdkConditionVariableType {
union {
s32 _arr[sizeof(impl::InternalConditionVariableStorage) / sizeof(s32)];
impl::InternalConditionVariableStorage _storage;
};
void Initialize() {
GetReference(this->_storage).Initialize();
}
void Wait(SdkMutexType &mutex);
bool TimedWait(SdkMutexType &mutex, TimeSpan timeout);
/* TODO: SdkRecursiveMutexType */
void Signal() {
GetReference(this->_storage).Signal();
}
void Broadcast() {
GetReference(this->_storage).Broadcast();
}
};
static_assert(std::is_trivial<SdkConditionVariableType>::value);
class SdkConditionVariable {
private:
SdkConditionVariableType cv;
public:
constexpr SdkConditionVariable() : cv{{0}} { /* ... */ }
void Wait(SdkMutex &m) {
return this->cv.Wait(m.mutex);
}
bool TimedWait(SdkMutex &m, TimeSpan timeout) {
return this->cv.TimedWait(m.mutex, timeout);
}
/* TODO: SdkRecursiveMutexType */
void Signal() {
return this->cv.Signal();
}
void Broadcast() {
return this->cv.Broadcast();
}
};
}

View File

@@ -0,0 +1,20 @@
/*
* 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/>.
*/
#pragma once
#include <stratosphere/pcv/pcv_types.hpp>
#include <stratosphere/pcv/pcv_api.hpp>

View File

@@ -0,0 +1,30 @@
/*
* 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/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/pcv/pcv_types.hpp>
namespace ams::pcv {
void Initialize();
void Finalize();
Result SetClockEnabled(Module module, bool en);
Result SetClockRate(Module module, ClockHz hz);
Result SetReset(Module module, bool en);
}

Some files were not shown because too many files have changed in this diff Show More