exo2: implement SmcIramCopy/reboot to payload/rcm

This commit is contained in:
Michael Scire 2020-06-08 09:02:50 -07:00 committed by SciresM
parent bb6671a94a
commit 6c145d76c7
31 changed files with 868 additions and 47 deletions

View file

@ -35,6 +35,7 @@
#include <exosphere/uart.hpp>
#include <exosphere/pinmux.hpp>
#include <exosphere/pmic.hpp>
#include <exosphere/rtc.hpp>
#include <exosphere/log.hpp>
#include <exosphere/clkrst.hpp>
#include <exosphere/actmon.hpp>

View file

@ -43,11 +43,13 @@ namespace ams::hw::arch::arm64 {
}
ALWAYS_INLINE void InvalidateTlb(uintptr_t address) {
__asm__ __volatile__("tlbi vae3is, %[address]" :: [address]"r"(address) : "memory");
const uintptr_t page_index = address / 4_KB;
__asm__ __volatile__("tlbi vae3is, %[page_index]" :: [page_index]"r"(page_index) : "memory");
}
ALWAYS_INLINE void InvalidateTlbLastLevel(uintptr_t address) {
__asm__ __volatile__("tlbi vale3is, %[address]" :: [address]"r"(address) : "memory");
const uintptr_t page_index = address / 4_KB;
__asm__ __volatile__("tlbi vale3is, %[page_index]" :: [page_index]"r"(page_index) : "memory");
}
void FlushDataCache(const void *ptr, size_t size);

View file

@ -140,7 +140,7 @@ namespace ams::mmu::arch::arm64 {
constexpr inline u64 MemoryRegionAttributeWidth = 8;
constexpr PageTableMappingAttribute AddMappingAttributeIndex(PageTableMappingAttribute attr, int index) {
constexpr ALWAYS_INLINE PageTableMappingAttribute AddMappingAttributeIndex(PageTableMappingAttribute attr, int index) {
return static_cast<PageTableMappingAttribute>(attr | (static_cast<typename std::underlying_type<PageTableMappingAttribute>::type>(index) << 2));
}
@ -169,35 +169,35 @@ namespace ams::mmu::arch::arm64 {
constexpr inline u64 EntryBlock = 0x1ul;
constexpr inline u64 EntryPage = 0x3ul;
constexpr u64 MakeTableEntry(u64 address, PageTableTableAttribute attr) {
constexpr ALWAYS_INLINE u64 MakeTableEntry(u64 address, PageTableTableAttribute attr) {
return address | static_cast<u64>(attr) | 0x3ul;
}
constexpr u64 MakeL1BlockEntry(u64 address, PageTableMappingAttribute attr) {
constexpr ALWAYS_INLINE u64 MakeL1BlockEntry(u64 address, PageTableMappingAttribute attr) {
return address | static_cast<u64>(attr) | static_cast<u64>(PageTableMappingAttribute_AccessFlagAccessed) | 0x1ul;
}
constexpr u64 MakeL2BlockEntry(u64 address, PageTableMappingAttribute attr) {
constexpr ALWAYS_INLINE u64 MakeL2BlockEntry(u64 address, PageTableMappingAttribute attr) {
return address | static_cast<u64>(attr) | static_cast<u64>(PageTableMappingAttribute_AccessFlagAccessed) | 0x1ul;
}
constexpr u64 MakeL3BlockEntry(u64 address, PageTableMappingAttribute attr) {
constexpr ALWAYS_INLINE u64 MakeL3BlockEntry(u64 address, PageTableMappingAttribute attr) {
return address | static_cast<u64>(attr) | static_cast<u64>(PageTableMappingAttribute_AccessFlagAccessed) | 0x3ul;
}
constexpr uintptr_t GetL2Offset(uintptr_t address) {
constexpr ALWAYS_INLINE uintptr_t GetL2Offset(uintptr_t address) {
return address & ((1ul << L2EntryShift) - 1);
}
constexpr u64 GetL1EntryIndex(uintptr_t address) {
constexpr ALWAYS_INLINE u64 GetL1EntryIndex(uintptr_t address) {
return ((address >> L1EntryShift) & TableEntryIndexMask);
}
constexpr u64 GetL2EntryIndex(uintptr_t address) {
constexpr ALWAYS_INLINE u64 GetL2EntryIndex(uintptr_t address) {
return ((address >> L2EntryShift) & TableEntryIndexMask);
}
constexpr u64 GetL3EntryIndex(uintptr_t address) {
constexpr ALWAYS_INLINE u64 GetL3EntryIndex(uintptr_t address) {
return ((address >> L3EntryShift) & TableEntryIndexMask);
}
@ -218,15 +218,15 @@ namespace ams::mmu::arch::arm64 {
SetTableEntryImpl(table, index, value);
}
constexpr void SetL1TableEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, PageTableTableAttribute attr) {
constexpr ALWAYS_INLINE void SetL1TableEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, PageTableTableAttribute attr) {
SetTableEntry(table, GetL1EntryIndex(virt_addr), MakeTableEntry(phys_addr & TableEntryMask, attr));
}
constexpr void SetL2TableEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, PageTableTableAttribute attr) {
constexpr ALWAYS_INLINE void SetL2TableEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, PageTableTableAttribute attr) {
SetTableEntry(table, GetL2EntryIndex(virt_addr), MakeTableEntry(phys_addr & TableEntryMask, attr));
}
constexpr void SetL1BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) {
constexpr ALWAYS_INLINE void SetL1BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) {
const u64 start = GetL1EntryIndex(virt_addr);
const u64 count = (size >> L1EntryShift);
@ -235,7 +235,7 @@ namespace ams::mmu::arch::arm64 {
}
}
constexpr void SetL2BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) {
constexpr ALWAYS_INLINE void SetL2BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) {
const u64 start = GetL2EntryIndex(virt_addr);
const u64 count = (size >> L2EntryShift);
@ -244,7 +244,7 @@ namespace ams::mmu::arch::arm64 {
}
}
constexpr void SetL3BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) {
constexpr ALWAYS_INLINE void SetL3BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) {
const u64 start = GetL3EntryIndex(virt_addr);
const u64 count = (size >> L3EntryShift);
@ -253,7 +253,7 @@ namespace ams::mmu::arch::arm64 {
}
}
constexpr void InvalidateL1Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) {
constexpr ALWAYS_INLINE void InvalidateL1Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) {
const u64 start = GetL1EntryIndex(virt_addr);
const u64 count = (size >> L1EntryShift);
const u64 end = start + count;
@ -263,7 +263,7 @@ namespace ams::mmu::arch::arm64 {
}
}
constexpr void InvalidateL2Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) {
constexpr ALWAYS_INLINE void InvalidateL2Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) {
const u64 start = GetL2EntryIndex(virt_addr);
const u64 count = (size >> L2EntryShift);
const u64 end = start + count;
@ -273,7 +273,7 @@ namespace ams::mmu::arch::arm64 {
}
}
constexpr void InvalidateL3Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) {
constexpr ALWAYS_INLINE void InvalidateL3Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) {
const u64 start = GetL3EntryIndex(virt_addr);
const u64 count = (size >> L3EntryShift);
const u64 end = start + count;

View file

@ -30,6 +30,7 @@ namespace ams::pmic {
void EnableVddCpu(Regulator regulator);
void DisableVddCpu(Regulator regulator);
void EnableSleep();
void PowerOff();
bool IsAcOk();
}

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::rtc {
void StopAlarm();
}

View file

@ -287,4 +287,6 @@ namespace ams::secmon {
constexpr inline const MemoryRegion MemoryRegionPhysicalIramWarmbootBin = MemoryRegion(UINT64_C(0x4003E000), 0x17F0);
constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootConfig = MemoryRegion(UINT64_C(0x4003F800), 0x400);
constexpr inline const MemoryRegion MemoryRegionPhysicalIramRebootStub = MemoryRegion(UINT64_C(0x4003F000), 0x1000);
}

View file

@ -44,6 +44,8 @@
#define APBDEV_PMC_CRYPTO_OP (0x0F4)
#define APBDEV_PMC_SCRATCH31 (0x118)
#define APBDEV_PMC_SCRATCH32 (0x11C)
#define APBDEV_PMC_SCRATCH33 (0x120)
#define APBDEV_PMC_SCRATCH40 (0x13C)
#define APBDEV_PMC_WAKE2_MASK (0x160)
#define APBDEV_PMC_WAKE2_LVL (0x164)
#define APBDEV_PMC_WAKE2_STATUS (0x168)
@ -54,6 +56,8 @@
#define APBDEV_PMC_IO_DPD2_REQ (0x1C0)
#define APBDEV_PMC_IO_DPD2_STATUS (0x1C4)
#define APBDEV_PMC_SEL_DPD_TIM (0x1C8)
#define APBDEV_PMC_SCRATCH45 (0x234)
#define APBDEV_PMC_SCRATCH46 (0x238)
#define APBDEV_PMC_TSC_MULT (0x2B4)
#define APBDEV_PMC_WEAK_BIAS (0x2C8)
#define APBDEV_PMC_GPU_RG_CNTRL (0x2D4)