fusee_cpp: rename source dir to fusee
This commit is contained in:
106
fusee/program/source/fatfs/diskio.c
Normal file
106
fusee/program/source/fatfs/diskio.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2019 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "ff.h" /* Obtains integer types */
|
||||
#include "diskio.h" /* Declarations of disk functions */
|
||||
#include "ffconf.h"
|
||||
|
||||
#include "diskio_cpp.h"
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
LBA_t sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case DRIVE_SD:
|
||||
return diskio_read_sd_card(buff, count * 512, sector, count) ? RES_OK : RES_ERROR;
|
||||
case DRIVE_SYS:
|
||||
return diskio_read_system(buff, count * 512, sector, count) ? RES_OK : RES_ERROR;
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if FF_FS_READONLY == 0
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
LBA_t sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case DRIVE_SD:
|
||||
return diskio_write_sd_card(sector, count, buff, count * 512) ? RES_OK : RES_ERROR;
|
||||
case DRIVE_SYS:
|
||||
return diskio_write_system(sector, count, buff, count * 512) ? RES_OK : RES_ERROR;
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
83
fusee/program/source/fatfs/diskio.h
Normal file
83
fusee/program/source/fatfs/diskio.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2019 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
/* Disk drives. */
|
||||
typedef enum {
|
||||
DRIVE_SD,
|
||||
DRIVE_SYS,
|
||||
} DDRIVE;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
30
fusee/program/source/fatfs/diskio_cpp.h
Normal file
30
fusee/program/source/fatfs/diskio_cpp.h
Normal 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool diskio_read_sd_card(void *dst, size_t size, size_t sector_index, size_t sector_count);
|
||||
bool diskio_write_sd_card(size_t sector_index, size_t sector_count, const void *src, size_t size);
|
||||
|
||||
bool diskio_read_system(void *dst, size_t size, size_t sector_index, size_t sector_count);
|
||||
bool diskio_write_system(size_t sector_index, size_t sector_count, const void *src, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
6864
fusee/program/source/fatfs/ff.c
Normal file
6864
fusee/program/source/fatfs/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
427
fusee/program/source/fatfs/ff.h
Normal file
427
fusee/program/source/fatfs/ff.h
Normal file
@@ -0,0 +1,427 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.14 /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2019, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 86606 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
typedef WORD WCHAR; /* UTF-16 character type */
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||
typedef WORD WCHAR; /* UTF-16 character type */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size and LBA variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#if FF_LBA64
|
||||
typedef QWORD LBA_t;
|
||||
#else
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
#else
|
||||
#if FF_LBA64
|
||||
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||
#endif
|
||||
typedef DWORD FSIZE_t;
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
LBA_t volbase; /* Volume base sector */
|
||||
LBA_t fatbase; /* FAT base sector */
|
||||
LBA_t dirbase; /* Root directory base sector/cluster */
|
||||
LBA_t database; /* Data base sector */
|
||||
#if FF_FS_EXFAT
|
||||
LBA_t bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
LBA_t winsect; /* Current sector appearing in the win[] */
|
||||
BYTE pad[4];
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
LBA_t sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* Format parameter structure (MKFS_PARM) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
|
||||
BYTE n_fat; /* Number of FATs */
|
||||
UINT align; /* Data area alignment (sector) */
|
||||
UINT n_root; /* Number of root directory entries */
|
||||
DWORD au_size; /* Cluster size (byte) */
|
||||
} MKFS_PARM;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
||||
298
fusee/program/source/fatfs/ffconf.h
Normal file
298
fusee/program/source/fatfs/ffconf.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86606 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 1
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 1
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 2
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 2
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 1
|
||||
#define FF_VOLUME_STRS "sdmc","sys"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_LBA64 0
|
||||
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
|
||||
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
|
||||
|
||||
|
||||
#define FF_MIN_GPT 0x100000000
|
||||
/* Minimum number of sectors to switch GPT format to create partition in f_mkfs and
|
||||
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2019
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
170
fusee/program/source/fatfs/ffsystem.c
Normal file
170
fusee/program/source/fatfs/ffsystem.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C)ChaN, 2018 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
|
||||
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
||||
// return (int)(*sobj != NULL);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
15593
fusee/program/source/fatfs/ffunicode.c
Normal file
15593
fusee/program/source/fatfs/ffunicode.c
Normal file
File diff suppressed because it is too large
Load Diff
35
fusee/program/source/fatfs/fusee_diskio.cpp
Normal file
35
fusee/program/source/fatfs/fusee_diskio.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "diskio_cpp.h"
|
||||
#include "../fusee_sd_card.hpp"
|
||||
#include "../fusee_emummc.hpp"
|
||||
|
||||
bool diskio_read_sd_card(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||
return R_SUCCEEDED(::ams::nxboot::ReadSdCard(dst, size, sector_index, sector_count));
|
||||
}
|
||||
|
||||
bool diskio_write_sd_card(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||
return R_SUCCEEDED(::ams::nxboot::WriteSdCard(sector_index, sector_count, src, size));
|
||||
}
|
||||
|
||||
bool diskio_read_system(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||
return R_SUCCEEDED(::ams::nxboot::ReadSystem(sector_index * 0x200, dst, size));
|
||||
}
|
||||
|
||||
bool diskio_write_system(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||
return false;
|
||||
}
|
||||
341
fusee/program/source/fs/fusee_fs_api.cpp
Normal file
341
fusee/program/source/fs/fusee_fs_api.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "../fatfs/ff.h"
|
||||
#include "fusee_fs_api.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
static_assert(sizeof(DirectoryEntry) == sizeof(FILINFO));
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t MaxFiles = 8 + 64;
|
||||
constexpr size_t MaxDirectories = 2;
|
||||
|
||||
constinit bool g_is_sd_mounted = false;
|
||||
constinit bool g_is_sys_mounted = false;
|
||||
|
||||
alignas(0x10) constinit FATFS g_sd_fs = {};
|
||||
alignas(0x10) constinit FATFS g_sys_fs = {};
|
||||
|
||||
alignas(0x10) constinit FIL g_files[MaxFiles] = {};
|
||||
alignas(0x10) constinit DIR g_dirs[MaxDirectories] = {};
|
||||
constinit bool g_files_opened[MaxFiles] = {};
|
||||
constinit bool g_dirs_opened[MaxFiles] = {};
|
||||
constinit int g_open_modes[MaxFiles] = {};
|
||||
|
||||
Result TranslateFatFsError(FRESULT res) {
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return ResultSuccess();
|
||||
case FR_DISK_ERR:
|
||||
return fs::ResultMmcAccessFailed();
|
||||
case FR_INT_ERR:
|
||||
return fs::ResultPreconditionViolation();
|
||||
case FR_NOT_READY:
|
||||
return fs::ResultMmcAccessFailed();
|
||||
case FR_NO_FILE:
|
||||
return fs::ResultPathNotFound();
|
||||
case FR_NO_PATH:
|
||||
return fs::ResultPathNotFound();
|
||||
case FR_INVALID_NAME:
|
||||
return fs::ResultInvalidPath();
|
||||
case FR_DENIED:
|
||||
return fs::ResultPermissionDenied();
|
||||
case FR_EXIST:
|
||||
return fs::ResultPathAlreadyExists();
|
||||
case FR_INVALID_OBJECT:
|
||||
return fs::ResultInvalidArgument();
|
||||
case FR_WRITE_PROTECTED:
|
||||
return fs::ResultWriteNotPermitted();
|
||||
case FR_INVALID_DRIVE:
|
||||
return fs::ResultInvalidMountName();
|
||||
case FR_NOT_ENABLED:
|
||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
||||
case FR_NO_FILESYSTEM:
|
||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
||||
case FR_TIMEOUT:
|
||||
return fs::ResultTargetLocked(); /* BAD/TODO */
|
||||
case FR_LOCKED:
|
||||
return fs::ResultTargetLocked();
|
||||
case FR_NOT_ENOUGH_CORE:
|
||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
||||
case FR_TOO_MANY_OPEN_FILES:
|
||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
||||
case FR_INVALID_PARAMETER:
|
||||
return fs::ResultInvalidArgument();
|
||||
default:
|
||||
return fs::ResultInternal();
|
||||
}
|
||||
}
|
||||
|
||||
int TranslateToFatFsMode(int mode) {
|
||||
int fmode = FA_OPEN_EXISTING;
|
||||
if ((mode & OpenMode_Read) != 0) {
|
||||
fmode |= FA_READ;
|
||||
}
|
||||
if ((mode & OpenMode_Write) != 0) {
|
||||
fmode |= FA_WRITE;
|
||||
}
|
||||
if ((mode & OpenMode_AllowAppend) != 0) {
|
||||
fmode |= FA_OPEN_APPEND;
|
||||
}
|
||||
return fmode;
|
||||
}
|
||||
|
||||
FIL *GetInternalFile(FileHandle handle) {
|
||||
return static_cast<FIL *>(handle._handle);
|
||||
}
|
||||
|
||||
DIR *GetInternalDirectory(DirectoryHandle handle) {
|
||||
return static_cast<DIR *>(handle._handle);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetFileIndex(FIL *fp) {
|
||||
const size_t file_index = (fp - g_files);
|
||||
AMS_ASSERT(file_index < MaxFiles);
|
||||
return file_index;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetDirectoryIndex(DIR *dp) {
|
||||
const size_t dir_index = (dp - g_dirs);
|
||||
AMS_ASSERT(dir_index < MaxDirectories);
|
||||
return dir_index;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool MountSdCard() {
|
||||
AMS_ASSERT(!g_is_sd_mounted);
|
||||
g_is_sd_mounted = f_mount(std::addressof(g_sd_fs), "sdmc:", 1) == FR_OK;
|
||||
return g_is_sd_mounted;
|
||||
}
|
||||
|
||||
void UnmountSdCard() {
|
||||
AMS_ASSERT(g_is_sd_mounted);
|
||||
f_unmount("sdmc:");
|
||||
g_is_sd_mounted = false;
|
||||
}
|
||||
|
||||
bool MountSystem() {
|
||||
AMS_ASSERT(!g_is_sys_mounted);
|
||||
g_is_sys_mounted = f_mount(std::addressof(g_sys_fs), "sys:", 1) == FR_OK;
|
||||
return g_is_sys_mounted;
|
||||
}
|
||||
|
||||
void UnmountSystem() {
|
||||
AMS_ASSERT(g_is_sys_mounted);
|
||||
f_unmount("sys:");
|
||||
g_is_sys_mounted = false;
|
||||
}
|
||||
|
||||
Result GetEntryType(DirectoryEntryType *out_entry_type, bool *out_archive, const char *path) {
|
||||
/* Get the file info. */
|
||||
FILINFO info;
|
||||
R_TRY(TranslateFatFsError(f_stat(path, std::addressof(info))));
|
||||
|
||||
/* Handle the file. */
|
||||
*out_entry_type = (info.fattrib & AM_DIR) ? DirectoryEntryType_Directory : DirectoryEntryType_File;
|
||||
*out_archive = (info.fattrib & AM_ARC);
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CreateFile(const char *path, s64 size) {
|
||||
/* Create the file. */
|
||||
FIL fp;
|
||||
R_TRY(TranslateFatFsError(f_open(std::addressof(fp), path, FA_CREATE_NEW | FA_READ | FA_WRITE)));
|
||||
|
||||
/* Ensure that we close the file when we're done with it. */
|
||||
ON_SCOPE_EXIT { f_close(std::addressof(fp)); };
|
||||
|
||||
/* Expand the file. */
|
||||
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char *path) {
|
||||
return TranslateFatFsError(f_mkdir(path));
|
||||
}
|
||||
|
||||
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
||||
/* Find a free file. */
|
||||
for (size_t i = 0; i < MaxFiles; ++i) {
|
||||
if (!g_files_opened[i]) {
|
||||
/* Open the file. */
|
||||
FIL *fp = std::addressof(g_files[i]);
|
||||
R_TRY(TranslateFatFsError(f_open(fp, path, TranslateToFatFsMode(mode))));
|
||||
|
||||
/* Set the output. */
|
||||
out_file->_handle = fp;
|
||||
g_files_opened[i] = true;
|
||||
g_open_modes[i] = mode;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
return fs::ResultOpenCountLimit();
|
||||
}
|
||||
|
||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path) {
|
||||
/* Find a free directory. */
|
||||
for (size_t i = 0; i < MaxDirectories; ++i) {
|
||||
if (!g_dirs_opened[i]) {
|
||||
/* Open the file. */
|
||||
DIR *dp = std::addressof(g_dirs[i]);
|
||||
R_TRY(TranslateFatFsError(f_opendir(dp, path)));
|
||||
|
||||
/* Set the output. */
|
||||
out_dir->_handle = dp;
|
||||
g_dirs_opened[i] = true;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
return fs::ResultOpenCountLimit();
|
||||
}
|
||||
|
||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
|
||||
DIR * const dp = GetInternalDirectory(handle);
|
||||
|
||||
s64 count = 0;
|
||||
while (count < max_entries) {
|
||||
R_TRY(TranslateFatFsError(f_readdir(dp, reinterpret_cast<FILINFO *>(out_entries + count))));
|
||||
|
||||
if (out_entries[count].file_name[0] == '\x00') {
|
||||
break;
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
*out_count = count;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void CloseDirectory(DirectoryHandle handle) {
|
||||
const size_t index = GetDirectoryIndex(GetInternalDirectory(handle));
|
||||
f_closedir(std::addressof(g_dirs[index]));
|
||||
g_dirs_opened[index] = false;
|
||||
}
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||
/* Option is unused. */
|
||||
AMS_UNUSED(option);
|
||||
|
||||
/* Seek to the offset we're reading at. */
|
||||
R_TRY(TranslateFatFsError(f_lseek(GetInternalFile(handle), offset)));
|
||||
|
||||
/* Read the data. */
|
||||
UINT br;
|
||||
R_TRY(TranslateFatFsError(f_read(GetInternalFile(handle), buffer, size, std::addressof(br))));
|
||||
|
||||
/* Check that we read the correct amount. */
|
||||
R_UNLESS(br == size, fs::ResultOutOfRange());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
return ReadFile(handle, offset, buffer, size, fs::ReadOption::None);
|
||||
}
|
||||
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||
/* Option is unused. */
|
||||
AMS_UNUSED(option);
|
||||
|
||||
/* Seek to the offset we're reading at. */
|
||||
R_TRY(TranslateFatFsError(f_lseek(GetInternalFile(handle), offset)));
|
||||
|
||||
/* Read the data. */
|
||||
UINT br;
|
||||
R_TRY(TranslateFatFsError(f_read(GetInternalFile(handle), buffer, size, std::addressof(br))));
|
||||
|
||||
/* Set the output size. */
|
||||
*out = br;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
|
||||
}
|
||||
|
||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||
FIL *fp = GetInternalFile(handle);
|
||||
*out = f_size(fp);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FlushFile(FileHandle handle) {
|
||||
return TranslateFatFsError(f_sync(GetInternalFile(handle)));
|
||||
}
|
||||
|
||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
||||
/* Seek to the offset we're writing at. */
|
||||
R_TRY(TranslateFatFsError(f_lseek(GetInternalFile(handle), offset)));
|
||||
|
||||
/* Write the data. */
|
||||
UINT bw;
|
||||
R_TRY(TranslateFatFsError(f_write(GetInternalFile(handle), buffer, size, std::addressof(bw))));
|
||||
|
||||
/* Check that we wrote the correct amount. */
|
||||
R_UNLESS(bw == size, fs::ResultOutOfRange());
|
||||
|
||||
/* If we should, flush the file. */
|
||||
if (option.HasFlushFlag()) {
|
||||
R_TRY(FlushFile(handle));
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SetFileSize(FileHandle handle, s64 size) {
|
||||
FIL *fp = GetInternalFile(handle);
|
||||
|
||||
/* Check if we have nothing to do. */
|
||||
const size_t fsize = f_size(fp);
|
||||
R_SUCCEED_IF(static_cast<FSIZE_t>(size) == fsize);
|
||||
|
||||
/* NOTE/TODO: This may not preserve file data. Do this in a way that does? */
|
||||
|
||||
/* Truncate the file. */
|
||||
R_TRY(TranslateFatFsError(f_truncate(fp)));
|
||||
|
||||
/* Expand the file. */
|
||||
R_TRY(TranslateFatFsError(f_expand(fp, size, 1)));
|
||||
|
||||
/* Ensure the file is synchronized. */
|
||||
R_TRY(FlushFile(handle));
|
||||
|
||||
/* Check that our expansion succeeded. */
|
||||
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
int GetFileOpenMode(FileHandle handle) {
|
||||
return g_open_modes[GetFileIndex(GetInternalFile(handle))];
|
||||
}
|
||||
|
||||
void CloseFile(FileHandle handle) {
|
||||
const size_t index = GetFileIndex(GetInternalFile(handle));
|
||||
f_close(std::addressof(g_files[index]));
|
||||
g_open_modes[index] = 0;
|
||||
g_files_opened[index] = false;
|
||||
}
|
||||
|
||||
}
|
||||
126
fusee/program/source/fs/fusee_fs_api.hpp
Normal file
126
fusee/program/source/fs/fusee_fs_api.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
enum OpenMode {
|
||||
OpenMode_Read = (1 << 0),
|
||||
OpenMode_Write = (1 << 1),
|
||||
OpenMode_AllowAppend = (1 << 2),
|
||||
|
||||
OpenMode_ReadWrite = (OpenMode_Read | OpenMode_Write),
|
||||
OpenMode_All = (OpenMode_ReadWrite | OpenMode_AllowAppend),
|
||||
};
|
||||
|
||||
struct ReadOption {
|
||||
u32 value;
|
||||
|
||||
static const ReadOption None;
|
||||
};
|
||||
|
||||
inline constexpr const ReadOption ReadOption::None = {0};
|
||||
|
||||
inline constexpr bool operator==(const ReadOption &lhs, const ReadOption &rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const ReadOption &lhs, const ReadOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
static_assert(util::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
|
||||
|
||||
struct WriteOption {
|
||||
u32 value;
|
||||
|
||||
constexpr inline bool HasFlushFlag() const {
|
||||
return this->value & 1;
|
||||
}
|
||||
|
||||
static const WriteOption None;
|
||||
static const WriteOption Flush;
|
||||
};
|
||||
|
||||
inline constexpr const WriteOption WriteOption::None = {0};
|
||||
inline constexpr const WriteOption WriteOption::Flush = {1};
|
||||
|
||||
inline constexpr bool operator==(const WriteOption &lhs, const WriteOption &rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const WriteOption &lhs, const WriteOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
static_assert(util::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
|
||||
|
||||
enum DirectoryEntryType {
|
||||
DirectoryEntryType_Directory = 0,
|
||||
DirectoryEntryType_File = 1,
|
||||
};
|
||||
|
||||
struct DirectoryEntry {
|
||||
u64 file_size;
|
||||
u16 file_date;
|
||||
u16 file_time;
|
||||
u8 file_attr;
|
||||
char altname[13];
|
||||
char file_name[0x100];
|
||||
};
|
||||
|
||||
constexpr ALWAYS_INLINE DirectoryEntryType GetEntryType(const DirectoryEntry &entry) {
|
||||
return (entry.file_attr & 0x10) ? DirectoryEntryType_Directory : DirectoryEntryType_File;
|
||||
}
|
||||
|
||||
struct FileHandle {
|
||||
void *_handle;
|
||||
};
|
||||
|
||||
struct DirectoryHandle {
|
||||
void *_handle;
|
||||
};
|
||||
|
||||
bool MountSdCard();
|
||||
void UnmountSdCard();
|
||||
|
||||
bool MountSystem();
|
||||
void UnmountSystem();
|
||||
|
||||
Result GetEntryType(DirectoryEntryType *out_entry_type, bool *out_archive, const char *path);
|
||||
|
||||
Result CreateFile(const char *path, s64 size);
|
||||
Result CreateDirectory(const char *path);
|
||||
Result OpenFile(FileHandle *out_file, const char *path, int mode);
|
||||
|
||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path);
|
||||
|
||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries);
|
||||
void CloseDirectory(DirectoryHandle handle);
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option);
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size);
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option);
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size);
|
||||
Result GetFileSize(s64 *out, FileHandle handle);
|
||||
Result FlushFile(FileHandle handle);
|
||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option);
|
||||
Result SetFileSize(FileHandle handle, s64 size);
|
||||
int GetFileOpenMode(FileHandle handle);
|
||||
void CloseFile(FileHandle handle);
|
||||
|
||||
}
|
||||
73
fusee/program/source/fs/fusee_fs_file_storage.cpp
Normal file
73
fusee/program/source/fs/fusee_fs_file_storage.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_fs_storage.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
Result FileHandleStorage::UpdateSize() {
|
||||
R_SUCCEED_IF(m_size != InvalidSize);
|
||||
return GetFileSize(std::addressof(m_size), m_handle);
|
||||
}
|
||||
|
||||
Result FileHandleStorage::Read(s64 offset, void *buffer, size_t size) {
|
||||
/* Immediately succeed if there's nothing to read. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate buffer. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Ensure our size is valid. */
|
||||
R_TRY(this->UpdateSize());
|
||||
|
||||
/* Ensure our access is valid. */
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
|
||||
return ReadFile(m_handle, offset, buffer, size, fs::ReadOption());
|
||||
}
|
||||
|
||||
Result FileHandleStorage::Write(s64 offset, const void *buffer, size_t size) {
|
||||
/* Immediately succeed if there's nothing to write. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate buffer. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Ensure our size is valid. */
|
||||
R_TRY(this->UpdateSize());
|
||||
|
||||
/* Ensure our access is valid. */
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
|
||||
return WriteFile(m_handle, offset, buffer, size, fs::WriteOption());
|
||||
}
|
||||
|
||||
Result FileHandleStorage::Flush() {
|
||||
return FlushFile(m_handle);
|
||||
}
|
||||
|
||||
Result FileHandleStorage::GetSize(s64 *out_size) {
|
||||
R_TRY(this->UpdateSize());
|
||||
*out_size = m_size;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileHandleStorage::SetSize(s64 size) {
|
||||
m_size = InvalidSize;
|
||||
return SetFileSize(m_handle, size);
|
||||
}
|
||||
|
||||
}
|
||||
145
fusee/program/source/fs/fusee_fs_storage.hpp
Normal file
145
fusee/program/source/fs/fusee_fs_storage.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "fusee_fs_api.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class IStorage {
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) = 0;
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) = 0;
|
||||
|
||||
virtual Result Flush() = 0;
|
||||
|
||||
virtual Result SetSize(s64 size) = 0;
|
||||
|
||||
virtual Result GetSize(s64 *out) = 0;
|
||||
public:
|
||||
static inline bool CheckAccessRange(s64 offset, s64 size, s64 total_size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
size <= total_size &&
|
||||
offset <= (total_size - size);
|
||||
}
|
||||
|
||||
static inline bool CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
||||
return CheckAccessRange(offset, static_cast<s64>(size), total_size);
|
||||
}
|
||||
|
||||
static inline bool CheckOffsetAndSize(s64 offset, s64 size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
offset <= (offset + size);
|
||||
}
|
||||
|
||||
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
|
||||
return CheckOffsetAndSize(offset, static_cast<s64>(size));
|
||||
}
|
||||
};
|
||||
|
||||
class ReadOnlyStorageAdapter : public IStorage {
|
||||
private:
|
||||
IStorage &m_storage;
|
||||
public:
|
||||
ReadOnlyStorageAdapter(IStorage &s) : m_storage(s) { /* ... */ }
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
return m_storage.Read(offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return m_storage.Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
return m_storage.GetSize(out);
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
class SubStorage : public IStorage {
|
||||
private:
|
||||
IStorage &m_storage;
|
||||
s64 m_offset;
|
||||
s64 m_size;
|
||||
public:
|
||||
SubStorage(IStorage &s, s64 o, s64 sz) : m_storage(s), m_offset(o), m_size(sz) { /* ... */ }
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
/* Succeed immediately on zero-sized operation. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments and read. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
return m_storage.Read(m_offset + offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
||||
/* Succeed immediately on zero-sized operation. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments and write. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
||||
return m_storage.Write(m_offset + offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return m_storage.Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
*out = m_size;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fs::ResultUnsupportedOperationInSubStorageA();
|
||||
}
|
||||
};
|
||||
|
||||
class FileHandleStorage : public IStorage {
|
||||
private:
|
||||
static constexpr s64 InvalidSize = -1;
|
||||
private:
|
||||
FileHandle m_handle;
|
||||
s64 m_size;
|
||||
public:
|
||||
constexpr explicit FileHandleStorage(FileHandle handle) : m_handle(handle), m_size(InvalidSize) { /* ... */ }
|
||||
|
||||
~FileHandleStorage() { fs::CloseFile(m_handle); }
|
||||
protected:
|
||||
Result UpdateSize();
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override;
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
|
||||
virtual Result Flush() override;
|
||||
virtual Result GetSize(s64 *out_size) override;
|
||||
virtual Result SetSize(s64 size) override;
|
||||
};
|
||||
|
||||
}
|
||||
181
fusee/program/source/fusee_cpu.cpp
Normal file
181
fusee/program/source/fusee_cpu.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_cpu.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t FLOW = secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress();
|
||||
constexpr inline const uintptr_t EVP = secmon::MemoryRegionPhysicalDeviceExceptionVectors.GetAddress();
|
||||
constexpr inline const uintptr_t SYSTEM = secmon::MemoryRegionPhysicalDeviceSystem.GetAddress();
|
||||
|
||||
bool IsPartitionPowered(u32 mask) {
|
||||
return (reg::Read(PMC + APBDEV_PMC_PWRGATE_STATUS) & mask) == mask;
|
||||
}
|
||||
|
||||
void PowerOnPartition(u32 status_mask, u32 toggle_mask) {
|
||||
/* Check if the partition is already powered on. */
|
||||
if (IsPartitionPowered(status_mask)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wait for PWRGATE_TOGGLE to be idle. */
|
||||
auto timeout = 5000;
|
||||
while (true) {
|
||||
if (reg::HasValue(PMC + APBDEV_PMC_PWRGATE_TOGGLE, PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_START, DISABLE))) {
|
||||
break;
|
||||
}
|
||||
|
||||
util::WaitMicroSeconds(1);
|
||||
if ((--timeout) < 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Toggle on the desired partition. */
|
||||
reg::SetField(toggle_mask, PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_START, ENABLE));
|
||||
reg::Write(PMC + APBDEV_PMC_PWRGATE_TOGGLE, toggle_mask);
|
||||
|
||||
/* Wait for the partition to be powered. */
|
||||
timeout = 5000;
|
||||
while (true) {
|
||||
if (IsPartitionPowered(status_mask)) {
|
||||
break;
|
||||
}
|
||||
|
||||
util::WaitMicroSeconds(1);
|
||||
if ((--timeout) < 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetupCpu(uintptr_t entrypoint) {
|
||||
/* Set ACTIVE_CLUSTER to FAST. */
|
||||
reg::ReadWrite(FLOW + FLOW_CTLR_BPMP_CLUSTER_CONTROL, FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_ACTIVE_CLUSTER, FAST));
|
||||
|
||||
/* Enable VDD_CPU. */
|
||||
pmic::EnableVddCpu(fuse::GetRegulator());
|
||||
|
||||
/* Enable clock to the cpu. */
|
||||
{
|
||||
/* Initialize PllX */
|
||||
if (!reg::HasValue(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, CLK_RST_REG_BITS_ENUM(PLLX_BASE_PLLX_ENABLE, ENABLE))) {
|
||||
/* Disable IDDQ. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLX_MISC3, CLK_RST_REG_BITS_VALUE(PLLX_MISC3_PLLX_IDDQ, 0));
|
||||
|
||||
/* Wait two microseconds. */
|
||||
util::WaitMicroSeconds(2);
|
||||
|
||||
/* Configure PLLX dividers. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, 0x80404E02);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, 0x00404E02);
|
||||
|
||||
/* Set PLLX_LOCK_ENABLE. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLX_MISC, CLK_RST_REG_BITS_ENUM(PLLX_MISC_PLLX_LOCK_ENABLE, ENABLE));
|
||||
|
||||
/* Enable PLLX. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, 0x40404E02);
|
||||
}
|
||||
|
||||
/* Wait for PLLX to be locked. */
|
||||
while (!reg::HasValue(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, CLK_RST_REG_BITS_ENUM(PLLX_BASE_PLLX_LOCK, LOCK))) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* Select MSELECT clock source as PLLP_OUT0 with divider of 4. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT, CLK_RST_REG_BITS_ENUM (CLK_SOURCE_MSELECT_MSELECT_CLK_SRC, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SOURCE_MSELECT_MSELECT_CLK_DIVISOR, 6));
|
||||
|
||||
/* Enable clock to MSELECT. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_REG_BITS_ENUM(CLK_OUT_ENB_V_CLK_ENB_MSELECT, ENABLE));
|
||||
|
||||
/* Configure CCLK_BURST_POLICY. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CCLK_BURST_POLICY, CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IDLE_SOURCE, PLLX_OUT0_LJ),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_RUN_SOURCE, PLLX_OUT0_LJ),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IRQ_SOURCE, PLLX_OUT0_LJ),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_FIQ_SOURCE, PLLX_OUT0_LJ),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CPU_STATE, RUN));
|
||||
|
||||
/* Configure SUPER_CCLK_DIVIDER. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER, CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_FIQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_FIQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_IRQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_IRQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVIDEND, 0),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVISOR, 0));
|
||||
|
||||
|
||||
/* Enable CPUG. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_V_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_V_SET_SET_CLK_ENB_CPUG, ENABLE));
|
||||
}
|
||||
|
||||
/* Enable coresight. */
|
||||
clkrst::EnableCsiteClock();
|
||||
|
||||
/* Restore PROD setting to CPU_SOFTRST_CTRL2 by clearing CAR2PMC_CPU_ACK_WIDTH. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2, CLK_RST_REG_BITS_VALUE(CPU_SOFTRST_CTRL2_CAR2PMC_CPU_ACK_WIDTH, 0));
|
||||
|
||||
/* Power on cpu rails. */
|
||||
{
|
||||
PowerOnPartition(reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_STATUS_CRAIL, ON)), reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_PARTID, CRAIL)));
|
||||
PowerOnPartition(reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_STATUS_C0NC, ON)), reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_PARTID, C0NC)));
|
||||
PowerOnPartition(reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_STATUS_CE0, ON)), reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_PARTID, CE0)));
|
||||
}
|
||||
|
||||
/* Do RAM Repair. */
|
||||
{
|
||||
reg::Write(FLOW + FLOW_CTLR_RAM_REPAIR, FLOW_REG_BITS_ENUM(RAM_REPAIR_REQ, ENABLE));
|
||||
|
||||
while (!reg::HasValue(FLOW + FLOW_CTLR_RAM_REPAIR, FLOW_REG_BITS_ENUM(RAM_REPAIR_STS, DONE))) {
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure CPU reset vector. */
|
||||
reg::Write(EVP + EVP_CPU_RESET_VECTOR, 0);
|
||||
|
||||
reg::Write(SYSTEM + SB_AA64_RESET_LOW, entrypoint | 0x1);
|
||||
reg::Write(SYSTEM + SB_AA64_RESET_HIGH, 0);
|
||||
reg::Write(SYSTEM + SB_CSR, SB_REG_BITS_ENUM(CSR_NS_RST_VEC_WR_DIS, DISABLE));
|
||||
reg::Read(SYSTEM + SB_CSR);
|
||||
}
|
||||
|
||||
void StartCpu() {
|
||||
/* NOTE: Here nintendo sets CPU_STRICT_TZ_APERTURE_CHECK, which we will not set. */
|
||||
|
||||
/* Clear MSELECT reset. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_REG_BITS_ENUM(RST_DEVICES_V_SWR_MSELECT_RST, DISABLE));
|
||||
|
||||
/* Take non-cpu out of reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR, CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_NONCPURESET, ENABLE));
|
||||
|
||||
/* Clear cpu reset. */
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR, CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_CPURESET0, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET0, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_PRESETDBG, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_L2RESET, ENABLE));
|
||||
}
|
||||
|
||||
}
|
||||
24
fusee/program/source/fusee_cpu.hpp
Normal file
24
fusee/program/source/fusee_cpu.hpp
Normal 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 <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void SetupCpu(uintptr_t entrypoint);
|
||||
void StartCpu();
|
||||
|
||||
}
|
||||
50
fusee/program/source/fusee_crt0.cpp
Normal file
50
fusee/program/source/fusee_crt0.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_exception_handler.hpp"
|
||||
|
||||
extern "C" void __libc_init_array();
|
||||
|
||||
namespace ams::nxboot::crt0 {
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE void SetExceptionVector(u32 which, uintptr_t impl) {
|
||||
reg::Write(secmon::MemoryRegionPhysicalDeviceExceptionVectors.GetAddress() + 0x200 + sizeof(u32) * which, static_cast<u32>(impl));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Initialize() {
|
||||
/* TODO: Collect timing information? */
|
||||
|
||||
/* Setup exception vectors. */
|
||||
{
|
||||
SetExceptionVector(0, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler0));
|
||||
SetExceptionVector(1, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler1));
|
||||
SetExceptionVector(2, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler2));
|
||||
SetExceptionVector(3, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler3));
|
||||
SetExceptionVector(4, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler4));
|
||||
SetExceptionVector(5, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler5));
|
||||
SetExceptionVector(6, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler6));
|
||||
SetExceptionVector(7, reinterpret_cast<uintptr_t>(::ams::nxboot::ExceptionHandler7));
|
||||
}
|
||||
|
||||
/* Call init array. */
|
||||
__libc_init_array();
|
||||
}
|
||||
|
||||
}
|
||||
653
fusee/program/source/fusee_display.cpp
Normal file
653
fusee/program/source/fusee_display.cpp
Normal file
@@ -0,0 +1,653 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_registers_di.hpp"
|
||||
#include "fusee_display.hpp"
|
||||
#include "fusee_print.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
#include "fusee_display_config.inc"
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Helpful defines. */
|
||||
constexpr int DsiWaitForCommandMilliSecondsMax = 250;
|
||||
constexpr int DsiWaitForCommandCompletionMilliSeconds = 5;
|
||||
constexpr int DsiWaitForHostControlMilliSecondsMax = 150;
|
||||
|
||||
constexpr inline int I2cAddressMax77620Pmic = 0x3C;
|
||||
|
||||
constexpr size_t GPIO_PORT3_CNF_0 = 0x200;
|
||||
constexpr size_t GPIO_PORT3_OE_0 = 0x210;
|
||||
constexpr size_t GPIO_PORT3_OUT_0 = 0x220;
|
||||
|
||||
constexpr size_t GPIO_PORT6_CNF_1 = 0x504;
|
||||
constexpr size_t GPIO_PORT6_OE_1 = 0x514;
|
||||
constexpr size_t GPIO_PORT6_OUT_1 = 0x524;
|
||||
|
||||
/* Globals. */
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc .GetAddress();
|
||||
constexpr inline const uintptr_t g_disp1_regs = secmon::MemoryRegionPhysicalDeviceDisp1 .GetAddress();
|
||||
constexpr inline const uintptr_t g_dsi_regs = secmon::MemoryRegionPhysicalDeviceDsi .GetAddress();
|
||||
constexpr inline const uintptr_t g_clk_rst_regs = secmon::MemoryRegionPhysicalDeviceClkRst .GetAddress();
|
||||
constexpr inline const uintptr_t g_gpio_regs = secmon::MemoryRegionPhysicalDeviceGpio .GetAddress();
|
||||
constexpr inline const uintptr_t g_apb_misc_regs = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress();
|
||||
constexpr inline const uintptr_t g_mipi_cal_regs = secmon::MemoryRegionPhysicalDeviceMipiCal.GetAddress();
|
||||
|
||||
constinit u32 *g_frame_buffer = nullptr;
|
||||
|
||||
constinit u32 g_lcd_vendor = 0;
|
||||
constinit bool g_display_initialized = false;
|
||||
|
||||
inline void DoRegisterWrites(uintptr_t base_address, const RegisterWrite *reg_writes, size_t num_writes) {
|
||||
for (size_t i = 0; i < num_writes; i++) {
|
||||
reg::Write(base_address + reg_writes[i].offset, reg_writes[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
inline void DoSocDependentRegisterWrites(uintptr_t base_address, const RegisterWrite *reg_writes_erista, size_t num_writes_erista, const RegisterWrite *reg_writes_mariko, size_t num_writes_mariko) {
|
||||
switch (fuse::GetSocType()) {
|
||||
case fuse::SocType_Erista: DoRegisterWrites(base_address, reg_writes_erista, num_writes_erista); break;
|
||||
case fuse::SocType_Mariko: DoRegisterWrites(base_address, reg_writes_mariko, num_writes_mariko); break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
inline void DoSleepOrRegisterWrites(uintptr_t base_address, const SleepOrRegisterWrite *reg_writes, size_t num_writes) {
|
||||
for (size_t i = 0; i < num_writes; i++) {
|
||||
switch (reg_writes[i].kind) {
|
||||
case SleepOrRegisterWriteKind_Write:
|
||||
reg::Write(base_address + sizeof(u32) * reg_writes[i].offset, reg_writes[i].value);
|
||||
break;
|
||||
case SleepOrRegisterWriteKind_Sleep:
|
||||
util::WaitMicroSeconds(reg_writes[i].offset * UINT64_C(1000));
|
||||
break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WaitDsiTrigger() {
|
||||
const u32 timeout = util::GetMicroSeconds() + (DsiWaitForCommandMilliSecondsMax * 1000u);
|
||||
|
||||
while (true) {
|
||||
if (util::GetMicroSeconds() >= timeout) {
|
||||
break;
|
||||
}
|
||||
if (reg::Read(g_dsi_regs + sizeof(u32) * DSI_TRIGGER) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
util::WaitMicroSeconds(DsiWaitForCommandCompletionMilliSeconds * 1000u);
|
||||
}
|
||||
|
||||
void WaitDsiHostControl() {
|
||||
const u32 timeout = util::GetMicroSeconds() + (DsiWaitForHostControlMilliSecondsMax * 1000u);
|
||||
|
||||
while (true) {
|
||||
if (util::GetMicroSeconds() >= timeout) {
|
||||
break;
|
||||
}
|
||||
if ((reg::Read(g_dsi_regs + sizeof(u32) * DSI_HOST_CONTROL) & DSI_HOST_CONTROL_IMM_BTA) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnableBacklightForVendor2050ForAula(int brightness) {
|
||||
/* Enable FRAME_END_INT */
|
||||
reg::Write(g_disp1_regs + sizeof(u32) * DC_CMD_INT_ENABLE, 2);
|
||||
|
||||
/* Configure DSI_LINE_TYPE as FOUR */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_VIDEO_MODE_CONTROL, 1);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_VIDEO_MODE_CONTROL, 9);
|
||||
|
||||
/* Set and wait for FRAME_END_INT */
|
||||
reg::Write(g_disp1_regs + sizeof(u32) * DC_CMD_INT_STATUS, 2);
|
||||
while ((reg::Read(g_disp1_regs + sizeof(u32) * DC_CMD_INT_STATUS) & 2) != 0) { /* ... */ }
|
||||
|
||||
/* Configure display brightness. */
|
||||
const u32 brightness_val = ((0x7FF * brightness) / 100);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x339);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, (brightness_val & 0x700) | ((brightness_val & 0xFF) << 16) | 0x51);
|
||||
|
||||
/* Set and wait for FRAME_END_INT */
|
||||
reg::Write(g_disp1_regs + sizeof(u32) * DC_CMD_INT_STATUS, 2);
|
||||
while ((reg::Read(g_disp1_regs + sizeof(u32) * DC_CMD_INT_STATUS) & 2) != 0) { /* ... */ }
|
||||
|
||||
/* Set client sync point block reset. */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_INCR_SYNCPT_CNTRL, 1);
|
||||
util::WaitMicroSeconds(300'000ul);
|
||||
|
||||
/* Clear client sync point block resest. */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_INCR_SYNCPT_CNTRL, 0);
|
||||
util::WaitMicroSeconds(300'000ul);
|
||||
|
||||
/* Clear DSI_LINE_TYPE config. */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_VIDEO_MODE_CONTROL, 0);
|
||||
|
||||
/* Disable FRAME_END_INT */
|
||||
reg::Write(g_disp1_regs + sizeof(u32) * DC_CMD_INT_ENABLE, 0);
|
||||
reg::Write(g_disp1_regs + sizeof(u32) * DC_CMD_INT_STATUS, 2);
|
||||
}
|
||||
|
||||
void EnableBacklightForGeneric(int brightness) {
|
||||
AMS_UNUSED(brightness);
|
||||
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x1);
|
||||
}
|
||||
|
||||
#define DO_REGISTER_WRITES(base_address, writes) DoRegisterWrites(base_address, writes, util::size(writes))
|
||||
#define DO_SOC_DEPENDENT_REGISTER_WRITES(base_address, writes) DoSocDependentRegisterWrites(base_address, writes##Erista, util::size(writes##Erista), writes##Mariko, util::size(writes##Mariko))
|
||||
#define DO_SLEEP_OR_REGISTER_WRITES(base_address, writes) DoSleepOrRegisterWrites(base_address, writes, util::size(writes))
|
||||
|
||||
void InitializeFrameBuffer() {
|
||||
if (g_frame_buffer == nullptr) {
|
||||
g_frame_buffer = reinterpret_cast<u32 *>(0xC0400000);
|
||||
}
|
||||
hw::FlushDataCache(g_frame_buffer, FrameBufferSize);
|
||||
}
|
||||
|
||||
[[maybe_unused]] void FinalizeFrameBuffer() {
|
||||
/* We don't actually support finalizing the framebuffer, so do nothing here. */
|
||||
}
|
||||
|
||||
constexpr const char *GetErrorDescription(u32 error_desc) {
|
||||
switch (error_desc) {
|
||||
case 0x100:
|
||||
return "Instruction Abort";
|
||||
case 0x101:
|
||||
return "Data Abort";
|
||||
case 0x102:
|
||||
return "PC Misalignment";
|
||||
case 0x103:
|
||||
return "SP Misalignment";
|
||||
case 0x104:
|
||||
return "Trap";
|
||||
case 0x106:
|
||||
return "SError";
|
||||
case 0x301:
|
||||
return "Bad SVC";
|
||||
case 0xF00:
|
||||
return "Kernel Panic";
|
||||
case 0xFFD:
|
||||
return "Stack overflow";
|
||||
case 0xFFE:
|
||||
return "std::abort() called";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSuggestedErrorFix(const ams::impl::FatalErrorContext *f_ctx) {
|
||||
/* Try to recognize certain errors automatically, and suggest fixes for them. */
|
||||
const char *suggestion = nullptr;
|
||||
|
||||
constexpr u64 ProgramIdAmsMitm = UINT64_C(0x010041544D530000);
|
||||
constexpr u64 ProgramIdBoot = UINT64_C(0x0100000000000005);
|
||||
if (f_ctx->error_desc == 0xFFE) {
|
||||
if (f_ctx->program_id == ProgramIdAmsMitm) {
|
||||
/* When a user has archive bits set improperly, attempting to create an automatic backup will fail */
|
||||
/* to create the file path with error 0x202 */
|
||||
if (f_ctx->gprs[0] == fs::ResultPathNotFound().GetValue()) {
|
||||
/* When the archive bit error is occurring, it manifests as failure to create automatic backup. */
|
||||
/* Thus, we can search the stack for the automatic backups path. */
|
||||
const char * const automatic_backups_prefix = "automatic_backups/X" /* ..... */;
|
||||
const int prefix_len = std::strlen(automatic_backups_prefix);
|
||||
|
||||
for (size_t i = 0; i + prefix_len < f_ctx->stack_dump_size; ++i) {
|
||||
if (std::memcmp(&f_ctx->stack_dump[i], automatic_backups_prefix, prefix_len) == 0) {
|
||||
suggestion = "The atmosphere directory may improperly have archive bits set.\n"
|
||||
"Please try running an archive bit fixer tool (for example, the one in Hekate).\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (f_ctx->gprs[0] == fs::ResultExFatUnavailable().GetValue()) {
|
||||
/* When a user installs non-exFAT firm but has an exFAT formatted SD card, this error will */
|
||||
/* be returned on attempt to access the SD card. */
|
||||
suggestion = "Your console has non-exFAT firmware installed, but your SD card\n"
|
||||
"is formatted as exFAT. Format your SD card as FAT32, or manually\n"
|
||||
"flash exFAT firmware to package2.\n";
|
||||
}
|
||||
} else if (f_ctx->program_id == ProgramIdBoot) {
|
||||
/* 9.x -> 10.x updated the API for SvcQueryIoMapping. */
|
||||
/* This can cause the kernel to reject incorrect-ABI calls by boot when a partial update is applied */
|
||||
/* (older kernel in package2, for some reason). */
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
if (f_ctx->gprs[i] == svc::ResultNotFound().GetValue()) {
|
||||
suggestion = "A partial update may have been improperly performed.\n"
|
||||
"To fix, try manually flashing latest package2 to MMC.\n"
|
||||
"\n"
|
||||
"For help doing this, seek support in the ReSwitched or\n"
|
||||
"Nintendo Homebrew discord servers.\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (f_ctx->error_desc == 0xF00) { /* Kernel Panic */
|
||||
suggestion = "Please contact SciresM#0524 on Discord, or create an issue on the Atmosphere\n"
|
||||
"GitHub issue tracker. Thank you very much for helping to test mesosphere.\n";
|
||||
}
|
||||
|
||||
/* If we found a suggestion, print it. */
|
||||
if (suggestion != nullptr) {
|
||||
Print("%s", suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDisplayInitialized() {
|
||||
return g_display_initialized;
|
||||
}
|
||||
|
||||
void InitializeDisplay() {
|
||||
if (IsDisplayInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup the framebuffer. */
|
||||
InitializeFrameBuffer();
|
||||
|
||||
/* Get the hardware type. */
|
||||
const auto hw_type = fuse::GetHardwareType();
|
||||
|
||||
/* Turn on DSI/voltage rail. */
|
||||
{
|
||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||
i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, 0x18, 0x3A);
|
||||
i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, 0x18, 0x3A);
|
||||
}
|
||||
i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, 0x23, 0xD0);
|
||||
}
|
||||
|
||||
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_RST_DEV_H_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_H_CLR_CLR_MIPI_CAL_RST, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_DEV_H_CLR_CLR_DSI_RST, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_ENB_H_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_SET_SET_CLK_ENB_MIPI_CAL, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_H_SET_SET_CLK_ENB_DSI, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_RST_DEV_L_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_L_CLR_CLR_HOST1X_RST, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_DEV_L_CLR_CLR_DISP1_RST, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_ENB_L_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_L_SET_SET_CLK_ENB_HOST1X, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_L_SET_SET_CLK_ENB_DISP1, ENABLE));
|
||||
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_ENB_X_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_X_SET_SET_CLK_ENB_UART_FST_MIPI_CAL, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL, CLK_RST_REG_BITS_VALUE(CLK_SOURCE_UART_FST_MIPI_CAL_UART_FST_MIPI_CAL_CLK_DIVISOR, 10),
|
||||
CLK_RST_REG_BITS_ENUM (CLK_SOURCE_UART_FST_MIPI_CAL_UART_FST_MIPI_CAL_CLK_SRC, PLLP_OUT3));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_ENB_W_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_W_SET_SET_CLK_ENB_DSIA_LP, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP, CLK_RST_REG_BITS_VALUE(CLK_SOURCE_DSIA_LP_DSIA_LP_CLK_DIVISOR, 10),
|
||||
CLK_RST_REG_BITS_ENUM (CLK_SOURCE_DSIA_LP_DSIA_LP_CLK_SRC, PLLP_OUT0));
|
||||
|
||||
/* Set IO_DPD_REQ to DPD_OFF. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_IO_DPD_REQ, PMC_REG_BITS_ENUM(IO_DPD_REQ_CODE, DPD_OFF));
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_IO_DPD2_REQ, PMC_REG_BITS_ENUM(IO_DPD2_REQ_CODE, DPD_OFF));
|
||||
|
||||
/* Configure LCD pinmux tristate + passthrough. */
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_NFC_EN, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_NFC_INT, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_LCD_BL_PWM, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_LCD_BL_EN, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_LCD_RST, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
|
||||
if (hw_type == fuse::HardwareType_Aula) {
|
||||
/* Configure LCD backlight. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_CNF_1, 0x4);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OE_1, 0x4);
|
||||
} else {
|
||||
/* Configure LCD power, VDD. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_CNF_0, 0x3);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_OE_0, 0x3);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_OUT_0, 0x1);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_OUT_0, 0x2);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
/* Configure LCD backlight. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_CNF_1, 0x7);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OE_1, 0x7);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x2);
|
||||
}
|
||||
|
||||
/* Configure display interface and display. */
|
||||
reg::Write(g_mipi_cal_regs + MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0);
|
||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||
reg::Write(g_mipi_cal_regs + MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0);
|
||||
reg::Write(g_apb_misc_regs + APB_MISC_GP_DSI_PAD_CONTROL, 0);
|
||||
}
|
||||
|
||||
/* Execute configs. */
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_clk_rst_regs, DisplayConfigPlld01);
|
||||
DO_SLEEP_OR_REGISTER_WRITES(g_disp1_regs, DisplayConfigDc01);
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init01);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init02);
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init03);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init04);
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init05);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsiPhyTiming);
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init06);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsiPhyTiming);
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init07);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
/* Enable backlight reset. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x4);
|
||||
util::WaitMicroSeconds(60'000ul);
|
||||
|
||||
if (hw_type == fuse::HardwareType_Aula) {
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_BTA_TIMING, 0x40103);
|
||||
} else {
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_BTA_TIMING, 0x50204);
|
||||
}
|
||||
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x337);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
WaitDsiTrigger();
|
||||
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x406);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
WaitDsiTrigger();
|
||||
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC);
|
||||
WaitDsiHostControl();
|
||||
util::WaitMicroSeconds(5'000ul);
|
||||
|
||||
/* Parse LCD vendor. */
|
||||
{
|
||||
u32 host_response[3];
|
||||
for (size_t i = 0; i < util::size(host_response); i++) {
|
||||
host_response[i] = reg::Read(g_dsi_regs + sizeof(u32) * DSI_RD_DATA);
|
||||
}
|
||||
|
||||
/* The last word from host response is:
|
||||
Bits 0-7: FAB
|
||||
Bits 8-15: REV
|
||||
Bits 16-23: Minor REV
|
||||
*/
|
||||
u32 lcd_vendor;
|
||||
if ((host_response[2] & 0xFF) == 0x10) {
|
||||
lcd_vendor = 0;
|
||||
} else {
|
||||
lcd_vendor = (host_response[2] >> 8) & 0xFF00;
|
||||
}
|
||||
g_lcd_vendor = (lcd_vendor & 0xFFFFFF00) | (host_response[2] & 0xFF);
|
||||
}
|
||||
|
||||
/* LCD vendor specific configuration. */
|
||||
switch (g_lcd_vendor) {
|
||||
case 0x10: /* Japan Display Inc screens. */
|
||||
DO_SLEEP_OR_REGISTER_WRITES(g_dsi_regs, DisplayConfigJdiSpecificInit01);
|
||||
break;
|
||||
case 0xF20: /* Innolux first revision screens. */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x1105);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(180'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x439);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x9483FFB9);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(5'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x739);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x751548B1);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x143209);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(5'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x2905);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
break;
|
||||
case 0xF30: /* AUO first revision screens. */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x1105);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(180'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x439);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x9483FFB9);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(5'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x739);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x711148B1);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x143209);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(5'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x2905);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
break;
|
||||
case 0x2050: /* Unknown (hardware type 5) screen. */
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x1105);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(180'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0xA015);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x205315);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x339);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x51);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(5'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x2905);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
break;
|
||||
case 0x1020: /* Innolux second revision screen. */
|
||||
case 0x1030: /* AUO second revision screen. */
|
||||
case 0x1040: /* Unknown second revision screen. */
|
||||
default:
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x1105);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
util::WaitMicroSeconds(120'000ul);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_WR_DATA, 0x2905);
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_TRIGGER, DSI_TRIGGER_HOST);
|
||||
break;
|
||||
}
|
||||
util::WaitMicroSeconds(20'000ul);
|
||||
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_clk_rst_regs, DisplayConfigPlld02);
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init08);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsiPhyTiming);
|
||||
DO_SLEEP_OR_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init09);
|
||||
|
||||
reg::Write(g_disp1_regs + sizeof(u32) * DC_DISP_DISP_CLOCK_CONTROL, SHIFT_CLK_DIVIDER(4));
|
||||
DO_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init10);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
/* Configure MIPI CAL. */
|
||||
DO_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal01);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal02);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init11);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal03);
|
||||
DO_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal04);
|
||||
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||
/* On Mariko the above configurations are executed twice, for some reason. */
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal02);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_dsi_regs, DisplayConfigDsi01Init11);
|
||||
DO_SOC_DEPENDENT_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal03);
|
||||
DO_REGISTER_WRITES(g_mipi_cal_regs, DisplayConfigMipiCal04);
|
||||
}
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
/* Write DISP1, FrameBuffer config. */
|
||||
DO_SLEEP_OR_REGISTER_WRITES(g_disp1_regs, DisplayConfigDc02);
|
||||
DO_SLEEP_OR_REGISTER_WRITES(g_disp1_regs, DisplayConfigFrameBuffer);
|
||||
if (g_lcd_vendor != 0x2050) {
|
||||
util::WaitMicroSeconds(35'000ul);
|
||||
}
|
||||
|
||||
g_display_initialized = true;
|
||||
}
|
||||
|
||||
void FinalizeDisplay() {
|
||||
if (!IsDisplayInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: What other configuration is needed, if any? */
|
||||
|
||||
/* Configure LCD pinmux tristate + passthrough. */
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_NFC_EN, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_NFC_INT, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_LCD_BL_PWM, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_LCD_BL_EN, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
reg::ClearBits(g_apb_misc_regs + PINMUX_AUX_LCD_RST, reg::EncodeMask(PINMUX_REG_BITS_MASK(AUX_TRISTATE)));
|
||||
|
||||
if (fuse::GetHardwareType() == fuse::HardwareType_Aula) {
|
||||
/* Configure LCD backlight. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_CNF_1, 0x4);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OE_1, 0x4);
|
||||
} else {
|
||||
/* Configure LCD power, VDD. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_CNF_0, 0x3);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_OE_0, 0x3);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_OUT_0, 0x1);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT3_OUT_0, 0x2);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
|
||||
/* Configure LCD backlight. */
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_CNF_1, 0x7);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OE_1, 0x7);
|
||||
reg::SetBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x2);
|
||||
}
|
||||
|
||||
/* Disable the LCD backlight. */
|
||||
if (g_lcd_vendor == 0x2050) {
|
||||
/* TODO: We're not sure display is alive. How to manage this? */
|
||||
/* This is probably incorrect backlight disable for hw-type 5. */
|
||||
reg::ClearBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x1);
|
||||
} else {
|
||||
reg::ClearBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x1);
|
||||
}
|
||||
|
||||
/* Disable backlight RST/Voltage. */
|
||||
reg::ClearBits(g_gpio_regs + GPIO_PORT6_OUT_1, 0x4);
|
||||
if (g_lcd_vendor == 0x2050) {
|
||||
util::WaitMicroSeconds(30'000ul);
|
||||
} else {
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
reg::ClearBits(g_gpio_regs + GPIO_PORT3_OUT_0, 0x2);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
reg::ClearBits(g_gpio_regs + GPIO_PORT3_OUT_0, 0x1);
|
||||
util::WaitMicroSeconds(10'000ul);
|
||||
}
|
||||
|
||||
/* Cut clock to DSI. */
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_RST_DEV_H_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_H_SET_SET_MIPI_CAL_RST, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_DEV_H_SET_SET_DSI_RST, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_ENB_H_CLR, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLR_CLR_CLK_ENB_MIPI_CAL, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLR_CLR_CLK_ENB_DSI, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_RST_DEV_L_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_L_SET_SET_HOST1X_RST, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_DEV_L_SET_SET_DISP1_RST, ENABLE));
|
||||
|
||||
reg::Write(g_clk_rst_regs + CLK_RST_CONTROLLER_CLK_ENB_L_CLR, CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLR_CLR_CLK_ENB_HOST1X, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLR_CLR_CLK_ENB_DISP1, ENABLE));
|
||||
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_PAD_CONTROL_0, (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)));
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * DSI_POWER_CONTROL, 0);
|
||||
|
||||
g_display_initialized = false;
|
||||
}
|
||||
|
||||
void ShowDisplay() {
|
||||
/* Enable backlight. */
|
||||
constexpr auto DisplayBrightness = 100;
|
||||
if (g_lcd_vendor == 0x2050) {
|
||||
EnableBacklightForVendor2050ForAula(DisplayBrightness);
|
||||
} else {
|
||||
EnableBacklightForGeneric(DisplayBrightness);
|
||||
}
|
||||
}
|
||||
|
||||
u16 GetDisplayLcdVendor() {
|
||||
return g_lcd_vendor;
|
||||
}
|
||||
|
||||
void ShowFatalError(const ams::impl::FatalErrorContext *f_ctx, const Result save_result) {
|
||||
/* If needed, initialize the display. */
|
||||
if (!IsDisplayInitialized()) {
|
||||
InitializeDisplay();
|
||||
}
|
||||
|
||||
/* Initialize the console. */
|
||||
InitializeConsole(g_frame_buffer);
|
||||
|
||||
{
|
||||
Print("%s\n", "A fatal error occurred when running Atmosph\xe8re.");
|
||||
Print("Program ID: %016" PRIx64 "\n", f_ctx->program_id);
|
||||
Print("Error Desc: %s (0x%" PRIx32 ")\n", GetErrorDescription(f_ctx->error_desc), f_ctx->error_desc);
|
||||
Print("\n");
|
||||
|
||||
if (R_SUCCEEDED(save_result)) {
|
||||
Print("Report saved to /atmosphere/fatal_errors/report_%016" PRIx64 ".bin", f_ctx->report_identifier);
|
||||
} else {
|
||||
Print("Failed to save report to the SD card! (%08" PRIx32 ")\n", save_result.GetValue());
|
||||
}
|
||||
|
||||
PrintSuggestedErrorFix(f_ctx);
|
||||
|
||||
Print("\nPress POWER to reboot.\n");
|
||||
}
|
||||
|
||||
/* Ensure the device will see consistent data. */
|
||||
hw::FlushDataCache(g_frame_buffer, FrameBufferSize);
|
||||
|
||||
/* Show the console. */
|
||||
ShowDisplay();
|
||||
}
|
||||
|
||||
void ShowFatalError(const char *fmt, ...) {
|
||||
/* If needed, initialize the display. */
|
||||
if (!IsDisplayInitialized()) {
|
||||
InitializeDisplay();
|
||||
}
|
||||
|
||||
/* Initialize the console. */
|
||||
InitializeConsole(g_frame_buffer);
|
||||
|
||||
{
|
||||
Print("%s\n", "A fatal error occurred when running Fus" "\xe9" "e.");
|
||||
{
|
||||
std::va_list vl;
|
||||
va_start(vl, fmt);
|
||||
VPrint(fmt, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
Print("\n");
|
||||
|
||||
Print("\nPress POWER to reboot.\n");
|
||||
}
|
||||
|
||||
/* Ensure the device will see consistent data. */
|
||||
hw::FlushDataCache(g_frame_buffer, FrameBufferSize);
|
||||
|
||||
/* Show the console. */
|
||||
ShowDisplay();
|
||||
|
||||
WaitForReboot();
|
||||
}
|
||||
|
||||
}
|
||||
33
fusee/program/source/fusee_display.hpp
Normal file
33
fusee/program/source/fusee_display.hpp
Normal 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 <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
constexpr inline size_t FrameBufferHeight = 768;
|
||||
constexpr inline size_t FrameBufferWidth = 1280;
|
||||
constexpr inline size_t FrameBufferSize = FrameBufferHeight * FrameBufferWidth * sizeof(u32);
|
||||
|
||||
bool IsDisplayInitialized();
|
||||
void InitializeDisplay();
|
||||
void FinalizeDisplay();
|
||||
|
||||
u16 GetDisplayLcdVendor();
|
||||
|
||||
void ShowDisplay();
|
||||
|
||||
}
|
||||
682
fusee/program/source/fusee_display_config.inc
Normal file
682
fusee/program/source/fusee_display_config.inc
Normal file
@@ -0,0 +1,682 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
struct RegisterWrite {
|
||||
u32 offset;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
enum SleepOrRegisterWriteKind : u16 {
|
||||
SleepOrRegisterWriteKind_Write = 0,
|
||||
SleepOrRegisterWriteKind_Sleep = 1,
|
||||
};
|
||||
|
||||
struct SleepOrRegisterWrite {
|
||||
SleepOrRegisterWriteKind kind;
|
||||
u16 offset;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigPlld01Erista[] = {
|
||||
{CLK_RST_CONTROLLER_CLK_SOURCE_DISP1, 0x40000000},
|
||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4830A001},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000020},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002D0AAA},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigPlld01Mariko[] = {
|
||||
{CLK_RST_CONTROLLER_CLK_SOURCE_DISP1, 0x40000000},
|
||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4830A001},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000000},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002DFC00},
|
||||
};
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigDc01[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_REG_ACT_CONTROL, 0x54},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DV_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_YOF, 0xF0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUR, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVR, 0x198},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUG, 0x39B},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVG, 0x32F},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUB, 0x204},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DV_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_YOF, 0xF0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUR, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVR, 0x198},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUG, 0x39B},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVG, 0x32F},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUB, 0x204},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DV_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_YOF, 0xF0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUR, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVR, 0x198},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUG, 0x39B},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVG, 0x32F},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUB, 0x204},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{SleepOrRegisterWriteKind_Write, 0x4E4, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_CRC_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, 0x716, 0x10000FF},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, 0x716, 0x10000FF},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, 0x716, 0x10000FF},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init01[] = {
|
||||
{sizeof(u32) * DSI_WR_DATA, 0x0},
|
||||
{sizeof(u32) * DSI_INT_ENABLE, 0x0},
|
||||
{sizeof(u32) * DSI_INT_STATUS, 0x0},
|
||||
{sizeof(u32) * DSI_INT_MASK, 0x0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_DATA_0, 0x0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_DATA_1, 0x0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_DATA_2, 0x0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_DATA_3, 0x0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init02Erista[] = {
|
||||
{sizeof(u32) * DSI_INIT_SEQ_DATA_15, 0x0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init02Mariko[] = {
|
||||
{sizeof(u32) * DSI_INIT_SEQ_DATA_15_MARIKO, 0x0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init03[] = {
|
||||
{sizeof(u32) * DSI_DCS_CMDS, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_0_LO, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_1_LO, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_2_LO, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_3_LO, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_4_LO, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_5_LO, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_0_HI, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_1_HI, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_2_HI, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_3_HI, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_4_HI, 0},
|
||||
{sizeof(u32) * DSI_PKT_SEQ_5_HI, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init04Erista[] = {
|
||||
/* No register writes. */
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init04Mariko[] = {
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_2, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_3, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_4, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_5_MARIKO, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_6_MARIKO, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_7_MARIKO, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init05[] = {
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_CD, 0},
|
||||
{sizeof(u32) * DSI_SOL_DELAY, 0x18},
|
||||
{sizeof(u32) * DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{sizeof(u32) * DSI_TRIGGER, 0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_CONTROL, 0},
|
||||
{sizeof(u32) * DSI_PKT_LEN_0_1, 0},
|
||||
{sizeof(u32) * DSI_PKT_LEN_2_3, 0},
|
||||
{sizeof(u32) * DSI_PKT_LEN_4_5, 0},
|
||||
{sizeof(u32) * DSI_PKT_LEN_6_7, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init06[] = {
|
||||
{sizeof(u32) * DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{sizeof(u32) * DSI_PHY_TIMING_2, 0x30109},
|
||||
{sizeof(u32) * DSI_BTA_TIMING, 0x190A14},
|
||||
{sizeof(u32) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{sizeof(u32) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{sizeof(u32) * DSI_TO_TALLY, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, 0},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init07[] = {
|
||||
{sizeof(u32) * DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{sizeof(u32) * DSI_PHY_TIMING_2, 0x30118},
|
||||
{sizeof(u32) * DSI_BTA_TIMING, 0x190A14},
|
||||
{sizeof(u32) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{sizeof(u32) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{sizeof(u32) * DSI_TO_TALLY, 0},
|
||||
{sizeof(u32) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{sizeof(u32) * DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{sizeof(u32) * DSI_MAX_THRESHOLD, 0x40},
|
||||
{sizeof(u32) * DSI_TRIGGER, 0},
|
||||
{sizeof(u32) * DSI_TX_CRC, 0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsiPhyTimingErista[] = {
|
||||
{sizeof(u32) * DSI_PHY_TIMING_0, 0x6070601},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsiPhyTimingMariko[] = {
|
||||
{sizeof(u32) * DSI_PHY_TIMING_0, 0x6070603},
|
||||
};
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigJdiSpecificInit01[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x439},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x9483FFB9},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xBD15},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x1939},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAAAAAAD8},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAAAAAAAA},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xAA},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x1BD15},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2739},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2BD15},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xF39},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xFFFFFF},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xBD15},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x6D915},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x439},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xB9},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x1105},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Sleep, 180, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2905},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigPlld02Erista[] = {
|
||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4810c001},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000020},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002D0AAA},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigPlld02Mariko[] = {
|
||||
{CLK_RST_CONTROLLER_PLLD_BASE, 0x4810c001},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC1, 0x00000000},
|
||||
{CLK_RST_CONTROLLER_PLLD_MISC, 0x002DFC00},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init08[] = {
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
};
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigDsi01Init09[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PHY_TIMING_2, 0x30172},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_BTA_TIMING, 0x190A14},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TO_TALLY, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_4_LO, 0x40000308},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_1_LO, 0x40000308},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_3_LO, 0x3F3B2B08},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_3_HI, 0x2CC},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_SEQ_5_HI, 0x2CC},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_LEN_0_1, 0xCE0000},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_LEN_4_5, 0x190},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_PKT_LEN_6_7, 0x190},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_HOST_CONTROL, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init10[] = {
|
||||
{sizeof(u32) * DSI_TRIGGER, 0},
|
||||
{sizeof(u32) * DSI_CONTROL, 0},
|
||||
{sizeof(u32) * DSI_SOL_DELAY, 6},
|
||||
{sizeof(u32) * DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{sizeof(u32) * DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{sizeof(u32) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{sizeof(u32) * DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{sizeof(u32) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{sizeof(u32) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init11Erista[] = {
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_2, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_4, 0}
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Init11Mariko[] = {
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_2, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_3, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_4, 0x77777},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_5_MARIKO, 0x77777},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_6_MARIKO, DSI_PAD_PREEMP_PD_CLK(0x1) | DSI_PAD_PREEMP_PU_CLK(0x1) | DSI_PAD_PREEMP_PD(0x01) | DSI_PAD_PREEMP_PU(0x1)},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_7_MARIKO, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigMipiCal01[] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 1},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigMipiCal02Erista[] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0x10010},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG1, 0x300},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigMipiCal02Mariko[] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0x10010},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG1, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigMipiCal03Erista[] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigMipiCal03Mariko[] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000},
|
||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigMipiCal04[] = {
|
||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILD_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILE_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILF_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001},
|
||||
};
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigDc02[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DV_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_YOF, 0xF0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUR, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVR, 0x198},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUG, 0x39B},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVG, 0x32F},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUB, 0x204},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DV_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_YOF, 0xF0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUR, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVR, 0x198},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUG, 0x39B},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVG, 0x32F},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUB, 0x204},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DV_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_YOF, 0xF0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUR, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVR, 0x198},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUG, 0x39B},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVG, 0x32F},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KUB, 0x204},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{SleepOrRegisterWriteKind_Write, 0x4E4, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_CRC_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, 0x716, 0x10000FF},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, 0x716, 0x10000FF},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, 0x716, 0x10000FF},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, 0},
|
||||
/* Set Display timings */
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_BACK_PORCH, 0x90048},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_ACTIVE, 0x50002D0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
/* End of Display timings */
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_CLOCK_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_ACCESS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
|
||||
};
|
||||
|
||||
constexpr u32 DisplayConfigFrameBufferAddress = 0xC0400000;
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigFrameBuffer[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_POSITION, 0}, //(0,0)
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_H_INITIAL_DDA, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_V_INITIAL_DDA, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_BUFFER_CONTROL, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WINBUF_START_ADDR, DisplayConfigFrameBufferAddress}, //Framebuffer address.
|
||||
{SleepOrRegisterWriteKind_Write, DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, 0},
|
||||
{SleepOrRegisterWriteKind_Write, DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{SleepOrRegisterWriteKind_Write, DC_WIN_WIN_OPTIONS, WIN_ENABLE}, //Enable window AD.
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
|
||||
{SleepOrRegisterWriteKind_Write, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDc01Fini01[] = {
|
||||
{sizeof(u32) * DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{sizeof(u32) * DC_CMD_INT_MASK, 0},
|
||||
{sizeof(u32) * DC_CMD_STATE_ACCESS, 0},
|
||||
{sizeof(u32) * DC_CMD_INT_ENABLE, 0},
|
||||
{sizeof(u32) * DC_CMD_CONT_SYNCPT_VSYNC, 0},
|
||||
{sizeof(u32) * DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||
{sizeof(u32) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{sizeof(u32) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{sizeof(u32) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{sizeof(u32) * DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{sizeof(u32) * DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{sizeof(u32) * DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{sizeof(u32) * DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Fini01[] = {
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, 0},
|
||||
{sizeof(u32) * DSI_PAD_CONTROL_1, 0},
|
||||
};
|
||||
|
||||
constexpr const RegisterWrite DisplayConfigDsi01Fini02[] = {
|
||||
{sizeof(u32) * DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{sizeof(u32) * DSI_PHY_TIMING_2, 0x30118},
|
||||
{sizeof(u32) * DSI_BTA_TIMING, 0x190A14},
|
||||
{sizeof(u32) * DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
||||
{sizeof(u32) * DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{sizeof(u32) * DSI_TO_TALLY, 0},
|
||||
{sizeof(u32) * DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{sizeof(u32) * DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{sizeof(u32) * DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{sizeof(u32) * DSI_MAX_THRESHOLD, 0x40},
|
||||
{sizeof(u32) * DSI_TRIGGER, 0},
|
||||
{sizeof(u32) * DSI_TX_CRC, 0},
|
||||
{sizeof(u32) * DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigJdiSpecificFini01[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x439},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x9483FFB9},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2139},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x191919D5},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xB39},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x4F0F41B1},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xF179A433},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2D81},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x439},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xB9},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
};
|
||||
|
||||
constexpr const SleepOrRegisterWrite DisplayConfigAuoRev1SpecificFini01[] = {
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x439},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x9483FFB9},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2C39},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x191919D5},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x2C39},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x191919D6},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x19191919},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xB39},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x711148B1},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x71143209},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x114D31},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0x439},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_WR_DATA, 0xB9},
|
||||
{SleepOrRegisterWriteKind_Write, DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{SleepOrRegisterWriteKind_Sleep, 5, 0},
|
||||
};
|
||||
485
fusee/program/source/fusee_emummc.cpp
Normal file
485
fusee/program/source/fusee_emummc.cpp
Normal file
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_emummc.hpp"
|
||||
#include "fusee_mmc.hpp"
|
||||
#include "fusee_sd_card.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
#include "fusee_malloc.hpp"
|
||||
#include "fs/fusee_fs_api.hpp"
|
||||
#include "fs/fusee_fs_storage.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
class SdCardStorage : public fs::IStorage {
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
if (!util::IsAligned(offset, sdmmc::SectorSize) || !util::IsAligned(size, sdmmc::SectorSize)) {
|
||||
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
|
||||
}
|
||||
|
||||
return ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
u32 num_sectors;
|
||||
R_TRY(GetSdCardMemoryCapacity(std::addressof(num_sectors)));
|
||||
|
||||
*out = static_cast<s64>(num_sectors) * static_cast<s64>(sdmmc::SectorSize);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
template<sdmmc::MmcPartition Partition>
|
||||
class MmcPartitionStorage : public fs::IStorage {
|
||||
public:
|
||||
constexpr MmcPartitionStorage() { /* ... */ }
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
if (!util::IsAligned(offset, sdmmc::SectorSize) || !util::IsAligned(size, sdmmc::SectorSize)) {
|
||||
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
|
||||
}
|
||||
|
||||
return ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
u32 num_sectors;
|
||||
R_TRY(GetMmcMemoryCapacity(std::addressof(num_sectors), Partition));
|
||||
|
||||
*out = num_sectors * sdmmc::SectorSize;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
using MmcBoot0Storage = MmcPartitionStorage<sdmmc::MmcPartition_BootPartition1>;
|
||||
using MmcUserStorage = MmcPartitionStorage<sdmmc::MmcPartition_UserData>;
|
||||
|
||||
constinit char g_emummc_path[0x300];
|
||||
|
||||
class EmummcFileStorage : public fs::IStorage {
|
||||
private:
|
||||
s64 m_file_size;
|
||||
fs::FileHandle m_handles[64];
|
||||
bool m_open[64];
|
||||
int m_file_path_ofs;
|
||||
private:
|
||||
void EnsureFile(int id) {
|
||||
if (!m_open[id]) {
|
||||
/* Update path. */
|
||||
g_emummc_path[m_file_path_ofs + 1] = '0' + (id % 10);
|
||||
g_emummc_path[m_file_path_ofs + 0] = '0' + (id / 10);
|
||||
|
||||
/* Open new file. */
|
||||
const Result result = fs::OpenFile(m_handles + id, g_emummc_path, fs::OpenMode_Read);
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to open emummc user %02d file: 0x%08" PRIx32 "!\n", id, result.GetValue());
|
||||
}
|
||||
|
||||
m_open[id] = true;
|
||||
}
|
||||
}
|
||||
public:
|
||||
EmummcFileStorage(fs::FileHandle user00, int ofs) : m_file_path_ofs(ofs) {
|
||||
const Result result = fs::GetFileSize(std::addressof(m_file_size), user00);
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to get emummc file size: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < util::size(m_handles); ++i) {
|
||||
m_open[i] = false;
|
||||
}
|
||||
|
||||
m_handles[0] = user00;
|
||||
m_open[0] = true;
|
||||
}
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
int file = offset / m_file_size;
|
||||
s64 subofs = offset % m_file_size;
|
||||
|
||||
u8 *cur_dst = static_cast<u8 *>(buffer);
|
||||
|
||||
for (/* ... */; size > 0; ++file) {
|
||||
/* Ensure the current file is open. */
|
||||
EnsureFile(file);
|
||||
|
||||
/* Perform the current read. */
|
||||
const size_t cur_size = std::min<size_t>(m_file_size - subofs, size);
|
||||
R_TRY(fs::ReadFile(m_handles[file], subofs, cur_dst, cur_size));
|
||||
|
||||
/* Advance. */
|
||||
cur_dst += cur_size;
|
||||
size -= cur_size;
|
||||
subofs = 0;
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
constinit SdCardStorage g_sd_card_storage;
|
||||
|
||||
constinit MmcBoot0Storage g_mmc_boot0_storage;
|
||||
constinit MmcUserStorage g_mmc_user_storage;
|
||||
|
||||
constinit fs::IStorage *g_boot0_storage = nullptr;
|
||||
constinit fs::IStorage *g_user_storage = nullptr;
|
||||
|
||||
class SystemPartitionStorage : public fs::IStorage {
|
||||
private:
|
||||
static constexpr size_t CacheEntries = BITSIZEOF(u32);
|
||||
static constexpr size_t SectorSize = 0x4000;
|
||||
private:
|
||||
fs::SubStorage m_storage;
|
||||
u8 *m_sector_cache;
|
||||
u32 *m_sector_ids;
|
||||
u32 m_sector_flags;
|
||||
u32 m_next_idx;
|
||||
private:
|
||||
Result LoadSector(u8 *sector, u32 sector_id) {
|
||||
/* Read the sector data. */
|
||||
R_TRY(m_storage.Read(static_cast<s64>(sector_id) * SectorSize, sector, SectorSize));
|
||||
|
||||
/* Decrypt the sector. */
|
||||
se::DecryptAes128Xts(sector, SectorSize, pkg1::AesKeySlot_BootloaderSystem0, pkg1::AesKeySlot_BootloaderSystem1, sector, SectorSize, sector_id);
|
||||
|
||||
/* Mark the sector as freshly loaded. */
|
||||
m_sector_flags &= ~(1u << (sector_id % CacheEntries));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetSector(u8 **out_sector, u32 sector_id) {
|
||||
/* Try to find in the cache. */
|
||||
for (size_t i = 0; i < CacheEntries; ++i) {
|
||||
if (m_sector_ids[i] == sector_id) {
|
||||
m_sector_flags &= ~(1u << i);
|
||||
*out_sector = m_sector_cache + SectorSize * i;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/* Find a sector to evict. */
|
||||
while ((m_sector_flags & (1u << m_next_idx)) == 0) {
|
||||
m_sector_flags |= (1u << m_next_idx);
|
||||
m_next_idx = (m_next_idx + 1) % CacheEntries;
|
||||
}
|
||||
|
||||
/* Get the chosen sector. */
|
||||
*out_sector = m_sector_cache + SectorSize * m_next_idx;
|
||||
m_next_idx = (m_next_idx + 1) % CacheEntries;
|
||||
|
||||
/* Load the sector. */
|
||||
return this->LoadSector(*out_sector, sector_id);
|
||||
}
|
||||
public:
|
||||
SystemPartitionStorage(s64 ofs, s64 size) : m_storage(*g_user_storage, ofs, size) {
|
||||
/* Allocate sector cache. */
|
||||
m_sector_cache = static_cast<u8 *>(AllocateAligned(CacheEntries * SectorSize, SectorSize));
|
||||
|
||||
/* Allocate sector ids. */
|
||||
m_sector_ids = static_cast<u32 *>(AllocateAligned(CacheEntries * sizeof(u32), alignof(u32)));
|
||||
for (size_t i = 0; i < CacheEntries; ++i) {
|
||||
m_sector_ids[i] = std::numeric_limits<u32>::max();
|
||||
}
|
||||
|
||||
/* All sectors are dirty. */
|
||||
m_sector_flags = ~0u;
|
||||
|
||||
/* Next sector is 0. */
|
||||
m_next_idx = 0;
|
||||
}
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
u32 sector_id = offset / SectorSize;
|
||||
s64 subofs = offset % SectorSize;
|
||||
|
||||
u8 *cur_dst = static_cast<u8 *>(buffer);
|
||||
while (size > 0) {
|
||||
/* Get the current sector. */
|
||||
u8 *sector;
|
||||
R_TRY(this->GetSector(std::addressof(sector), sector_id++));
|
||||
|
||||
/* Copy the data. */
|
||||
const size_t cur_size = std::min<size_t>(SectorSize - subofs, size);
|
||||
std::memcpy(cur_dst, sector + subofs, cur_size);
|
||||
|
||||
/* Advance. */
|
||||
cur_dst += cur_size;
|
||||
size -= cur_size;
|
||||
subofs = 0;
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return m_storage.Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
return m_storage.GetSize(out);
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
};
|
||||
|
||||
constinit SystemPartitionStorage *g_system_storage = nullptr;
|
||||
constinit fs::SubStorage *g_package2_storage = nullptr;
|
||||
|
||||
struct Guid {
|
||||
u32 data1;
|
||||
u16 data2;
|
||||
u16 data3;
|
||||
u8 data4[8];
|
||||
};
|
||||
static_assert(sizeof(Guid) == 0x10);
|
||||
|
||||
struct GptHeader {
|
||||
char signature[8];
|
||||
u32 revision;
|
||||
u32 header_size;
|
||||
u32 header_crc32;
|
||||
u32 reserved0;
|
||||
u64 my_lba;
|
||||
u64 alt_lba;
|
||||
u64 first_usable_lba;
|
||||
u64 last_usable_lba;
|
||||
Guid disk_guid;
|
||||
u64 partition_entry_lba;
|
||||
u32 number_of_partition_entries;
|
||||
u32 size_of_partition_entry;
|
||||
u32 partition_entry_array_crc32;
|
||||
u32 reserved1;
|
||||
};
|
||||
static_assert(sizeof(GptHeader) == 0x60);
|
||||
|
||||
struct GptPartitionEntry {
|
||||
Guid partition_type_guid;
|
||||
Guid unique_partition_guid;
|
||||
u64 starting_lba;
|
||||
u64 ending_lba;
|
||||
u64 attributes;
|
||||
char partition_name[0x48];
|
||||
};
|
||||
static_assert(sizeof(GptPartitionEntry) == 0x80);
|
||||
|
||||
struct Gpt {
|
||||
GptHeader header;
|
||||
u8 padding[0x1A0];
|
||||
GptPartitionEntry entries[128];
|
||||
};
|
||||
static_assert(sizeof(Gpt) == 16_KB + 0x200);
|
||||
|
||||
constexpr const u16 SystemPartitionName[] = {
|
||||
'S', 'Y', 'S', 'T', 'E', 'M', 0
|
||||
};
|
||||
|
||||
constexpr const u16 Package2PartitionName[] = {
|
||||
'B', 'C', 'P', 'K', 'G', '2', '-', '1', '-', 'N', 'o', 'r', 'm', 'a', 'l', '-', 'M', 'a', 'i', 'n', 0
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void InitializeEmummc(bool emummc_enabled, const secmon::EmummcConfiguration &emummc_cfg) {
|
||||
Result result;
|
||||
if (emummc_enabled) {
|
||||
/* Get sd card size. */
|
||||
s64 sd_card_size;
|
||||
if (R_FAILED((result = g_sd_card_storage.GetSize(std::addressof(sd_card_size))))) {
|
||||
ShowFatalError("Failed to get sd card size: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
if (emummc_cfg.base_cfg.type == secmon::EmummcType_Partition) {
|
||||
const s64 partition_start = emummc_cfg.partition_cfg.start_sector * sdmmc::SectorSize;
|
||||
g_boot0_storage = AllocateObject<fs::SubStorage>(g_sd_card_storage, partition_start, 4_MB);
|
||||
g_user_storage = AllocateObject<fs::SubStorage>(g_sd_card_storage, partition_start + 8_MB, sd_card_size - (partition_start + 8_MB));
|
||||
} else if (emummc_cfg.base_cfg.type == secmon::EmummcType_File) {
|
||||
/* Get the base emummc path. */
|
||||
std::memcpy(g_emummc_path, emummc_cfg.file_cfg.path.str, sizeof(emummc_cfg.file_cfg.path.str));
|
||||
|
||||
/* Get path length. */
|
||||
auto len = std::strlen(g_emummc_path);
|
||||
|
||||
/* Append emmc. */
|
||||
std::memcpy(g_emummc_path + len, "/eMMC", 6);
|
||||
len += 5;
|
||||
|
||||
/* Open boot0. */
|
||||
fs::FileHandle boot0_file;
|
||||
std::memcpy(g_emummc_path + len, "/boot0", 7);
|
||||
if (R_FAILED((result = fs::OpenFile(std::addressof(boot0_file), g_emummc_path, fs::OpenMode_Read)))) {
|
||||
ShowFatalError("Failed to open emummc boot0 file: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
/* Open boot1. */
|
||||
g_emummc_path[len + 5] = '1';
|
||||
{
|
||||
fs::DirectoryEntryType entry_type;
|
||||
bool is_archive;
|
||||
if (R_FAILED((result = fs::GetEntryType(std::addressof(entry_type), std::addressof(is_archive), g_emummc_path)))) {
|
||||
ShowFatalError("Failed to find emummc boot1 file: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
if (entry_type != fs::DirectoryEntryType_File) {
|
||||
ShowFatalError("emummc boot1 file is not a file!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Open userdata. */
|
||||
std::memcpy(g_emummc_path + len, "/00", 4);
|
||||
fs::FileHandle user00_file;
|
||||
if (R_FAILED((result = fs::OpenFile(std::addressof(user00_file), g_emummc_path, fs::OpenMode_Read)))) {
|
||||
ShowFatalError("Failed to open emummc user %02d file: 0x%08" PRIx32 "!\n", 0, result.GetValue());
|
||||
}
|
||||
|
||||
/* Create partitions. */
|
||||
g_boot0_storage = AllocateObject<fs::FileHandleStorage>(boot0_file);
|
||||
g_user_storage = AllocateObject<EmummcFileStorage>(user00_file, len + 1);
|
||||
} else {
|
||||
ShowFatalError("Unknown emummc type %d\n", static_cast<int>(emummc_cfg.base_cfg.type));
|
||||
}
|
||||
} else {
|
||||
/* Initialize access to mmc. */
|
||||
{
|
||||
const Result result = InitializeMmc();
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to initialize mmc: 0x%08" PRIx32 "\n", result.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
/* Create storages. */
|
||||
g_boot0_storage = std::addressof(g_mmc_boot0_storage);
|
||||
g_user_storage = std::addressof(g_mmc_user_storage);
|
||||
}
|
||||
if (g_boot0_storage == nullptr) {
|
||||
ShowFatalError("Failed to initialize BOOT0\n");
|
||||
}
|
||||
if (g_user_storage == nullptr) {
|
||||
ShowFatalError("Failed to initialize Raw EMMC\n");
|
||||
}
|
||||
|
||||
/* Read the GPT. */
|
||||
Gpt *gpt = static_cast<Gpt *>(AllocateAligned(sizeof(Gpt), 0x200));
|
||||
{
|
||||
const Result result = g_user_storage->Read(0x200, gpt, sizeof(*gpt));
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to read GPT: 0x%08" PRIx32 "\n", result.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the GPT. */
|
||||
if (std::memcmp(gpt->header.signature, "EFI PART", 8) != 0) {
|
||||
ShowFatalError("Invalid GPT signature\n");
|
||||
}
|
||||
if (gpt->header.number_of_partition_entries > util::size(gpt->entries)) {
|
||||
ShowFatalError("Too many GPT entries\n");
|
||||
}
|
||||
|
||||
/* Create system storage. */
|
||||
for (u32 i = 0; i < gpt->header.number_of_partition_entries; ++i) {
|
||||
if (gpt->entries[i].starting_lba < gpt->header.first_usable_lba) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const s64 offset = INT64_C(0x200) * gpt->entries[i].starting_lba;
|
||||
const u64 size = UINT64_C(0x200) * (gpt->entries[i].ending_lba + 1 - gpt->entries[i].starting_lba);
|
||||
|
||||
if (std::memcmp(gpt->entries[i].partition_name, SystemPartitionName, sizeof(SystemPartitionName)) == 0) {
|
||||
g_system_storage = AllocateObject<SystemPartitionStorage>(offset, size);
|
||||
} else if (std::memcmp(gpt->entries[i].partition_name, Package2PartitionName, sizeof(Package2PartitionName)) == 0) {
|
||||
g_package2_storage = AllocateObject<fs::SubStorage>(*g_user_storage, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that we created system storage. */
|
||||
if (g_system_storage == nullptr) {
|
||||
ShowFatalError("Failed to initialize SYSTEM\n");
|
||||
}
|
||||
|
||||
/* Check that we created package2 storage. */
|
||||
if (g_package2_storage == nullptr) {
|
||||
ShowFatalError("Failed to initialize Package2\n");
|
||||
}
|
||||
|
||||
/* Mount system. */
|
||||
if (!fs::MountSystem()) {
|
||||
ShowFatalError("Failed to mount SYSTEM\n");
|
||||
}
|
||||
}
|
||||
|
||||
Result ReadBoot0(s64 offset, void *dst, size_t size) {
|
||||
return g_boot0_storage->Read(offset, dst, size);
|
||||
}
|
||||
|
||||
Result ReadPackage2(s64 offset, void *dst, size_t size) {
|
||||
return g_package2_storage->Read(offset, dst, size);
|
||||
}
|
||||
|
||||
Result ReadSystem(s64 offset, void *dst, size_t size) {
|
||||
return g_system_storage->Read(offset, dst, size);
|
||||
}
|
||||
|
||||
}
|
||||
29
fusee/program/source/fusee_emummc.hpp
Normal file
29
fusee/program/source/fusee_emummc.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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/secmon/secmon_emummc_context.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void InitializeEmummc(bool emummc_enabled, const secmon::EmummcConfiguration &emummc_cfg);
|
||||
|
||||
Result ReadBoot0(s64 offset, void *dst, size_t size);
|
||||
Result ReadPackage2(s64 offset, void *dst, size_t size);
|
||||
Result ReadSystem(s64 offset, void *dst, size_t size);
|
||||
|
||||
}
|
||||
75
fusee/program/source/fusee_exception_handler.cpp
Normal file
75
fusee/program/source/fusee_exception_handler.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_exception_handler.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
NORETURN void ErrorStop() {
|
||||
/* ABORT? */
|
||||
*reinterpret_cast<volatile u32 *>(0x40038000) = 0xDEADDEAD;
|
||||
*reinterpret_cast<volatile u32 *>(0x7000E400) = 0x10;
|
||||
|
||||
/* Halt ourselves. */
|
||||
while (true) {
|
||||
reg::Write(secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress() + FLOW_CTLR_HALT_COP_EVENTS, FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_MODE, FLOW_MODE_STOP),
|
||||
FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_JTAG, ENABLED));
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN void ExceptionHandlerImpl(s32 which, u32 lr, u32 svc_lr) {
|
||||
/* TODO */
|
||||
*reinterpret_cast<volatile u32 *>(0x40038004) = 0xCAFEBABE;
|
||||
*reinterpret_cast<volatile u32 *>(0x40038008) = which;
|
||||
*reinterpret_cast<volatile u32 *>(0x4003800C) = lr;
|
||||
*reinterpret_cast<volatile u32 *>(0x40038010) = svc_lr;
|
||||
ErrorStop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ams::diag {
|
||||
|
||||
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value, const char *format, ...) {
|
||||
AMS_UNUSED(file, line, func, expr, value, format);
|
||||
{
|
||||
u32 lr;
|
||||
__asm__ __volatile__("mov %0, lr" : "=r"(lr) :: "memory");
|
||||
*reinterpret_cast<volatile u32 *>(0x40038004) = lr;
|
||||
}
|
||||
ams::nxboot::ErrorStop();
|
||||
}
|
||||
|
||||
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value) {
|
||||
AMS_UNUSED(file, line, func, expr, value);
|
||||
{
|
||||
u32 lr;
|
||||
__asm__ __volatile__("mov %0, lr" : "=r"(lr) :: "memory");
|
||||
*reinterpret_cast<volatile u32 *>(0x40038004) = lr;
|
||||
}
|
||||
ams::nxboot::ErrorStop();
|
||||
}
|
||||
|
||||
NORETURN void AbortImpl() {
|
||||
{
|
||||
u32 lr;
|
||||
__asm__ __volatile__("mov %0, lr" : "=r"(lr) :: "memory");
|
||||
*reinterpret_cast<volatile u32 *>(0x40038004) = lr;
|
||||
}
|
||||
ams::nxboot::ErrorStop();
|
||||
}
|
||||
|
||||
}
|
||||
32
fusee/program/source/fusee_exception_handler.hpp
Normal file
32
fusee/program/source/fusee_exception_handler.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
NORETURN void ExceptionHandler();
|
||||
|
||||
NORETURN void ExceptionHandler0();
|
||||
NORETURN void ExceptionHandler1();
|
||||
NORETURN void ExceptionHandler2();
|
||||
NORETURN void ExceptionHandler3();
|
||||
NORETURN void ExceptionHandler4();
|
||||
NORETURN void ExceptionHandler5();
|
||||
NORETURN void ExceptionHandler6();
|
||||
NORETURN void ExceptionHandler7();
|
||||
|
||||
}
|
||||
114
fusee/program/source/fusee_exception_handler_asm.s
Normal file
114
fusee/program/source/fusee_exception_handler_asm.s
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandlerNEl, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
.type _ZN3ams6nxboot17ExceptionHandlerNEl, %function
|
||||
_ZN3ams6nxboot17ExceptionHandlerNEl:
|
||||
/* Get the normal return address. */
|
||||
mov r1, lr
|
||||
|
||||
/* Get the SVC return address. */
|
||||
msr cpsr_cf, #0xD3
|
||||
mov r2, lr
|
||||
|
||||
/* Invoke the exception handler in abort mode. */
|
||||
msr cpsr_cf, #0xD7
|
||||
b _ZN3ams6nxboot20ExceptionHandlerImplElmm
|
||||
|
||||
|
||||
.section .text._ZN3ams6nxboot16ExceptionHandlerEv, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot16ExceptionHandlerEv
|
||||
.type _ZN3ams6nxboot16ExceptionHandlerEv, %function
|
||||
_ZN3ams6nxboot16ExceptionHandlerEv:
|
||||
mov r0, #-1
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler0Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler0Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler0Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler0Ev:
|
||||
mov r0, #0
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler1Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler1Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler1Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler1Ev:
|
||||
mov r0, #1
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler2Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler2Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler2Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler2Ev:
|
||||
mov r0, #2
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler3Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler3Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler3Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler3Ev:
|
||||
mov r0, #3
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler4Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler4Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler4Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler4Ev:
|
||||
mov r0, #4
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler5Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler5Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler5Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler5Ev:
|
||||
mov r0, #5
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler6Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler6Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler6Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler6Ev:
|
||||
mov r0, #6
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
|
||||
.section .text._ZN3ams6nxboot17ExceptionHandler7Ev, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot17ExceptionHandler7Ev
|
||||
.type _ZN3ams6nxboot17ExceptionHandler7Ev, %function
|
||||
_ZN3ams6nxboot17ExceptionHandler7Ev:
|
||||
mov r0, #7
|
||||
b _ZN3ams6nxboot17ExceptionHandlerNEl
|
||||
91
fusee/program/source/fusee_fatal.cpp
Normal file
91
fusee/program/source/fusee_fatal.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_fatal.hpp"
|
||||
#include "fs/fusee_fs_api.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
Result SaveFatalErrorContext(const ams::impl::FatalErrorContext *ctx) {
|
||||
/* Create and open the file. */
|
||||
fs::FileHandle file;
|
||||
{
|
||||
/* Generate the file path. */
|
||||
char path[0x40];
|
||||
util::TSNPrintf(path, sizeof(path), "sdmc:/atmosphere/fatal_errors/report_%016" PRIx64 ".bin", ctx->report_identifier);
|
||||
|
||||
/* Create the file. */
|
||||
R_TRY(fs::CreateFile(path, sizeof(*ctx)));
|
||||
|
||||
/* Open the file. */
|
||||
R_TRY(fs::OpenFile(std::addressof(file), path, fs::OpenMode_ReadWrite));
|
||||
}
|
||||
|
||||
/* Ensure we close the file when done with it. */
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
|
||||
/* Write the context to the file. */
|
||||
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SaveAndShowFatalError() {
|
||||
/* Get the context (at static location in memory). */
|
||||
ams::impl::FatalErrorContext *f_ctx = reinterpret_cast<ams::impl::FatalErrorContext *>(0x4003E000);
|
||||
|
||||
/* Check for valid magic. */
|
||||
if (f_ctx->magic != ams::impl::FatalErrorContext::Magic) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Show the fatal error. */
|
||||
ShowFatalError(f_ctx, SaveFatalErrorContext(f_ctx));
|
||||
|
||||
/* Clear the magic. */
|
||||
f_ctx->magic = ~f_ctx->magic;
|
||||
|
||||
/* Wait for reboot. */
|
||||
WaitForReboot();
|
||||
}
|
||||
|
||||
void WaitForReboot() {
|
||||
/* Wait for power button to be pressed. */
|
||||
while (!pmic::IsPowerButtonPressed()) {
|
||||
util::WaitMicroSeconds(100);
|
||||
}
|
||||
|
||||
/* If not erista, just do a normal reboot. */
|
||||
if (fuse::GetSocType() != fuse::SocType_Erista) {
|
||||
/* Reboot. */
|
||||
pmic::ShutdownSystem(true);
|
||||
|
||||
/* Wait for our reboot to complete. */
|
||||
AMS_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
/* TODO: Reboot to payload. */
|
||||
pmic::ShutdownSystem(true);
|
||||
|
||||
/* Wait for our reboot to complete. */
|
||||
AMS_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
}
|
||||
29
fusee/program/source/fusee_fatal.hpp
Normal file
29
fusee/program/source/fusee_fatal.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
NORETURN void ShowFatalError(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
void ShowFatalError(const ams::impl::FatalErrorContext *f_ctx, const Result save_result);
|
||||
|
||||
void SaveAndShowFatalError();
|
||||
|
||||
NORETURN void WaitForReboot();
|
||||
|
||||
|
||||
}
|
||||
4655
fusee/program/source/fusee_font.inc
Normal file
4655
fusee/program/source/fusee_font.inc
Normal file
File diff suppressed because it is too large
Load Diff
181
fusee/program/source/fusee_ini.cpp
Normal file
181
fusee/program/source/fusee_ini.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_ini.hpp"
|
||||
#include "fusee_malloc.hpp"
|
||||
#include "fs/fusee_fs_api.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr s64 IniFileSizeMax = 64_KB;
|
||||
|
||||
constexpr bool IsWhiteSpace(char c) {
|
||||
return c == ' ' || c == '\r';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ParseIniResult ParseIniFile(IniSectionList &out_sections, const char *ini_path) {
|
||||
/* Open the ini file. */
|
||||
fs::FileHandle file;
|
||||
if (R_FAILED(fs::OpenFile(std::addressof(file), ini_path, fs::OpenMode_Read))) {
|
||||
return ParseIniResult_NoFile;
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
|
||||
/* Get file size. */
|
||||
s64 file_size;
|
||||
if (R_FAILED(fs::GetFileSize(std::addressof(file_size), file))) {
|
||||
return ParseIniResult_NoFile;
|
||||
}
|
||||
|
||||
/* Cap file size. */
|
||||
file_size = std::min(IniFileSizeMax, file_size);
|
||||
|
||||
/* Allocate memory for file. */
|
||||
char *buffer = static_cast<char *>(AllocateAligned(util::AlignUp(file_size + 1, 0x10), 0x10));
|
||||
buffer[file_size] = '\x00';
|
||||
|
||||
/* Read file. */
|
||||
if (R_FAILED(fs::ReadFile(file, 0, buffer, file_size))) {
|
||||
return ParseIniResult_NoFile;
|
||||
}
|
||||
|
||||
/* Parse the file. */
|
||||
enum class State {
|
||||
Newline,
|
||||
Comment,
|
||||
SectionName,
|
||||
Key,
|
||||
KvSpace,
|
||||
KvSpace2,
|
||||
Value,
|
||||
TrailingSpace,
|
||||
};
|
||||
|
||||
char *sec_start, *key_start, *val_start;
|
||||
IniSection *cur_sec = nullptr;
|
||||
|
||||
State state = State::Newline;
|
||||
for (int i = 0; i < file_size; ++i) {
|
||||
const char c = buffer[i];
|
||||
|
||||
switch (state) {
|
||||
case State::Newline:
|
||||
if (c == '[') {
|
||||
sec_start = buffer + i + 1;
|
||||
state = State::SectionName;
|
||||
} else if (c == ';' || c == '#') {
|
||||
state = State::Comment;
|
||||
} else if (IsWhiteSpace(c) || c == '\n') {
|
||||
state = State::Newline;
|
||||
} else if (cur_sec != nullptr) {
|
||||
key_start = buffer + i;
|
||||
state = State::Key;
|
||||
} else {
|
||||
return ParseIniResult_InvalidFormat;
|
||||
}
|
||||
break;
|
||||
case State::Comment:
|
||||
if (c == '\n') {
|
||||
state = State::Newline;
|
||||
}
|
||||
break;
|
||||
case State::SectionName:
|
||||
if (c == '\n') {
|
||||
return ParseIniResult_InvalidFormat;
|
||||
} else if (c == ']') {
|
||||
cur_sec = AllocateObject<IniSection>();
|
||||
|
||||
cur_sec->name = sec_start;
|
||||
buffer[i] = '\x00';
|
||||
|
||||
out_sections.push_back(*cur_sec);
|
||||
|
||||
state = State::TrailingSpace;
|
||||
}
|
||||
break;
|
||||
case State::Key:
|
||||
if (c == '\n') {
|
||||
return ParseIniResult_InvalidFormat;
|
||||
} else if (IsWhiteSpace(c)) {
|
||||
buffer[i] = '\x00';
|
||||
|
||||
state = State::KvSpace;
|
||||
} else if (c == '=') {
|
||||
buffer[i] = '\x00';
|
||||
|
||||
state = State::KvSpace2;
|
||||
}
|
||||
break;
|
||||
case State::KvSpace:
|
||||
if (c == '=') {
|
||||
state = State::KvSpace2;
|
||||
} else if (!IsWhiteSpace(c)) {
|
||||
return ParseIniResult_InvalidFormat;
|
||||
}
|
||||
break;
|
||||
case State::KvSpace2:
|
||||
if (c == '\n') {
|
||||
buffer[i] = '\x00';
|
||||
|
||||
auto *entry = AllocateObject<IniKeyValueEntry>();
|
||||
entry->key = key_start;
|
||||
entry->value = buffer + i;
|
||||
|
||||
cur_sec->kv_list.push_back(*entry);
|
||||
|
||||
state = State::Newline;
|
||||
} else if (!IsWhiteSpace(c)) {
|
||||
val_start = buffer + i;
|
||||
|
||||
state = State::Value;
|
||||
}
|
||||
break;
|
||||
case State::Value:
|
||||
if (IsWhiteSpace(c) || c == '\n') {
|
||||
buffer[i] = '\x00';
|
||||
|
||||
auto *entry = AllocateObject<IniKeyValueEntry>();
|
||||
entry->key = key_start;
|
||||
entry->value = val_start;
|
||||
|
||||
cur_sec->kv_list.push_back(*entry);
|
||||
|
||||
state = (c == '\n') ? State::Newline : State::TrailingSpace;
|
||||
}
|
||||
break;
|
||||
case State::TrailingSpace:
|
||||
if (c == '\n') {
|
||||
state = State::Newline;
|
||||
} else if (!IsWhiteSpace(c)) {
|
||||
return ParseIniResult_InvalidFormat;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == State::TrailingSpace || state == State::Comment || state == State::Newline) {
|
||||
return ParseIniResult_Success;
|
||||
} else {
|
||||
return ParseIniResult_InvalidFormat;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
45
fusee/program/source/fusee_ini.hpp
Normal file
45
fusee/program/source/fusee_ini.hpp
Normal 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/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
struct IniKeyValueEntry {
|
||||
util::IntrusiveListNode list_node;
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
using IniKeyValueList = typename util::IntrusiveListMemberTraits<&IniKeyValueEntry::list_node>::ListType;
|
||||
|
||||
struct IniSection {
|
||||
util::IntrusiveListNode list_node;
|
||||
IniKeyValueList kv_list;
|
||||
char *name;
|
||||
};
|
||||
|
||||
using IniSectionList = typename util::IntrusiveListMemberTraits<&IniSection::list_node>::ListType;
|
||||
|
||||
enum ParseIniResult {
|
||||
ParseIniResult_Success,
|
||||
ParseIniResult_NoFile,
|
||||
ParseIniResult_InvalidFormat,
|
||||
};
|
||||
|
||||
ParseIniResult ParseIniFile(IniSectionList &out_sections, const char *ini_path);
|
||||
|
||||
}
|
||||
302
fusee/program/source/fusee_key_derivation.cpp
Normal file
302
fusee/program/source/fusee_key_derivation.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_key_derivation.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x75, 0x2D, 0x2E, 0xF3, 0x2F, 0x3F, 0xFE, 0x65, 0xF4, 0xA9, 0x83, 0xB4, 0xED, 0x42, 0x63, 0xBA
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = {
|
||||
/* TODO: Update on next change of keys. */
|
||||
0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = {
|
||||
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySource[se::AesBlockSize] = {
|
||||
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceKeySource[se::AesBlockSize] = {
|
||||
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKeySourceKekSource[se::AesBlockSize] = {
|
||||
0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSource[se::AesBlockSize] = {
|
||||
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKeySourceSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
{ 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D }, /* 4.x Device Master Key Source Source. */
|
||||
{ 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C }, /* 5.x Device Master Key Source Source. */
|
||||
{ 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 }, /* 6.x Device Master Key Source Source. */
|
||||
{ 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 }, /* 6.2.0 Device Master Key Source Source. */
|
||||
{ 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D }, /* 7.0.0 Device Master Key Source Source. */
|
||||
{ 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE }, /* 8.1.0 Device Master Key Source Source. */
|
||||
{ 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 }, /* 9.0.0 Device Master Key Source Source. */
|
||||
{ 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 }, /* 9.1.0 Device Master Key Source Source. */
|
||||
{ 0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6 }, /* 12.1.0 Device Master Key Source Source. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
{ 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D }, /* 4.x Device Master Kek Source. */
|
||||
{ 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E }, /* 5.x Device Master Kek Source. */
|
||||
{ 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF }, /* 6.x Device Master Kek Source. */
|
||||
{ 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB }, /* 6.2.0 Device Master Kek Source. */
|
||||
{ 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E }, /* 7.0.0 Device Master Kek Source. */
|
||||
{ 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D }, /* 8.1.0 Device Master Kek Source. */
|
||||
{ 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED }, /* 9.0.0 Device Master Kek Source. */
|
||||
{ 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 }, /* 9.1.0 Device Master Kek Source. */
|
||||
{ 0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3 }, /* 12.1.0 Device Master Kek Source. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {
|
||||
{ 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 }, /* 4.x Device Master Kek Source. */
|
||||
{ 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 }, /* 5.x Device Master Kek Source. */
|
||||
{ 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 }, /* 6.x Device Master Kek Source. */
|
||||
{ 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 }, /* 6.2.0 Device Master Kek Source. */
|
||||
{ 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE }, /* 7.0.0 Device Master Kek Source. */
|
||||
{ 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 }, /* 8.1.0 Device Master Kek Source. */
|
||||
{ 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F }, /* 9.0.0 Device Master Kek Source. */
|
||||
{ 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B }, /* 9.1.0 Device Master Kek Source. */
|
||||
{ 0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB }, /* 12.1.0 Device Master Kek Source. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||
{ 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D }, /* Zeroes encrypted with Master Key 00. */
|
||||
{ 0x29, 0x4C, 0x04, 0xC8, 0xEB, 0x10, 0xED, 0x9D, 0x51, 0x64, 0x97, 0xFB, 0xF3, 0x4D, 0x50, 0xDD }, /* Master key 00 encrypted with Master key 01. */
|
||||
{ 0xDE, 0xCF, 0xEB, 0xEB, 0x10, 0xAE, 0x74, 0xD8, 0xAD, 0x7C, 0xF4, 0x9E, 0x62, 0xE0, 0xE8, 0x72 }, /* Master key 01 encrypted with Master key 02. */
|
||||
{ 0x0A, 0x0D, 0xDF, 0x34, 0x22, 0x06, 0x6C, 0xA4, 0xE6, 0xB1, 0xEC, 0x71, 0x85, 0xCA, 0x4E, 0x07 }, /* Master key 02 encrypted with Master key 03. */
|
||||
{ 0x6E, 0x7D, 0x2D, 0xC3, 0x0F, 0x59, 0xC8, 0xFA, 0x87, 0xA8, 0x2E, 0xD5, 0x89, 0x5E, 0xF3, 0xE9 }, /* Master key 03 encrypted with Master key 04. */
|
||||
{ 0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE }, /* Master key 04 encrypted with Master key 05. */
|
||||
{ 0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57 }, /* Master key 05 encrypted with Master key 06. */
|
||||
{ 0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F }, /* Master key 06 encrypted with Master key 07. */
|
||||
{ 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 }, /* Master key 07 encrypted with Master key 08. */
|
||||
{ 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 }, /* Master key 08 encrypted with Master key 09. */
|
||||
{ 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A }, /* Master key 09 encrypted with Master key 0A. */
|
||||
{ 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 }, /* Master key 0A encrypted with Master key 0B. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = {
|
||||
{ 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE }, /* Zeroes encrypted with Master Key 00. */
|
||||
{ 0x39, 0x33, 0xF9, 0x31, 0xBA, 0xE4, 0xA7, 0x21, 0x2C, 0xDD, 0xB7, 0xD8, 0xB4, 0x4E, 0x37, 0x23 }, /* Master key 00 encrypted with Master key 01. */
|
||||
{ 0x97, 0x29, 0xB0, 0x32, 0x43, 0x14, 0x8C, 0xA6, 0x85, 0xE9, 0x5A, 0x94, 0x99, 0x39, 0xAC, 0x5D }, /* Master key 01 encrypted with Master key 02. */
|
||||
{ 0x2C, 0xCA, 0x9C, 0x31, 0x1E, 0x07, 0xB0, 0x02, 0x97, 0x0A, 0xD8, 0x03, 0xA2, 0x76, 0x3F, 0xA3 }, /* Master key 02 encrypted with Master key 03. */
|
||||
{ 0x9B, 0x84, 0x76, 0x14, 0x72, 0x94, 0x52, 0xCB, 0x54, 0x92, 0x9B, 0xC4, 0x8C, 0x5B, 0x0F, 0xBA }, /* Master key 03 encrypted with Master key 04. */
|
||||
{ 0x78, 0xD5, 0xF1, 0x20, 0x3D, 0x16, 0xE9, 0x30, 0x32, 0x27, 0x34, 0x6F, 0xCF, 0xE0, 0x27, 0xDC }, /* Master key 04 encrypted with Master key 05. */
|
||||
{ 0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E }, /* Master key 05 encrypted with Master key 06. */
|
||||
{ 0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19 }, /* Master key 06 encrypted with Master key 07. */
|
||||
{ 0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04 }, /* Master key 07 encrypted with Master key 08. */
|
||||
{ 0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE }, /* Master key 08 encrypted with Master key 09. */
|
||||
{ 0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4 }, /* Master key 09 encrypted with Master key 0A. */
|
||||
{ 0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C }, /* Master key 0A encrypted with Master key 0B. */
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {};
|
||||
alignas(se::AesBlockSize) constinit u8 DeviceMasterKeys[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = {};
|
||||
|
||||
void DeriveMasterKeys(bool is_prod) {
|
||||
/* Decrypt the vector chain from current generation to start. */
|
||||
int slot = pkg1::AesKeySlot_BootloaderMaster;
|
||||
for (int i = pkg1::KeyGeneration_Current; i > pkg1::KeyGeneration_1_0_0; --i) {
|
||||
/* Decrypt the old master key. */
|
||||
se::DecryptAes128(MasterKeys[i - 1], se::AesBlockSize, slot, is_prod ? MasterKeySources[i] : MasterKeySourcesDev[i], se::AesBlockSize);
|
||||
|
||||
/* Set the old master key into a temporary keyslot. */
|
||||
se::SetAesKey(pkg1::AesKeySlot_BootloaderTemporary, MasterKeys[i - 1], se::AesBlockSize);
|
||||
|
||||
/* Perform the next decryption with the older master key. */
|
||||
slot = pkg1::AesKeySlot_BootloaderTemporary;
|
||||
}
|
||||
|
||||
/* Decrypt the final vector. */
|
||||
alignas(se::AesBlockSize) u8 test_vector[se::AesBlockSize];
|
||||
se::DecryptAes128(test_vector, se::AesBlockSize, pkg1::AesKeySlot_BootloaderTemporary, is_prod ? MasterKeySources[pkg1::KeyGeneration_1_0_0] : MasterKeySourcesDev[pkg1::KeyGeneration_1_0_0], se::AesBlockSize);
|
||||
|
||||
/* Verify the vector chain. */
|
||||
alignas(se::AesBlockSize) constexpr u8 ZeroBlock[se::AesBlockSize] = {};
|
||||
if (!crypto::IsSameBytes(ZeroBlock, test_vector, se::AesBlockSize)) {
|
||||
ShowFatalError("Failed to derive master keys!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DeriveDeviceMasterKeys(fuse::SocType soc_type, bool is_prod) {
|
||||
alignas(se::AesBlockSize) u8 work_block[se::AesBlockSize];
|
||||
|
||||
/* Iterate for all generations. */
|
||||
for (int i = 0; i < pkg1::OldDeviceMasterKeyCount; ++i) {
|
||||
const int generation = pkg1::KeyGeneration_4_0_0 + i;
|
||||
|
||||
/* Load the first master key into the temporary keyslot keyslot. */
|
||||
se::SetAesKey(pkg1::AesKeySlot_BootloaderTemporary, MasterKeys[pkg1::KeyGeneration_1_0_0], se::AesBlockSize);
|
||||
|
||||
/* Decrypt the device master kek for the generation. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderTemporary, pkg1::AesKeySlot_BootloaderTemporary, is_prod ? DeviceMasterKekSources[i] : DeviceMasterKekSourcesDev[i], se::AesBlockSize);
|
||||
|
||||
/* Decrypt the device master key source into the work block. */
|
||||
se::DecryptAes128(work_block, se::AesBlockSize, pkg1::AesKeySlot_DeviceMasterKeySourceKekErista, DeviceMasterKeySourceSources[i], se::AesBlockSize);
|
||||
|
||||
if (generation == pkg1::KeyGeneration_Current) {
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderDeviceMaster, pkg1::AesKeySlot_BootloaderTemporary, work_block, se::AesBlockSize);
|
||||
|
||||
/* If on erista, derive the current device master key into the DeviceMaster key slot. */
|
||||
if (soc_type == fuse::SocType_Erista) {
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_DeviceMaster, pkg1::AesKeySlot_BootloaderTemporary, work_block, se::AesBlockSize);
|
||||
}
|
||||
} else {
|
||||
/* Decrypt the device master key. */
|
||||
se::DecryptAes128(DeviceMasterKeys[i], se::AesBlockSize, pkg1::AesKeySlot_BootloaderTemporary, work_block, se::AesBlockSize);
|
||||
|
||||
/* If on mariko, ensure that we derive device key 0 here. */
|
||||
if (soc_type == fuse::SocType_Mariko && i == 0) {
|
||||
se::SetAesKey(pkg1::AesKeySlot_Device, DeviceMasterKeys[i], se::AesBlockSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 GeneratePersonalizedAesKeyKekKekSource[se::AesBlockSize] = {
|
||||
0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 GeneratePersonalizedAesKeyKeyKekSource[se::AesBlockSize] = {
|
||||
0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8
|
||||
};
|
||||
|
||||
void GeneratePersonalizedAesKeyForBis(int slot, const void *kek_source, const void *key_source, int generation) {
|
||||
/* Derive kek. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderTemporary, PrepareDeviceMasterKey(generation), GeneratePersonalizedAesKeyKekKekSource, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderTemporary, pkg1::AesKeySlot_BootloaderTemporary, kek_source, se::AesBlockSize);
|
||||
|
||||
/* Derive key. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderTemporary, pkg1::AesKeySlot_BootloaderTemporary, GeneratePersonalizedAesKeyKeyKekSource, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(slot, pkg1::AesKeySlot_BootloaderTemporary, key_source, se::AesBlockSize);
|
||||
}
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 BisKekSource[se::AesBlockSize] = {
|
||||
0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F
|
||||
};
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 BisPartitionSystemKeySources[2][se::AesBlockSize] = {
|
||||
{ 0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C },
|
||||
{ 0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4 },
|
||||
};
|
||||
|
||||
void DeriveBisPartitionSystemKeys() {
|
||||
/* Determine key generation. */
|
||||
const int key_generation = std::max<int>(0, static_cast<int>(fuse::GetDeviceUniqueKeyGeneration()) - 1);
|
||||
|
||||
/* Generate desired keys. */
|
||||
GeneratePersonalizedAesKeyForBis(pkg1::AesKeySlot_BootloaderSystem0, BisKekSource, BisPartitionSystemKeySources[0], key_generation);
|
||||
GeneratePersonalizedAesKeyForBis(pkg1::AesKeySlot_BootloaderSystem1, BisKekSource, BisPartitionSystemKeySources[1], key_generation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DeriveKeysErista() {
|
||||
/* Get work buffer. */
|
||||
alignas(se::AesBlockSize) u8 work_buffer[se::AesBlockSize];
|
||||
|
||||
/* Get whether we're using dev keys. */
|
||||
const bool is_prod = fuse::GetHardwareState() == fuse::HardwareState_Production;
|
||||
|
||||
/* Derive Keyblob Key. */
|
||||
se::DecryptAes128(work_buffer, se::AesBlockSize, pkg1::AesKeySlot_Tsec, KeyblobKeySource, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_Device, pkg1::AesKeySlot_SecureBoot, work_buffer, se::AesBlockSize);
|
||||
|
||||
/* Derive Master Kek. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_MasterKek, is_prod ? pkg1::AesKeySlot_TsecRoot : pkg1::AesKeySlot_TsecRootDev, EristaMasterKekSource, se::AesBlockSize);
|
||||
|
||||
/* Derive Master Key. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderMaster, pkg1::AesKeySlot_MasterKek, MasterKeySource, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_Master, pkg1::AesKeySlot_MasterKek, MasterKeySource, se::AesBlockSize);
|
||||
|
||||
/* Derive Device Master Key Source Kek, Device Key. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_DeviceMasterKeySourceKekErista, pkg1::AesKeySlot_Device, DeviceMasterKeySourceKekSource, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_Device, pkg1::AesKeySlot_Device, DeviceKeySource, se::AesBlockSize);
|
||||
|
||||
/* Derive all master keys. */
|
||||
DeriveMasterKeys(is_prod);
|
||||
|
||||
/* Derive all device master keys. */
|
||||
DeriveDeviceMasterKeys(fuse::SocType_Erista, is_prod);
|
||||
|
||||
/* Derive system partition keys. */
|
||||
DeriveBisPartitionSystemKeys();
|
||||
}
|
||||
|
||||
void DeriveKeysMariko() {
|
||||
/* Get whether we're using dev keys. */
|
||||
const bool is_prod = fuse::GetHardwareState() == fuse::HardwareState_Production;
|
||||
|
||||
/* Derive Device Master Key Source Kek, Master Key. */
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_DeviceMasterKeySourceKekErista, pkg1::AesKeySlot_SecureBoot, DeviceMasterKeySourceKekSource, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderMaster, pkg1::AesKeySlot_MarikoKek, is_prod ? MarikoMasterKekSource : MarikoMasterKekSourceDev, se::AesBlockSize);
|
||||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_BootloaderMaster, pkg1::AesKeySlot_BootloaderMaster, MasterKeySource, se::AesBlockSize);
|
||||
|
||||
/* Derive all master keys. */
|
||||
DeriveMasterKeys(is_prod);
|
||||
|
||||
/* Derive all device master keys. */
|
||||
DeriveDeviceMasterKeys(fuse::SocType_Mariko, is_prod);
|
||||
|
||||
/* Derive system partition keys. */
|
||||
DeriveBisPartitionSystemKeys();
|
||||
}
|
||||
|
||||
int PrepareMasterKey(int generation) {
|
||||
if (generation == pkg1::KeyGeneration_Current) {
|
||||
return pkg1::AesKeySlot_BootloaderMaster;
|
||||
}
|
||||
|
||||
se::SetAesKey(pkg1::AesKeySlot_BootloaderTemporary, MasterKeys[generation], se::AesBlockSize);
|
||||
|
||||
return pkg1::AesKeySlot_BootloaderTemporary;
|
||||
}
|
||||
|
||||
int PrepareDeviceMasterKey(int generation) {
|
||||
if (generation == pkg1::KeyGeneration_1_0_0) {
|
||||
return pkg1::AesKeySlot_Device;
|
||||
}
|
||||
|
||||
if (generation == pkg1::KeyGeneration_Current) {
|
||||
return pkg1::AesKeySlot_BootloaderDeviceMaster;
|
||||
}
|
||||
|
||||
const int index = std::max(0, generation - pkg1::KeyGeneration_4_0_0);
|
||||
se::SetAesKey(pkg1::AesKeySlot_BootloaderTemporary, DeviceMasterKeys[index], se::AesBlockSize);
|
||||
|
||||
return pkg1::AesKeySlot_BootloaderTemporary;
|
||||
}
|
||||
|
||||
}
|
||||
27
fusee/program/source/fusee_key_derivation.hpp
Normal file
27
fusee/program/source/fusee_key_derivation.hpp
Normal 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 <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void DeriveKeysErista();
|
||||
void DeriveKeysMariko();
|
||||
|
||||
int PrepareMasterKey(int generation);
|
||||
int PrepareDeviceMasterKey(int generation);
|
||||
|
||||
}
|
||||
157
fusee/program/source/fusee_main.cpp
Normal file
157
fusee/program/source/fusee_main.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_display.hpp"
|
||||
#include "sein/fusee_secure_initialize.hpp"
|
||||
#include "sdram/fusee_sdram.hpp"
|
||||
#include "mtc/fusee_mtc.hpp"
|
||||
#include "fs/fusee_fs_api.hpp"
|
||||
#include "fusee_overlay_manager.hpp"
|
||||
#include "fusee_sd_card.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
#include "fusee_secondary_archive.hpp"
|
||||
#include "fusee_setup_horizon.hpp"
|
||||
#include "fusee_secmon_sync.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
/* TODO: Change to fusee-secondary.bin when development is done. */
|
||||
constexpr const char SecondaryArchiveFilePath[] = "sdmc:/atmosphere/fusee-boogaloo.bin";
|
||||
|
||||
constinit fs::FileHandle g_archive_file;
|
||||
|
||||
void OpenSecondaryArchive() {
|
||||
Result result;
|
||||
|
||||
/* Open fusee-secondary. */
|
||||
if (R_FAILED((result = fs::OpenFile(std::addressof(g_archive_file), SecondaryArchiveFilePath, fs::OpenMode_Read)))) {
|
||||
ShowFatalError("Failed to open %s!\n", SecondaryArchiveFilePath);
|
||||
}
|
||||
|
||||
/* Get file size. */
|
||||
s64 file_size;
|
||||
if (R_FAILED((result = fs::GetFileSize(std::addressof(file_size), g_archive_file)))) {
|
||||
ShowFatalError("Failed to get fusee-secondary size: 0x%08" PRIx32 "\n", result.GetValue());
|
||||
}
|
||||
|
||||
/* Check file size. */
|
||||
if (static_cast<size_t>(file_size) != SecondaryArchiveSize) {
|
||||
ShowFatalError("fusee-secondary seems corrupted (size 0x%zx != 0x%zx)", static_cast<size_t>(file_size), SecondaryArchiveSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadFullSecondaryArchive() {
|
||||
Result result;
|
||||
|
||||
if (R_FAILED((result = fs::ReadFile(g_archive_file, 0, const_cast<void *>(static_cast<const void *>(std::addressof(GetSecondaryArchive()))), SecondaryArchiveSize)))) {
|
||||
ShowFatalError("Failed to read %s!\n", SecondaryArchiveFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
void CloseSecondaryArchive() {
|
||||
fs::CloseFile(g_archive_file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Main() {
|
||||
/* Perform secure hardware initialization. */
|
||||
SecureInitialize(true);
|
||||
|
||||
/* Overclock the bpmp. */
|
||||
clkrst::SetBpmpClockRate(fuse::GetSocType() == fuse::SocType_Mariko ? clkrst::BpmpClockRate_589MHz : clkrst::BpmpClockRate_576MHz);
|
||||
|
||||
/* Initialize Sdram. */
|
||||
InitializeSdram();
|
||||
|
||||
/* Initialize cache. */
|
||||
hw::InitializeDataCache();
|
||||
|
||||
/* Initialize SD card. */
|
||||
{
|
||||
Result result = InitializeSdCard();
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to initialize the SD card: 0x%08" PRIx32 "\n", result.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
/* Mount SD card. */
|
||||
if (!fs::MountSdCard()) {
|
||||
ShowFatalError("Failed to mount the SD card.");
|
||||
}
|
||||
|
||||
/* If we have a fatal error, save and display it. */
|
||||
SaveAndShowFatalError();
|
||||
|
||||
/* Open the secondary archive. */
|
||||
OpenSecondaryArchive();
|
||||
|
||||
/* Load the memory training overlay. */
|
||||
LoadOverlay(g_archive_file, OverlayId_MemoryTraining);
|
||||
|
||||
/* Do memory training. */
|
||||
DoMemoryTraining();
|
||||
|
||||
/* Read the rest of the archive file. */
|
||||
ReadFullSecondaryArchive();
|
||||
|
||||
/* Save the memory training overlay. */
|
||||
SaveMemoryTrainingOverlay();
|
||||
|
||||
/* Initialize display (splash screen will be visible from this point onwards). */
|
||||
InitializeDisplay();
|
||||
ShowDisplay();
|
||||
|
||||
/* Close the secondary archive. */
|
||||
CloseSecondaryArchive();
|
||||
|
||||
/* Perform rest of the boot process. */
|
||||
SetupAndStartHorizon();
|
||||
|
||||
/* Restore the memory training overlay. */
|
||||
RestoreMemoryTrainingOverlay();
|
||||
|
||||
/* Restore memory clock rate. */
|
||||
RestoreMemoryClockRate();
|
||||
|
||||
/* Restore secure monitor code. */
|
||||
RestoreSecureMonitorOverlay();
|
||||
|
||||
/* Finalize display. */
|
||||
FinalizeDisplay();
|
||||
|
||||
/* Finalize sd card. */
|
||||
FinalizeSdCard();
|
||||
|
||||
/* Finalize the data cache. */
|
||||
hw::FinalizeDataCache();
|
||||
|
||||
/* Downclock the bpmp. */
|
||||
clkrst::SetBpmpClockRate(clkrst::BpmpClockRate_408MHz);
|
||||
|
||||
/* Signal to the secure monitor that we're done. */
|
||||
SetBootloaderState(pkg1::BootloaderState_Done);
|
||||
|
||||
/* Halt ourselves. */
|
||||
while (true) {
|
||||
reg::Write(secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress() + FLOW_CTLR_HALT_COP_EVENTS, FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_MODE, FLOW_MODE_STOP),
|
||||
FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_JTAG, ENABLED));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
40
fusee/program/source/fusee_malloc.cpp
Normal file
40
fusee/program/source/fusee_malloc.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_malloc.hpp"
|
||||
#include "fusee_secondary_archive.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constinit uintptr_t g_heap_address = 0xC1000000;
|
||||
|
||||
}
|
||||
|
||||
void *AllocateMemory(size_t size) {
|
||||
/* Get the current heap address. */
|
||||
void * const allocated = reinterpret_cast<void *>(g_heap_address);
|
||||
|
||||
/* Advance the current heap address. */
|
||||
g_heap_address += size;
|
||||
|
||||
/* Return the allocated chunk. */
|
||||
return allocated;
|
||||
}
|
||||
|
||||
}
|
||||
36
fusee/program/source/fusee_malloc.hpp
Normal file
36
fusee/program/source/fusee_malloc.hpp
Normal 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/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void *AllocateMemory(size_t size);
|
||||
|
||||
ALWAYS_INLINE void *AllocateAligned(size_t size, size_t align) {
|
||||
return reinterpret_cast<void *>(util::AlignUp(reinterpret_cast<uintptr_t>(AllocateMemory(size + align)), align));
|
||||
}
|
||||
|
||||
template<typename T, typename... Args> requires std::constructible_from<T, Args...>
|
||||
inline T *AllocateObject(Args &&... args) {
|
||||
T * const obj = static_cast<T *>(AllocateAligned(sizeof(T), alignof(T)));
|
||||
|
||||
std::construct_at(obj, std::forward<Args>(args)...);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
75
fusee/program/source/fusee_mmc.cpp
Normal file
75
fusee/program/source/fusee_mmc.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_mmc.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline auto MmcPort = sdmmc::Port_Mmc0;
|
||||
|
||||
alignas(0x10) constinit u8 g_mmc_work_buffer[sdmmc::MmcWorkBufferSize];
|
||||
|
||||
constinit inline auto g_mmc_partition = sdmmc::MmcPartition_Unknown;
|
||||
|
||||
Result SelectMmcPartition(sdmmc::MmcPartition partition) {
|
||||
/* Change partition, if we need to. */
|
||||
if (partition != g_mmc_partition) {
|
||||
R_TRY(sdmmc::SelectMmcPartition(MmcPort, partition));
|
||||
|
||||
g_mmc_partition = partition;
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result InitializeMmc() {
|
||||
/* Initialize the mmc. */
|
||||
sdmmc::Initialize(MmcPort);
|
||||
|
||||
/* Set the mmc work buffer. */
|
||||
sdmmc::SetMmcWorkBuffer(MmcPort, g_mmc_work_buffer, sizeof(g_mmc_work_buffer));
|
||||
|
||||
/* Activate the mmc. */
|
||||
return sdmmc::Activate(MmcPort);
|
||||
}
|
||||
|
||||
Result CheckMmcConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||
return sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort);
|
||||
}
|
||||
|
||||
Result GetMmcMemoryCapacity(u32 *out_num_sectors, sdmmc::MmcPartition partition) {
|
||||
if (partition == sdmmc::MmcPartition_UserData) {
|
||||
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort);
|
||||
} else {
|
||||
return sdmmc::GetMmcBootPartitionCapacity(out_num_sectors, MmcPort);
|
||||
}
|
||||
}
|
||||
|
||||
Result ReadMmc(void *dst, size_t size, sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count) {
|
||||
R_TRY(SelectMmcPartition(partition));
|
||||
return sdmmc::Read(dst, size, MmcPort, sector_index, sector_count);
|
||||
}
|
||||
|
||||
Result WriteMmc(sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||
R_TRY(SelectMmcPartition(partition));
|
||||
return sdmmc::Write(MmcPort, sector_index, sector_count, src, size);
|
||||
}
|
||||
|
||||
}
|
||||
28
fusee/program/source/fusee_mmc.hpp
Normal file
28
fusee/program/source/fusee_mmc.hpp
Normal 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/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
Result InitializeMmc();
|
||||
Result CheckMmcConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw);
|
||||
Result GetMmcMemoryCapacity(u32 *out_num_sectors, sdmmc::MmcPartition partition);
|
||||
|
||||
Result ReadMmc(void *dst, size_t size, sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count);
|
||||
Result WriteMmc(sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count, const void *src, size_t size);
|
||||
|
||||
}
|
||||
91
fusee/program/source/fusee_overlay_manager.cpp
Normal file
91
fusee/program/source/fusee_overlay_manager.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_overlay_manager.hpp"
|
||||
#include "fusee_secondary_archive.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constinit u8 g_secmon_debug_storage[secmon::MemoryRegionPhysicalIramSecureMonitorDebug.GetSize()];
|
||||
|
||||
ALWAYS_INLINE void *GetOverlayDestination() {
|
||||
return reinterpret_cast<void *>(0x4002C000);
|
||||
}
|
||||
|
||||
void LoadMemoryTrainingOverlay(fs::FileHandle archive_file) {
|
||||
Result result;
|
||||
u32 verif_hash;
|
||||
u32 store_hash;
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
result = fs::ReadFile(archive_file, __builtin_offsetof(SecondaryArchive, ovl_mtc_erista), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_erista));
|
||||
verif_hash = reinterpret_cast<const u32 *>(GetOverlayDestination())[-2];
|
||||
store_hash = reinterpret_cast<const u32 *>(GetOverlayDestination())[(sizeof(SecondaryArchive{}.ovl_mtc_erista) / sizeof(u32)) - 1];
|
||||
} else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ {
|
||||
result = fs::ReadFile(archive_file, __builtin_offsetof(SecondaryArchive, ovl_mtc_mariko), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_mariko));
|
||||
verif_hash = reinterpret_cast<const u32 *>(GetOverlayDestination())[-1];
|
||||
store_hash = reinterpret_cast<const u32 *>(GetOverlayDestination())[(sizeof(SecondaryArchive{}.ovl_mtc_mariko) / sizeof(u32)) - 1];
|
||||
}
|
||||
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to load MTC overlay: 0x%08" PRIx32 "\n", result.GetValue());
|
||||
}
|
||||
|
||||
if (verif_hash != store_hash) {
|
||||
ShowFatalError("Incorrect fusee version! (program=0x%08" PRIx32 ", mtc=0x%08" PRIx32 ")\n", verif_hash, store_hash);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LoadOverlay(fs::FileHandle archive_file, OverlayId ovl) {
|
||||
switch (ovl) {
|
||||
case OverlayId_MemoryTraining:
|
||||
LoadMemoryTrainingOverlay(archive_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveMemoryTrainingOverlay() {
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
/* NOTE: Erista does not do memory clock restoration. */
|
||||
/* std::memcpy(const_cast<u8 *>(GetSecondaryArchive().ovl_mtc_erista), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_erista)); */
|
||||
} else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ {
|
||||
std::memcpy(const_cast<u8 *>(GetSecondaryArchive().ovl_mtc_mariko), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_mariko) - 0x2000);
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreMemoryTrainingOverlay() {
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
/* NOTE: Erista does not do memory clock restoration. */
|
||||
/* std::memcpy(GetOverlayDestination(), GetSecondaryArchive().ovl_mtc_erista, sizeof(SecondaryArchive{}.ovl_mtc_erista)); */
|
||||
} else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ {
|
||||
std::memcpy(g_secmon_debug_storage, secmon::MemoryRegionPhysicalIramSecureMonitorDebug.GetPointer<void>(), sizeof(g_secmon_debug_storage));
|
||||
std::memcpy(GetOverlayDestination(), GetSecondaryArchive().ovl_mtc_mariko, sizeof(SecondaryArchive{}.ovl_mtc_mariko) - 0x2000);
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreSecureMonitorOverlay() {
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
/* NOTE: Erista does not do memory clock restoration. */
|
||||
} else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ {
|
||||
std::memcpy(secmon::MemoryRegionPhysicalIramSecureMonitorDebug.GetPointer<void>(), g_secmon_debug_storage, sizeof(g_secmon_debug_storage));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
33
fusee/program/source/fusee_overlay_manager.hpp
Normal file
33
fusee/program/source/fusee_overlay_manager.hpp
Normal 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 <exosphere.hpp>
|
||||
#include "fs/fusee_fs_api.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
enum OverlayId {
|
||||
/* OverlayId_SecureInitializer = 0, */
|
||||
OverlayId_MemoryTraining = 1,
|
||||
};
|
||||
|
||||
void LoadOverlay(fs::FileHandle archive_file, OverlayId ovl);
|
||||
|
||||
void SaveMemoryTrainingOverlay();
|
||||
void RestoreMemoryTrainingOverlay();
|
||||
void RestoreSecureMonitorOverlay();
|
||||
|
||||
}
|
||||
165
fusee/program/source/fusee_package2.cpp
Normal file
165
fusee/program/source/fusee_package2.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_package2.hpp"
|
||||
#include "fusee_key_derivation.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
alignas(se::AesBlockSize) constexpr inline const u8 Package2KeySource[se::AesBlockSize] = {
|
||||
0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7
|
||||
};
|
||||
|
||||
void PreparePackage2Key(int pkg2_slot, int key_generation) {
|
||||
/* Get keyslot for the desired master key. */
|
||||
const int master_slot = PrepareMasterKey(key_generation);
|
||||
|
||||
/* Load the package2 key into the desired keyslot. */
|
||||
se::SetEncryptedAesKey128(pkg2_slot, master_slot, Package2KeySource, sizeof(Package2KeySource));
|
||||
}
|
||||
|
||||
void DecryptPackage2(void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv, size_t iv_size, u8 key_generation) {
|
||||
/* Ensure that the SE sees consistent data. */
|
||||
hw::FlushDataCache(src, src_size);
|
||||
if (src != dst) {
|
||||
hw::FlushDataCache(dst, dst_size);
|
||||
}
|
||||
|
||||
/* Load the package2 key into the temporary keyslot. */
|
||||
PreparePackage2Key(pkg1::AesKeySlot_Temporary, key_generation);
|
||||
|
||||
/* Decrypt the data. */
|
||||
se::ComputeAes128Ctr(dst, dst_size, pkg1::AesKeySlot_Temporary, src, src_size, iv, iv_size);
|
||||
|
||||
/* Clear the keyslot we just used. */
|
||||
se::ClearAesKeySlot(pkg1::AesKeySlot_Temporary);
|
||||
|
||||
/* Ensure that the cpu sees consistent data. */
|
||||
hw::InvalidateDataCache(dst, dst_size);
|
||||
}
|
||||
|
||||
void DecryptPackage2Header(pkg2::Package2Meta *dst, const pkg2::Package2Meta &src) {
|
||||
constexpr int IvSize = 0x10;
|
||||
|
||||
/* Decrypt the header. */
|
||||
DecryptPackage2(dst, sizeof(*dst), std::addressof(src), sizeof(src), std::addressof(src), IvSize, src.GetKeyGeneration());
|
||||
|
||||
/* Copy back the iv, which encodes encrypted metadata. */
|
||||
std::memcpy(dst, std::addressof(src), IvSize);
|
||||
}
|
||||
|
||||
bool VerifyPackage2Meta(const pkg2::Package2Meta &meta) {
|
||||
/* Get the obfuscated metadata. */
|
||||
const size_t size = meta.GetSize();
|
||||
const u8 key_generation = meta.GetKeyGeneration();
|
||||
|
||||
/* Check that size is big enough for the header. */
|
||||
if (size <= sizeof(pkg2::Package2Header)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that the size isn't larger than what we allow. */
|
||||
if (size > pkg2::Package2SizeMax) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 12);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the magic number. */
|
||||
if (!crypto::IsSameBytes(meta.magic, pkg2::Package2Meta::Magic::String, sizeof(meta.magic))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the payload alignments. */
|
||||
if ((meta.entrypoint % pkg2::PayloadAlignment) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if ((meta.payload_sizes[i] % pkg2::PayloadAlignment) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the sizes sum to the total. */
|
||||
if (size != sizeof(pkg2::Package2Header) + meta.payload_sizes[0] + meta.payload_sizes[1] + meta.payload_sizes[2]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that the payloads do not overflow. */
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (meta.payload_offsets[i] > meta.payload_offsets[i] + meta.payload_sizes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that no payloads overlap. */
|
||||
for (int i = 0; i < pkg2::PayloadCount - 1; ++i) {
|
||||
for (int j = i + 1; j < pkg2::PayloadCount; ++j) {
|
||||
if (util::HasOverlap(meta.payload_offsets[i], meta.payload_sizes[i], meta.payload_offsets[j], meta.payload_sizes[j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether any payload contains the entrypoint. */
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (util::Contains(meta.payload_offsets[i], meta.payload_sizes[i], meta.entrypoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* No payload contains the entrypoint, so we're not valid. */
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DecryptPackage2(u8 *package2) {
|
||||
/* Decrypt package2 header. */
|
||||
pkg2::Package2Header *header = reinterpret_cast<pkg2::Package2Header *>(package2);
|
||||
{
|
||||
pkg2::Package2Header tmp = *header;
|
||||
DecryptPackage2Header(std::addressof(header->meta), tmp.meta);
|
||||
}
|
||||
|
||||
/* Check package2 magic. */
|
||||
if (!VerifyPackage2Meta(header->meta)) {
|
||||
ShowFatalError("Package2 meta is invalid!\n");
|
||||
}
|
||||
|
||||
/* Decrypt package2 payloads. */
|
||||
u8 *payload = package2 + sizeof(*header);
|
||||
const u8 key_generation = header->meta.GetKeyGeneration();
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (header->meta.payload_sizes[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DecryptPackage2(payload, header->meta.payload_sizes[i], payload, header->meta.payload_sizes[i], header->meta.payload_ivs[i], sizeof(header->meta.payload_ivs[i]), key_generation);
|
||||
|
||||
payload += header->meta.payload_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
23
fusee/program/source/fusee_package2.hpp
Normal file
23
fusee/program/source/fusee_package2.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void DecryptPackage2(u8 *package2);
|
||||
|
||||
}
|
||||
126
fusee/program/source/fusee_print.cpp
Normal file
126
fusee/program/source/fusee_print.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_display.hpp"
|
||||
#include "fusee_print.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
#include "fusee_font.inc"
|
||||
|
||||
constexpr inline const u32 TextColor = 0xFFA0A0A0;
|
||||
|
||||
constexpr inline const size_t ConsoleWidth = FrameBufferWidth / FontWidth;
|
||||
constexpr inline const size_t ConsoleHeight = FrameBufferHeight / FontHeight;
|
||||
|
||||
constinit u32 *g_frame_buffer = nullptr;
|
||||
constinit size_t g_col = 1;
|
||||
constinit size_t g_row = 0;
|
||||
|
||||
void SetPixel(size_t x, size_t y, u32 color) {
|
||||
g_frame_buffer[(FrameBufferWidth - x) * FrameBufferHeight + y] = color;
|
||||
}
|
||||
|
||||
void PutCarriageReturn() {
|
||||
g_col = 1;
|
||||
}
|
||||
|
||||
void PutNewLine() {
|
||||
g_col = 1;
|
||||
++g_row;
|
||||
|
||||
/* TODO: Support scrolling? */
|
||||
}
|
||||
|
||||
void PutCharImpl(const char c) {
|
||||
/* Get the character data for the font. */
|
||||
const u8 * cdata = FontData + c * (FontHeight * util::DivideUp(FontWidth, BITSIZEOF(u8)));
|
||||
|
||||
/* Determine where to start drawing. */
|
||||
const size_t x = g_col * FontWidth;
|
||||
const size_t y = g_row * FontHeight;
|
||||
|
||||
for (size_t cur_y = 0; cur_y < FontHeight; ++cur_y) {
|
||||
size_t cur_x = 0;
|
||||
int wbits = FontWidth;
|
||||
while (wbits > 0) {
|
||||
const auto bits = *(cdata++);
|
||||
|
||||
SetPixel(x + cur_x + 0, y + cur_y, FontDrawTable[(bits >> 4) & 0xF][0] & TextColor);
|
||||
SetPixel(x + cur_x + 1, y + cur_y, FontDrawTable[(bits >> 4) & 0xF][1] & TextColor);
|
||||
SetPixel(x + cur_x + 2, y + cur_y, FontDrawTable[(bits >> 4) & 0xF][2] & TextColor);
|
||||
SetPixel(x + cur_x + 3, y + cur_y, FontDrawTable[(bits >> 4) & 0xF][3] & TextColor);
|
||||
SetPixel(x + cur_x + 4, y + cur_y, FontDrawTable[(bits >> 0) & 0xF][0] & TextColor);
|
||||
SetPixel(x + cur_x + 5, y + cur_y, FontDrawTable[(bits >> 0) & 0xF][1] & TextColor);
|
||||
SetPixel(x + cur_x + 6, y + cur_y, FontDrawTable[(bits >> 0) & 0xF][2] & TextColor);
|
||||
SetPixel(x + cur_x + 7, y + cur_y, FontDrawTable[(bits >> 0) & 0xF][3] & TextColor);
|
||||
|
||||
cur_x += BITSIZEOF(u8);
|
||||
wbits -= BITSIZEOF(u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PutChar(const char c) {
|
||||
switch (c) {
|
||||
case '\r':
|
||||
PutCarriageReturn();
|
||||
break;
|
||||
case '\n':
|
||||
PutNewLine();
|
||||
break;
|
||||
default:
|
||||
PutCharImpl(c);
|
||||
if ((++g_col) >= ConsoleWidth) {
|
||||
PutNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InitializeConsole(u32 *frame_buffer) {
|
||||
/* Setup the console variables. */
|
||||
g_frame_buffer = frame_buffer;
|
||||
g_col = 1;
|
||||
g_row = 0;
|
||||
|
||||
/* Clear the console. */
|
||||
std::memset(g_frame_buffer, 0, FrameBufferSize);
|
||||
}
|
||||
|
||||
void VPrint(const char *fmt, std::va_list vl) {
|
||||
/* Generate the string. */
|
||||
char log_str[1_KB];
|
||||
util::TVSNPrintf(log_str, sizeof(log_str), fmt, vl);
|
||||
|
||||
/* Print each character. */
|
||||
const size_t len = std::strlen(log_str);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
PutChar(log_str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Print(const char *fmt, ...) {
|
||||
std::va_list vl;
|
||||
va_start(vl, fmt);
|
||||
VPrint(fmt, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
}
|
||||
25
fusee/program/source/fusee_print.hpp
Normal file
25
fusee/program/source/fusee_print.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void InitializeConsole(u32 *frame_buffer);
|
||||
void Print(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
void VPrint(const char *fmt, std::va_list vl);
|
||||
|
||||
}
|
||||
354
fusee/program/source/fusee_registers_di.hpp
Normal file
354
fusee/program/source/fusee_registers_di.hpp
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* 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 <exosphere.hpp>
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
|
||||
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
|
||||
|
||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||
#define SYNCPT_VSYNC_ENABLE (1 << 8)
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND 0x32
|
||||
#define DISP_CTRL_MODE_STOP (0 << 5)
|
||||
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
|
||||
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
|
||||
#define DISP_CTRL_MODE_MASK (3 << 5)
|
||||
|
||||
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
|
||||
#define PW0_ENABLE (1 << 0)
|
||||
#define PW1_ENABLE (1 << 2)
|
||||
#define PW2_ENABLE (1 << 4)
|
||||
#define PW3_ENABLE (1 << 6)
|
||||
#define PW4_ENABLE (1 << 8)
|
||||
#define PM0_ENABLE (1 << 16)
|
||||
#define PM1_ENABLE (1 << 18)
|
||||
|
||||
#define DC_CMD_INT_STATUS 0x37
|
||||
#define DC_CMD_INT_MASK 0x38
|
||||
#define DC_CMD_INT_ENABLE 0x39
|
||||
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define READ_MUX (1 << 0)
|
||||
#define WRITE_MUX (1 << 2)
|
||||
|
||||
#define DC_CMD_STATE_CONTROL 0x41
|
||||
#define GENERAL_ACT_REQ (1 << 0)
|
||||
#define WIN_A_ACT_REQ (1 << 1)
|
||||
#define WIN_B_ACT_REQ (1 << 2)
|
||||
#define WIN_C_ACT_REQ (1 << 3)
|
||||
#define CURSOR_ACT_REQ (1 << 7)
|
||||
#define GENERAL_UPDATE (1 << 8)
|
||||
#define WIN_A_UPDATE (1 << 9)
|
||||
#define WIN_B_UPDATE (1 << 10)
|
||||
#define WIN_C_UPDATE (1 << 11)
|
||||
#define CURSOR_UPDATE (1 << 15)
|
||||
#define NC_HOST_TRIG (1 << 24)
|
||||
|
||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||
#define WINDOW_A_SELECT (1 << 4)
|
||||
#define WINDOW_B_SELECT (1 << 5)
|
||||
#define WINDOW_C_SELECT (1 << 6)
|
||||
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
||||
|
||||
#define DC_COM_CRC_CONTROL 0x300
|
||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
||||
|
||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
||||
|
||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
||||
#define HDMI_ENABLE (1 << 30)
|
||||
#define DSI_ENABLE (1 << 29)
|
||||
#define SOR1_TIMING_CYA (1 << 27)
|
||||
#define SOR1_ENABLE (1 << 26)
|
||||
#define SOR_ENABLE (1 << 25)
|
||||
#define CURSOR_ENABLE (1 << 16)
|
||||
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
||||
#define DC_DISP_REF_TO_SYNC 0x406
|
||||
#define DC_DISP_SYNC_WIDTH 0x407
|
||||
#define DC_DISP_BACK_PORCH 0x408
|
||||
#define DC_DISP_ACTIVE 0x409
|
||||
#define DC_DISP_FRONT_PORCH 0x40A
|
||||
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
|
||||
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
|
||||
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
|
||||
#define DISP_DATA_FORMAT_DF2S (4 << 0)
|
||||
#define DISP_DATA_FORMAT_DF3S (5 << 0)
|
||||
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
|
||||
#define DISP_ALIGNMENT_MSB (0 << 8)
|
||||
#define DISP_ALIGNMENT_LSB (1 << 8)
|
||||
#define DISP_ORDER_RED_BLUE (0 << 9)
|
||||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
||||
|
||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
||||
#define DITHER_CONTROL_MASK (3 << 8)
|
||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
||||
#define BASE_COLOR_SIZE_333 (3 << 0)
|
||||
#define BASE_COLOR_SIZE_444 (4 << 0)
|
||||
#define BASE_COLOR_SIZE_555 (5 << 0)
|
||||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
||||
|
||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
||||
#define SC1_H_QUALIFIER_NONE (1 << 16)
|
||||
#define SC0_H_QUALIFIER_NONE (1 << 0)
|
||||
|
||||
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
|
||||
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
|
||||
#define DE_SELECT_ACTIVE (1 << 0)
|
||||
#define DE_SELECT_ACTIVE_IS (2 << 0)
|
||||
#define DE_CONTROL_ONECLK (0 << 2)
|
||||
#define DE_CONTROL_NORMAL (1 << 2)
|
||||
#define DE_CONTROL_EARLY_EXT (2 << 2)
|
||||
#define DE_CONTROL_EARLY (3 << 2)
|
||||
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
|
||||
|
||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
||||
#define DC_DISP_SD_BL_PARAMETERS 0x4D7
|
||||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
|
||||
#define DC_WIN_CSC_YOF 0x611
|
||||
#define DC_WIN_CSC_KYRGB 0x612
|
||||
#define DC_WIN_CSC_KUR 0x613
|
||||
#define DC_WIN_CSC_KVR 0x614
|
||||
#define DC_WIN_CSC_KUG 0x615
|
||||
#define DC_WIN_CSC_KVG 0x616
|
||||
#define DC_WIN_CSC_KUB 0x617
|
||||
#define DC_WIN_CSC_KVB 0x618
|
||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION (1 << 0)
|
||||
#define V_DIRECTION (1 << 2)
|
||||
#define SCAN_COLUMN (1 << 4)
|
||||
#define COLOR_EXPAND (1 << 6)
|
||||
#define CSC_ENABLE (1 << 18)
|
||||
#define WIN_ENABLE (1 << 30)
|
||||
|
||||
#define DC_WIN_COLOR_DEPTH 0x703
|
||||
#define WIN_COLOR_DEPTH_P1 0x0
|
||||
#define WIN_COLOR_DEPTH_P2 0x1
|
||||
#define WIN_COLOR_DEPTH_P4 0x2
|
||||
#define WIN_COLOR_DEPTH_P8 0x3
|
||||
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
|
||||
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
|
||||
#define WIN_COLOR_DEPTH_B5G6R5 0x6
|
||||
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
|
||||
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
|
||||
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
|
||||
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
|
||||
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
|
||||
#define WIN_COLOR_DEPTH_YCbCr422 0x10
|
||||
#define WIN_COLOR_DEPTH_YUV422 0x11
|
||||
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
|
||||
#define WIN_COLOR_DEPTH_YUV420P 0x13
|
||||
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
|
||||
#define WIN_COLOR_DEPTH_YUV422P 0x15
|
||||
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
|
||||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
||||
|
||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||
#define DC_WIN_POSITION 0x704
|
||||
|
||||
#define DC_WIN_SIZE 0x705
|
||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
||||
|
||||
#define DC_WIN_DDA_INC 0x709
|
||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DC_WIN_LINE_STRIDE 0x70A
|
||||
#define LINE_STRIDE(x) (x)
|
||||
#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
|
||||
#define DC_WIN_DV_CONTROL 0x70E
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WINBUF_START_ADDR 0x800
|
||||
#define DC_WINBUF_ADDR_H_OFFSET 0x806
|
||||
#define DC_WINBUF_ADDR_V_OFFSET 0x808
|
||||
#define DC_WINBUF_SURFACE_KIND 0x80B
|
||||
#define PITCH (0 << 0)
|
||||
#define TILED (1 << 0)
|
||||
#define BLOCK (2 << 0)
|
||||
#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
|
||||
#define DSI_INCR_SYNCPT_CNTRL 0x1
|
||||
|
||||
#define DSI_RD_DATA 0x9
|
||||
#define DSI_WR_DATA 0xA
|
||||
|
||||
#define DSI_POWER_CONTROL 0xB
|
||||
#define DSI_POWER_CONTROL_ENABLE 1
|
||||
|
||||
#define DSI_INT_ENABLE 0xC
|
||||
#define DSI_INT_STATUS 0xD
|
||||
#define DSI_INT_MASK 0xE
|
||||
|
||||
#define DSI_HOST_CONTROL 0xF
|
||||
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
|
||||
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
#define DSI_HOST_CONTROL_RAW (1 << 6)
|
||||
#define DSI_HOST_CONTROL_HS (1 << 5)
|
||||
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
|
||||
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
|
||||
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
|
||||
#define DSI_HOST_CONTROL_CS (1 << 1)
|
||||
#define DSI_HOST_CONTROL_ECC (1 << 0)
|
||||
|
||||
#define DSI_CONTROL 0x10
|
||||
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
|
||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
||||
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
|
||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
||||
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
|
||||
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
|
||||
|
||||
#define DSI_SOL_DELAY 0x11
|
||||
#define DSI_MAX_THRESHOLD 0x12
|
||||
|
||||
#define DSI_TRIGGER 0x13
|
||||
#define DSI_TRIGGER_HOST (1 << 1)
|
||||
#define DSI_TRIGGER_VIDEO (1 << 0)
|
||||
|
||||
#define DSI_TX_CRC 0x14
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||
#define DSI_INIT_SEQ_DATA_1 0x1C
|
||||
#define DSI_INIT_SEQ_DATA_2 0x1D
|
||||
#define DSI_INIT_SEQ_DATA_3 0x1E
|
||||
#define DSI_PKT_SEQ_0_LO 0x23
|
||||
#define DSI_PKT_SEQ_0_HI 0x24
|
||||
#define DSI_PKT_SEQ_1_LO 0x25
|
||||
#define DSI_PKT_SEQ_1_HI 0x26
|
||||
#define DSI_PKT_SEQ_2_LO 0x27
|
||||
#define DSI_PKT_SEQ_2_HI 0x28
|
||||
#define DSI_PKT_SEQ_3_LO 0x29
|
||||
#define DSI_PKT_SEQ_3_HI 0x2A
|
||||
#define DSI_PKT_SEQ_4_LO 0x2B
|
||||
#define DSI_PKT_SEQ_4_HI 0x2C
|
||||
#define DSI_PKT_SEQ_5_LO 0x2D
|
||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
||||
#define DSI_DCS_CMDS 0x33
|
||||
#define DSI_PKT_LEN_0_1 0x34
|
||||
#define DSI_PKT_LEN_2_3 0x35
|
||||
#define DSI_PKT_LEN_4_5 0x36
|
||||
#define DSI_PKT_LEN_6_7 0x37
|
||||
#define DSI_PHY_TIMING_0 0x3C
|
||||
#define DSI_PHY_TIMING_1 0x3D
|
||||
#define DSI_PHY_TIMING_2 0x3E
|
||||
#define DSI_BTA_TIMING 0x3F
|
||||
|
||||
#define DSI_TIMEOUT_0 0x44
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
||||
|
||||
#define DSI_TIMEOUT_1 0x45
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
||||
|
||||
#define DSI_TO_TALLY 0x46
|
||||
|
||||
#define DSI_PAD_CONTROL_0 0x4B
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
||||
|
||||
#define DSI_PAD_CONTROL_CD 0x4c
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
||||
|
||||
#define DSI_PAD_CONTROL_1 0x4F
|
||||
#define DSI_PAD_CONTROL_2 0x50
|
||||
|
||||
#define DSI_PAD_CONTROL_3 0x51
|
||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
||||
|
||||
#define DSI_PAD_CONTROL_4 0x52
|
||||
#define DSI_PAD_CONTROL_5_MARIKO 0x53
|
||||
#define DSI_PAD_CONTROL_6_MARIKO 0x54
|
||||
#define DSI_PAD_CONTROL_7_MARIKO 0x55
|
||||
#define DSI_INIT_SEQ_DATA_15 0x5F
|
||||
|
||||
#define DSI_INIT_SEQ_DATA_15_MARIKO 0x62
|
||||
|
||||
#define NV_PVIC_THI_SLCG_OVERRIDE_LOW_A 0x8C
|
||||
108
fusee/program/source/fusee_sd_card.cpp
Normal file
108
fusee/program/source/fusee_sd_card.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_sd_card.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline auto SdCardPort = sdmmc::Port_SdCard0;
|
||||
|
||||
constexpr inline const uintptr_t APB = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress();
|
||||
|
||||
alignas(0x10) constinit u8 g_sd_work_buffer[sdmmc::SdCardWorkBufferSize];
|
||||
|
||||
void ConfigureInitialSdCardPinmux() {
|
||||
/* Normally, these pints get configured by boot sysmodule during initial pinmux config. */
|
||||
/* However, they're required to access the SD card, so we must do them ahead of time. */
|
||||
reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_CLK, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_DOWN),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CLK_PM, SDMMC1));
|
||||
|
||||
reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_CMD, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_CMD_PM, SDMMC1));
|
||||
|
||||
reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT3, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT3_PM, SDMMC1));
|
||||
|
||||
reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT2, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT2_PM, SDMMC1));
|
||||
|
||||
reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT1, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT1_PM, SDMMC1));
|
||||
|
||||
reg::ReadWrite(APB + PINMUX_AUX_SDMMC1_DAT0, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_PUPD, PULL_UP),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, SDMMC1));
|
||||
|
||||
reg::ReadWrite(APB + PINMUX_AUX_DMIC3_CLK, PINMUX_REG_BITS_ENUM(AUX_E_OD, DISABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_E_INPUT, DISABLE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_TRISTATE, PASSTHROUGH),
|
||||
PINMUX_REG_BITS_ENUM(AUX_SDMMC1_DAT0_PM, RSVD2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result InitializeSdCard() {
|
||||
/* Perform initial pinmux config to enable sd card access. */
|
||||
ConfigureInitialSdCardPinmux();
|
||||
|
||||
/* Initialize the SD card. */
|
||||
sdmmc::Initialize(SdCardPort);
|
||||
|
||||
/* Set the SD card work buffer. */
|
||||
sdmmc::SetSdCardWorkBuffer(SdCardPort, g_sd_work_buffer, sizeof(g_sd_work_buffer));
|
||||
|
||||
/* Activate the SD card. */
|
||||
return sdmmc::Activate(SdCardPort);
|
||||
}
|
||||
|
||||
void FinalizeSdCard() {
|
||||
/* Deactivate the SD card. */
|
||||
sdmmc::Deactivate(SdCardPort);
|
||||
|
||||
/* Finalize the SD card. */
|
||||
sdmmc::Finalize(SdCardPort);
|
||||
}
|
||||
|
||||
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||
return sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort);
|
||||
}
|
||||
|
||||
Result GetSdCardMemoryCapacity(u32 *out_num_sectors) {
|
||||
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort);
|
||||
}
|
||||
|
||||
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||
return sdmmc::Read(dst, size, SdCardPort, sector_index, sector_count);
|
||||
}
|
||||
|
||||
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||
return sdmmc::Write(SdCardPort, sector_index, sector_count, src, size);
|
||||
}
|
||||
|
||||
}
|
||||
30
fusee/program/source/fusee_sd_card.hpp
Normal file
30
fusee/program/source/fusee_sd_card.hpp
Normal 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/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
Result InitializeSdCard();
|
||||
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw);
|
||||
Result GetSdCardMemoryCapacity(u32 *out_num_sectors);
|
||||
|
||||
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count);
|
||||
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size);
|
||||
|
||||
void FinalizeSdCard();
|
||||
|
||||
}
|
||||
48
fusee/program/source/fusee_secmon_sync.cpp
Normal file
48
fusee/program/source/fusee_secmon_sync.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_secmon_sync.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE pkg1::SecureMonitorParameters &GetSecureMonitorParameters() {
|
||||
return *secmon::MemoryRegionPhysicalDeviceBootloaderParams.GetPointer<pkg1::SecureMonitorParameters>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InitializeSecureMonitorMailbox() {
|
||||
std::memset(std::addressof(GetSecureMonitorParameters()), 0, sizeof(GetSecureMonitorParameters()));
|
||||
}
|
||||
|
||||
void WaitSecureMonitorState(pkg1::SecureMonitorState state) {
|
||||
auto &secmon_params = GetSecureMonitorParameters();
|
||||
|
||||
while (secmon_params.secmon_state != state) {
|
||||
hw::InvalidateDataCache(std::addressof(secmon_params.secmon_state), sizeof(secmon_params.secmon_state));
|
||||
util::WaitMicroSeconds(1);
|
||||
}
|
||||
}
|
||||
|
||||
void SetBootloaderState(pkg1::BootloaderState state) {
|
||||
auto &secmon_params = GetSecureMonitorParameters();
|
||||
secmon_params.bootloader_state = state;
|
||||
hw::FlushDataCache(std::addressof(secmon_params.bootloader_state), sizeof(secmon_params.bootloader_state));
|
||||
}
|
||||
|
||||
}
|
||||
26
fusee/program/source/fusee_secmon_sync.hpp
Normal file
26
fusee/program/source/fusee_secmon_sync.hpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void InitializeSecureMonitorMailbox();
|
||||
|
||||
void WaitSecureMonitorState(pkg1::SecureMonitorState state);
|
||||
void SetBootloaderState(pkg1::BootloaderState state);
|
||||
|
||||
}
|
||||
87
fusee/program/source/fusee_secondary_archive.hpp
Normal file
87
fusee/program/source/fusee_secondary_archive.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "fusee_display.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
constexpr inline const size_t SecondaryArchiveSize = 8_MB;
|
||||
|
||||
constexpr inline const size_t InitialProcessStorageSizeMax = 3_MB / 8;
|
||||
|
||||
struct SecondaryArchiveContentMeta {
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u8 type;
|
||||
u8 flags[3];
|
||||
u32 pad;
|
||||
char name[0x10];
|
||||
};
|
||||
static_assert(sizeof(SecondaryArchiveContentMeta) == 0x20);
|
||||
|
||||
struct SecondaryArchiveKipMeta {
|
||||
u64 program_id;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
se::Sha256Hash hash;
|
||||
};
|
||||
static_assert(sizeof(SecondaryArchiveKipMeta) == 0x30);
|
||||
|
||||
struct SecondaryArchiveHeader {
|
||||
static constexpr u32 Magic = util::FourCC<'F','S','S','0'>::Code;
|
||||
|
||||
u32 reserved0; /* Previously entrypoint. */
|
||||
u32 metadata_offset;
|
||||
u32 flags;
|
||||
u32 meso_size;
|
||||
u32 num_kips;
|
||||
u32 reserved1[3];
|
||||
u32 magic;
|
||||
u32 total_size;
|
||||
u32 reserved2; /* Previously crt0 offset. */
|
||||
u32 content_header_offset;
|
||||
u32 num_content_headers;
|
||||
u32 supported_hos_version;
|
||||
u32 release_version;
|
||||
u32 git_revision;
|
||||
SecondaryArchiveContentMeta content_metas[(0x400 - 0x40) / sizeof(SecondaryArchiveContentMeta)];
|
||||
SecondaryArchiveKipMeta emummc_meta;
|
||||
SecondaryArchiveKipMeta kip_metas[8];
|
||||
u8 reserved3[0x800 - (0x400 + 9 * sizeof(SecondaryArchiveKipMeta))];
|
||||
};
|
||||
static_assert(sizeof(SecondaryArchiveHeader) == 0x800);
|
||||
|
||||
struct SecondaryArchive {
|
||||
SecondaryArchiveHeader header; /* 0x000000-0x000800 */
|
||||
u8 warmboot[0x1800]; /* 0x000800-0x002000 */
|
||||
u8 tsec_keygen[0x2000]; /* 0x002000-0x004000 */
|
||||
u8 mariko_fatal[0x1C000]; /* 0x004000-0x020000 */
|
||||
u8 ovl_mtc_erista[0x14000]; /* 0x020000-0x034000 */
|
||||
u8 ovl_mtc_mariko[0x14000]; /* 0x034000-0x048000 */
|
||||
u8 exosphere[0xE000]; /* 0x048000-0x056000 */
|
||||
u8 mesosphere[0xAA000]; /* 0x056000-0x100000 */
|
||||
u8 kips[3_MB]; /* 0x100000-0x400000 */
|
||||
u8 splash_screen_fb[FrameBufferSize]; /* 0x400000-0x7C0000 */
|
||||
u8 fusee[0x20000]; /* 0x7C0000-0x7E0000 */
|
||||
u8 reboot_stub[0x1000]; /* 0x7E0000-0x7E1000 */
|
||||
u8 reserved[0x1F000]; /* 0x7E1000-0x800000 */
|
||||
};
|
||||
static_assert(sizeof(SecondaryArchive) == SecondaryArchiveSize);
|
||||
|
||||
ALWAYS_INLINE const SecondaryArchive &GetSecondaryArchive() { return *reinterpret_cast<const SecondaryArchive *>(0xC0000000); }
|
||||
|
||||
}
|
||||
847
fusee/program/source/fusee_setup_horizon.cpp
Normal file
847
fusee/program/source/fusee_setup_horizon.cpp
Normal file
@@ -0,0 +1,847 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include <exosphere/secmon/secmon_monitor_context.hpp>
|
||||
#include "fusee_key_derivation.hpp"
|
||||
#include "fusee_secondary_archive.hpp"
|
||||
#include "fusee_setup_horizon.hpp"
|
||||
#include "fusee_ini.hpp"
|
||||
#include "fusee_emummc.hpp"
|
||||
#include "fusee_mmc.hpp"
|
||||
#include "fusee_cpu.hpp"
|
||||
#include "fusee_fatal.hpp"
|
||||
#include "fusee_package2.hpp"
|
||||
#include "fusee_malloc.hpp"
|
||||
#include "fusee_secmon_sync.hpp"
|
||||
#include "fusee_stratosphere.hpp"
|
||||
#include "fs/fusee_fs_api.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t MC = secmon::MemoryRegionPhysicalDeviceMemoryController.GetAddress();
|
||||
|
||||
constinit secmon::EmummcConfiguration g_emummc_cfg = {};
|
||||
|
||||
void DeriveAllKeys(const fuse::SocType soc_type) {
|
||||
/* If on erista, run the TSEC keygen firmware. */
|
||||
if (soc_type == fuse::SocType_Erista) {
|
||||
clkrst::SetBpmpClockRate(clkrst::BpmpClockRate_408MHz);
|
||||
|
||||
if (!tsec::RunTsecFirmware(GetSecondaryArchive().tsec_keygen, sizeof(GetSecondaryArchive().tsec_keygen))) {
|
||||
ShowFatalError("Failed to run tsec_keygen firmware!\n");
|
||||
}
|
||||
|
||||
clkrst::SetBpmpClockRate(clkrst::BpmpClockRate_576MHz);
|
||||
}
|
||||
|
||||
/* Derive master/device keys. */
|
||||
if (soc_type == fuse::SocType_Erista) {
|
||||
DeriveKeysErista();
|
||||
} else /* if (soc_type == fuse::SocType_Mariko) */ {
|
||||
DeriveKeysMariko();
|
||||
}
|
||||
}
|
||||
|
||||
bool ParseIniSafe(IniSectionList &out_sections, const char *ini_path) {
|
||||
const auto result = ParseIniFile(out_sections, ini_path);
|
||||
if (result == ParseIniResult_Success) {
|
||||
return true;
|
||||
} else if (result == ParseIniResult_NoFile) {
|
||||
return false;
|
||||
} else {
|
||||
ShowFatalError("Failed to parse %s!\n", ini_path);
|
||||
}
|
||||
}
|
||||
|
||||
u32 ParseHexInteger(const char *s) {
|
||||
u32 x = 0;
|
||||
if (s[0] == '0' && s[1] == 'x') {
|
||||
s += 2;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const char c = *(s++);
|
||||
|
||||
if (c == '\x00') {
|
||||
return x;
|
||||
} else {
|
||||
x <<= 4;
|
||||
|
||||
if ('0' <= c && c <= '9') {
|
||||
x |= (c - '0');
|
||||
} else if ('a' <= c && c <= 'f') {
|
||||
x |= (c - 'a') + 10;
|
||||
} else if ('A' <= c && c <= 'F') {
|
||||
x |= (c - 'A') + 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 ParseDecimalInteger(const char *s) {
|
||||
u32 x = 0;
|
||||
while (true) {
|
||||
const char c = *(s++);
|
||||
|
||||
if (c == '\x00') {
|
||||
return x;
|
||||
} else {
|
||||
x *= 10;
|
||||
|
||||
if ('0' <= c && c <= '9') {
|
||||
x += c - '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDirectoryExist(const char *path) {
|
||||
fs::DirectoryEntryType entry_type;
|
||||
bool archive;
|
||||
return R_SUCCEEDED(fs::GetEntryType(std::addressof(entry_type), std::addressof(archive), path)) && entry_type == fs::DirectoryEntryType_Directory;
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool IsFileExist(const char *path) {
|
||||
fs::DirectoryEntryType entry_type;
|
||||
bool archive;
|
||||
return R_SUCCEEDED(fs::GetEntryType(std::addressof(entry_type), std::addressof(archive), path)) && entry_type == fs::DirectoryEntryType_File;
|
||||
}
|
||||
|
||||
bool IsConcatenationFileExist(const char *path) {
|
||||
fs::DirectoryEntryType entry_type;
|
||||
bool archive;
|
||||
return R_SUCCEEDED(fs::GetEntryType(std::addressof(entry_type), std::addressof(archive), path)) && ((entry_type == fs::DirectoryEntryType_File) || (entry_type == fs::DirectoryEntryType_Directory && archive));
|
||||
}
|
||||
|
||||
constinit char g_nca_path[0x40] = "sys:/contents/registered/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.nca";
|
||||
|
||||
bool IsNcaExist(const char *nca_name) {
|
||||
std::memcpy(g_nca_path + 0x19, nca_name, 0x20);
|
||||
|
||||
return IsConcatenationFileExist(g_nca_path);
|
||||
}
|
||||
|
||||
bool ConfigureEmummc() {
|
||||
/* Set magic. */
|
||||
g_emummc_cfg.base_cfg.magic = secmon::EmummcBaseConfiguration::Magic;
|
||||
|
||||
/* Parse ini. */
|
||||
bool enabled = false;
|
||||
u32 id = 0;
|
||||
u32 sector = 0;
|
||||
const char *path = "";
|
||||
const char *n_path = "";
|
||||
{
|
||||
IniSectionList sections;
|
||||
if (ParseIniSafe(sections, "sdmc:/emummc/emummc.ini")) {
|
||||
for (const auto §ion : sections) {
|
||||
/* We only care about the [emummc] section. */
|
||||
if (std::strcmp(section.name, "emummc")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle individual fields. */
|
||||
for (const auto &entry : section.kv_list) {
|
||||
if (std::strcmp(entry.key, "enabled") == 0) {
|
||||
enabled = entry.value[0] == '1';
|
||||
} else if (std::strcmp(entry.key, "id") == 0) {
|
||||
id = ParseHexInteger(entry.value);
|
||||
} else if (std::strcmp(entry.key, "sector") == 0) {
|
||||
sector = ParseHexInteger(entry.value);
|
||||
} else if (std::strcmp(entry.key, "path") == 0) {
|
||||
path = entry.value;
|
||||
} else if (std::strcmp(entry.key, "nintendo_path") == 0) {
|
||||
n_path = entry.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set values parsed from config. */
|
||||
g_emummc_cfg.base_cfg.id = id;
|
||||
std::strncpy(g_emummc_cfg.emu_dir_path.str, n_path, sizeof(g_emummc_cfg.emu_dir_path.str));
|
||||
g_emummc_cfg.emu_dir_path.str[sizeof(g_emummc_cfg.emu_dir_path.str) - 1] = '\x00';
|
||||
|
||||
if (enabled) {
|
||||
if (sector > 0) {
|
||||
g_emummc_cfg.base_cfg.type = secmon::EmummcType_Partition;
|
||||
g_emummc_cfg.partition_cfg.start_sector = sector;
|
||||
} else if (path[0] != '\x00' && IsDirectoryExist(path)) {
|
||||
g_emummc_cfg.base_cfg.type = secmon::EmummcType_File;
|
||||
|
||||
std::strncpy(g_emummc_cfg.file_cfg.path.str, path, sizeof(g_emummc_cfg.file_cfg.path.str));
|
||||
g_emummc_cfg.file_cfg.path.str[sizeof(g_emummc_cfg.file_cfg.path.str) - 1] = '\x00';
|
||||
} else {
|
||||
ShowFatalError("Invalid emummc setting!\n");
|
||||
}
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
u8 *LoadPackage1(fuse::SocType soc_type) {
|
||||
u8 *package1 = static_cast<u8 *>(AllocateAligned(0x40000, 0x1000));
|
||||
|
||||
const Result result = ReadBoot0(0x100000, package1, 0x40000);
|
||||
if (R_FAILED(result)) {
|
||||
ShowFatalError("Failed to read boot0: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
if (soc_type == fuse::SocType_Mariko) {
|
||||
package1 += 0x170;
|
||||
|
||||
se::DecryptAes128Cbc(package1 + 0x20, 0x40000 - (0x20 + 0x170), pkg1::AesKeySlot_MarikoBek, package1 + 0x20, 0x40000 - (0x20 + 0x170), package1 + 0x10, se::AesBlockSize);
|
||||
|
||||
hw::InvalidateDataCache(package1 + 0x20, 0x40000 - (0x20 + 0x170));
|
||||
|
||||
if (std::memcmp(package1, package1 + 0x20, 0x20) != 0) {
|
||||
ShowFatalError("Package1 seems corrupt!\n");
|
||||
}
|
||||
}
|
||||
|
||||
return package1;
|
||||
}
|
||||
|
||||
ams::TargetFirmware GetTargetFirmware(const u8 *package1) {
|
||||
/* Get first an approximation of the target firmware. */
|
||||
ams::TargetFirmware target_firmware = ams::TargetFirmware_Current;
|
||||
switch (package1[0x1F]) {
|
||||
case 0x01:
|
||||
target_firmware = ams::TargetFirmware_1_0_0;
|
||||
break;
|
||||
case 0x02:
|
||||
target_firmware = ams::TargetFirmware_2_0_0;
|
||||
break;
|
||||
case 0x04:
|
||||
target_firmware = ams::TargetFirmware_3_0_0;
|
||||
break;
|
||||
case 0x07:
|
||||
target_firmware = ams::TargetFirmware_4_0_0;
|
||||
break;
|
||||
case 0x0B:
|
||||
target_firmware = ams::TargetFirmware_5_0_0;
|
||||
break;
|
||||
case 0x0E:
|
||||
if (std::memcmp(package1 + 0x10, "20180802", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_6_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20181107", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_6_2_0;
|
||||
} else {
|
||||
ShowFatalError("Unable to identify package1!\n");
|
||||
}
|
||||
break;
|
||||
case 0x0F:
|
||||
target_firmware = ams::TargetFirmware_7_0_0;
|
||||
break;
|
||||
case 0x10:
|
||||
if (std::memcmp(package1 + 0x10, "20190314", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_8_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20190531", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_8_1_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20190809", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_9_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20191021", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_9_1_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20200303", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_10_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20201030", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_11_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20210129", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_12_0_0;
|
||||
} else if (std::memcmp(package1 + 0x10, "20210422", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_12_0_2;
|
||||
} else if (std::memcmp(package1 + 0x10, "20210607", 8) == 0) {
|
||||
target_firmware = ams::TargetFirmware_12_1_0;
|
||||
} else {
|
||||
ShowFatalError("Unable to identify package1!\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ShowFatalError("Unable to identify package1!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#define CHECK_NCA(NCA_ID, VERSION) do { if (IsNcaExist(NCA_ID)) { return ams::TargetFirmware_##VERSION; } } while(0)
|
||||
|
||||
if (target_firmware >= ams::TargetFirmware_12_1_0) {
|
||||
CHECK_NCA("9d9d83d68d9517f245f3e8cd7f93c416", 12_1_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_12_0_2) {
|
||||
CHECK_NCA("a1863a5c0e1cedd442f5e60b0422dc15", 12_0_3);
|
||||
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
|
||||
} else if (target_firmware >= ams::TargetFirmware_12_0_0) {
|
||||
CHECK_NCA("e65114b456f9d0b566a80e53bade2d89", 12_0_1);
|
||||
CHECK_NCA("bd4185843550fbba125b20787005d1d2", 12_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_11_0_0) {
|
||||
CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1);
|
||||
CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_10_0_0) {
|
||||
CHECK_NCA("26325de4db3909e0ef2379787c7e671d", 10_2_0);
|
||||
CHECK_NCA("5077973537f6735b564dd7475b779f87", 10_1_1); /* Exclusive to China. */
|
||||
CHECK_NCA("fd1faed0ca750700d254c0915b93d506", 10_1_0);
|
||||
CHECK_NCA("34728c771299443420820d8ae490ea41", 10_0_4);
|
||||
CHECK_NCA("5b1df84f88c3334335bbb45d8522cbb4", 10_0_3);
|
||||
CHECK_NCA("e951bc9dedcd54f65ffd83d4d050f9e0", 10_0_2);
|
||||
CHECK_NCA("36ab1acf0c10a2beb9f7d472685f9a89", 10_0_1);
|
||||
CHECK_NCA("5625cdc21d5f1ca52f6c36ba261505b9", 10_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_9_1_0) {
|
||||
CHECK_NCA("09ef4d92bb47b33861e695ba524a2c17", 9_2_0);
|
||||
CHECK_NCA("c5fbb49f2e3648c8cfca758020c53ecb", 9_1_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_9_0_0) {
|
||||
CHECK_NCA("fd1ffb82dc1da76346343de22edbc97c", 9_0_1);
|
||||
CHECK_NCA("a6af05b33f8f903aab90c8b0fcbcc6a4", 9_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_8_1_0) {
|
||||
CHECK_NCA("724d9b432929ea43e787ad81bf09ae65", 8_1_1); /* 8.1.1-100 from Lite */
|
||||
CHECK_NCA("e9bb0602e939270a9348bddd9b78827b", 8_1_1); /* 8.1.1-12 from chinese gamecard */
|
||||
CHECK_NCA("7eedb7006ad855ec567114be601b2a9d", 8_1_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_8_0_0) {
|
||||
CHECK_NCA("6c5426d27c40288302ad616307867eba", 8_0_1);
|
||||
CHECK_NCA("4fe7b4abcea4a0bcc50975c1a926efcb", 8_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_7_0_0) {
|
||||
CHECK_NCA("e6b22c40bb4fa66a151f1dc8db5a7b5c", 7_0_1);
|
||||
CHECK_NCA("c613bd9660478de69bc8d0e2e7ea9949", 7_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_6_2_0) {
|
||||
CHECK_NCA("6dfaaf1a3cebda6307aa770d9303d9b6", 6_2_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_6_0_0) {
|
||||
CHECK_NCA("1d21680af5a034d626693674faf81b02", 6_1_0);
|
||||
CHECK_NCA("663e74e45ffc86fbbaeb98045feea315", 6_0_1);
|
||||
CHECK_NCA("258c1786b0f6844250f34d9c6f66095b", 6_0_0); /* Release 6.0.0-5.0 */
|
||||
CHECK_NCA("286e30bafd7e4197df6551ad802dd815", 6_0_0); /* Pre-Release 6.0.0-4.0 */
|
||||
} else if (target_firmware >= ams::TargetFirmware_5_0_0) {
|
||||
CHECK_NCA("fce3b0ea366f9c95fe6498b69274b0e7", 5_1_0);
|
||||
CHECK_NCA("c5758b0cb8c6512e8967e38842d35016", 5_0_2);
|
||||
CHECK_NCA("53eb605d4620e8fd50064b24fd57783a", 5_0_1);
|
||||
CHECK_NCA("09a2f9c16ce1c121ae6d231b35d17515", 5_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_4_0_0) {
|
||||
CHECK_NCA("77e1ae7661ad8a718b9b13b70304aeea", 4_1_0);
|
||||
CHECK_NCA("d0e5d20e3260f3083bcc067483b71274", 4_0_1);
|
||||
CHECK_NCA("483a24ee3fd7149f9112d1931166a678", 4_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_3_0_0) {
|
||||
CHECK_NCA("704129fc89e1fcb85c37b3112e51b0fc", 3_0_2);
|
||||
CHECK_NCA("1fb00543307337d523ccefa9923e0c50", 3_0_1);
|
||||
CHECK_NCA("6ebd3447473bade18badbeb5032af87d", 3_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_2_0_0) {
|
||||
CHECK_NCA("d1c991c53a8a9038f8c3157a553d876d", 2_3_0);
|
||||
CHECK_NCA("7f90353dff2d7ce69e19e07ebc0d5489", 2_2_0);
|
||||
CHECK_NCA("e9b3e75fce00e52fe646156634d229b4", 2_1_0);
|
||||
CHECK_NCA("7a1f79f8184d4b9bae1755090278f52c", 2_0_0);
|
||||
} else if (target_firmware >= ams::TargetFirmware_1_0_0) {
|
||||
CHECK_NCA("a1b287e07f8455e8192f13d0e45a2aaf", 1_0_0); /* 1.0.0 from Factory */
|
||||
CHECK_NCA("117f7b9c7da3e8cef02340596af206b3", 1_0_0); /* 1.0.0 from Gamecard */
|
||||
} else {
|
||||
ShowFatalError("Unable to determine target firmware!\n");
|
||||
}
|
||||
|
||||
#undef CHECK_NCA
|
||||
|
||||
/* If we didn't find a more specific firmware, return our package1 approximation. */
|
||||
return target_firmware;
|
||||
}
|
||||
|
||||
u8 *LoadBootConfigAndPackage2() {
|
||||
Result result;
|
||||
|
||||
/* Load boot config. */
|
||||
if (R_FAILED((result = ReadPackage2(0, secmon::MemoryRegionPhysicalIramBootConfig.GetPointer<void>(), secmon::MemoryRegionPhysicalIramBootConfig.GetSize())))) {
|
||||
ShowFatalError("Failed to read boot config: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
/* Read package2 header. */
|
||||
u8 *package2;
|
||||
size_t package2_size;
|
||||
{
|
||||
constexpr s64 Package2Offset = __builtin_offsetof(pkg2::StorageLayout, package2_header);
|
||||
|
||||
pkg2::Package2Header header;
|
||||
if (R_FAILED((result = ReadPackage2(Package2Offset, std::addressof(header), sizeof(header))))) {
|
||||
ShowFatalError("Failed to read package2 header: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
package2_size = header.meta.GetSize();
|
||||
package2 = static_cast<u8 *>(AllocateAligned(util::AlignUp(package2_size, 0x4000), 0x4000));
|
||||
|
||||
if (R_FAILED((result = ReadPackage2(Package2Offset, package2, util::AlignUp(package2_size, 0x4000))))) {
|
||||
ShowFatalError("Failed to read package2: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
/* Decrypt package2. */
|
||||
DecryptPackage2(package2);
|
||||
|
||||
return package2;
|
||||
}
|
||||
|
||||
constexpr inline const u8 PkcModulusErista[0x100] = {
|
||||
0xF7, 0x86, 0x47, 0xAB, 0x71, 0x89, 0x81, 0xB5, 0xCF, 0x0C, 0xB0, 0xE8, 0x48, 0xA7, 0xFD, 0xAD,
|
||||
0xCB, 0x4E, 0x4A, 0x52, 0x0B, 0x1A, 0x8E, 0xDE, 0x41, 0x87, 0x6F, 0xB7, 0x31, 0x05, 0x5F, 0xAA,
|
||||
0xEA, 0x97, 0x76, 0x21, 0x20, 0x2B, 0x40, 0x48, 0x76, 0x55, 0x35, 0x03, 0xFE, 0x7F, 0x67, 0x62,
|
||||
0xFD, 0x4E, 0xE1, 0x22, 0xF8, 0xF0, 0x97, 0x39, 0xEF, 0xEA, 0x47, 0x89, 0x3C, 0xDB, 0xF0, 0x02,
|
||||
0xAD, 0x0C, 0x96, 0xCA, 0x82, 0xAB, 0xB3, 0xCB, 0x98, 0xC8, 0xDC, 0xC6, 0xAC, 0x5C, 0x93, 0x3B,
|
||||
0x84, 0x3D, 0x51, 0x91, 0x9E, 0xC1, 0x29, 0x22, 0x95, 0xF0, 0xA1, 0x51, 0xBA, 0xAF, 0x5D, 0xC3,
|
||||
0xAB, 0x04, 0x1B, 0x43, 0x61, 0x7D, 0xEA, 0x65, 0x95, 0x24, 0x3C, 0x51, 0x3E, 0x8F, 0xDB, 0xDB,
|
||||
0xC1, 0xC4, 0x2D, 0x04, 0x29, 0x5A, 0xD7, 0x34, 0x6B, 0xCC, 0xF1, 0x06, 0xF9, 0xC9, 0xE1, 0xF9,
|
||||
0x61, 0x52, 0xE2, 0x05, 0x51, 0xB1, 0x3D, 0x88, 0xF9, 0xA9, 0x27, 0xA5, 0x6F, 0x4D, 0xE7, 0x22,
|
||||
0x48, 0xA5, 0xF8, 0x12, 0xA2, 0xC2, 0x5A, 0xA0, 0xBF, 0xC8, 0x76, 0x4B, 0x66, 0xFE, 0x1C, 0x73,
|
||||
0x00, 0x29, 0x26, 0xCD, 0x18, 0x4F, 0xC2, 0xB0, 0x51, 0x77, 0x2E, 0x91, 0x09, 0x1B, 0x41, 0x5D,
|
||||
0x89, 0x5E, 0xEE, 0x24, 0x22, 0x47, 0xE5, 0xE5, 0xF1, 0x86, 0x99, 0x67, 0x08, 0x28, 0x42, 0xF0,
|
||||
0x58, 0x62, 0x54, 0xC6, 0x5B, 0xDC, 0xE6, 0x80, 0x85, 0x6F, 0xE2, 0x72, 0xB9, 0x7E, 0x36, 0x64,
|
||||
0x48, 0x85, 0x10, 0xA4, 0x75, 0x38, 0x79, 0x76, 0x8B, 0x51, 0xD5, 0x87, 0xC3, 0x02, 0xC9, 0x1B,
|
||||
0x93, 0x22, 0x49, 0xEA, 0xAB, 0xA0, 0xB5, 0xB1, 0x3C, 0x10, 0xC4, 0x71, 0xF0, 0xF1, 0x81, 0x1A,
|
||||
0x3A, 0x9C, 0xFC, 0x51, 0x61, 0xB1, 0x4B, 0x18, 0xB2, 0x3D, 0xAA, 0xD6, 0xAC, 0x72, 0x26, 0xB7
|
||||
};
|
||||
|
||||
constexpr inline const u8 PkcModulusDevelopmentErista[0x100] = {
|
||||
0x37, 0x84, 0x14, 0xB3, 0x78, 0xA4, 0x7F, 0xD8, 0x71, 0x45, 0xCD, 0x90, 0x51, 0x51, 0xBF, 0x2C,
|
||||
0x27, 0x03, 0x30, 0x46, 0xBE, 0x8F, 0x99, 0x3E, 0x9F, 0x36, 0x4D, 0xEB, 0xF7, 0x0E, 0x81, 0x7F,
|
||||
0xE4, 0x6B, 0xA8, 0x42, 0x8A, 0xA5, 0x4F, 0x76, 0xCC, 0xCB, 0xC5, 0x31, 0xA8, 0x5A, 0x70, 0x51,
|
||||
0x34, 0xBF, 0x1E, 0x8D, 0x6E, 0xCF, 0x05, 0x84, 0xCF, 0x8B, 0xE5, 0x9C, 0x3A, 0xA5, 0xCD, 0x1A,
|
||||
0x9C, 0xAC, 0x59, 0x30, 0x09, 0x21, 0x3C, 0xBE, 0x07, 0x5C, 0x8D, 0x1C, 0xD1, 0xA3, 0xC9, 0x8F,
|
||||
0x26, 0xE2, 0x99, 0xB2, 0x3C, 0x28, 0xAD, 0x63, 0x0F, 0xF5, 0xA0, 0x1C, 0xA2, 0x34, 0xC4, 0x0E,
|
||||
0xDB, 0xD7, 0xE1, 0xA9, 0x5E, 0xE9, 0xA5, 0xA8, 0x64, 0x3A, 0xFC, 0x48, 0xB5, 0x97, 0xDF, 0x55,
|
||||
0x7C, 0x9A, 0xD2, 0x8C, 0x32, 0x36, 0x1D, 0xC5, 0xA0, 0xC5, 0x66, 0xDF, 0x8A, 0xAD, 0x76, 0x18,
|
||||
0x46, 0x3E, 0xDF, 0xD8, 0xEF, 0xB9, 0xE5, 0xDC, 0xCD, 0x08, 0x59, 0xBC, 0x36, 0x68, 0xD6, 0xFC,
|
||||
0x3F, 0xFA, 0x11, 0x00, 0x0D, 0x50, 0xE0, 0x69, 0x0F, 0x70, 0x78, 0x7E, 0xD1, 0xA5, 0x85, 0xCD,
|
||||
0x13, 0xBC, 0x42, 0x74, 0x33, 0x0C, 0x11, 0x24, 0x1E, 0x33, 0xD5, 0x31, 0xB7, 0x3E, 0x48, 0x94,
|
||||
0xCC, 0x81, 0x29, 0x1E, 0xB1, 0xCF, 0x4C, 0x36, 0x7F, 0xE1, 0x1C, 0x15, 0xD4, 0x3F, 0xFB, 0x12,
|
||||
0xC2, 0x73, 0x22, 0x16, 0x52, 0xE0, 0x5C, 0x4C, 0x94, 0xE0, 0x87, 0x47, 0xEA, 0xD0, 0x9F, 0x42,
|
||||
0x9B, 0xAC, 0xB6, 0xB5, 0xB6, 0x34, 0xE4, 0x55, 0x49, 0xD7, 0xC0, 0xAE, 0xD4, 0x22, 0xB3, 0x5C,
|
||||
0x87, 0x64, 0x42, 0xEC, 0x11, 0x6D, 0xBC, 0x09, 0xC0, 0x80, 0x07, 0xD0, 0xBD, 0xBA, 0x45, 0xFE,
|
||||
0xD5, 0x52, 0xDA, 0xEC, 0x41, 0xA4, 0xAD, 0x7B, 0x36, 0x86, 0x18, 0xB4, 0x5B, 0xD1, 0x30, 0xBB
|
||||
};
|
||||
|
||||
void LoadWarmbootFirmware(fuse::SocType soc_type, ams::TargetFirmware target_firmware, const u8 *package1) {
|
||||
u8 *warmboot_dst = secmon::MemoryRegionPhysicalIramWarmbootBin.GetPointer<u8>();
|
||||
size_t warmboot_size = std::min(sizeof(GetSecondaryArchive().warmboot), secmon::MemoryRegionPhysicalIramWarmbootBin.GetSize());
|
||||
if (soc_type == fuse::SocType_Erista) {
|
||||
/* Copy the ams warmboot binary. */
|
||||
std::memcpy(warmboot_dst, GetSecondaryArchive().warmboot, warmboot_size);
|
||||
|
||||
/* Set the rsa modulus. */
|
||||
if (fuse::GetHardwareState() == fuse::HardwareState_Production) {
|
||||
std::memcpy(warmboot_dst + 0x10, PkcModulusErista, sizeof(PkcModulusErista));
|
||||
} else {
|
||||
std::memcpy(warmboot_dst + 0x10, PkcModulusDevelopmentErista, sizeof(PkcModulusDevelopmentErista));
|
||||
}
|
||||
|
||||
/* Set the target firmware. */
|
||||
std::memcpy(warmboot_dst + 0x248, std::addressof(target_firmware), sizeof(target_firmware));
|
||||
} else /* if (soc_type == fuse::SocType_Mariko) */ {
|
||||
/* Declare path for mariko warmboot files. */
|
||||
char warmboot_path[0x80] = "sdmc:/warmboot_mariko/wb_xx.bin";
|
||||
|
||||
auto UpdateWarmbootPath = [&warmboot_path](u8 fuses) {
|
||||
warmboot_path[0x19] = "0123456789abcdef"[(fuses >> 4) & 0xF];
|
||||
warmboot_path[0x1A] = "0123456789abcdef"[(fuses >> 0) & 0xF];
|
||||
};
|
||||
|
||||
/* Get expected/burnt fuse counts. */
|
||||
const u32 expected_fuses = fuse::GetExpectedFuseVersion(target_firmware);
|
||||
const u32 burnt_fuses = fuse::GetFuseVersion();
|
||||
u32 used_fuses = expected_fuses;
|
||||
|
||||
/* Get warmboot from package1. */
|
||||
const u8 *warmboot_src = nullptr;
|
||||
size_t warmboot_src_size = 0;
|
||||
{
|
||||
const u32 *package1_pk11 = reinterpret_cast<const u32 *>(package1 + (target_firmware >= ams::TargetFirmware_6_2_0 ? 0x7000 : 0x4000));
|
||||
if (std::memcmp(package1_pk11, "PK11", 4) != 0) {
|
||||
ShowFatalError("Invalid package1 magic!\n");
|
||||
}
|
||||
|
||||
const u32 *package1_pk11_data = reinterpret_cast<const u32 *>(package1_pk11 + (0x20 / sizeof(u32)));
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
switch (*package1_pk11_data) {
|
||||
case 0xD5034FDF:
|
||||
package1_pk11_data += package1_pk11[6] / sizeof(u32);
|
||||
break;
|
||||
case 0xE328F0C0:
|
||||
case 0xF0C0A7F0:
|
||||
package1_pk11_data += package1_pk11[4] / sizeof(u32);
|
||||
break;
|
||||
default:
|
||||
warmboot_src = reinterpret_cast<const u8 *>(package1_pk11_data);
|
||||
i = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
warmboot_src_size = *package1_pk11_data;
|
||||
if (!(0x800 <= warmboot_src_size && warmboot_src_size < 0x1000)) {
|
||||
ShowFatalError("Package1 warmboot firmware seems invalid!\n");
|
||||
}
|
||||
|
||||
/* If we should, save the current warmboot firmware. */
|
||||
UpdateWarmbootPath(expected_fuses);
|
||||
if (!IsFileExist(warmboot_path)) {
|
||||
fs::CreateDirectory("sdmc:/warmboot_mariko");
|
||||
fs::CreateFile(warmboot_path, warmboot_src_size);
|
||||
|
||||
Result result;
|
||||
fs::FileHandle file;
|
||||
if (R_FAILED((result = fs::OpenFile(std::addressof(file), warmboot_path, fs::OpenMode_ReadWrite)))) {
|
||||
ShowFatalError("Failed to save %s!\n", warmboot_path);
|
||||
}
|
||||
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
|
||||
if (R_FAILED((result = fs::WriteFile(file, 0, warmboot_src, warmboot_src_size, fs::WriteOption::Flush)))) {
|
||||
ShowFatalError("Failed to save %s!\n", warmboot_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we need to, find a cached warmboot firmware that we can use. */
|
||||
if (burnt_fuses > expected_fuses) {
|
||||
warmboot_src = nullptr;
|
||||
warmboot_src_size = 0;
|
||||
for (u32 attempt = burnt_fuses; attempt <= 32; ++attempt) {
|
||||
/* Open the current cache file. */
|
||||
UpdateWarmbootPath(attempt);
|
||||
|
||||
fs::FileHandle file;
|
||||
if (R_FAILED(fs::OpenFile(std::addressof(file), warmboot_path, fs::OpenMode_Read))) {
|
||||
continue;
|
||||
}
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
|
||||
/* Get the size. */
|
||||
s64 size;
|
||||
if (R_FAILED(fs::GetFileSize(std::addressof(size), file)) || !(0x800 <= size && size < 0x1000)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate memory. */
|
||||
warmboot_src_size = static_cast<size_t>(size);
|
||||
void *tmp = AllocateAligned(warmboot_src_size, 0x10);
|
||||
|
||||
/* Read the file. */
|
||||
if (R_FAILED(fs::ReadFile(file, 0, tmp, warmboot_src_size))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Use the cached file. */
|
||||
used_fuses = attempt;
|
||||
warmboot_src = static_cast<const u8 *>(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that we found a firmware. */
|
||||
if (warmboot_src == nullptr) {
|
||||
ShowFatalError("Failed to locate warmboot firmware!\n");
|
||||
}
|
||||
|
||||
/* Copy the warmboot firmware. */
|
||||
std::memcpy(warmboot_dst, warmboot_src, std::min(warmboot_size, warmboot_src_size));
|
||||
|
||||
/* Set the warmboot firmware magic. */
|
||||
switch (used_fuses) {
|
||||
case 7:
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH32, 0x87);
|
||||
case 8:
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH32, 0xA8);
|
||||
default:
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH32, (0x108 + 0x21 * (used_fuses - 8)));
|
||||
break;
|
||||
}
|
||||
reg::SetBits(PMC + APBDEV_PMC_SEC_DISABLE3, (1 << 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureExosphere(fuse::SocType soc_type, ams::TargetFirmware target_firmware, bool emummc_enabled, u32 fs_version) {
|
||||
/* Get monitor configuration. */
|
||||
auto &storage_ctx = *secmon::MemoryRegionPhysicalDramMonitorConfiguration.GetPointer<secmon::SecureMonitorStorageConfiguration>();
|
||||
std::memset(std::addressof(storage_ctx), 0, sizeof(storage_ctx));
|
||||
|
||||
/* Set magic. */
|
||||
storage_ctx.magic = secmon::SecureMonitorStorageConfiguration::Magic;
|
||||
|
||||
/* Set some defaults. */
|
||||
storage_ctx.target_firmware = target_firmware;
|
||||
storage_ctx.lcd_vendor = GetDisplayLcdVendor();
|
||||
storage_ctx.emummc_cfg = g_emummc_cfg;
|
||||
storage_ctx.flags[0] = secmon::SecureMonitorConfigurationFlag_Default;
|
||||
storage_ctx.flags[1] = secmon::SecureMonitorConfigurationFlag_None;
|
||||
storage_ctx.log_port = uart::Port_ReservedDebug;
|
||||
storage_ctx.log_baud_rate = 115200;
|
||||
|
||||
/* Set the fs version. */
|
||||
storage_ctx.emummc_cfg.base_cfg.fs_version = fs_version;
|
||||
|
||||
/* Parse fields from exosphere.ini */
|
||||
{
|
||||
IniSectionList sections;
|
||||
if (ParseIniSafe(sections, "sdmc:/exosphere.ini")) {
|
||||
for (const auto §ion : sections) {
|
||||
/* We only care about the [exosphere] section. */
|
||||
if (std::strcmp(section.name, "exosphere")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle individual fields. */
|
||||
for (const auto &entry : section.kv_list) {
|
||||
if (std::strcmp(entry.key, "debugmode") == 0) {
|
||||
if (entry.value[0] == '1') {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "debugmode_user") == 0) {
|
||||
if (entry.value[0] == '1') {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForUser;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForUser;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "disable_user_exception_handlers") == 0) {
|
||||
if (entry.value[0] == '1') {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_DisableUserModeExceptionHandlers;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_DisableUserModeExceptionHandlers;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "enable_user_pmu_access") == 0) {
|
||||
if (entry.value[0] == '1') {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "blank_prodinfo_sysmmc") == 0) {
|
||||
if (entry.value[0] == '1' && !emummc_enabled) {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "blank_prodinfo_emummc") == 0) {
|
||||
if (entry.value[0] == '1' && emummc_enabled) {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "allow_writing_to_cal_sysmmc") == 0) {
|
||||
if (entry.value[0] == '1') {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc;
|
||||
} else {
|
||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "log_port") == 0) {
|
||||
const u32 log_port = ParseDecimalInteger(entry.value);
|
||||
if (0 <= log_port && log_port < 4) {
|
||||
storage_ctx.log_port = log_port;
|
||||
}
|
||||
} else if (std::strcmp(entry.key, "log_baud_rate") == 0) {
|
||||
storage_ctx.log_baud_rate = ParseDecimalInteger(entry.value);
|
||||
} else if (std::strcmp(entry.key, "log_inverted") == 0) {
|
||||
if (entry.value[0] == 1) {
|
||||
storage_ctx.log_flags |= uart::Flag_Inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse usb setting from system_settings.ini */
|
||||
{
|
||||
IniSectionList sections;
|
||||
if (ParseIniSafe(sections, "sdmc:/atmosphere/config/system_settings.ini")) {
|
||||
for (const auto §ion : sections) {
|
||||
/* We only care about the [usb] section. */
|
||||
if (std::strcmp(section.name, "usb")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle individual fields. */
|
||||
for (const auto &entry : section.kv_list) {
|
||||
if (std::strcmp(entry.key, "usb30_force_enabled") == 0) {
|
||||
if (std::strcmp(entry.value, "u8!0x1") == 0) {
|
||||
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_ForceEnableUsb30;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy exosphere. */
|
||||
void *exosphere_dst = reinterpret_cast<void *>(0x40030000);
|
||||
bool use_sd_exo = false;
|
||||
{
|
||||
/* Try to use an sd card file, if present. */
|
||||
fs::FileHandle exo_file;
|
||||
if (R_SUCCEEDED(fs::OpenFile(std::addressof(exo_file), "sdmc:/atmosphere/exosphere.bin", fs::OpenMode_Read))) {
|
||||
ON_SCOPE_EXIT { fs::CloseFile(exo_file); };
|
||||
|
||||
/* Note that we're using sd_exo. */
|
||||
use_sd_exo = true;
|
||||
|
||||
Result result;
|
||||
|
||||
/* Get the size. */
|
||||
s64 size;
|
||||
if (R_FAILED((result = fs::GetFileSize(std::addressof(size), exo_file))) || size > sizeof(GetSecondaryArchive().exosphere)) {
|
||||
ShowFatalError("Invalid SD exosphere size: 0x%08" PRIx32 ", %" PRIx64 "!\n", result.GetValue(), static_cast<u64>(size));
|
||||
}
|
||||
|
||||
/* Read the file. */
|
||||
if (R_FAILED((result = fs::ReadFile(exo_file, 0, exosphere_dst, size)))) {
|
||||
ShowFatalError("Failed to read SD exosphere: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_sd_exo) {
|
||||
std::memcpy(exosphere_dst, GetSecondaryArchive().exosphere, sizeof(GetSecondaryArchive().exosphere));
|
||||
}
|
||||
|
||||
/* Copy mariko fatal. */
|
||||
if (soc_type == fuse::SocType_Mariko) {
|
||||
u8 *mariko_fatal_dst = secmon::MemoryRegionPhysicalMarikoProgramImage.GetPointer<u8>();
|
||||
bool use_sd_mariko_fatal = false;
|
||||
{
|
||||
/* Try to use an sd card file, if present. */
|
||||
fs::FileHandle mariko_program_file;
|
||||
if (R_SUCCEEDED(fs::OpenFile(std::addressof(mariko_program_file), "sdmc:/atmosphere/mariko_fatal.bin", fs::OpenMode_Read))) {
|
||||
ON_SCOPE_EXIT { fs::CloseFile(mariko_program_file); };
|
||||
|
||||
/* Note that we're using sd mariko fatal. */
|
||||
use_sd_mariko_fatal = true;
|
||||
|
||||
Result result;
|
||||
|
||||
/* Get the size. */
|
||||
s64 size;
|
||||
if (R_FAILED((result = fs::GetFileSize(std::addressof(size), mariko_program_file))) || size > sizeof(GetSecondaryArchive().mariko_fatal)) {
|
||||
ShowFatalError("Invalid SD mariko_fatal size: 0x%08" PRIx32 ", %" PRIx64 "!\n", result.GetValue(), static_cast<u64>(size));
|
||||
}
|
||||
|
||||
/* Read the file. */
|
||||
if (R_FAILED((result = fs::ReadFile(mariko_program_file, 0, mariko_fatal_dst, size)))) {
|
||||
ShowFatalError("Failed to read SD mariko_fatal: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||
}
|
||||
|
||||
/* Clear the remainder. */
|
||||
std::memset(mariko_fatal_dst + size, 0, sizeof(GetSecondaryArchive().mariko_fatal) - size);
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_sd_mariko_fatal) {
|
||||
std::memcpy(mariko_fatal_dst, GetSecondaryArchive().mariko_fatal, sizeof(GetSecondaryArchive().mariko_fatal));
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the CPU to boot exosphere. */
|
||||
SetupCpu(reinterpret_cast<uintptr_t>(exosphere_dst));
|
||||
|
||||
/* Initialize bootloader parameters. */
|
||||
InitializeSecureMonitorMailbox();
|
||||
|
||||
/* Set our bootloader state. */
|
||||
SetBootloaderState(pkg1::BootloaderState_LoadedBootConfig);
|
||||
|
||||
/* Ensure that the CPU will see consistent data. */
|
||||
hw::FlushEntireDataCache();
|
||||
}
|
||||
|
||||
bool IsNogcEnabled(ams::TargetFirmware target_firmware) {
|
||||
/* First parse from ini. */
|
||||
{
|
||||
IniSectionList sections;
|
||||
if (ParseIniSafe(sections, "sdmc:/atmosphere/config/stratosphere.ini")) {
|
||||
for (const auto §ion : sections) {
|
||||
/* We only care about the [stratosphere] section. */
|
||||
if (std::strcmp(section.name, "stratosphere")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle individual fields. */
|
||||
for (const auto &entry : section.kv_list) {
|
||||
if (std::strcmp(entry.key, "nogc") == 0) {
|
||||
return entry.value[0] == '1';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* That failed, so try to decide automatically. */
|
||||
const auto fuse_version = fuse::GetFuseVersion();
|
||||
if (target_firmware >= ams::TargetFirmware_12_0_2 && fuse_version < fuse::GetExpectedFuseVersion(ams::TargetFirmware_12_0_2)) {
|
||||
return true;
|
||||
}
|
||||
if (target_firmware >= ams::TargetFirmware_11_0_0 && fuse_version < fuse::GetExpectedFuseVersion(ams::TargetFirmware_11_0_0)) {
|
||||
return true;
|
||||
}
|
||||
if (target_firmware >= ams::TargetFirmware_9_0_0 && fuse_version < fuse::GetExpectedFuseVersion(ams::TargetFirmware_9_0_0)) {
|
||||
return true;
|
||||
}
|
||||
if (target_firmware >= ams::TargetFirmware_4_0_0 && fuse_version < fuse::GetExpectedFuseVersion(ams::TargetFirmware_4_0_0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetupAndStartHorizon() {
|
||||
/* Get soc type. */
|
||||
const auto soc_type = fuse::GetSocType();
|
||||
|
||||
/* Derive all keys. */
|
||||
DeriveAllKeys(soc_type);
|
||||
|
||||
/* Determine whether we're using emummc. */
|
||||
const bool emummc_enabled = ConfigureEmummc();
|
||||
|
||||
/* Initialize emummc. */
|
||||
/* NOTE: SYSTEM:/ accessible past this point. */
|
||||
InitializeEmummc(emummc_enabled, g_emummc_cfg);
|
||||
|
||||
/* Read bootloader. */
|
||||
const u8 * const package1 = LoadPackage1(soc_type);
|
||||
|
||||
/* Get target firmware. */
|
||||
const auto target_firmware = GetTargetFirmware(package1);
|
||||
|
||||
/* Read/decrypt package2. */
|
||||
u8 * const package2 = LoadBootConfigAndPackage2();
|
||||
|
||||
/* Setup warmboot firmware. */
|
||||
LoadWarmbootFirmware(soc_type, target_firmware, package1);
|
||||
|
||||
/* Decide whether to use nogc patches. */
|
||||
const bool nogc_enabled = IsNogcEnabled(target_firmware);
|
||||
|
||||
/* Decide what KIPs/patches we're loading. */
|
||||
const auto fs_version = ConfigureStratosphere(package2, target_firmware, emummc_enabled, nogc_enabled);
|
||||
|
||||
/* Setup exosphere. */
|
||||
ConfigureExosphere(soc_type, target_firmware, emummc_enabled, fs_version);
|
||||
|
||||
/* Start CPU. */
|
||||
StartCpu();
|
||||
|
||||
/* Build modified package2. */
|
||||
RebuildPackage2(target_firmware, emummc_enabled);
|
||||
|
||||
/* Wait for confirmation that exosphere is ready. */
|
||||
WaitSecureMonitorState(pkg1::SecureMonitorState_Initialized);
|
||||
}
|
||||
|
||||
}
|
||||
23
fusee/program/source/fusee_setup_horizon.hpp
Normal file
23
fusee/program/source/fusee_setup_horizon.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void SetupAndStartHorizon();
|
||||
|
||||
}
|
||||
68
fusee/program/source/fusee_start.s
Normal file
68
fusee/program/source/fusee_start.s
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.section .crt0._ZN3ams6nxboot5StartEv, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _ZN3ams6nxboot5StartEv
|
||||
.type _ZN3ams6nxboot5StartEv, %function
|
||||
_ZN3ams6nxboot5StartEv:
|
||||
/* Setup all registers as = 0. */
|
||||
msr cpsr_f, #0xC0
|
||||
mov r0, #0
|
||||
mov r1, #0
|
||||
mov r2, #0
|
||||
mov r3, #0
|
||||
mov r4, #0
|
||||
mov r5, #0
|
||||
mov r6, #0
|
||||
mov r7, #0
|
||||
mov r8, #0
|
||||
mov r9, #0
|
||||
mov r10, #0
|
||||
mov r11, #0
|
||||
mov r12, #0
|
||||
|
||||
/* Setup all modes as pointing to our exception handler. */
|
||||
msr cpsr_cf, #0xDF
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD2
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD1
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD7
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xDB
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
msr cpsr_cf, #0xD3
|
||||
ldr sp, =0x40001000
|
||||
ldr lr, =_ZN3ams6nxboot16ExceptionHandlerEv
|
||||
|
||||
/* Perform runtime initialization. */
|
||||
bl _ZN3ams6nxboot4crt010InitializeEv
|
||||
|
||||
/* Perform nx boot procedure. */
|
||||
bl _ZN3ams6nxboot4MainEv
|
||||
1112
fusee/program/source/fusee_stratosphere.cpp
Normal file
1112
fusee/program/source/fusee_stratosphere.cpp
Normal file
File diff suppressed because it is too large
Load Diff
25
fusee/program/source/fusee_stratosphere.hpp
Normal file
25
fusee/program/source/fusee_stratosphere.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
u32 ConfigureStratosphere(const u8 *nn_package2, ams::TargetFirmware target_firmware, bool emummc_enabled, bool nogc_enabled);
|
||||
|
||||
void RebuildPackage2(ams::TargetFirmware target_firmware, bool emummc_enabled);
|
||||
|
||||
}
|
||||
103
fusee/program/source/fusee_uncompress.cpp
Normal file
103
fusee/program/source/fusee_uncompress.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_uncompress.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
class Lz4Uncompressor {
|
||||
private:
|
||||
const u8 *src;
|
||||
size_t src_size;
|
||||
size_t src_offset;
|
||||
u8 *dst;
|
||||
size_t dst_size;
|
||||
size_t dst_offset;
|
||||
public:
|
||||
Lz4Uncompressor(void *dst, size_t dst_size, const void *src, size_t src_size) : src(static_cast<const u8 *>(src)), src_size(src_size), src_offset(0), dst(static_cast<u8 *>(dst)), dst_size(dst_size), dst_offset(0) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
void Uncompress() {
|
||||
while (true) {
|
||||
/* Read a control byte. */
|
||||
const u8 control = this->ReadByte();
|
||||
|
||||
/* Copy what it specifies we should copy. */
|
||||
this->Copy(this->GetCopySize(control >> 4));
|
||||
|
||||
/* If we've exceeded size, we're done. */
|
||||
if (this->src_offset >= this->src_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read the wide copy offset. */
|
||||
u16 wide_offset = this->ReadByte();
|
||||
AMS_ABORT_UNLESS(this->CanRead());
|
||||
wide_offset |= (this->ReadByte() << 8);
|
||||
|
||||
/* Determine the copy size. */
|
||||
const size_t wide_copy_size = this->GetCopySize(control & 0xF);
|
||||
|
||||
/* Copy bytes. */
|
||||
const size_t end_offset = this->dst_offset + wide_copy_size + 4;
|
||||
for (size_t cur_offset = this->dst_offset; cur_offset < end_offset; this->dst_offset = (++cur_offset)) {
|
||||
AMS_ABORT_UNLESS(wide_offset <= cur_offset);
|
||||
|
||||
this->dst[cur_offset] = this->dst[cur_offset - wide_offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
u8 ReadByte() {
|
||||
return this->src[this->src_offset++];
|
||||
}
|
||||
|
||||
bool CanRead() const {
|
||||
return this->src_offset < this->src_size;
|
||||
}
|
||||
|
||||
size_t GetCopySize(u8 control) {
|
||||
size_t size = control;
|
||||
|
||||
if (control >= 0xF) {
|
||||
do {
|
||||
AMS_ABORT_UNLESS(this->CanRead());
|
||||
control = this->ReadByte();
|
||||
size += control;
|
||||
} while (control == 0xFF);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void Copy(size_t size) {
|
||||
__builtin_memcpy(this->dst + this->dst_offset, this->src + this->src_offset, size);
|
||||
this->dst_offset += size;
|
||||
this->src_offset += size;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
/* Create an execute a decompressor. */
|
||||
Lz4Uncompressor(dst, dst_size, src, src_size).Uncompress();
|
||||
}
|
||||
|
||||
}
|
||||
23
fusee/program/source/fusee_uncompress.hpp
Normal file
23
fusee/program/source/fusee_uncompress.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <vapours.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
}
|
||||
92
fusee/program/source/mtc/fusee_mtc.cpp
Normal file
92
fusee/program/source/mtc/fusee_mtc.cpp
Normal 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/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void DoMemoryTrainingErista(int index, void *mtc_tables_buffer);
|
||||
void DoMemoryTrainingMariko(bool *out_did_training, int index, void *mtc_tables_buffer);
|
||||
|
||||
void RestoreMemoryClockRateMariko(void *mtc_tables_buffer);
|
||||
|
||||
namespace {
|
||||
|
||||
alignas(4) constinit u8 g_mtc_tables_buffer[0x26C0];
|
||||
|
||||
constinit bool g_did_training_mariko = false;
|
||||
|
||||
constexpr const u8 MemoryTrainingTableIndex_Invalid = std::numeric_limits<u8>::max();
|
||||
|
||||
constexpr const u8 MemoryTrainingTableIndices[] = {
|
||||
/* DramId_EristaIcosaSamsung4gb */ 0x00,
|
||||
/* DramId_EristaIcosaHynix4gb */ 0x02,
|
||||
/* DramId_EristaIcosaMicron4gb */ 0x03,
|
||||
/* DramId_MarikoIowaHynix1y4gb */ 0x10,
|
||||
/* DramId_EristaIcosaSamsung6gb */ 0x01,
|
||||
/* DramId_MarikoHoagHynix1y4gb */ 0x10,
|
||||
/* DramId_EristaCopperMicron4gb */ MemoryTrainingTableIndex_Invalid,
|
||||
/* DramId_MarikoIowax1x2Samsung4gb */ 0x00,
|
||||
/* DramId_MarikoIowaSamsung4gb */ 0x05,
|
||||
/* DramId_MarikoIowaSamsung8gb */ 0x06,
|
||||
/* DramId_MarikoIowaHynix4gb */ 0x07,
|
||||
/* DramId_MarikoIowaMicron4gb */ 0x08,
|
||||
/* DramId_MarikoHoagSamsung4gb */ 0x05,
|
||||
/* DramId_MarikoHoagSamsung8gb */ 0x06,
|
||||
/* DramId_MarikoHoagHynix4gb */ 0x07,
|
||||
/* DramId_MarikoHoagMicron4gb */ 0x08,
|
||||
/* DramId_MarikoIowaSamsung4gbY */ 0x09,
|
||||
/* DramId_MarikoIowaSamsung1y4gbX */ 0x0C,
|
||||
/* DramId_MarikoIowaSamsung1y8gbX */ 0x0D,
|
||||
/* DramId_MarikoHoagSamsung1y4gbX */ 0x0C,
|
||||
/* DramId_MarikoIowaSamsung1y4gbY */ 0x0A,
|
||||
/* DramId_MarikoIowaSamsung1y8gbY */ 0x0B,
|
||||
/* DramId_MarikoAulaSamsung1y4gb */ 0x0E,
|
||||
/* DramId_MarikoHoagSamsung1y8gbX */ 0x0D,
|
||||
/* DramId_MarikoAulaSamsung1y4gbX */ 0x0C,
|
||||
/* DramId_MarikoIowaMicron1y4gb */ 0x0F,
|
||||
/* DramId_MarikoHoagMicron1y4gb */ 0x0F,
|
||||
/* DramId_MarikoAulaMicron1y4gb */ 0x0F,
|
||||
/* DramId_MarikoAulaSamsung1y8gbX */ 0x0D,
|
||||
};
|
||||
|
||||
int GetMemoryTrainingTableIndex() {
|
||||
if (const auto dram_id = fuse::GetDramId(); dram_id < util::size(MemoryTrainingTableIndices) && MemoryTrainingTableIndices[dram_id] != MemoryTrainingTableIndex_Invalid) {
|
||||
return static_cast<int>(MemoryTrainingTableIndices[dram_id]);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DoMemoryTraining() {
|
||||
const auto index = GetMemoryTrainingTableIndex();
|
||||
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
DoMemoryTrainingErista(index, g_mtc_tables_buffer);
|
||||
} else {
|
||||
DoMemoryTrainingMariko(std::addressof(g_did_training_mariko), index, g_mtc_tables_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreMemoryClockRate() {
|
||||
/* NOTE: This resolves an off-by-one issue in PCV's detection of memory clock rate on Mariko. */
|
||||
if (fuse::GetSocType() == fuse::SocType_Mariko && g_did_training_mariko) {
|
||||
RestoreMemoryClockRateMariko(g_mtc_tables_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
25
fusee/program/source/mtc/fusee_mtc.hpp
Normal file
25
fusee/program/source/mtc/fusee_mtc.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void DoMemoryTraining();
|
||||
|
||||
void RestoreMemoryClockRate();
|
||||
|
||||
}
|
||||
2879
fusee/program/source/mtc/fusee_mtc_erista.cpp
Normal file
2879
fusee/program/source/mtc/fusee_mtc_erista.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2837
fusee/program/source/mtc/fusee_mtc_mariko.cpp
Normal file
2837
fusee/program/source/mtc/fusee_mtc_mariko.cpp
Normal file
File diff suppressed because it is too large
Load Diff
427
fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc
Normal file
427
fusee/program/source/mtc/fusee_mtc_ram_training_pattern.inc
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
struct EmcRamTrainingPattern {
|
||||
u32 dq[0x100];
|
||||
u8 dmi[0x100];
|
||||
};
|
||||
|
||||
constexpr const u8 EmcRamTrainingPatternData[] {
|
||||
0x18, 0x18, 0x18, 0x18, 0x61, 0x61, 0x61, 0x61, 0x85, 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x14,
|
||||
0x51, 0x51, 0x51, 0x51, 0x47, 0x47, 0x47, 0x47, 0x1E, 0x1E, 0x1E, 0x1E, 0x79, 0x79, 0x79, 0x79,
|
||||
0xE5, 0xE5, 0xE5, 0xE5, 0x94, 0x94, 0x94, 0x94, 0x51, 0x51, 0x51, 0x51, 0x46, 0x46, 0x46, 0x46,
|
||||
0x19, 0x19, 0x19, 0x19, 0x67, 0x67, 0x67, 0x67, 0x9C, 0x9C, 0x9C, 0x9C, 0x71, 0x71, 0x71, 0x71,
|
||||
0xC5, 0xC5, 0xC5, 0xC5, 0x17, 0x17, 0x17, 0x17, 0x5F, 0x5F, 0x5F, 0x5F, 0x7E, 0x7E, 0x7E, 0x7E,
|
||||
0xFB, 0xFB, 0xFB, 0xFB, 0xED, 0xED, 0xED, 0xED, 0xB4, 0xB4, 0xB4, 0xB4, 0xD2, 0xD2, 0xD2, 0xD2,
|
||||
0x48, 0x48, 0x48, 0x48, 0x21, 0x21, 0x21, 0x21, 0x85, 0x85, 0x85, 0x85, 0x16, 0x16, 0x16, 0x16,
|
||||
0x59, 0x59, 0x59, 0x59, 0x66, 0x66, 0x66, 0x66, 0x9A, 0x9A, 0x9A, 0x9A, 0x69, 0x69, 0x69, 0x69,
|
||||
0xA4, 0xA4, 0xA4, 0xA4, 0x93, 0x93, 0x93, 0x93, 0x4F, 0x4F, 0x4F, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0xFC, 0xFC, 0xFC, 0xFC, 0xF3, 0xF3, 0xF3, 0xF3, 0xCD, 0xCD, 0xCD, 0xCD, 0x37, 0x37, 0x37, 0x37,
|
||||
0xDC, 0xDC, 0xDC, 0xDC, 0x70, 0x70, 0x70, 0x70, 0xC3, 0xC3, 0xC3, 0xC3, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x3E, 0x3E, 0x3E, 0x3E, 0xFA, 0xFA, 0xFA, 0xFA, 0xEB, 0xEB, 0xEB, 0xEB, 0xAC, 0xAC, 0xAC, 0xAC,
|
||||
0xB3, 0xB3, 0xB3, 0xB3, 0xCC, 0xCC, 0xCC, 0xCC, 0x31, 0x31, 0x31, 0x31, 0xC5, 0xC5, 0xC5, 0xC5,
|
||||
0x15, 0x15, 0x15, 0x15, 0x57, 0x57, 0x57, 0x57, 0x5F, 0x5F, 0x5F, 0x5F, 0x7F, 0x7F, 0x7F, 0x7F,
|
||||
0xFD, 0xFD, 0xFD, 0xFD, 0xF4, 0xF4, 0xF4, 0xF4, 0xD0, 0xD0, 0xD0, 0xD0, 0x42, 0x42, 0x42, 0x42,
|
||||
0x08, 0x08, 0x08, 0x08, 0x23, 0x23, 0x23, 0x23, 0x8F, 0x8F, 0x8F, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x18, 0x18, 0x18, 0x18, 0x61, 0x61, 0x61, 0x61, 0x85, 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x14,
|
||||
0x51, 0x51, 0x51, 0x51, 0x47, 0x47, 0x47, 0x47, 0x1E, 0x1E, 0x1E, 0x1E, 0x79, 0x79, 0x79, 0x79,
|
||||
0xE5, 0xE5, 0xE5, 0xE5, 0x94, 0x94, 0x94, 0x94, 0x51, 0x51, 0x51, 0x51, 0x46, 0x46, 0x46, 0x46,
|
||||
0x19, 0x19, 0x19, 0x19, 0x67, 0x67, 0x67, 0x67, 0x9C, 0x9C, 0x9C, 0x9C, 0x71, 0x71, 0x71, 0x71,
|
||||
0xC5, 0xC5, 0xC5, 0xC5, 0x17, 0x17, 0x17, 0x17, 0x5F, 0x5F, 0x5F, 0x5F, 0x7E, 0x7E, 0x7E, 0x7E,
|
||||
0xFB, 0xFB, 0xFB, 0xFB, 0xED, 0xED, 0xED, 0xED, 0xB4, 0xB4, 0xB4, 0xB4, 0xD2, 0xD2, 0xD2, 0xD2,
|
||||
0x48, 0x48, 0x48, 0x48, 0x21, 0x21, 0x21, 0x21, 0x85, 0x85, 0x85, 0x85, 0x16, 0x16, 0x16, 0x16,
|
||||
0x59, 0x59, 0x59, 0x59, 0x66, 0x66, 0x66, 0x66, 0x9A, 0x9A, 0x9A, 0x9A, 0x69, 0x69, 0x69, 0x69,
|
||||
0xA4, 0xA4, 0xA4, 0xA4, 0x93, 0x93, 0x93, 0x93, 0x4F, 0x4F, 0x4F, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0xFC, 0xFC, 0xFC, 0xFC, 0xF3, 0xF3, 0xF3, 0xF3, 0xCD, 0xCD, 0xCD, 0xCD, 0x37, 0x37, 0x37, 0x37,
|
||||
0xDC, 0xDC, 0xDC, 0xDC, 0x70, 0x70, 0x70, 0x70, 0xC3, 0xC3, 0xC3, 0xC3, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x3E, 0x3E, 0x3E, 0x3E, 0xFA, 0xFA, 0xFA, 0xFA, 0xEB, 0xEB, 0xEB, 0xEB, 0xAC, 0xAC, 0xAC, 0xAC,
|
||||
0xB3, 0xB3, 0xB3, 0xB3, 0xCC, 0xCC, 0xCC, 0xCC, 0x31, 0x31, 0x31, 0x31, 0xC5, 0xC5, 0xC5, 0xC5,
|
||||
0x15, 0x15, 0x15, 0x15, 0x57, 0x57, 0x57, 0x57, 0x5F, 0x5F, 0x5F, 0x5F, 0x7F, 0x7F, 0x7F, 0x7F,
|
||||
0xFD, 0xFD, 0xFD, 0xFD, 0xF4, 0xF4, 0xF4, 0xF4, 0xD0, 0xD0, 0xD0, 0xD0, 0x42, 0x42, 0x42, 0x42,
|
||||
0x08, 0x08, 0x08, 0x08, 0x23, 0x23, 0x23, 0x23, 0x8F, 0x8F, 0x8F, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x06, 0x06, 0x06, 0x06, 0x18, 0x18, 0x18, 0x18, 0x21, 0x21, 0x21, 0x21, 0x05, 0x05, 0x05, 0x05,
|
||||
0x14, 0x14, 0x14, 0x14, 0x11, 0x11, 0x11, 0x11, 0x07, 0x07, 0x07, 0x07, 0x1E, 0x1E, 0x1E, 0x1E,
|
||||
0x39, 0x39, 0x39, 0x39, 0x25, 0x25, 0x25, 0x25, 0x14, 0x14, 0x14, 0x14, 0x11, 0x11, 0x11, 0x11,
|
||||
0x06, 0x06, 0x06, 0x06, 0x19, 0x19, 0x19, 0x19, 0x27, 0x27, 0x27, 0x27, 0x1C, 0x1C, 0x1C, 0x1C,
|
||||
0x31, 0x31, 0x31, 0x31, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x17, 0x17, 0x1F, 0x1F, 0x1F, 0x1F,
|
||||
0x3E, 0x3E, 0x3E, 0x3E, 0x3B, 0x3B, 0x3B, 0x3B, 0x2D, 0x2D, 0x2D, 0x2D, 0x34, 0x34, 0x34, 0x34,
|
||||
0x12, 0x12, 0x12, 0x12, 0x08, 0x08, 0x08, 0x08, 0x21, 0x21, 0x21, 0x21, 0x05, 0x05, 0x05, 0x05,
|
||||
0x16, 0x16, 0x16, 0x16, 0x19, 0x19, 0x19, 0x19, 0x26, 0x26, 0x26, 0x26, 0x1A, 0x1A, 0x1A, 0x1A,
|
||||
0x29, 0x29, 0x29, 0x29, 0x24, 0x24, 0x24, 0x24, 0x13, 0x13, 0x13, 0x13, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3C, 0x3C, 0x3C, 0x3C, 0x33, 0x33, 0x33, 0x33, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x37, 0x37, 0x37, 0x37, 0x1C, 0x1C, 0x1C, 0x1C, 0x30, 0x30, 0x30, 0x30, 0x03, 0x03, 0x03, 0x03,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x3E, 0x3E, 0x3E, 0x3E, 0x3A, 0x3A, 0x3A, 0x3A, 0x2B, 0x2B, 0x2B, 0x2B,
|
||||
0x2C, 0x2C, 0x2C, 0x2C, 0x33, 0x33, 0x33, 0x33, 0x0C, 0x0C, 0x0C, 0x0C, 0x31, 0x31, 0x31, 0x31,
|
||||
0x05, 0x05, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x17, 0x17, 0x17, 0x17, 0x1F, 0x1F, 0x1F, 0x1F,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3D, 0x3D, 0x3D, 0x3D, 0x34, 0x34, 0x34, 0x34, 0x10, 0x10, 0x10, 0x10,
|
||||
0x02, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x08, 0x23, 0x23, 0x23, 0x23, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x06, 0x06, 0x06, 0x06, 0x18, 0x18, 0x18, 0x18, 0x21, 0x21, 0x21, 0x21, 0x05, 0x05, 0x05, 0x05,
|
||||
0x14, 0x14, 0x14, 0x14, 0x11, 0x11, 0x11, 0x11, 0x07, 0x07, 0x07, 0x07, 0x1E, 0x1E, 0x1E, 0x1E,
|
||||
0x39, 0x39, 0x39, 0x39, 0x25, 0x25, 0x25, 0x25, 0x14, 0x14, 0x14, 0x14, 0x11, 0x11, 0x11, 0x11,
|
||||
0x06, 0x06, 0x06, 0x06, 0x19, 0x19, 0x19, 0x19, 0x27, 0x27, 0x27, 0x27, 0x1C, 0x1C, 0x1C, 0x1C,
|
||||
0x31, 0x31, 0x31, 0x31, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x17, 0x17, 0x1F, 0x1F, 0x1F, 0x1F,
|
||||
0x3E, 0x3E, 0x3E, 0x3E, 0x3B, 0x3B, 0x3B, 0x3B, 0x2D, 0x2D, 0x2D, 0x2D, 0x34, 0x34, 0x34, 0x34,
|
||||
0x12, 0x12, 0x12, 0x12, 0x08, 0x08, 0x08, 0x08, 0x21, 0x21, 0x21, 0x21, 0x05, 0x05, 0x05, 0x05,
|
||||
0x16, 0x16, 0x16, 0x16, 0x19, 0x19, 0x19, 0x19, 0x26, 0x26, 0x26, 0x26, 0x1A, 0x1A, 0x1A, 0x1A,
|
||||
0x29, 0x29, 0x29, 0x29, 0x24, 0x24, 0x24, 0x24, 0x13, 0x13, 0x13, 0x13, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3C, 0x3C, 0x3C, 0x3C, 0x33, 0x33, 0x33, 0x33, 0x0D, 0x0D, 0x0D, 0x0D,
|
||||
0x37, 0x37, 0x37, 0x37, 0x1C, 0x1C, 0x1C, 0x1C, 0x30, 0x30, 0x30, 0x30, 0x03, 0x03, 0x03, 0x03,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x3E, 0x3E, 0x3E, 0x3E, 0x3A, 0x3A, 0x3A, 0x3A, 0x2B, 0x2B, 0x2B, 0x2B,
|
||||
0x2C, 0x2C, 0x2C, 0x2C, 0x33, 0x33, 0x33, 0x33, 0x0C, 0x0C, 0x0C, 0x0C, 0x31, 0x31, 0x31, 0x31,
|
||||
0x05, 0x05, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x17, 0x17, 0x17, 0x17, 0x1F, 0x1F, 0x1F, 0x1F,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3D, 0x3D, 0x3D, 0x3D, 0x34, 0x34, 0x34, 0x34, 0x10, 0x10, 0x10, 0x10,
|
||||
0x02, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x08, 0x23, 0x23, 0x23, 0x23, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00,
|
||||
0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03,
|
||||
0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03, 0x0A, 0x05, 0x0C, 0x03
|
||||
};
|
||||
|
||||
ALWAYS_INLINE const EmcRamTrainingPattern *GetEmcRamTrainingPattern() {
|
||||
return reinterpret_cast<const EmcRamTrainingPattern *>(EmcRamTrainingPatternData);
|
||||
}
|
||||
2797
fusee/program/source/mtc/fusee_mtc_tables_erista.inc
Normal file
2797
fusee/program/source/mtc/fusee_mtc_tables_erista.inc
Normal file
File diff suppressed because it is too large
Load Diff
1422
fusee/program/source/mtc/fusee_mtc_tables_mariko.inc
Normal file
1422
fusee/program/source/mtc/fusee_mtc_tables_mariko.inc
Normal file
File diff suppressed because it is too large
Load Diff
527
fusee/program/source/mtc/fusee_mtc_timing_table_common.hpp
Normal file
527
fusee/program/source/mtc/fusee_mtc_timing_table_common.hpp
Normal file
@@ -0,0 +1,527 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
#define MC_BASE (0x70019000)
|
||||
#define EMC_BASE (0x7001B000)
|
||||
#define EMC0_BASE (0x7001E000)
|
||||
#define EMC1_BASE (0x7001F000)
|
||||
|
||||
enum {
|
||||
PLLM_OUT0 = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLM_OUT0,
|
||||
PLLC_OUT0 = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLC_OUT0,
|
||||
PLLP_OUT0 = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLP_OUT0,
|
||||
CLK_M = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_CLK_M,
|
||||
PLLM_UD = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLM_UD,
|
||||
PLLMB_UD = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLMB_UD,
|
||||
PLLMB_OUT0 = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLMB_OUT0,
|
||||
PLLP_UD = CLK_RST_CONTROLLER_CLK_SOURCE_EMC_EMC_2X_CLK_SRC_PLLP_UD
|
||||
};
|
||||
|
||||
enum {
|
||||
ONE_RANK = 1,
|
||||
TWO_RANK = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
DLL_OFF = 0,
|
||||
DLL_ON = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AUTO_PD = 0,
|
||||
MAN_SR = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
NO_TRAINING = (0 << 0),
|
||||
CA_TRAINING = (1 << 0),
|
||||
CA_VREF_TRAINING = (1 << 1),
|
||||
QUSE_TRAINING = (1 << 2),
|
||||
QUSE_VREF_TRAINING = (1 << 3),
|
||||
WRITE_TRAINING = (1 << 4),
|
||||
WRITE_VREF_TRAINING = (1 << 5),
|
||||
READ_TRAINING = (1 << 6),
|
||||
READ_VREF_TRAINING = (1 << 7),
|
||||
TRAIN_SECOND_RANK = (1 << 8),
|
||||
BIT_LEVEL_TRAINING = (1 << 9),
|
||||
};
|
||||
|
||||
enum {
|
||||
DRAM_TYPE_DDR4 = EMC_FBIO_CFG5_DRAM_TYPE_DDR4,
|
||||
DRAM_TYPE_LPDDR4 = EMC_FBIO_CFG5_DRAM_TYPE_LPDDR4,
|
||||
DRAM_TYPE_LPDDR2 = EMC_FBIO_CFG5_DRAM_TYPE_LPDDR2,
|
||||
DRAM_TYPE_DDR2 = EMC_FBIO_CFG5_DRAM_TYPE_DDR2
|
||||
};
|
||||
|
||||
enum {
|
||||
ASSEMBLY = EMC_DBG_WRITE_MUX_ASSEMBLY,
|
||||
ACTIVE = EMC_DBG_WRITE_MUX_ACTIVE,
|
||||
};
|
||||
|
||||
enum {
|
||||
DVFS_SEQUENCE = 1,
|
||||
WRITE_TRAINING_SEQUENCE = 2,
|
||||
PERIODIC_TRAINING_SEQUENCE = 3,
|
||||
DVFS_PT1 = 10,
|
||||
DVFS_UPDATE = 11,
|
||||
TRAINING_PT1 = 12,
|
||||
TRAINING_UPDATE = 13,
|
||||
PERIODIC_TRAINING_UPDATE = 14,
|
||||
};
|
||||
|
||||
/*
|
||||
* Do arithmetic in fixed point.
|
||||
*/
|
||||
#define MOVAVG_PRECISION_FACTOR 100
|
||||
|
||||
/*
|
||||
* The division portion of the average operation.
|
||||
*/
|
||||
#define __AVERAGE_PTFV(dev) \
|
||||
({ dst_timing->ptfv_dqsosc_movavg_##dev = \
|
||||
dst_timing->ptfv_dqsosc_movavg_##dev / \
|
||||
dst_timing->ptfv_dvfs_samples; })
|
||||
|
||||
/*
|
||||
* The division portion of the average write operation.
|
||||
*/
|
||||
#define __AVERAGE_WRITE_PTFV(dev) \
|
||||
({ dst_timing->ptfv_dqsosc_movavg_##dev = \
|
||||
dst_timing->ptfv_dqsosc_movavg_##dev / \
|
||||
dst_timing->ptfv_write_samples; })
|
||||
|
||||
/*
|
||||
* Convert val to fixed point and add it to the temporary average.
|
||||
*/
|
||||
#define __INCREMENT_PTFV(dev, val) \
|
||||
({ dst_timing->ptfv_dqsosc_movavg_##dev += \
|
||||
((val) * MOVAVG_PRECISION_FACTOR); })
|
||||
|
||||
/*
|
||||
* Convert a moving average back to integral form and return the value.
|
||||
*/
|
||||
#define __MOVAVG_AC(timing, dev) \
|
||||
((timing)->ptfv_dqsosc_movavg_##dev / \
|
||||
MOVAVG_PRECISION_FACTOR)
|
||||
|
||||
/* Weighted update. */
|
||||
#define __WEIGHTED_UPDATE_PTFV(dev, nval) \
|
||||
do { \
|
||||
dst_timing->ptfv_dqsosc_movavg_##dev = \
|
||||
((nval * MOVAVG_PRECISION_FACTOR) + \
|
||||
(dst_timing->ptfv_dqsosc_movavg_##dev * \
|
||||
dst_timing->ptfv_movavg_weight)) / \
|
||||
(dst_timing->ptfv_movavg_weight + 1); \
|
||||
} while (0)
|
||||
|
||||
/* Access a particular average. */
|
||||
#define __MOVAVG(timing, dev) \
|
||||
((timing)->ptfv_dqsosc_movavg_##dev)
|
||||
|
||||
#define FOREACH_PER_CHANNEL_BURST_REG(HANDLER) \
|
||||
HANDLER(EMC0, EMC_MRW10, emc0_mrw10) \
|
||||
HANDLER(EMC1, EMC_MRW10, emc1_mrw10) \
|
||||
HANDLER(EMC0, EMC_MRW11, emc0_mrw11) \
|
||||
HANDLER(EMC1, EMC_MRW11, emc1_mrw11) \
|
||||
HANDLER(EMC0, EMC_MRW12, emc0_mrw12) \
|
||||
HANDLER(EMC1, EMC_MRW12, emc1_mrw12) \
|
||||
HANDLER(EMC0, EMC_MRW13, emc0_mrw13) \
|
||||
HANDLER(EMC1, EMC_MRW13, emc1_mrw13) \
|
||||
|
||||
#define FOREACH_TRIM_REG(HANDLER) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0, emc_pmacro_ib_ddll_long_dqs_rank0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1, emc_pmacro_ib_ddll_long_dqs_rank0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2, emc_pmacro_ib_ddll_long_dqs_rank0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3, emc_pmacro_ib_ddll_long_dqs_rank0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0, emc_pmacro_ib_ddll_long_dqs_rank1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1, emc_pmacro_ib_ddll_long_dqs_rank1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2, emc_pmacro_ib_ddll_long_dqs_rank1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3, emc_pmacro_ib_ddll_long_dqs_rank1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0, emc_pmacro_ib_ddll_short_dq_rank0_byte0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1, emc_pmacro_ib_ddll_short_dq_rank0_byte0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2, emc_pmacro_ib_ddll_short_dq_rank0_byte0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0, emc_pmacro_ib_ddll_short_dq_rank0_byte1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1, emc_pmacro_ib_ddll_short_dq_rank0_byte1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2, emc_pmacro_ib_ddll_short_dq_rank0_byte1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0, emc_pmacro_ib_ddll_short_dq_rank0_byte2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1, emc_pmacro_ib_ddll_short_dq_rank0_byte2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2, emc_pmacro_ib_ddll_short_dq_rank0_byte2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0, emc_pmacro_ib_ddll_short_dq_rank0_byte3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1, emc_pmacro_ib_ddll_short_dq_rank0_byte3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2, emc_pmacro_ib_ddll_short_dq_rank0_byte3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0, emc_pmacro_ib_ddll_short_dq_rank0_byte4_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1, emc_pmacro_ib_ddll_short_dq_rank0_byte4_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2, emc_pmacro_ib_ddll_short_dq_rank0_byte4_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0, emc_pmacro_ib_ddll_short_dq_rank0_byte5_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1, emc_pmacro_ib_ddll_short_dq_rank0_byte5_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2, emc_pmacro_ib_ddll_short_dq_rank0_byte5_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0, emc_pmacro_ib_ddll_short_dq_rank0_byte6_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1, emc_pmacro_ib_ddll_short_dq_rank0_byte6_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2, emc_pmacro_ib_ddll_short_dq_rank0_byte6_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0, emc_pmacro_ib_ddll_short_dq_rank0_byte7_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1, emc_pmacro_ib_ddll_short_dq_rank0_byte7_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2, emc_pmacro_ib_ddll_short_dq_rank0_byte7_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0, emc_pmacro_ib_ddll_short_dq_rank1_byte0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1, emc_pmacro_ib_ddll_short_dq_rank1_byte0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2, emc_pmacro_ib_ddll_short_dq_rank1_byte0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0, emc_pmacro_ib_ddll_short_dq_rank1_byte1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1, emc_pmacro_ib_ddll_short_dq_rank1_byte1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2, emc_pmacro_ib_ddll_short_dq_rank1_byte1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0, emc_pmacro_ib_ddll_short_dq_rank1_byte2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1, emc_pmacro_ib_ddll_short_dq_rank1_byte2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2, emc_pmacro_ib_ddll_short_dq_rank1_byte2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0, emc_pmacro_ib_ddll_short_dq_rank1_byte3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1, emc_pmacro_ib_ddll_short_dq_rank1_byte3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2, emc_pmacro_ib_ddll_short_dq_rank1_byte3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0, emc_pmacro_ib_ddll_short_dq_rank1_byte4_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1, emc_pmacro_ib_ddll_short_dq_rank1_byte4_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2, emc_pmacro_ib_ddll_short_dq_rank1_byte4_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0, emc_pmacro_ib_ddll_short_dq_rank1_byte5_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1, emc_pmacro_ib_ddll_short_dq_rank1_byte5_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2, emc_pmacro_ib_ddll_short_dq_rank1_byte5_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0, emc_pmacro_ib_ddll_short_dq_rank1_byte6_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1, emc_pmacro_ib_ddll_short_dq_rank1_byte6_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2, emc_pmacro_ib_ddll_short_dq_rank1_byte6_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0, emc_pmacro_ib_ddll_short_dq_rank1_byte7_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1, emc_pmacro_ib_ddll_short_dq_rank1_byte7_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2, emc_pmacro_ib_ddll_short_dq_rank1_byte7_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_VREF_DQS_0, emc_pmacro_ib_vref_dqs_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_VREF_DQS_1, emc_pmacro_ib_vref_dqs_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_VREF_DQ_0, emc_pmacro_ib_vref_dq_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_VREF_DQ_1, emc_pmacro_ib_vref_dq_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0, emc_pmacro_ob_ddll_long_dq_rank0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1, emc_pmacro_ob_ddll_long_dq_rank0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2, emc_pmacro_ob_ddll_long_dq_rank0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3, emc_pmacro_ob_ddll_long_dq_rank0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4, emc_pmacro_ob_ddll_long_dq_rank0_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5, emc_pmacro_ob_ddll_long_dq_rank0_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0, emc_pmacro_ob_ddll_long_dq_rank1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1, emc_pmacro_ob_ddll_long_dq_rank1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2, emc_pmacro_ob_ddll_long_dq_rank1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3, emc_pmacro_ob_ddll_long_dq_rank1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0, emc_pmacro_ob_ddll_short_dq_rank0_byte0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1, emc_pmacro_ob_ddll_short_dq_rank0_byte0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2, emc_pmacro_ob_ddll_short_dq_rank0_byte0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0, emc_pmacro_ob_ddll_short_dq_rank0_byte1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1, emc_pmacro_ob_ddll_short_dq_rank0_byte1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2, emc_pmacro_ob_ddll_short_dq_rank0_byte1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0, emc_pmacro_ob_ddll_short_dq_rank0_byte2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1, emc_pmacro_ob_ddll_short_dq_rank0_byte2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2, emc_pmacro_ob_ddll_short_dq_rank0_byte2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0, emc_pmacro_ob_ddll_short_dq_rank0_byte3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1, emc_pmacro_ob_ddll_short_dq_rank0_byte3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2, emc_pmacro_ob_ddll_short_dq_rank0_byte3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0, emc_pmacro_ob_ddll_short_dq_rank0_byte4_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1, emc_pmacro_ob_ddll_short_dq_rank0_byte4_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2, emc_pmacro_ob_ddll_short_dq_rank0_byte4_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0, emc_pmacro_ob_ddll_short_dq_rank0_byte5_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1, emc_pmacro_ob_ddll_short_dq_rank0_byte5_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2, emc_pmacro_ob_ddll_short_dq_rank0_byte5_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0, emc_pmacro_ob_ddll_short_dq_rank0_byte6_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1, emc_pmacro_ob_ddll_short_dq_rank0_byte6_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2, emc_pmacro_ob_ddll_short_dq_rank0_byte6_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0, emc_pmacro_ob_ddll_short_dq_rank0_byte7_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1, emc_pmacro_ob_ddll_short_dq_rank0_byte7_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2, emc_pmacro_ob_ddll_short_dq_rank0_byte7_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0, emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1, emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2, emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0, emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1, emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2, emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0, emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1, emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2, emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0, emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1, emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2, emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0, emc_pmacro_ob_ddll_short_dq_rank1_byte0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1, emc_pmacro_ob_ddll_short_dq_rank1_byte0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2, emc_pmacro_ob_ddll_short_dq_rank1_byte0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0, emc_pmacro_ob_ddll_short_dq_rank1_byte1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1, emc_pmacro_ob_ddll_short_dq_rank1_byte1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2, emc_pmacro_ob_ddll_short_dq_rank1_byte1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0, emc_pmacro_ob_ddll_short_dq_rank1_byte2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1, emc_pmacro_ob_ddll_short_dq_rank1_byte2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2, emc_pmacro_ob_ddll_short_dq_rank1_byte2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0, emc_pmacro_ob_ddll_short_dq_rank1_byte3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1, emc_pmacro_ob_ddll_short_dq_rank1_byte3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2, emc_pmacro_ob_ddll_short_dq_rank1_byte3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0, emc_pmacro_ob_ddll_short_dq_rank1_byte4_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1, emc_pmacro_ob_ddll_short_dq_rank1_byte4_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2, emc_pmacro_ob_ddll_short_dq_rank1_byte4_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0, emc_pmacro_ob_ddll_short_dq_rank1_byte5_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1, emc_pmacro_ob_ddll_short_dq_rank1_byte5_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2, emc_pmacro_ob_ddll_short_dq_rank1_byte5_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0, emc_pmacro_ob_ddll_short_dq_rank1_byte6_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1, emc_pmacro_ob_ddll_short_dq_rank1_byte6_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2, emc_pmacro_ob_ddll_short_dq_rank1_byte6_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0, emc_pmacro_ob_ddll_short_dq_rank1_byte7_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1, emc_pmacro_ob_ddll_short_dq_rank1_byte7_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2, emc_pmacro_ob_ddll_short_dq_rank1_byte7_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_0, emc_pmacro_quse_ddll_rank0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_1, emc_pmacro_quse_ddll_rank0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_2, emc_pmacro_quse_ddll_rank0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_3, emc_pmacro_quse_ddll_rank0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_0, emc_pmacro_quse_ddll_rank1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_1, emc_pmacro_quse_ddll_rank1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_2, emc_pmacro_quse_ddll_rank1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_3, emc_pmacro_quse_ddll_rank1_3)
|
||||
|
||||
#define FOREACH_PER_CHANNEL_TRIM_REG(HANDLER) \
|
||||
HANDLER(EMC0, EMC_CMD_BRLSHFT_0, emc0_cmd_brlshft_0) \
|
||||
HANDLER(EMC1, EMC_CMD_BRLSHFT_1, emc1_cmd_brlshft_1) \
|
||||
HANDLER(EMC0, EMC_DATA_BRLSHFT_0, emc0_data_brlshft_0) \
|
||||
HANDLER(EMC1, EMC_DATA_BRLSHFT_0, emc1_data_brlshft_0) \
|
||||
HANDLER(EMC0, EMC_DATA_BRLSHFT_1, emc0_data_brlshft_1) \
|
||||
HANDLER(EMC1, EMC_DATA_BRLSHFT_1, emc1_data_brlshft_1) \
|
||||
HANDLER(EMC0, EMC_QUSE_BRLSHFT_0, emc0_quse_brlshft_0) \
|
||||
HANDLER(EMC1, EMC_QUSE_BRLSHFT_1, emc1_quse_brlshft_1) \
|
||||
HANDLER(EMC0, EMC_QUSE_BRLSHFT_2, emc0_quse_brlshft_2) \
|
||||
HANDLER(EMC1, EMC_QUSE_BRLSHFT_3, emc1_quse_brlshft_3)
|
||||
|
||||
#define FOREACH_PER_CHANNEL_VREF_REG(HANDLER) \
|
||||
HANDLER(EMC0, EMC_TRAINING_OPT_DQS_IB_VREF_RANK0, emc0_training_opt_dqs_ib_vref_rank0) \
|
||||
HANDLER(EMC1, EMC_TRAINING_OPT_DQS_IB_VREF_RANK0, emc1_training_opt_dqs_ib_vref_rank0) \
|
||||
HANDLER(EMC0, EMC_TRAINING_OPT_DQS_IB_VREF_RANK1, emc0_training_opt_dqs_ib_vref_rank1) \
|
||||
HANDLER(EMC1, EMC_TRAINING_OPT_DQS_IB_VREF_RANK1, emc1_training_opt_dqs_ib_vref_rank1)
|
||||
|
||||
#define FOREACH_PER_CHANNEL_TRAINING_MOD_REG(HANDLER) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE0, emc0_training_rw_offset_ib_byte0) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE0, emc1_training_rw_offset_ib_byte0) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE1, emc0_training_rw_offset_ib_byte1) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE1, emc1_training_rw_offset_ib_byte1) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE2, emc0_training_rw_offset_ib_byte2) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE2, emc1_training_rw_offset_ib_byte2) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_IB_BYTE3, emc0_training_rw_offset_ib_byte3) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_IB_BYTE3, emc1_training_rw_offset_ib_byte3) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_IB_MISC, emc0_training_rw_offset_ib_misc) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_IB_MISC, emc1_training_rw_offset_ib_misc) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE0, emc0_training_rw_offset_ob_byte0) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE0, emc1_training_rw_offset_ob_byte0) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE1, emc0_training_rw_offset_ob_byte1) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE1, emc1_training_rw_offset_ob_byte1) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE2, emc0_training_rw_offset_ob_byte2) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE2, emc1_training_rw_offset_ob_byte2) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_OB_BYTE3, emc0_training_rw_offset_ob_byte3) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_OB_BYTE3, emc1_training_rw_offset_ob_byte3) \
|
||||
HANDLER(EMC0, EMC_TRAINING_RW_OFFSET_OB_MISC, emc0_training_rw_offset_ob_misc) \
|
||||
HANDLER(EMC1, EMC_TRAINING_RW_OFFSET_OB_MISC, emc1_training_rw_offset_ob_misc)
|
||||
|
||||
#define FOREACH_BURST_MC_REG(HANDLER) \
|
||||
HANDLER(MC, MC_EMEM_ARB_CFG, mc_emem_arb_cfg) \
|
||||
HANDLER(MC, MC_EMEM_ARB_OUTSTANDING_REQ, mc_emem_arb_outstanding_req) \
|
||||
HANDLER(MC, MC_EMEM_ARB_REFPB_HP_CTRL, mc_emem_arb_refpb_hp_ctrl) \
|
||||
HANDLER(MC, MC_EMEM_ARB_REFPB_BANK_CTRL, mc_emem_arb_refpb_bank_ctrl) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RCD, mc_emem_arb_timing_rcd) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RP, mc_emem_arb_timing_rp) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RC, mc_emem_arb_timing_rc) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RAS, mc_emem_arb_timing_ras) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_FAW, mc_emem_arb_timing_faw) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RRD, mc_emem_arb_timing_rrd) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RAP2PRE, mc_emem_arb_timing_rap2pre) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_WAP2PRE, mc_emem_arb_timing_wap2pre) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_R2R, mc_emem_arb_timing_r2r) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_W2W, mc_emem_arb_timing_w2w) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_R2W, mc_emem_arb_timing_r2w) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_CCDMW, mc_emem_arb_timing_ccdmw) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_W2R, mc_emem_arb_timing_w2r) \
|
||||
HANDLER(MC, MC_EMEM_ARB_TIMING_RFCPB, mc_emem_arb_timing_rfcpb) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DA_TURNS, mc_emem_arb_da_turns) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DA_COVERS, mc_emem_arb_da_covers) \
|
||||
HANDLER(MC, MC_EMEM_ARB_MISC0, mc_emem_arb_misc0) \
|
||||
HANDLER(MC, MC_EMEM_ARB_MISC1, mc_emem_arb_misc1) \
|
||||
HANDLER(MC, MC_EMEM_ARB_MISC2, mc_emem_arb_misc2) \
|
||||
HANDLER(MC, MC_EMEM_ARB_RING1_THROTTLE, mc_emem_arb_ring1_throttle) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_CTRL, mc_emem_arb_dhyst_ctrl) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0, mc_emem_arb_dhyst_timeout_util_0) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1, mc_emem_arb_dhyst_timeout_util_1) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2, mc_emem_arb_dhyst_timeout_util_2) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3, mc_emem_arb_dhyst_timeout_util_3) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4, mc_emem_arb_dhyst_timeout_util_4) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5, mc_emem_arb_dhyst_timeout_util_5) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6, mc_emem_arb_dhyst_timeout_util_6) \
|
||||
HANDLER(MC, MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7, mc_emem_arb_dhyst_timeout_util_7)
|
||||
|
||||
#define FOREACH_LA_SCALE_REG(HANDLER) \
|
||||
HANDLER(MC, MC_MLL_MPCORER_PTSA_RATE, mc_mll_mpcorer_ptsa_rate) \
|
||||
HANDLER(MC, MC_FTOP_PTSA_RATE, mc_ftop_ptsa_rate) \
|
||||
HANDLER(MC, MC_PTSA_GRANT_DECREMENT, mc_ptsa_grant_decrement) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_XUSB_0, mc_latency_allowance_xusb_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_XUSB_1, mc_latency_allowance_xusb_1) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_TSEC_0, mc_latency_allowance_tsec_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_SDMMCA_0, mc_latency_allowance_sdmmca_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_SDMMCAA_0, mc_latency_allowance_sdmmcaa_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_SDMMC_0, mc_latency_allowance_sdmmc_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_SDMMCAB_0, mc_latency_allowance_sdmmcab_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_PPCS_0, mc_latency_allowance_ppcs_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_PPCS_1, mc_latency_allowance_ppcs_1) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_MPCORE_0, mc_latency_allowance_mpcore_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_HC_0, mc_latency_allowance_hc_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_HC_1, mc_latency_allowance_hc_1) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_AVPC_0, mc_latency_allowance_avpc_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_GPU_0, mc_latency_allowance_gpu_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_GPU2_0, mc_latency_allowance_gpu2_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_NVENC_0, mc_latency_allowance_nvenc_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_NVDEC_0, mc_latency_allowance_nvdec_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_VIC_0, mc_latency_allowance_vic_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_VI2_0, mc_latency_allowance_vi2_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_ISP2_0, mc_latency_allowance_isp2_0) \
|
||||
HANDLER(MC, MC_LATENCY_ALLOWANCE_ISP2_1, mc_latency_allowance_isp2_1)
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT
|
||||
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT \
|
||||
16
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT \
|
||||
0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_MASK \
|
||||
0x3ff << \
|
||||
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT
|
||||
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT 21
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT 18
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT 15
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT 12
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT 9
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT 6
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT 3
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT 0
|
||||
#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)
|
||||
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT 21
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT 18
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT 15
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT 12
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT 9
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT 6
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT 3
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT 0
|
||||
#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_MASK \
|
||||
(0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)
|
||||
|
||||
}
|
||||
359
fusee/program/source/mtc/fusee_mtc_timing_table_erista.hpp
Normal file
359
fusee/program/source/mtc/fusee_mtc_timing_table_erista.hpp
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "fusee_mtc_timing_table_common.hpp"
|
||||
|
||||
namespace ams::nxboot::erista {
|
||||
|
||||
#define FOREACH_BURST_REG(HANDLER) \
|
||||
HANDLER(EMC, EMC_RC, emc_rc) \
|
||||
HANDLER(EMC, EMC_RFC, emc_rfc) \
|
||||
HANDLER(EMC, EMC_RFCPB, emc_rfcpb) \
|
||||
HANDLER(EMC, EMC_REFCTRL2, emc_refctrl2) \
|
||||
HANDLER(EMC, EMC_RFC_SLR, emc_rfc_slr) \
|
||||
HANDLER(EMC, EMC_RAS, emc_ras) \
|
||||
HANDLER(EMC, EMC_RP, emc_rp) \
|
||||
HANDLER(EMC, EMC_R2W, emc_r2w) \
|
||||
HANDLER(EMC, EMC_W2R, emc_w2r) \
|
||||
HANDLER(EMC, EMC_R2P, emc_r2p) \
|
||||
HANDLER(EMC, EMC_W2P, emc_w2p) \
|
||||
HANDLER(EMC, EMC_R2R, emc_r2r) \
|
||||
HANDLER(EMC, EMC_TPPD, emc_tppd) \
|
||||
HANDLER(EMC, EMC_CCDMW, emc_ccdmw) \
|
||||
HANDLER(EMC, EMC_RD_RCD, emc_rd_rcd) \
|
||||
HANDLER(EMC, EMC_WR_RCD, emc_wr_rcd) \
|
||||
HANDLER(EMC, EMC_RRD, emc_rrd) \
|
||||
HANDLER(EMC, EMC_REXT, emc_rext) \
|
||||
HANDLER(EMC, EMC_WEXT, emc_wext) \
|
||||
HANDLER(EMC, EMC_WDV_CHK, emc_wdv_chk) \
|
||||
HANDLER(EMC, EMC_WDV, emc_wdv) \
|
||||
HANDLER(EMC, EMC_WSV, emc_wsv) \
|
||||
HANDLER(EMC, EMC_WEV, emc_wev) \
|
||||
HANDLER(EMC, EMC_WDV_MASK, emc_wdv_mask) \
|
||||
HANDLER(EMC, EMC_WS_DURATION, emc_ws_duration) \
|
||||
HANDLER(EMC, EMC_WE_DURATION, emc_we_duration) \
|
||||
HANDLER(EMC, EMC_QUSE, emc_quse) \
|
||||
HANDLER(EMC, EMC_QUSE_WIDTH, emc_quse_width) \
|
||||
HANDLER(EMC, EMC_IBDLY, emc_ibdly) \
|
||||
HANDLER(EMC, EMC_OBDLY, emc_obdly) \
|
||||
HANDLER(EMC, EMC_EINPUT, emc_einput) \
|
||||
HANDLER(EMC, EMC_MRW6, emc_mrw6) \
|
||||
HANDLER(EMC, EMC_EINPUT_DURATION, emc_einput_duration) \
|
||||
HANDLER(EMC, EMC_PUTERM_EXTRA, emc_puterm_extra) \
|
||||
HANDLER(EMC, EMC_PUTERM_WIDTH, emc_puterm_width) \
|
||||
HANDLER(EMC, EMC_QRST, emc_qrst) \
|
||||
HANDLER(EMC, EMC_QSAFE, emc_qsafe) \
|
||||
HANDLER(EMC, EMC_RDV, emc_rdv) \
|
||||
HANDLER(EMC, EMC_RDV_MASK, emc_rdv_mask) \
|
||||
HANDLER(EMC, EMC_RDV_EARLY, emc_rdv_early) \
|
||||
HANDLER(EMC, EMC_RDV_EARLY_MASK, emc_rdv_early_mask) \
|
||||
HANDLER(EMC, EMC_REFRESH, emc_refresh) \
|
||||
HANDLER(EMC, EMC_BURST_REFRESH_NUM, emc_burst_refresh_num) \
|
||||
HANDLER(EMC, EMC_PRE_REFRESH_REQ_CNT, emc_pre_refresh_req_cnt) \
|
||||
HANDLER(EMC, EMC_PDEX2WR, emc_pdex2wr) \
|
||||
HANDLER(EMC, EMC_PDEX2RD, emc_pdex2rd) \
|
||||
HANDLER(EMC, EMC_PCHG2PDEN, emc_pchg2pden) \
|
||||
HANDLER(EMC, EMC_ACT2PDEN, emc_act2pden) \
|
||||
HANDLER(EMC, EMC_AR2PDEN, emc_ar2pden) \
|
||||
HANDLER(EMC, EMC_RW2PDEN, emc_rw2pden) \
|
||||
HANDLER(EMC, EMC_CKE2PDEN, emc_cke2pden) \
|
||||
HANDLER(EMC, EMC_PDEX2CKE, emc_pdex2cke) \
|
||||
HANDLER(EMC, EMC_PDEX2MRR, emc_pdex2mrr) \
|
||||
HANDLER(EMC, EMC_TXSR, emc_txsr) \
|
||||
HANDLER(EMC, EMC_TXSRDLL, emc_txsrdll) \
|
||||
HANDLER(EMC, EMC_TCKE, emc_tcke) \
|
||||
HANDLER(EMC, EMC_TCKESR, emc_tckesr) \
|
||||
HANDLER(EMC, EMC_TPD, emc_tpd) \
|
||||
HANDLER(EMC, EMC_TFAW, emc_tfaw) \
|
||||
HANDLER(EMC, EMC_TRPAB, emc_trpab) \
|
||||
HANDLER(EMC, EMC_TCLKSTABLE, emc_tclkstable) \
|
||||
HANDLER(EMC, EMC_TCLKSTOP, emc_tclkstop) \
|
||||
HANDLER(EMC, EMC_MRW7, emc_mrw7) \
|
||||
HANDLER(EMC, EMC_TREFBW, emc_trefbw) \
|
||||
HANDLER(EMC, EMC_ODT_WRITE, emc_odt_write) \
|
||||
HANDLER(EMC, EMC_FBIO_CFG5, emc_fbio_cfg5) \
|
||||
HANDLER(EMC, EMC_FBIO_CFG7, emc_fbio_cfg7) \
|
||||
HANDLER(EMC, EMC_CFG_DIG_DLL, emc_cfg_dig_dll) \
|
||||
HANDLER(EMC, EMC_CFG_DIG_DLL_PERIOD, emc_cfg_dig_dll_period) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_RXRT, emc_pmacro_ib_rxrt) \
|
||||
HANDLER(EMC, EMC_CFG_PIPE_1, emc_cfg_pipe_1) \
|
||||
HANDLER(EMC, EMC_CFG_PIPE_2, emc_cfg_pipe_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_4, emc_pmacro_quse_ddll_rank0_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_5, emc_pmacro_quse_ddll_rank0_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_4, emc_pmacro_quse_ddll_rank1_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_5, emc_pmacro_quse_ddll_rank1_5) \
|
||||
HANDLER(EMC, EMC_MRW8, emc_mrw8) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4, emc_pmacro_ob_ddll_long_dq_rank1_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5, emc_pmacro_ob_ddll_long_dq_rank1_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0, emc_pmacro_ob_ddll_long_dqs_rank0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1, emc_pmacro_ob_ddll_long_dqs_rank0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2, emc_pmacro_ob_ddll_long_dqs_rank0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3, emc_pmacro_ob_ddll_long_dqs_rank0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4, emc_pmacro_ob_ddll_long_dqs_rank0_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5, emc_pmacro_ob_ddll_long_dqs_rank0_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0, emc_pmacro_ob_ddll_long_dqs_rank1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1, emc_pmacro_ob_ddll_long_dqs_rank1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2, emc_pmacro_ob_ddll_long_dqs_rank1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3, emc_pmacro_ob_ddll_long_dqs_rank1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4, emc_pmacro_ob_ddll_long_dqs_rank1_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5, emc_pmacro_ob_ddll_long_dqs_rank1_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_0, emc_pmacro_ddll_long_cmd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_1, emc_pmacro_ddll_long_cmd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_2, emc_pmacro_ddll_long_cmd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_3, emc_pmacro_ddll_long_cmd_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_4, emc_pmacro_ddll_long_cmd_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_SHORT_CMD_0, emc_pmacro_ddll_short_cmd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_SHORT_CMD_1, emc_pmacro_ddll_short_cmd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_SHORT_CMD_2, emc_pmacro_ddll_short_cmd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3, emc_pmacro_ob_ddll_short_dq_rank0_byte0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3, emc_pmacro_ob_ddll_short_dq_rank0_byte1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3, emc_pmacro_ob_ddll_short_dq_rank0_byte2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3, emc_pmacro_ob_ddll_short_dq_rank0_byte3_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3, emc_pmacro_ob_ddll_short_dq_rank0_byte4_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3, emc_pmacro_ob_ddll_short_dq_rank0_byte5_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3, emc_pmacro_ob_ddll_short_dq_rank0_byte6_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3, emc_pmacro_ob_ddll_short_dq_rank0_byte7_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd3_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3, emc_pmacro_ob_ddll_short_dq_rank1_byte0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3, emc_pmacro_ob_ddll_short_dq_rank1_byte1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3, emc_pmacro_ob_ddll_short_dq_rank1_byte2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3, emc_pmacro_ob_ddll_short_dq_rank1_byte3_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3, emc_pmacro_ob_ddll_short_dq_rank1_byte4_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3, emc_pmacro_ob_ddll_short_dq_rank1_byte5_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3, emc_pmacro_ob_ddll_short_dq_rank1_byte6_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3, emc_pmacro_ob_ddll_short_dq_rank1_byte7_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_3) \
|
||||
HANDLER(EMC, EMC_TXDSRVTTGEN, emc_txdsrvttgen) \
|
||||
HANDLER(EMC, EMC_FDPD_CTRL_DQ, emc_fdpd_ctrl_dq) \
|
||||
HANDLER(EMC, EMC_FDPD_CTRL_CMD, emc_fdpd_ctrl_cmd) \
|
||||
HANDLER(EMC, EMC_FBIO_SPARE, emc_fbio_spare) \
|
||||
HANDLER(EMC, EMC_ZCAL_INTERVAL, emc_zcal_interval) \
|
||||
HANDLER(EMC, EMC_ZCAL_WAIT_CNT, emc_zcal_wait_cnt) \
|
||||
HANDLER(EMC, EMC_MRS_WAIT_CNT, emc_mrs_wait_cnt) \
|
||||
HANDLER(EMC, EMC_MRS_WAIT_CNT2, emc_mrs_wait_cnt2) \
|
||||
HANDLER(EMC, EMC_AUTO_CAL_CHANNEL, emc_auto_cal_channel) \
|
||||
HANDLER(EMC, EMC_DLL_CFG_0, emc_dll_cfg_0) \
|
||||
HANDLER(EMC, EMC_DLL_CFG_1, emc_dll_cfg_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_AUTOCAL_CFG_COMMON, emc_pmacro_autocal_cfg_common) \
|
||||
HANDLER(EMC, EMC_PMACRO_ZCTRL, emc_pmacro_zctrl) \
|
||||
HANDLER(EMC, EMC_CFG, emc_cfg) \
|
||||
HANDLER(EMC, EMC_CFG_PIPE, emc_cfg_pipe) \
|
||||
HANDLER(EMC, EMC_DYN_SELF_REF_CONTROL, emc_dyn_self_ref_control) \
|
||||
HANDLER(EMC, EMC_QPOP, emc_qpop) \
|
||||
HANDLER(EMC, EMC_DQS_BRLSHFT_0, emc_dqs_brlshft_0) \
|
||||
HANDLER(EMC, EMC_DQS_BRLSHFT_1, emc_dqs_brlshft_1) \
|
||||
HANDLER(EMC, EMC_CMD_BRLSHFT_2, emc_cmd_brlshft_2) \
|
||||
HANDLER(EMC, EMC_CMD_BRLSHFT_3, emc_cmd_brlshft_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_PAD_CFG_CTRL, emc_pmacro_pad_cfg_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_PAD_RX_CTRL, emc_pmacro_data_pad_rx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_PAD_RX_CTRL, emc_pmacro_cmd_pad_rx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_RX_TERM_MODE, emc_pmacro_data_rx_term_mode) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_RX_TERM_MODE, emc_pmacro_cmd_rx_term_mode) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_PAD_TX_CTRL, emc_pmacro_cmd_pad_tx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_PAD_TX_CTRL, emc_pmacro_data_pad_tx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_COMMON_PAD_TX_CTRL, emc_pmacro_common_pad_tx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_VTTGEN_CTRL_0, emc_pmacro_vttgen_ctrl_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_VTTGEN_CTRL_1, emc_pmacro_vttgen_ctrl_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_VTTGEN_CTRL_2, emc_pmacro_vttgen_ctrl_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_BRICK_CTRL_RFU1, emc_pmacro_brick_ctrl_rfu1) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_BRICK_CTRL_FDPD, emc_pmacro_cmd_brick_ctrl_fdpd) \
|
||||
HANDLER(EMC, EMC_PMACRO_BRICK_CTRL_RFU2, emc_pmacro_brick_ctrl_rfu2) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_BRICK_CTRL_FDPD, emc_pmacro_data_brick_ctrl_fdpd) \
|
||||
HANDLER(EMC, EMC_PMACRO_BG_BIAS_CTRL_0, emc_pmacro_bg_bias_ctrl_0) \
|
||||
HANDLER(EMC, EMC_CFG_3, emc_cfg_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_0, emc_pmacro_tx_pwrd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_1, emc_pmacro_tx_pwrd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_2, emc_pmacro_tx_pwrd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_3, emc_pmacro_tx_pwrd_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_4, emc_pmacro_tx_pwrd_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_5, emc_pmacro_tx_pwrd_5) \
|
||||
HANDLER(EMC, EMC_CONFIG_SAMPLE_DELAY, emc_config_sample_delay) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_0, emc_pmacro_tx_sel_clk_src_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_1, emc_pmacro_tx_sel_clk_src_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_2, emc_pmacro_tx_sel_clk_src_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_3, emc_pmacro_tx_sel_clk_src_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_4, emc_pmacro_tx_sel_clk_src_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_5, emc_pmacro_tx_sel_clk_src_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_BYPASS, emc_pmacro_ddll_bypass) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_PWRD_0, emc_pmacro_ddll_pwrd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_PWRD_1, emc_pmacro_ddll_pwrd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_PWRD_2, emc_pmacro_ddll_pwrd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_CTRL_0, emc_pmacro_cmd_ctrl_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_CTRL_1, emc_pmacro_cmd_ctrl_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_CTRL_2, emc_pmacro_cmd_ctrl_2) \
|
||||
HANDLER(EMC, EMC_TR_TIMING_0, emc_tr_timing_0) \
|
||||
HANDLER(EMC, EMC_TR_DVFS, emc_tr_dvfs) \
|
||||
HANDLER(EMC, EMC_TR_CTRL_1, emc_tr_ctrl_1) \
|
||||
HANDLER(EMC, EMC_TR_RDV, emc_tr_rdv) \
|
||||
HANDLER(EMC, EMC_TR_QPOP, emc_tr_qpop) \
|
||||
HANDLER(EMC, EMC_TR_RDV_MASK, emc_tr_rdv_mask) \
|
||||
HANDLER(EMC, EMC_MRW14, emc_mrw14) \
|
||||
HANDLER(EMC, EMC_TR_QSAFE, emc_tr_qsafe) \
|
||||
HANDLER(EMC, EMC_TR_QRST, emc_tr_qrst) \
|
||||
HANDLER(EMC, EMC_TRAINING_CTRL, emc_training_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_SETTLE, emc_training_settle) \
|
||||
HANDLER(EMC, EMC_TRAINING_VREF_SETTLE, emc_training_vref_settle) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_FINE_CTRL, emc_training_ca_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_CTRL_MISC, emc_training_ca_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_CTRL_MISC1, emc_training_ca_ctrl_misc1) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_VREF_CTRL, emc_training_ca_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_CORS_CTRL, emc_training_quse_cors_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_FINE_CTRL, emc_training_quse_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_CTRL_MISC, emc_training_quse_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_VREF_CTRL, emc_training_quse_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_READ_FINE_CTRL, emc_training_read_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_READ_CTRL_MISC, emc_training_read_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_READ_VREF_CTRL, emc_training_read_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_WRITE_FINE_CTRL, emc_training_write_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_WRITE_CTRL_MISC, emc_training_write_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_WRITE_VREF_CTRL, emc_training_write_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_MPC, emc_training_mpc) \
|
||||
HANDLER(EMC, EMC_MRW15, emc_mrw15)
|
||||
|
||||
#define DECLARE_STRUCT_MEMBER_HANDLER(BASE, REG, NAME) uint32_t NAME;
|
||||
|
||||
#define DECLARE_ARRAY_AND_STRUCT_MEMBERS(NAME, FOREACH_HANDLER) \
|
||||
union { struct { FOREACH_HANDLER(DECLARE_STRUCT_MEMBER_HANDLER) } NAME; uint32_t NAME##_arr[sizeof(NAME) / sizeof(uint32_t)]; }
|
||||
|
||||
struct EmcDvfsTimingTable {
|
||||
uint32_t rev;
|
||||
char dvfs_ver[60];
|
||||
uint32_t rate_khz;
|
||||
uint32_t min_volt;
|
||||
uint32_t gpu_min_volt;
|
||||
char clock_src[32];
|
||||
uint32_t clk_src_emc;
|
||||
uint32_t needs_training;
|
||||
uint32_t training_pattern;
|
||||
uint32_t trained;
|
||||
|
||||
uint32_t periodic_training;
|
||||
uint32_t trained_dram_clktree_c0d0u0;
|
||||
uint32_t trained_dram_clktree_c0d0u1;
|
||||
uint32_t trained_dram_clktree_c0d1u0;
|
||||
uint32_t trained_dram_clktree_c0d1u1;
|
||||
uint32_t trained_dram_clktree_c1d0u0;
|
||||
uint32_t trained_dram_clktree_c1d0u1;
|
||||
uint32_t trained_dram_clktree_c1d1u0;
|
||||
uint32_t trained_dram_clktree_c1d1u1;
|
||||
uint32_t current_dram_clktree_c0d0u0;
|
||||
uint32_t current_dram_clktree_c0d0u1;
|
||||
uint32_t current_dram_clktree_c0d1u0;
|
||||
uint32_t current_dram_clktree_c0d1u1;
|
||||
uint32_t current_dram_clktree_c1d0u0;
|
||||
uint32_t current_dram_clktree_c1d0u1;
|
||||
uint32_t current_dram_clktree_c1d1u0;
|
||||
uint32_t current_dram_clktree_c1d1u1;
|
||||
uint32_t run_clocks;
|
||||
uint32_t tree_margin;
|
||||
|
||||
uint32_t num_burst;
|
||||
uint32_t num_burst_per_ch;
|
||||
uint32_t num_trim;
|
||||
uint32_t num_trim_per_ch;
|
||||
uint32_t num_mc_regs;
|
||||
uint32_t num_up_down;
|
||||
uint32_t vref_num;
|
||||
uint32_t training_mod_num;
|
||||
uint32_t dram_timing_num;
|
||||
|
||||
uint32_t ptfv_dqsosc_movavg_c0d0u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c0d0u1;
|
||||
uint32_t ptfv_dqsosc_movavg_c0d1u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c0d1u1;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d0u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d0u1;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d1u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d1u1;
|
||||
uint32_t ptfv_write_samples;
|
||||
uint32_t ptfv_dvfs_samples;
|
||||
uint32_t ptfv_movavg_weight;
|
||||
uint32_t ptfv_config_ctrl;
|
||||
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(burst_regs, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(burst_perch_regs, FOREACH_PER_CHANNEL_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(shadow_regs_ca_train, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(shadow_regs_quse_train, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(shadow_regs_rdwr_train, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(trim_regs, FOREACH_TRIM_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(trim_perch_regs, FOREACH_PER_CHANNEL_TRIM_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(vref_perch_regs, FOREACH_PER_CHANNEL_VREF_REG);
|
||||
|
||||
struct {
|
||||
uint32_t t_rp;
|
||||
uint32_t t_fc_lpddr4;
|
||||
uint32_t t_rfc;
|
||||
uint32_t t_pdex;
|
||||
uint32_t rl;
|
||||
} dram_timings;
|
||||
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(training_mod_regs, FOREACH_PER_CHANNEL_TRAINING_MOD_REG);
|
||||
|
||||
uint32_t save_restore_mod_regs[12];
|
||||
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(burst_mc_regs, FOREACH_BURST_MC_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(la_scale_regs, FOREACH_LA_SCALE_REG);
|
||||
|
||||
uint32_t min_mrs_wait;
|
||||
uint32_t emc_mrw;
|
||||
uint32_t emc_mrw2;
|
||||
uint32_t emc_mrw3;
|
||||
uint32_t emc_mrw4;
|
||||
uint32_t emc_mrw9;
|
||||
uint32_t emc_mrs;
|
||||
uint32_t emc_emrs;
|
||||
uint32_t emc_emrs2;
|
||||
uint32_t emc_auto_cal_config;
|
||||
uint32_t emc_auto_cal_config2;
|
||||
uint32_t emc_auto_cal_config3;
|
||||
uint32_t emc_auto_cal_config4;
|
||||
uint32_t emc_auto_cal_config5;
|
||||
uint32_t emc_auto_cal_config6;
|
||||
uint32_t emc_auto_cal_config7;
|
||||
uint32_t emc_auto_cal_config8;
|
||||
uint32_t emc_cfg_2;
|
||||
uint32_t emc_sel_dpd_ctrl;
|
||||
uint32_t emc_fdpd_ctrl_cmd_no_ramp;
|
||||
uint32_t dll_clk_src;
|
||||
uint32_t clk_out_enb_x_0_clk_enb_emc_dll;
|
||||
uint32_t latency;
|
||||
};
|
||||
|
||||
#undef DECLARE_STRUCT_MEMBER_HANDLER
|
||||
#undef DECLARE_ARRAY_AND_STRUCT_MEMBERS
|
||||
|
||||
static_assert(sizeof(EmcDvfsTimingTable) == 0x1340);
|
||||
|
||||
}
|
||||
409
fusee/program/source/mtc/fusee_mtc_timing_table_mariko.hpp
Normal file
409
fusee/program/source/mtc/fusee_mtc_timing_table_mariko.hpp
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "fusee_mtc_timing_table_common.hpp"
|
||||
|
||||
namespace ams::nxboot::mariko {
|
||||
|
||||
#define FOREACH_BURST_REG(HANDLER) \
|
||||
HANDLER(EMC, EMC_RC, emc_rc) \
|
||||
HANDLER(EMC, EMC_RFC, emc_rfc) \
|
||||
HANDLER(EMC, EMC_RFCPB, emc_rfcpb) \
|
||||
HANDLER(EMC, EMC_REFCTRL2, emc_refctrl2) \
|
||||
HANDLER(EMC, EMC_RFC_SLR, emc_rfc_slr) \
|
||||
HANDLER(EMC, EMC_RAS, emc_ras) \
|
||||
HANDLER(EMC, EMC_RP, emc_rp) \
|
||||
HANDLER(EMC, EMC_R2W, emc_r2w) \
|
||||
HANDLER(EMC, EMC_W2R, emc_w2r) \
|
||||
HANDLER(EMC, EMC_R2P, emc_r2p) \
|
||||
HANDLER(EMC, EMC_W2P, emc_w2p) \
|
||||
HANDLER(EMC, EMC_R2R, emc_r2r) \
|
||||
HANDLER(EMC, EMC_TPPD, emc_tppd) \
|
||||
HANDLER(EMC, EMC_TRTM, emc_trtm) \
|
||||
HANDLER(EMC, EMC_TWTM, emc_twtm) \
|
||||
HANDLER(EMC, EMC_TRATM, emc_tratm) \
|
||||
HANDLER(EMC, EMC_TWATM, emc_twatm) \
|
||||
HANDLER(EMC, EMC_TR2REF, emc_tr2ref) \
|
||||
HANDLER(EMC, EMC_CCDMW, emc_ccdmw) \
|
||||
HANDLER(EMC, EMC_RD_RCD, emc_rd_rcd) \
|
||||
HANDLER(EMC, EMC_WR_RCD, emc_wr_rcd) \
|
||||
HANDLER(EMC, EMC_RRD, emc_rrd) \
|
||||
HANDLER(EMC, EMC_REXT, emc_rext) \
|
||||
HANDLER(EMC, EMC_WEXT, emc_wext) \
|
||||
HANDLER(EMC, EMC_WDV_CHK, emc_wdv_chk) \
|
||||
HANDLER(EMC, EMC_WDV, emc_wdv) \
|
||||
HANDLER(EMC, EMC_WSV, emc_wsv) \
|
||||
HANDLER(EMC, EMC_WEV, emc_wev) \
|
||||
HANDLER(EMC, EMC_WDV_MASK, emc_wdv_mask) \
|
||||
HANDLER(EMC, EMC_WS_DURATION, emc_ws_duration) \
|
||||
HANDLER(EMC, EMC_WE_DURATION, emc_we_duration) \
|
||||
HANDLER(EMC, EMC_QUSE, emc_quse) \
|
||||
HANDLER(EMC, EMC_QUSE_WIDTH, emc_quse_width) \
|
||||
HANDLER(EMC, EMC_IBDLY, emc_ibdly) \
|
||||
HANDLER(EMC, EMC_OBDLY, emc_obdly) \
|
||||
HANDLER(EMC, EMC_EINPUT, emc_einput) \
|
||||
HANDLER(EMC, EMC_MRW6, emc_mrw6) \
|
||||
HANDLER(EMC, EMC_EINPUT_DURATION, emc_einput_duration) \
|
||||
HANDLER(EMC, EMC_PUTERM_EXTRA, emc_puterm_extra) \
|
||||
HANDLER(EMC, EMC_PUTERM_WIDTH, emc_puterm_width) \
|
||||
HANDLER(EMC, EMC_QRST, emc_qrst) \
|
||||
HANDLER(EMC, EMC_QSAFE, emc_qsafe) \
|
||||
HANDLER(EMC, EMC_RDV, emc_rdv) \
|
||||
HANDLER(EMC, EMC_RDV_MASK, emc_rdv_mask) \
|
||||
HANDLER(EMC, EMC_RDV_EARLY, emc_rdv_early) \
|
||||
HANDLER(EMC, EMC_RDV_EARLY_MASK, emc_rdv_early_mask) \
|
||||
HANDLER(EMC, EMC_REFRESH, emc_refresh) \
|
||||
HANDLER(EMC, EMC_BURST_REFRESH_NUM, emc_burst_refresh_num) \
|
||||
HANDLER(EMC, EMC_PRE_REFRESH_REQ_CNT, emc_pre_refresh_req_cnt) \
|
||||
HANDLER(EMC, EMC_PDEX2WR, emc_pdex2wr) \
|
||||
HANDLER(EMC, EMC_PDEX2RD, emc_pdex2rd) \
|
||||
HANDLER(EMC, EMC_PCHG2PDEN, emc_pchg2pden) \
|
||||
HANDLER(EMC, EMC_ACT2PDEN, emc_act2pden) \
|
||||
HANDLER(EMC, EMC_AR2PDEN, emc_ar2pden) \
|
||||
HANDLER(EMC, EMC_RW2PDEN, emc_rw2pden) \
|
||||
HANDLER(EMC, EMC_CKE2PDEN, emc_cke2pden) \
|
||||
HANDLER(EMC, EMC_PDEX2CKE, emc_pdex2cke) \
|
||||
HANDLER(EMC, EMC_PDEX2MRR, emc_pdex2mrr) \
|
||||
HANDLER(EMC, EMC_TXSR, emc_txsr) \
|
||||
HANDLER(EMC, EMC_TXSRDLL, emc_txsrdll) \
|
||||
HANDLER(EMC, EMC_TCKE, emc_tcke) \
|
||||
HANDLER(EMC, EMC_TCKESR, emc_tckesr) \
|
||||
HANDLER(EMC, EMC_TPD, emc_tpd) \
|
||||
HANDLER(EMC, EMC_TFAW, emc_tfaw) \
|
||||
HANDLER(EMC, EMC_TRPAB, emc_trpab) \
|
||||
HANDLER(EMC, EMC_TCLKSTABLE, emc_tclkstable) \
|
||||
HANDLER(EMC, EMC_TCLKSTOP, emc_tclkstop) \
|
||||
HANDLER(EMC, EMC_MRW7, emc_mrw7) \
|
||||
HANDLER(EMC, EMC_TREFBW, emc_trefbw) \
|
||||
HANDLER(EMC, EMC_ODT_WRITE, emc_odt_write) \
|
||||
HANDLER(EMC, EMC_FBIO_CFG5, emc_fbio_cfg5) \
|
||||
HANDLER(EMC, EMC_FBIO_CFG7, emc_fbio_cfg7) \
|
||||
HANDLER(EMC, EMC_CFG_DIG_DLL, emc_cfg_dig_dll) \
|
||||
HANDLER(EMC, EMC_CFG_DIG_DLL_PERIOD, emc_cfg_dig_dll_period) \
|
||||
HANDLER(EMC, EMC_PMACRO_IB_RXRT, emc_pmacro_ib_rxrt) \
|
||||
HANDLER(EMC, EMC_CFG_PIPE_1, emc_cfg_pipe_1) \
|
||||
HANDLER(EMC, EMC_CFG_PIPE_2, emc_cfg_pipe_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_4, emc_pmacro_quse_ddll_rank0_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK0_5, emc_pmacro_quse_ddll_rank0_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_4, emc_pmacro_quse_ddll_rank1_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_QUSE_DDLL_RANK1_5, emc_pmacro_quse_ddll_rank1_5) \
|
||||
HANDLER(EMC, EMC_MRW8, emc_mrw8) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4, emc_pmacro_ob_ddll_long_dq_rank1_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5, emc_pmacro_ob_ddll_long_dq_rank1_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0, emc_pmacro_ob_ddll_long_dqs_rank0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1, emc_pmacro_ob_ddll_long_dqs_rank0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2, emc_pmacro_ob_ddll_long_dqs_rank0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3, emc_pmacro_ob_ddll_long_dqs_rank0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4, emc_pmacro_ob_ddll_long_dqs_rank0_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5, emc_pmacro_ob_ddll_long_dqs_rank0_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0, emc_pmacro_ob_ddll_long_dqs_rank1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1, emc_pmacro_ob_ddll_long_dqs_rank1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2, emc_pmacro_ob_ddll_long_dqs_rank1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3, emc_pmacro_ob_ddll_long_dqs_rank1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4, emc_pmacro_ob_ddll_long_dqs_rank1_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5, emc_pmacro_ob_ddll_long_dqs_rank1_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_0, emc_pmacro_ddll_long_cmd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_1, emc_pmacro_ddll_long_cmd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_2, emc_pmacro_ddll_long_cmd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_3, emc_pmacro_ddll_long_cmd_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_LONG_CMD_4, emc_pmacro_ddll_long_cmd_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_SHORT_CMD_0, emc_pmacro_ddll_short_cmd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_SHORT_CMD_1, emc_pmacro_ddll_short_cmd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_SHORT_CMD_2, emc_pmacro_ddll_short_cmd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3, emc_pmacro_ob_ddll_short_dq_rank0_byte0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3, emc_pmacro_ob_ddll_short_dq_rank0_byte1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3, emc_pmacro_ob_ddll_short_dq_rank0_byte2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3, emc_pmacro_ob_ddll_short_dq_rank0_byte3_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3, emc_pmacro_ob_ddll_short_dq_rank0_byte4_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3, emc_pmacro_ob_ddll_short_dq_rank0_byte5_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3, emc_pmacro_ob_ddll_short_dq_rank0_byte6_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3, emc_pmacro_ob_ddll_short_dq_rank0_byte7_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3, emc_pmacro_ob_ddll_short_dq_rank0_cmd3_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3, emc_pmacro_ob_ddll_short_dq_rank1_byte0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3, emc_pmacro_ob_ddll_short_dq_rank1_byte1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3, emc_pmacro_ob_ddll_short_dq_rank1_byte2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3, emc_pmacro_ob_ddll_short_dq_rank1_byte3_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3, emc_pmacro_ob_ddll_short_dq_rank1_byte4_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3, emc_pmacro_ob_ddll_short_dq_rank1_byte5_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3, emc_pmacro_ob_ddll_short_dq_rank1_byte6_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3, emc_pmacro_ob_ddll_short_dq_rank1_byte7_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd0_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd1_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd2_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3, emc_pmacro_ob_ddll_short_dq_rank1_cmd3_3) \
|
||||
HANDLER(EMC, EMC_TXDSRVTTGEN, emc_txdsrvttgen) \
|
||||
HANDLER(EMC, EMC_FDPD_CTRL_DQ, emc_fdpd_ctrl_dq) \
|
||||
HANDLER(EMC, EMC_FDPD_CTRL_CMD, emc_fdpd_ctrl_cmd) \
|
||||
HANDLER(EMC, EMC_FBIO_SPARE, emc_fbio_spare) \
|
||||
HANDLER(EMC, EMC_ZCAL_INTERVAL, emc_zcal_interval) \
|
||||
HANDLER(EMC, EMC_ZCAL_WAIT_CNT, emc_zcal_wait_cnt) \
|
||||
HANDLER(EMC, EMC_MRS_WAIT_CNT, emc_mrs_wait_cnt) \
|
||||
HANDLER(EMC, EMC_MRS_WAIT_CNT2, emc_mrs_wait_cnt2) \
|
||||
HANDLER(EMC, EMC_AUTO_CAL_CHANNEL, emc_auto_cal_channel) \
|
||||
HANDLER(EMC, EMC_PMACRO_DLL_CFG_0, emc_pmacro_dll_cfg_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DLL_CFG_1, emc_pmacro_dll_cfg_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DLL_CFG_2, emc_pmacro_dll_cfg_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_AUTOCAL_CFG_COMMON, emc_pmacro_autocal_cfg_common) \
|
||||
HANDLER(EMC, EMC_PMACRO_ZCTRL, emc_pmacro_zctrl) \
|
||||
HANDLER(EMC, EMC_CFG, emc_cfg) \
|
||||
HANDLER(EMC, EMC_CFG_PIPE, emc_cfg_pipe) \
|
||||
HANDLER(EMC, EMC_DYN_SELF_REF_CONTROL, emc_dyn_self_ref_control) \
|
||||
HANDLER(EMC, EMC_QPOP, emc_qpop) \
|
||||
HANDLER(EMC, EMC_DQS_BRLSHFT_0, emc_dqs_brlshft_0) \
|
||||
HANDLER(EMC, EMC_DQS_BRLSHFT_1, emc_dqs_brlshft_1) \
|
||||
HANDLER(EMC, EMC_CMD_BRLSHFT_2, emc_cmd_brlshft_2) \
|
||||
HANDLER(EMC, EMC_CMD_BRLSHFT_3, emc_cmd_brlshft_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_PAD_CFG_CTRL, emc_pmacro_pad_cfg_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_PAD_RX_CTRL, emc_pmacro_data_pad_rx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_PAD_RX_CTRL, emc_pmacro_cmd_pad_rx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_RX_TERM_MODE, emc_pmacro_data_rx_term_mode) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_RX_TERM_MODE, emc_pmacro_cmd_rx_term_mode) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_PAD_TX_CTRL, emc_pmacro_cmd_pad_tx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_PAD_TX_CTRL, emc_pmacro_data_pad_tx_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_VTTGEN_CTRL_0, emc_pmacro_vttgen_ctrl_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_VTTGEN_CTRL_1, emc_pmacro_vttgen_ctrl_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_VTTGEN_CTRL_2, emc_pmacro_vttgen_ctrl_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_BRICK_CTRL_RFU1, emc_pmacro_brick_ctrl_rfu1) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_BRICK_CTRL_FDPD, emc_pmacro_cmd_brick_ctrl_fdpd) \
|
||||
HANDLER(EMC, EMC_PMACRO_BRICK_CTRL_RFU2, emc_pmacro_brick_ctrl_rfu2) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_BRICK_CTRL_FDPD, emc_pmacro_data_brick_ctrl_fdpd) \
|
||||
HANDLER(EMC, EMC_PMACRO_BG_BIAS_CTRL_0, emc_pmacro_bg_bias_ctrl_0) \
|
||||
HANDLER(EMC, EMC_CFG_3, emc_cfg_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_0, emc_pmacro_tx_pwrd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_1, emc_pmacro_tx_pwrd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_2, emc_pmacro_tx_pwrd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_3, emc_pmacro_tx_pwrd_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_4, emc_pmacro_tx_pwrd_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_PWRD_5, emc_pmacro_tx_pwrd_5) \
|
||||
HANDLER(EMC, EMC_CONFIG_SAMPLE_DELAY, emc_config_sample_delay) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_0, emc_pmacro_tx_sel_clk_src_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_1, emc_pmacro_tx_sel_clk_src_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_2, emc_pmacro_tx_sel_clk_src_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_3, emc_pmacro_tx_sel_clk_src_3) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_4, emc_pmacro_tx_sel_clk_src_4) \
|
||||
HANDLER(EMC, EMC_PMACRO_TX_SEL_CLK_SRC_5, emc_pmacro_tx_sel_clk_src_5) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_BYPASS, emc_pmacro_ddll_bypass) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_PWRD_0, emc_pmacro_ddll_pwrd_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_PWRD_1, emc_pmacro_ddll_pwrd_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_DDLL_PWRD_2, emc_pmacro_ddll_pwrd_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_CTRL_0, emc_pmacro_cmd_ctrl_0) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_CTRL_1, emc_pmacro_cmd_ctrl_1) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_CTRL_2, emc_pmacro_cmd_ctrl_2) \
|
||||
HANDLER(EMC, EMC_PMACRO_DATA_PI_CTRL, emc_pmacro_data_pi_ctrl) \
|
||||
HANDLER(EMC, EMC_PMACRO_CMD_PI_CTRL, emc_pmacro_cmd_pi_ctrl) \
|
||||
HANDLER(EMC, EMC_TR_TIMING_0, emc_tr_timing_0) \
|
||||
HANDLER(EMC, EMC_TR_DVFS, emc_tr_dvfs) \
|
||||
HANDLER(EMC, EMC_TR_CTRL_1, emc_tr_ctrl_1) \
|
||||
HANDLER(EMC, EMC_TR_RDV, emc_tr_rdv) \
|
||||
HANDLER(EMC, EMC_TR_QPOP, emc_tr_qpop) \
|
||||
HANDLER(EMC, EMC_TR_RDV_MASK, emc_tr_rdv_mask) \
|
||||
HANDLER(EMC, EMC_MRW14, emc_mrw14) \
|
||||
HANDLER(EMC, EMC_TR_QSAFE, emc_tr_qsafe) \
|
||||
HANDLER(EMC, EMC_TR_QRST, emc_tr_qrst) \
|
||||
HANDLER(EMC, EMC_TRAINING_CTRL, emc_training_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_SETTLE, emc_training_settle) \
|
||||
HANDLER(EMC, EMC_TRAINING_VREF_SETTLE, emc_training_vref_settle) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_FINE_CTRL, emc_training_ca_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_CTRL_MISC, emc_training_ca_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_CTRL_MISC1, emc_training_ca_ctrl_misc1) \
|
||||
HANDLER(EMC, EMC_TRAINING_CA_VREF_CTRL, emc_training_ca_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_CORS_CTRL, emc_training_quse_cors_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_FINE_CTRL, emc_training_quse_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_CTRL_MISC, emc_training_quse_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_QUSE_VREF_CTRL, emc_training_quse_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_READ_FINE_CTRL, emc_training_read_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_READ_CTRL_MISC, emc_training_read_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_READ_VREF_CTRL, emc_training_read_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_WRITE_FINE_CTRL, emc_training_write_fine_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_WRITE_CTRL_MISC, emc_training_write_ctrl_misc) \
|
||||
HANDLER(EMC, EMC_TRAINING_WRITE_VREF_CTRL, emc_training_write_vref_ctrl) \
|
||||
HANDLER(EMC, EMC_TRAINING_MPC, emc_training_mpc) \
|
||||
HANDLER(EMC, EMC_MRW15, emc_mrw15)
|
||||
|
||||
#define DECLARE_STRUCT_MEMBER_HANDLER(BASE, REG, NAME) uint32_t NAME;
|
||||
|
||||
#define DECLARE_ARRAY_AND_STRUCT_MEMBERS(NAME, FOREACH_HANDLER) \
|
||||
union { struct { FOREACH_HANDLER(DECLARE_STRUCT_MEMBER_HANDLER) } NAME; uint32_t NAME##_arr[sizeof(NAME) / sizeof(uint32_t)]; }
|
||||
|
||||
struct EmcDvfsTimingTable {
|
||||
uint32_t rev;
|
||||
char dvfs_ver[60];
|
||||
uint32_t rate_khz;
|
||||
uint32_t min_volt;
|
||||
uint32_t gpu_min_volt;
|
||||
char clock_src[32];
|
||||
uint32_t clk_src_emc;
|
||||
uint32_t pll_en_ssc;
|
||||
uint32_t needs_training;
|
||||
uint32_t training_pattern;
|
||||
uint32_t trained;
|
||||
|
||||
uint32_t periodic_training;
|
||||
uint32_t trained_dram_clktree_c0d0u0;
|
||||
uint32_t trained_dram_clktree_c0d0u1;
|
||||
uint32_t trained_dram_clktree_c0d1u0;
|
||||
uint32_t trained_dram_clktree_c0d1u1;
|
||||
uint32_t trained_dram_clktree_c1d0u0;
|
||||
uint32_t trained_dram_clktree_c1d0u1;
|
||||
uint32_t trained_dram_clktree_c1d1u0;
|
||||
uint32_t trained_dram_clktree_c1d1u1;
|
||||
uint32_t current_dram_clktree_c0d0u0;
|
||||
uint32_t current_dram_clktree_c0d0u1;
|
||||
uint32_t current_dram_clktree_c0d1u0;
|
||||
uint32_t current_dram_clktree_c0d1u1;
|
||||
uint32_t current_dram_clktree_c1d0u0;
|
||||
uint32_t current_dram_clktree_c1d0u1;
|
||||
uint32_t current_dram_clktree_c1d1u0;
|
||||
uint32_t current_dram_clktree_c1d1u1;
|
||||
uint32_t emc_fbio_cfg7;
|
||||
uint32_t run_clocks;
|
||||
uint32_t tree_margin;
|
||||
|
||||
uint32_t num_burst;
|
||||
uint32_t num_burst_per_ch;
|
||||
uint32_t num_trim;
|
||||
uint32_t num_trim_per_ch;
|
||||
uint32_t num_mc_regs;
|
||||
uint32_t num_up_down;
|
||||
uint32_t vref_num;
|
||||
uint32_t training_mod_num;
|
||||
uint32_t dram_timing_num;
|
||||
|
||||
uint32_t ptfv_dqsosc_movavg_c0d0u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c0d0u1;
|
||||
uint32_t ptfv_dqsosc_movavg_c0d1u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c0d1u1;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d0u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d0u1;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d1u0;
|
||||
uint32_t ptfv_dqsosc_movavg_c1d1u1;
|
||||
uint32_t ptfv_write_samples;
|
||||
uint32_t ptfv_dvfs_samples;
|
||||
uint32_t ptfv_movavg_weight;
|
||||
uint32_t ptfv_config_ctrl;
|
||||
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(burst_regs, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(burst_perch_regs, FOREACH_PER_CHANNEL_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(shadow_regs_ca_train, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(shadow_regs_rdwr_train, FOREACH_BURST_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(trim_regs, FOREACH_TRIM_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(trim_perch_regs, FOREACH_PER_CHANNEL_TRIM_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(vref_perch_regs, FOREACH_PER_CHANNEL_VREF_REG);
|
||||
|
||||
struct {
|
||||
uint32_t t_rp;
|
||||
uint32_t t_fc_lpddr4;
|
||||
uint32_t t_rfc;
|
||||
uint32_t t_pdex;
|
||||
uint32_t rl;
|
||||
} dram_timings;
|
||||
|
||||
uint32_t zq_op_cc_long_zcal;
|
||||
uint32_t zq_op_cc_short_zcal;
|
||||
uint32_t zcal_wait_time_ps_cc_long_zcal;
|
||||
uint32_t zcal_wait_time_ps_cc_short_zcal;
|
||||
uint32_t tZQCAL_lpddr4;
|
||||
uint32_t zqcal_before_cc_cutoff;
|
||||
uint32_t opt_cc_short_zcal;
|
||||
uint32_t opt_short_zcal;
|
||||
uint32_t opt_do_sw_qrst;
|
||||
uint32_t save_restore_clkstop_pd;
|
||||
uint32_t opt_E90;
|
||||
uint32_t cya_allow_ref_cc;
|
||||
uint32_t ref_b4_sref_en;
|
||||
uint32_t cya_issue_pc_ref;
|
||||
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(training_mod_regs, FOREACH_PER_CHANNEL_TRAINING_MOD_REG);
|
||||
|
||||
uint32_t save_restore_mod_regs[12];
|
||||
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(burst_mc_regs, FOREACH_BURST_MC_REG);
|
||||
DECLARE_ARRAY_AND_STRUCT_MEMBERS(la_scale_regs, FOREACH_LA_SCALE_REG);
|
||||
|
||||
uint32_t unk_0;
|
||||
uint32_t vtt_vdda_ctrl_0;
|
||||
uint32_t src_clock_div;
|
||||
uint32_t vtt_vdda_dual_channel;
|
||||
uint32_t vtt_vdda_ctrl_1;
|
||||
uint32_t vtt_vdda_ctrl_2;
|
||||
uint32_t vtt_vdda_ctrl_3;
|
||||
uint32_t vtt_vdda_ctrl_4;
|
||||
uint32_t misc_cfg_0;
|
||||
uint32_t misc_cfg_1;
|
||||
uint32_t misc_cfg_2;
|
||||
uint32_t unk_1;
|
||||
uint32_t unk_2;
|
||||
uint32_t pipe_clk_delay;
|
||||
uint32_t clkchange_delay;
|
||||
uint32_t pllm_ss_cfg;
|
||||
uint32_t pllm_ss_ctrl1;
|
||||
uint32_t pllm_ss_ctrl2;
|
||||
uint32_t pllmb_ss_cfg;
|
||||
uint32_t pllmb_ss_ctrl1;
|
||||
uint32_t pllmb_ss_ctrl2;
|
||||
uint32_t pllmb_divm;
|
||||
uint32_t pllmb_divn;
|
||||
uint32_t pllmb_divp;
|
||||
uint32_t min_mrs_wait;
|
||||
uint32_t ramp_wait;
|
||||
uint32_t emc_mrw;
|
||||
uint32_t emc_mrw2;
|
||||
uint32_t emc_mrw3;
|
||||
uint32_t emc_mrw4;
|
||||
uint32_t emc_mrw9;
|
||||
uint32_t emc_mrs;
|
||||
uint32_t emc_emrs;
|
||||
uint32_t emc_emrs2;
|
||||
uint32_t emc_auto_cal_config;
|
||||
uint32_t emc_auto_cal_config2;
|
||||
uint32_t emc_auto_cal_config3;
|
||||
uint32_t emc_auto_cal_config4;
|
||||
uint32_t emc_auto_cal_config5;
|
||||
uint32_t emc_auto_cal_config6;
|
||||
uint32_t emc_auto_cal_config7;
|
||||
uint32_t emc_auto_cal_config8;
|
||||
uint32_t emc_cfg_2;
|
||||
uint32_t emc_sel_dpd_ctrl;
|
||||
uint32_t emc_fdpd_ctrl_cmd_no_ramp;
|
||||
uint32_t emc_tr_ctrl_0;
|
||||
uint32_t dll_clk_src;
|
||||
uint32_t clk_out_enb_x_0_clk_enb_emc_dll;
|
||||
uint32_t latency;
|
||||
uint32_t pllm_misc1_0_pllm_clamp_ph90;
|
||||
};
|
||||
|
||||
#undef DECLARE_STRUCT_MEMBER_HANDLER
|
||||
#undef DECLARE_ARRAY_AND_STRUCT_MEMBERS
|
||||
|
||||
static_assert(sizeof(EmcDvfsTimingTable) == 0x10CC);
|
||||
|
||||
}
|
||||
1107
fusee/program/source/sdram/fusee_sdram.cpp
Normal file
1107
fusee/program/source/sdram/fusee_sdram.cpp
Normal file
File diff suppressed because it is too large
Load Diff
23
fusee/program/source/sdram/fusee_sdram.hpp
Normal file
23
fusee/program/source/sdram/fusee_sdram.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void InitializeSdram();
|
||||
|
||||
}
|
||||
829
fusee/program/source/sdram/fusee_sdram_params.inc
Normal file
829
fusee/program/source/sdram/fusee_sdram_params.inc
Normal file
@@ -0,0 +1,829 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
constexpr inline const u8 SdramParamsErista0_1[0x3CB] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4,
|
||||
0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00,
|
||||
0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01,
|
||||
0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00,
|
||||
0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04,
|
||||
0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C,
|
||||
0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13,
|
||||
0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04,
|
||||
0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00,
|
||||
0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00,
|
||||
0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0,
|
||||
0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C,
|
||||
0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
|
||||
0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05,
|
||||
0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
|
||||
0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01,
|
||||
0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08,
|
||||
0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00,
|
||||
0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15,
|
||||
0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F,
|
||||
0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0,
|
||||
0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0,
|
||||
0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00,
|
||||
0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10,
|
||||
0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12,
|
||||
0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30,
|
||||
0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05,
|
||||
0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00,
|
||||
0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00,
|
||||
0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04,
|
||||
0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03,
|
||||
0x60, 0x03, 0x02, 0xA1, 0x01, 0x7B, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x01, 0x28, 0x00, 0x00,
|
||||
0x01, 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32,
|
||||
0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56,
|
||||
0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04,
|
||||
0x00, 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F,
|
||||
0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82,
|
||||
0x00, 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B,
|
||||
0x94, 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02,
|
||||
0x00, 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04,
|
||||
0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01,
|
||||
0x05, 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01,
|
||||
0x00, 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00,
|
||||
0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x58, 0x01, 0xB2,
|
||||
0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01,
|
||||
0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02,
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00,
|
||||
0x00, 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68,
|
||||
0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08,
|
||||
0x0E, 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50,
|
||||
0x02, 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F,
|
||||
0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04,
|
||||
0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00,
|
||||
0x2F, 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xF9, 0x1F, 0x0D, 0x68, 0x07, 0x4C, 0x03,
|
||||
0x5F, 0x01, 0x1F, 0x80, 0x68, 0x07, 0xFF, 0xFF, 0xFF, 0x71, 0x1F, 0x02, 0x68, 0x07, 0xB7, 0x1F,
|
||||
0x05, 0x68, 0x07, 0xFF, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista0 = SdramParamsErista0_1;
|
||||
constexpr inline const size_t SdramParamsSizeErista0 = sizeof(SdramParamsErista0_1);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista1 = SdramParamsErista0_1;
|
||||
constexpr inline const size_t SdramParamsSizeErista1 = sizeof(SdramParamsErista0_1);
|
||||
|
||||
constexpr inline const u8 SdramParamsErista2_3[0x3C7] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4,
|
||||
0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00,
|
||||
0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01,
|
||||
0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00,
|
||||
0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04,
|
||||
0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C,
|
||||
0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13,
|
||||
0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04,
|
||||
0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00,
|
||||
0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00,
|
||||
0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0,
|
||||
0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C,
|
||||
0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
|
||||
0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05,
|
||||
0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
|
||||
0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01,
|
||||
0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08,
|
||||
0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00,
|
||||
0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15,
|
||||
0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F,
|
||||
0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0,
|
||||
0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0,
|
||||
0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00,
|
||||
0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10,
|
||||
0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12,
|
||||
0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30,
|
||||
0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05,
|
||||
0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00,
|
||||
0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00,
|
||||
0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04,
|
||||
0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03,
|
||||
0x60, 0x03, 0x02, 0xA1, 0x01, 0x7B, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x01, 0x28, 0x00, 0x00,
|
||||
0x01, 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32,
|
||||
0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56,
|
||||
0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04,
|
||||
0x00, 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F,
|
||||
0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82,
|
||||
0x00, 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B,
|
||||
0x94, 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02,
|
||||
0x00, 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04,
|
||||
0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01,
|
||||
0x05, 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01,
|
||||
0x00, 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00,
|
||||
0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x58, 0x01, 0xB2,
|
||||
0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01,
|
||||
0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02,
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00,
|
||||
0x00, 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68,
|
||||
0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08,
|
||||
0x0E, 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50,
|
||||
0x02, 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F,
|
||||
0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04,
|
||||
0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00,
|
||||
0x2F, 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xFF, 0x9E, 0x1F, 0x12, 0x68, 0x07, 0x18,
|
||||
0x1F, 0x03, 0x68, 0x07, 0xFF, 0xFF, 0xAE, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x68, 0x07, 0xFF, 0xFF,
|
||||
0xAE, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista2 = SdramParamsErista2_3;
|
||||
constexpr inline const size_t SdramParamsSizeErista2 = sizeof(SdramParamsErista2_3);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista3 = SdramParamsErista2_3;
|
||||
constexpr inline const size_t SdramParamsSizeErista3 = sizeof(SdramParamsErista2_3);
|
||||
|
||||
constexpr inline const u8 SdramParamsErista4_5[0x418] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4,
|
||||
0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00,
|
||||
0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01,
|
||||
0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00,
|
||||
0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04,
|
||||
0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C,
|
||||
0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13,
|
||||
0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04,
|
||||
0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00,
|
||||
0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00,
|
||||
0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0,
|
||||
0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C,
|
||||
0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
|
||||
0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05,
|
||||
0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
|
||||
0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01,
|
||||
0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08,
|
||||
0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00,
|
||||
0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15,
|
||||
0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F,
|
||||
0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0,
|
||||
0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0,
|
||||
0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00,
|
||||
0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10,
|
||||
0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12,
|
||||
0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30,
|
||||
0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05,
|
||||
0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00,
|
||||
0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00,
|
||||
0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04,
|
||||
0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03,
|
||||
0x60, 0x03, 0x02, 0xA1, 0x01, 0x7B, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x01, 0x28, 0x00, 0x00,
|
||||
0x01, 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32,
|
||||
0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56,
|
||||
0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04,
|
||||
0x00, 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F,
|
||||
0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82,
|
||||
0x00, 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B,
|
||||
0x94, 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02,
|
||||
0x00, 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04,
|
||||
0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01,
|
||||
0x05, 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01,
|
||||
0x00, 0x01, 0x24, 0x01, 0x21, 0x03, 0x0C, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00,
|
||||
0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x18, 0x58, 0x01, 0xB2,
|
||||
0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01,
|
||||
0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02,
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00,
|
||||
0x00, 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68,
|
||||
0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08,
|
||||
0x0E, 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50,
|
||||
0x02, 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F,
|
||||
0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04,
|
||||
0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00,
|
||||
0x2F, 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xF9, 0x1F, 0x0D, 0x68, 0x07, 0x4C, 0x03,
|
||||
0x5F, 0x01, 0x1F, 0x80, 0x68, 0x07, 0x29, 0x1F, 0x12, 0x68, 0x07, 0x18, 0x1F, 0x03, 0x68, 0x07,
|
||||
0xFF, 0x45, 0x11, 0x15, 0xF6, 0x06, 0x1F, 0x16, 0x18, 0x00, 0x06, 0xF5, 0x00, 0x32, 0x00, 0x2F,
|
||||
0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x0C, 0x02, 0x0E, 0x18,
|
||||
0x00, 0x0F, 0x68, 0x07, 0x13, 0x13, 0x15, 0x5A, 0x00, 0x02, 0x5E, 0x00, 0x3F, 0x16, 0x00, 0x15,
|
||||
0x68, 0x07, 0xD4, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x68, 0x07, 0x3E, 0x1F, 0x02, 0x68, 0x07, 0x65,
|
||||
0x11, 0x07, 0x04, 0x00, 0x0D, 0x68, 0x07, 0x1F, 0x10, 0x68, 0x07, 0x27, 0x1F, 0x05, 0x68, 0x07,
|
||||
0xFF, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista4 = SdramParamsErista4_5;
|
||||
constexpr inline const size_t SdramParamsSizeErista4 = sizeof(SdramParamsErista4_5);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista5 = SdramParamsErista4_5;
|
||||
constexpr inline const size_t SdramParamsSizeErista5 = sizeof(SdramParamsErista4_5);
|
||||
|
||||
constexpr inline const u8 SdramParamsErista6_7[0x3BD] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4,
|
||||
0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00,
|
||||
0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01,
|
||||
0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00,
|
||||
0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04,
|
||||
0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x2C,
|
||||
0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13,
|
||||
0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04,
|
||||
0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00,
|
||||
0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x17, 0x05, 0x54, 0x00,
|
||||
0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x13, 0x05, 0x30, 0x00,
|
||||
0x00, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x29, 0x00, 0xF1,
|
||||
0x29, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,
|
||||
0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
|
||||
0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E,
|
||||
0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01,
|
||||
0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0,
|
||||
0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08,
|
||||
0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08,
|
||||
0x67, 0x02, 0x70, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08,
|
||||
0x11, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00,
|
||||
0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
|
||||
0x10, 0x00, 0xA2, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3,
|
||||
0x08, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13,
|
||||
0x11, 0x01, 0x00, 0x10, 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C,
|
||||
0x7F, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x18, 0x00, 0x06, 0xF5, 0x00, 0x32, 0x00, 0x2F,
|
||||
0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x0C, 0x02, 0x0F, 0x18,
|
||||
0x00, 0x05, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x13, 0x15, 0x5A, 0x00, 0x02, 0x5E, 0x00, 0x3B, 0x16,
|
||||
0x00, 0x15, 0x78, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F,
|
||||
0x00, 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x0C, 0x02, 0x54, 0xAB, 0x00, 0x0A,
|
||||
0x04, 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17,
|
||||
0x03, 0x60, 0x03, 0x02, 0xA1, 0x01, 0x7B, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x01, 0x28, 0x00,
|
||||
0x00, 0x01, 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47,
|
||||
0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72,
|
||||
0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24,
|
||||
0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13,
|
||||
0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
|
||||
0x82, 0x00, 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03,
|
||||
0x0B, 0x94, 0x04, 0x11, 0x37, 0x16, 0x03, 0x30, 0x00, 0x00, 0x10, 0x05, 0x00, 0x51, 0x30, 0x00,
|
||||
0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03,
|
||||
0x05, 0x12, 0x00, 0x00, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B,
|
||||
0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC,
|
||||
0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03,
|
||||
0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B,
|
||||
0x00, 0x10, 0x58, 0x01, 0xB2, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10,
|
||||
0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00,
|
||||
0x11, 0x07, 0x10, 0x00, 0xC4, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F,
|
||||
0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80,
|
||||
0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F,
|
||||
0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00,
|
||||
0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04,
|
||||
0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00,
|
||||
0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01,
|
||||
0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2E, 0xEC, 0x00, 0x3C, 0x01, 0x0F, 0x01, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista6 = SdramParamsErista6_7;
|
||||
constexpr inline const size_t SdramParamsSizeErista6 = sizeof(SdramParamsErista6_7);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsErista7 = SdramParamsErista6_7;
|
||||
constexpr inline const size_t SdramParamsSizeErista7 = sizeof(SdramParamsErista6_7);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko0_1[0x3EE] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x82,
|
||||
0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x0E, 0x00, 0x11, 0x88, 0x04, 0x00, 0x26, 0x20,
|
||||
0x12, 0x0C, 0x00, 0x02, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, 0xBC, 0xBC, 0xC5, 0xB3, 0x3C, 0x9E,
|
||||
0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00,
|
||||
0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, 0x01, 0x00, 0x00, 0x30, 0x39, 0x00,
|
||||
0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, 0x74, 0x00, 0x13, 0x03, 0x04, 0x00,
|
||||
0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00,
|
||||
0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57,
|
||||
0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17,
|
||||
0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24,
|
||||
0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18,
|
||||
0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61,
|
||||
0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60,
|
||||
0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00,
|
||||
0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1,
|
||||
0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,
|
||||
0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
|
||||
0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E,
|
||||
0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02,
|
||||
0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E,
|
||||
0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C,
|
||||
0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, 0x16, 0x16, 0x16, 0x88, 0x2C, 0x00, 0x2C,
|
||||
0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3,
|
||||
0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00,
|
||||
0x0C, 0x00, 0x01, 0x0C, 0x00, 0xA2, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07,
|
||||
0x1C, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB,
|
||||
0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12,
|
||||
0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, 0x31, 0x7F, 0x22, 0x00, 0x0E, 0x00, 0x10, 0x00, 0x1B,
|
||||
0x18, 0x00, 0x06, 0xF3, 0x02, 0x43, 0x00, 0x49, 0x00, 0x45, 0x00, 0x42, 0x00, 0x47, 0x00, 0x49,
|
||||
0x00, 0x47, 0x00, 0x46, 0x00, 0x16, 0xE6, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x1F, 0x28, 0x02, 0x00,
|
||||
0x0C, 0x11, 0x22, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x1B, 0x00, 0x22, 0x94,
|
||||
0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,
|
||||
0x80, 0x18, 0x00, 0x04, 0x08, 0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C,
|
||||
0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14,
|
||||
0x00, 0x8B, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x32,
|
||||
0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34,
|
||||
0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23,
|
||||
0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01,
|
||||
0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01,
|
||||
0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x24, 0x34,
|
||||
0x10, 0x0A, 0x00, 0x0F, 0xCC, 0x00, 0x02, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02,
|
||||
0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00,
|
||||
0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xDF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44,
|
||||
0x5B, 0x8A, 0x67, 0x76, 0x00, 0x01, 0x00, 0x4C, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF,
|
||||
0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00,
|
||||
0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,
|
||||
0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xEF, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
|
||||
0x28, 0x10, 0x00, 0x80, 0x01, 0xC0, 0x01, 0x00, 0x04, 0x08, 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13,
|
||||
0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3,
|
||||
0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01,
|
||||
0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, 0x68, 0x43, 0xC3, 0xBA, 0xE4,
|
||||
0xD3, 0x1E, 0x0B, 0x05, 0x2F, 0xF0, 0xFF, 0xF4, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6,
|
||||
0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34,
|
||||
0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F,
|
||||
0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00,
|
||||
0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00,
|
||||
0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0x9C, 0x7F, 0x16, 0x00, 0x0D, 0x00,
|
||||
0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00,
|
||||
0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06,
|
||||
0x0F, 0x38, 0x08, 0x0D, 0x11, 0x16, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17,
|
||||
0x00, 0x16, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xF6, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko0 = SdramParamsMariko0_1;
|
||||
constexpr inline const size_t SdramParamsSizeMariko0 = sizeof(SdramParamsMariko0_1);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko1 = SdramParamsMariko0_1;
|
||||
constexpr inline const size_t SdramParamsSizeMariko1 = sizeof(SdramParamsMariko0_1);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko2_3[0x449] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0,
|
||||
0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88,
|
||||
0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00,
|
||||
0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17,
|
||||
0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x61, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x30, 0x01, 0x13,
|
||||
0x02, 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x3A, 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13,
|
||||
0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15,
|
||||
0x08, 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03,
|
||||
0x18, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18,
|
||||
0x00, 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00,
|
||||
0x80, 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16,
|
||||
0x0C, 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40,
|
||||
0x00, 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04,
|
||||
0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00,
|
||||
0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B,
|
||||
0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E,
|
||||
0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25,
|
||||
0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07,
|
||||
0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00,
|
||||
0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x08, 0x00, 0x00,
|
||||
0x0B, 0x08, 0x5D, 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00,
|
||||
0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00,
|
||||
0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F,
|
||||
0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xA2, 0x08,
|
||||
0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x1C, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00,
|
||||
0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x00, 0x64, 0x01, 0xB3, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80,
|
||||
0x0F, 0xF4, 0x20, 0x02, 0x35, 0x01, 0x00, 0x13, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F,
|
||||
0x0F, 0xF4, 0x02, 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1,
|
||||
0x02, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46,
|
||||
0x00, 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x10, 0x02, 0x00, 0x0C, 0x11, 0x16,
|
||||
0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05,
|
||||
0x54, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x18, 0x00, 0x63,
|
||||
0x80, 0x01, 0x00, 0x00, 0x40, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01,
|
||||
0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x05, 0x78, 0x03, 0x8B, 0x01, 0x22,
|
||||
0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x80,
|
||||
0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34,
|
||||
0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,
|
||||
0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04,
|
||||
0x00, 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85,
|
||||
0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x24, 0x34, 0x10, 0x0A, 0x00, 0x0F,
|
||||
0xCC, 0x00, 0x02, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21,
|
||||
0x15, 0x04, 0x14, 0x40, 0x8B, 0x02, 0x1D, 0x00, 0x9D, 0x02, 0x01, 0x04, 0x04, 0xDF, 0x81, 0x10,
|
||||
0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x00, 0x01, 0x00, 0x4C, 0x22, 0x10,
|
||||
0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4C, 0x1C, 0x1C, 0x1C, 0x1C, 0xF0,
|
||||
0x01, 0x31, 0x02, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57,
|
||||
0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x20, 0x20, 0x00, 0xB1, 0x08, 0x4C,
|
||||
0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x04, 0x02, 0x0D, 0xC0, 0x01, 0x04, 0x08,
|
||||
0x00, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x11, 0x07, 0x10, 0x00, 0xE2, 0x02, 0x02,
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F,
|
||||
0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x04, 0x84, 0x03, 0x35, 0x00, 0x00, 0xF0,
|
||||
0x24, 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C,
|
||||
0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05,
|
||||
0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38,
|
||||
0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08,
|
||||
0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00,
|
||||
0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38,
|
||||
0x08, 0xC3, 0x2F, 0x00, 0x00, 0x38, 0x08, 0x0B, 0x2F, 0xC5, 0xB3, 0x38, 0x08, 0x29, 0x1F, 0x00,
|
||||
0x38, 0x08, 0x84, 0x13, 0x05, 0x1C, 0x00, 0x08, 0xDC, 0x02, 0x1F, 0x0D, 0x38, 0x08, 0xC7, 0x93,
|
||||
0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x38, 0x08, 0xF2, 0x0A, 0x88, 0x00, 0x00,
|
||||
0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00,
|
||||
0x0D, 0x8C, 0x16, 0x16, 0x16, 0x88, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x43, 0x1B, 0x02, 0x38, 0x08,
|
||||
0x04, 0x30, 0x08, 0x0F, 0x38, 0x08, 0x91, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x0F, 0x38, 0x08, 0x24,
|
||||
0x14, 0x80, 0x38, 0x08, 0x04, 0x20, 0x00, 0x0F, 0x38, 0x08, 0xFF, 0x1E, 0x7F, 0x80, 0x00, 0x40,
|
||||
0x00, 0x04, 0x10, 0x80, 0x38, 0x08, 0x82, 0x1F, 0x00, 0x38, 0x08, 0x09, 0x1F, 0x10, 0x38, 0x08,
|
||||
0x1F, 0x1F, 0x01, 0x38, 0x08, 0x00, 0x1F, 0x00, 0x38, 0x08, 0x36, 0x0E, 0x1C, 0x00, 0x0F, 0x38,
|
||||
0x08, 0xFF, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko2 = SdramParamsMariko2_3;
|
||||
constexpr inline const size_t SdramParamsSizeMariko2 = sizeof(SdramParamsMariko2_3);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko3 = SdramParamsMariko2_3;
|
||||
constexpr inline const size_t SdramParamsSizeMariko3 = sizeof(SdramParamsMariko2_3);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko4_5[0x3F7] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0,
|
||||
0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88,
|
||||
0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00,
|
||||
0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17,
|
||||
0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03,
|
||||
0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A,
|
||||
0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B,
|
||||
0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08,
|
||||
0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18,
|
||||
0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00,
|
||||
0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A,
|
||||
0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00,
|
||||
0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13,
|
||||
0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05,
|
||||
0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0,
|
||||
0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03,
|
||||
0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26,
|
||||
0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B,
|
||||
0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0xBF, 0x01,
|
||||
0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00,
|
||||
0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D,
|
||||
0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, 0x14,
|
||||
0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, 0x00, 0x0A,
|
||||
0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, 0x30, 0x01,
|
||||
0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10,
|
||||
0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, 0x01,
|
||||
0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80,
|
||||
0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, 0x31,
|
||||
0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45,
|
||||
0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01,
|
||||
0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, 0x5C,
|
||||
0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, 0x40,
|
||||
0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, 0x01,
|
||||
0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03,
|
||||
0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x8B, 0x01, 0x22, 0x04, 0xFF, 0x9F,
|
||||
0xAF, 0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10,
|
||||
0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01,
|
||||
0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24,
|
||||
0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90,
|
||||
0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF,
|
||||
0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x24, 0x34, 0x10, 0x0A, 0x00, 0x0F, 0xCC, 0x00, 0x02,
|
||||
0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14,
|
||||
0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04,
|
||||
0xDF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x00, 0x01, 0x00,
|
||||
0x4C, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C,
|
||||
0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00,
|
||||
0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2,
|
||||
0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01,
|
||||
0x04, 0x08, 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2,
|
||||
0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16,
|
||||
0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15,
|
||||
0xF0, 0x24, 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0B, 0x05, 0x3B, 0x80, 0x2A, 0x02,
|
||||
0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00,
|
||||
0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04,
|
||||
0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00,
|
||||
0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01,
|
||||
0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F,
|
||||
0x38, 0x08, 0xFF, 0xFF, 0xFF, 0x40, 0x13, 0x32, 0x01, 0x00, 0x0F, 0x38, 0x08, 0x41, 0x3E, 0x18,
|
||||
0x00, 0x0F, 0x38, 0x08, 0x07, 0x18, 0x00, 0x93, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00,
|
||||
0x47, 0x20, 0x08, 0x11, 0x0D, 0x8E, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x78, 0x02, 0x00,
|
||||
0x0C, 0x11, 0x18, 0x5A, 0x00, 0x15, 0x0F, 0x38, 0x08, 0x1F, 0x18, 0x38, 0x08, 0xFF, 0xFF, 0xFF,
|
||||
0xF6, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko4 = SdramParamsMariko4_5;
|
||||
constexpr inline const size_t SdramParamsSizeMariko4 = sizeof(SdramParamsMariko4_5);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko5 = SdramParamsMariko4_5;
|
||||
constexpr inline const size_t SdramParamsSizeMariko5 = sizeof(SdramParamsMariko4_5);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko6_7[0x427] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0,
|
||||
0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88,
|
||||
0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00,
|
||||
0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17,
|
||||
0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03,
|
||||
0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A,
|
||||
0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B,
|
||||
0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08,
|
||||
0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18,
|
||||
0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00,
|
||||
0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80,
|
||||
0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C,
|
||||
0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00,
|
||||
0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00,
|
||||
0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00,
|
||||
0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
|
||||
0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D,
|
||||
0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,
|
||||
0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
|
||||
0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02,
|
||||
0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B,
|
||||
0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D,
|
||||
0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC,
|
||||
0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00,
|
||||
0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44,
|
||||
0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C,
|
||||
0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, 0x22, 0x20,
|
||||
0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02,
|
||||
0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00,
|
||||
0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA,
|
||||
0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00,
|
||||
0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3,
|
||||
0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00,
|
||||
0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4,
|
||||
0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x8B, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF,
|
||||
0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32,
|
||||
0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,
|
||||
0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00,
|
||||
0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00,
|
||||
0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F,
|
||||
0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x24, 0x34, 0x10, 0x0A, 0x00, 0x0F, 0xCC, 0x00, 0x02, 0x31,
|
||||
0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40,
|
||||
0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xDF,
|
||||
0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x00, 0x01, 0x00, 0x4C,
|
||||
0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C,
|
||||
0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44,
|
||||
0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08,
|
||||
0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04,
|
||||
0x08, 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02,
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F,
|
||||
0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0,
|
||||
0x24, 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C,
|
||||
0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05,
|
||||
0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38,
|
||||
0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08,
|
||||
0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00,
|
||||
0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38,
|
||||
0x08, 0xFF, 0x22, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x05, 0x1F, 0x08, 0x38, 0x08, 0x5B, 0x93, 0x08,
|
||||
0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, 0x38, 0x08, 0xF2, 0x0A, 0x08, 0x00, 0x00, 0x0B,
|
||||
0x08, 0x5D, 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D,
|
||||
0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x32, 0x1C, 0x00, 0x38, 0x08, 0x1F,
|
||||
0x00, 0x38, 0x08, 0xFF, 0x00, 0x04, 0x18, 0x00, 0x00, 0x34, 0x06, 0x1F, 0x40, 0x38, 0x08, 0xFF,
|
||||
0x22, 0x04, 0x12, 0x00, 0x0F, 0x38, 0x08, 0x81, 0x1F, 0x01, 0x38, 0x08, 0x09, 0x1F, 0x20, 0x38,
|
||||
0x08, 0x0F, 0x1B, 0x01, 0x38, 0x08, 0x1F, 0x02, 0x38, 0x08, 0x00, 0x1F, 0x01, 0x38, 0x08, 0xFF,
|
||||
0x8C, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko6 = SdramParamsMariko6_7;
|
||||
constexpr inline const size_t SdramParamsSizeMariko6 = sizeof(SdramParamsMariko6_7);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko7 = SdramParamsMariko6_7;
|
||||
constexpr inline const size_t SdramParamsSizeMariko7 = sizeof(SdramParamsMariko6_7);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko8_9[0x428] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0,
|
||||
0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88,
|
||||
0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00,
|
||||
0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17,
|
||||
0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03,
|
||||
0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A,
|
||||
0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B,
|
||||
0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08,
|
||||
0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18,
|
||||
0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00,
|
||||
0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A,
|
||||
0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00,
|
||||
0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13,
|
||||
0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05,
|
||||
0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00,
|
||||
0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
|
||||
0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D,
|
||||
0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,
|
||||
0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
|
||||
0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02,
|
||||
0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B,
|
||||
0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D,
|
||||
0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC,
|
||||
0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00,
|
||||
0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44,
|
||||
0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C,
|
||||
0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22,
|
||||
0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4,
|
||||
0x02, 0x31, 0x7F, 0x18, 0x00, 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x48,
|
||||
0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D,
|
||||
0x8E, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x18, 0x5A, 0x00,
|
||||
0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x18, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01,
|
||||
0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08,
|
||||
0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F,
|
||||
0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x8B, 0x01, 0x22, 0x04,
|
||||
0xFF, 0x9F, 0xAF, 0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00,
|
||||
0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67,
|
||||
0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32,
|
||||
0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00,
|
||||
0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF,
|
||||
0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x24, 0x34, 0x10, 0x0A, 0x00, 0x0F, 0xCC,
|
||||
0x00, 0x02, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15,
|
||||
0x04, 0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80,
|
||||
0x04, 0x04, 0xDF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x00,
|
||||
0x01, 0x00, 0x4C, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D,
|
||||
0x1C, 0x1C, 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF,
|
||||
0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4,
|
||||
0x01, 0xB2, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x08,
|
||||
0xC0, 0x01, 0x17, 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07,
|
||||
0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70,
|
||||
0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70, 0x04, 0x24, 0x00, 0x80,
|
||||
0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0B, 0x05, 0x3B,
|
||||
0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F,
|
||||
0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F,
|
||||
0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40,
|
||||
0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00,
|
||||
0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C,
|
||||
0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, 0x22, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x74, 0x93, 0x08, 0x00,
|
||||
0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, 0x38, 0x08, 0xF2, 0x0A, 0x08, 0x00, 0x00, 0x0B, 0x08,
|
||||
0x5D, 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C,
|
||||
0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x32, 0x1C, 0x00, 0x38, 0x08, 0x1B, 0x00,
|
||||
0x38, 0x08, 0x13, 0x32, 0x01, 0x00, 0x0F, 0x38, 0x08, 0xE8, 0x04, 0x18, 0x00, 0x00, 0x34, 0x06,
|
||||
0x1F, 0x40, 0x38, 0x08, 0xFF, 0x22, 0x04, 0x12, 0x00, 0x0F, 0x38, 0x08, 0x81, 0x1F, 0x01, 0x38,
|
||||
0x08, 0x09, 0x1F, 0x20, 0x38, 0x08, 0x1F, 0x1F, 0x02, 0x38, 0x08, 0x00, 0x1F, 0x01, 0x38, 0x08,
|
||||
0xFF, 0x8C, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko8 = SdramParamsMariko8_9;
|
||||
constexpr inline const size_t SdramParamsSizeMariko8 = sizeof(SdramParamsMariko8_9);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko9 = SdramParamsMariko8_9;
|
||||
constexpr inline const size_t SdramParamsSizeMariko9 = sizeof(SdramParamsMariko8_9);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko10_11[0x4A3] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0,
|
||||
0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88,
|
||||
0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00,
|
||||
0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17,
|
||||
0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03,
|
||||
0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A,
|
||||
0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B,
|
||||
0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08,
|
||||
0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18,
|
||||
0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00,
|
||||
0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A,
|
||||
0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00,
|
||||
0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13,
|
||||
0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05,
|
||||
0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00,
|
||||
0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x06, 0x1B, 0x04, 0x1C,
|
||||
0x07, 0x03, 0x05, 0x02, 0x00, 0x25, 0x25, 0x03, 0x00, 0x1E, 0x1D, 0x08, 0x0D, 0x0A, 0x0C, 0x09,
|
||||
0x0B, 0x26, 0x26, 0x05, 0x02, 0x04, 0x03, 0x05, 0x00, 0x06, 0x1C, 0x1B, 0x07, 0x25, 0x25, 0x07,
|
||||
0x0A, 0x0B, 0x1D, 0x0C, 0x0D, 0x09, 0x00, 0x08, 0x1E, 0x26, 0x26, 0x09, 0x24, 0x06, 0x08, 0x2A,
|
||||
0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02,
|
||||
0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B,
|
||||
0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D,
|
||||
0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC,
|
||||
0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00,
|
||||
0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44,
|
||||
0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C,
|
||||
0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22,
|
||||
0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4,
|
||||
0x02, 0x31, 0x7F, 0x10, 0x00, 0x14, 0x00, 0x0B, 0x00, 0x13, 0x18, 0x00, 0x06, 0xFF, 0x08, 0x47,
|
||||
0x00, 0x45, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x46, 0x00, 0x46, 0x00, 0x48, 0x00, 0x48, 0x00, 0x08,
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x10,
|
||||
0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x13, 0x00, 0x10, 0x94, 0x00, 0x00, 0x05,
|
||||
0x54, 0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00,
|
||||
0x04, 0x08, 0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04,
|
||||
0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x8B, 0x01,
|
||||
0x28, 0x40, 0xFF, 0x9F, 0x9F, 0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x31, 0x9F, 0xFF, 0x37,
|
||||
0x08, 0x00, 0xF0, 0x11, 0x57, 0x21, 0x03, 0x64, 0x67, 0x04, 0x32, 0x51, 0x21, 0x56, 0x73, 0x04,
|
||||
0x12, 0x60, 0x35, 0x47, 0x73, 0x56, 0x04, 0x12, 0x10, 0x72, 0x65, 0x43, 0x37, 0x21, 0x40, 0x65,
|
||||
0x64, 0x21, 0x30, 0x57, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13,
|
||||
0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C,
|
||||
0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xCF, 0x33, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0,
|
||||
0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03,
|
||||
0x13, 0x21, 0x15, 0x04, 0x03, 0xC1, 0x04, 0x08, 0x5B, 0x01, 0x90, 0x10, 0x08, 0x01, 0x03, 0x00,
|
||||
0x50, 0x00, 0x40, 0x01, 0x04, 0x04, 0xDF, 0x81, 0x10, 0x08, 0x29, 0x32, 0x93, 0xA5, 0x54, 0x4A,
|
||||
0x6B, 0x76, 0x87, 0x00, 0x01, 0x00, 0x4C, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00,
|
||||
0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1,
|
||||
0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C,
|
||||
0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28,
|
||||
0x10, 0x30, 0x03, 0x08, 0xC0, 0x01, 0x17, 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04,
|
||||
0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72,
|
||||
0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70,
|
||||
0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, 0x60, 0x43, 0xCB, 0xFA, 0xE4, 0xD3,
|
||||
0xFE, 0x0B, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00,
|
||||
0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00,
|
||||
0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00,
|
||||
0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46,
|
||||
0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0x9C,
|
||||
0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, 0xBA, 0x13, 0x06, 0x7C, 0x03, 0x08,
|
||||
0xDC, 0x01, 0x1F, 0x0C, 0x38, 0x08, 0x78, 0xFF, 0x25, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07,
|
||||
0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26,
|
||||
0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D,
|
||||
0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0x38, 0x08, 0xF9,
|
||||
0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45,
|
||||
0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01,
|
||||
0x1F, 0x0D, 0x18, 0x00, 0x06, 0x0F, 0x38, 0x08, 0x0D, 0x11, 0x16, 0x5A, 0x00, 0x11, 0x0D, 0x38,
|
||||
0x08, 0x5F, 0x17, 0x00, 0x17, 0x00, 0x16, 0x38, 0x08, 0x76, 0x5F, 0x22, 0x04, 0xFF, 0x9F, 0xAF,
|
||||
0x38, 0x08, 0x0A, 0xFF, 0x11, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76,
|
||||
0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74,
|
||||
0x56, 0x01, 0x45, 0x32, 0x67, 0x38, 0x08, 0x2B, 0x12, 0xAF, 0x38, 0x08, 0x2F, 0xD7, 0x36, 0x38,
|
||||
0x08, 0x41, 0x92, 0x00, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x38, 0x08, 0xBF, 0x09,
|
||||
0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x00, 0x38, 0x08, 0xFF, 0x16, 0x5F, 0xC3,
|
||||
0xBA, 0xE4, 0xD3, 0x1E, 0x38, 0x08, 0xFF, 0x28, 0x1F, 0xEC, 0x38, 0x08, 0x0B, 0x50, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko10 = SdramParamsMariko10_11;
|
||||
constexpr inline const size_t SdramParamsSizeMariko10 = sizeof(SdramParamsMariko10_11);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko11 = SdramParamsMariko10_11;
|
||||
constexpr inline const size_t SdramParamsSizeMariko11 = sizeof(SdramParamsMariko10_11);
|
||||
|
||||
constexpr inline const u8 SdramParamsMariko12_13[0x3C2] = {
|
||||
0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01,
|
||||
0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0,
|
||||
0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88,
|
||||
0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00,
|
||||
0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17,
|
||||
0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1,
|
||||
0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03,
|
||||
0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A,
|
||||
0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B,
|
||||
0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08,
|
||||
0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18,
|
||||
0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00,
|
||||
0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80,
|
||||
0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C,
|
||||
0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00,
|
||||
0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00,
|
||||
0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03,
|
||||
0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05,
|
||||
0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B,
|
||||
0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25,
|
||||
0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06,
|
||||
0x07, 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00,
|
||||
0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00,
|
||||
0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00,
|
||||
0x00, 0x0D, 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10,
|
||||
0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23,
|
||||
0x0F, 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0,
|
||||
0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0,
|
||||
0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F,
|
||||
0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F,
|
||||
0xF4, 0x02, 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02,
|
||||
0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00,
|
||||
0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A,
|
||||
0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54,
|
||||
0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04,
|
||||
0x08, 0x00, 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00,
|
||||
0x0F, 0xE4, 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x8B, 0x01, 0x22, 0x04, 0xFF,
|
||||
0x9F, 0xAF, 0x4F, 0x01, 0x24, 0x00, 0x00, 0x01, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0,
|
||||
0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25,
|
||||
0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
|
||||
0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C,
|
||||
0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF,
|
||||
0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x24, 0x34, 0x10, 0x0A, 0x00, 0x0F, 0xCC, 0x00,
|
||||
0x02, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04,
|
||||
0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04,
|
||||
0x04, 0xDF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x00, 0x01,
|
||||
0x00, 0x4C, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C,
|
||||
0x1C, 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF,
|
||||
0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01,
|
||||
0xB2, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x08, 0xC0,
|
||||
0x01, 0x17, 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62,
|
||||
0x00, 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42,
|
||||
0x00, 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70, 0x04, 0x24, 0x00, 0x80, 0x96,
|
||||
0x00, 0x15, 0xF0, 0x24, 0x04, 0x60, 0x43, 0xCB, 0xFA, 0xE4, 0xD3, 0xFE, 0x0F, 0x05, 0x3B, 0x80,
|
||||
0x2A, 0x02, 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03,
|
||||
0x2C, 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A,
|
||||
0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04,
|
||||
0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A,
|
||||
0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0E, 0x3C, 0x01,
|
||||
0x0F, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2C, 0x50, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
};
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko12 = SdramParamsMariko12_13;
|
||||
constexpr inline const size_t SdramParamsSizeMariko12 = sizeof(SdramParamsMariko12_13);
|
||||
|
||||
constexpr inline const u8 * const SdramParamsMariko13 = SdramParamsMariko12_13;
|
||||
constexpr inline const size_t SdramParamsSizeMariko13 = sizeof(SdramParamsMariko12_13);
|
||||
|
||||
947
fusee/program/source/sdram/fusee_sdram_params_lp0_erista.inc
Normal file
947
fusee/program/source/sdram/fusee_sdram_params_lp0_erista.inc
Normal file
@@ -0,0 +1,947 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define FOREACH_SDRAM_SCRATCH_REGISTER_ERISTA(HANDLER) \
|
||||
/* PMC SCRATCH fields. */ \
|
||||
HANDLER(EmcClockSource, 6, 7:0, 15:8) \
|
||||
HANDLER(EmcClockSourceDll, 6, 7:0, 23:16) \
|
||||
HANDLER(EmcClockSource, 6, 31:29, 26:24) \
|
||||
HANDLER(EmcClockSourceDll, 6, 31:29, 29:27) \
|
||||
HANDLER(EmcClockSourceDll, 6, 11:10, 31:30) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 9:8, 1:0) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 2:1, 3:2) \
|
||||
HANDLER(EmcZqCalLpDdr4WarmBoot, 7, 31:30, 5:4) \
|
||||
HANDLER(EmcClockSource, 7, 15:15, 6:6) \
|
||||
HANDLER(EmcClockSource, 7, 26:26, 7:7) \
|
||||
HANDLER(EmcClockSource, 7, 20:20, 8:8) \
|
||||
HANDLER(EmcClockSource, 7, 19:19, 9:9) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 13:13, 10:10) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 12:12, 11:11) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 11:11, 12:12) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 10:10, 13:13) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 5:5, 14:14) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 4:4, 15:15) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 3:3, 16:16) \
|
||||
HANDLER(ClkRstControllerPllmMisc2Override, 7, 0:0, 17:17) \
|
||||
HANDLER(EmcZqCalLpDdr4WarmBoot, 7, 1:0, 19:18) \
|
||||
HANDLER(EmcZqCalLpDdr4WarmBoot, 7, 4:4, 20:20) \
|
||||
HANDLER(EmcOdtWrite, 7, 5:0, 26:21) \
|
||||
HANDLER(EmcOdtWrite, 7, 11:8, 30:27) \
|
||||
HANDLER(EmcOdtWrite, 7, 31:31, 31:31) \
|
||||
HANDLER(EmcFdpdCtrlCmdNoRamp, 13, 0:0, 30:30) \
|
||||
HANDLER(EmcCfgPipeClk, 13, 0:0, 31:31) \
|
||||
HANDLER(McEmemArbMisc2, 14, 0:0, 30:30) \
|
||||
HANDLER(McDaCfg0, 14, 0:0, 31:31) \
|
||||
HANDLER(EmcQRst, 15, 6:0, 26:20) \
|
||||
HANDLER(EmcQRst, 15, 20:16, 31:27) \
|
||||
HANDLER(EmcPmacroCmdTxDrv, 16, 5:0, 25:20) \
|
||||
HANDLER(EmcPmacroCmdTxDrv, 16, 13:8, 31:26) \
|
||||
HANDLER(EmcPmacroAutocalCfg0, 17, 2:0, 22:20) \
|
||||
HANDLER(EmcPmacroAutocalCfg0, 17, 10:8, 25:23) \
|
||||
HANDLER(EmcPmacroAutocalCfg0, 17, 18:16, 28:26) \
|
||||
HANDLER(EmcPmacroAutocalCfg0, 17, 26:24, 31:29) \
|
||||
HANDLER(EmcPmacroAutocalCfg1, 18, 2:0, 22:20) \
|
||||
HANDLER(EmcPmacroAutocalCfg1, 18, 10:8, 25:23) \
|
||||
HANDLER(EmcPmacroAutocalCfg1, 18, 18:16, 28:26) \
|
||||
HANDLER(EmcPmacroAutocalCfg1, 18, 26:24, 31:29) \
|
||||
HANDLER(EmcPmacroAutocalCfg2, 19, 2:0, 22:20) \
|
||||
HANDLER(EmcPmacroAutocalCfg2, 19, 10:8, 25:23) \
|
||||
HANDLER(EmcPmacroAutocalCfg2, 19, 18:16, 28:26) \
|
||||
HANDLER(EmcPmacroAutocalCfg2, 19, 26:24, 31:29) \
|
||||
HANDLER(EmcCfgRsv, 22, 31:0, 31:0) \
|
||||
HANDLER(EmcAutoCalConfig, 23, 31:0, 31:0) \
|
||||
HANDLER(EmcAutoCalVrefSel0, 24, 31:0, 31:0) \
|
||||
HANDLER(EmcPmacroBrickCtrlRfu1, 25, 31:0, 31:0) \
|
||||
HANDLER(EmcPmacroBrickCtrlRfu2, 26, 31:0, 31:0) \
|
||||
HANDLER(EmcPmcScratch1, 27, 31:0, 31:0) \
|
||||
HANDLER(EmcPmcScratch2, 28, 31:0, 31:0) \
|
||||
HANDLER(EmcPmcScratch3, 29, 31:0, 31:0) \
|
||||
HANDLER(McEmemArbDaTurns, 30, 31:0, 31:0) \
|
||||
HANDLER(EmcFbioSpare, 58, 31:24, 7:0) \
|
||||
HANDLER(EmcFbioSpare, 58, 23:16, 15:8) \
|
||||
HANDLER(EmcFbioSpare, 58, 15:8, 23:16) \
|
||||
HANDLER(EmcFbioSpare, 58, 7:2, 29:24) \
|
||||
HANDLER(EmcFbioSpare, 58, 0:0, 30:30) \
|
||||
HANDLER(EmcDllCfg0, 59, 29:0, 29:0) \
|
||||
HANDLER(EmcPmacroDdllBypass, 60, 11:0, 11:0) \
|
||||
HANDLER(EmcPmacroDdllBypass, 60, 27:13, 26:12) \
|
||||
HANDLER(EmcPmacroDdllBypass, 60, 31:29, 29:27) \
|
||||
HANDLER(McEmemArbMisc0, 61, 14:0, 14:0) \
|
||||
HANDLER(McEmemArbMisc0, 61, 30:16, 29:15) \
|
||||
HANDLER(EmcFdpdCtrlCmd, 62, 16:0, 16:0) \
|
||||
HANDLER(EmcFdpdCtrlCmd, 62, 31:20, 28:17) \
|
||||
HANDLER(EmcAutoCalConfig2, 63, 27:0, 27:0) \
|
||||
HANDLER(EmcBurstRefreshNum, 63, 3:0, 31:28) \
|
||||
HANDLER(EmcPmacroZctrl, 64, 27:0, 27:0) \
|
||||
HANDLER(EmcTppd, 64, 3:0, 31:28) \
|
||||
HANDLER(EmcCfgDigDll, 65, 10:0, 10:0) \
|
||||
HANDLER(EmcCfgDigDll, 65, 25:12, 24:11) \
|
||||
HANDLER(EmcCfgDigDll, 65, 27:27, 25:25) \
|
||||
HANDLER(EmcCfgDigDll, 65, 31:30, 27:26) \
|
||||
HANDLER(EmcR2r, 65, 3:0, 31:28) \
|
||||
HANDLER(EmcFdpdCtrlDq, 66, 16:0, 16:0) \
|
||||
HANDLER(EmcFdpdCtrlDq, 66, 28:20, 25:17) \
|
||||
HANDLER(EmcFdpdCtrlDq, 66, 31:30, 27:26) \
|
||||
HANDLER(EmcW2w, 66, 3:0, 31:28) \
|
||||
HANDLER(EmcPmacroTxPwrd4, 67, 13:0, 13:0) \
|
||||
HANDLER(EmcPmacroTxPwrd4, 67, 29:16, 27:14) \
|
||||
HANDLER(EmcPmacroCommonPadTxCtrl, 67, 3:0, 31:28) \
|
||||
HANDLER(EmcPmacroTxPwrd5, 68, 13:0, 13:0) \
|
||||
HANDLER(EmcPmacroTxPwrd5, 68, 29:16, 27:14) \
|
||||
HANDLER(EmcPmacroDdllPwrd0, 69, 4:0, 4:0) \
|
||||
HANDLER(EmcPmacroDdllPwrd0, 69, 12:6, 11:5) \
|
||||
HANDLER(EmcPmacroDdllPwrd0, 69, 20:14, 18:12) \
|
||||
HANDLER(EmcPmacroDdllPwrd0, 69, 28:22, 25:19) \
|
||||
HANDLER(EmcPmacroDdllPwrd0, 69, 31:30, 27:26) \
|
||||
HANDLER(EmcCfg, 69, 4:4, 31:31) \
|
||||
HANDLER(EmcPmacroDdllPwrd1, 70, 4:0, 4:0) \
|
||||
HANDLER(EmcPmacroDdllPwrd1, 70, 12:6, 11:5) \
|
||||
HANDLER(EmcPmacroDdllPwrd1, 70, 20:14, 18:12) \
|
||||
HANDLER(EmcPmacroDdllPwrd1, 70, 28:22, 25:19) \
|
||||
HANDLER(EmcPmacroDdllPwrd1, 70, 31:30, 27:26) \
|
||||
HANDLER(EmcCfg, 70, 5:5, 31:31) \
|
||||
HANDLER(EmcPmacroDdllPwrd2, 71, 4:0, 4:0) \
|
||||
HANDLER(EmcPmacroDdllPwrd2, 71, 12:6, 11:5) \
|
||||
HANDLER(EmcPmacroDdllPwrd2, 71, 20:14, 18:12) \
|
||||
HANDLER(EmcPmacroDdllPwrd2, 71, 28:22, 25:19) \
|
||||
HANDLER(EmcPmacroDdllPwrd2, 71, 31:30, 27:26) \
|
||||
HANDLER(EmcFbioCfg5, 71, 23:20, 31:28) \
|
||||
HANDLER(EmcPmacroIbVrefDq_0, 72, 6:0, 6:0) \
|
||||
HANDLER(EmcPmacroIbVrefDq_0, 72, 14:8, 13:7) \
|
||||
HANDLER(EmcPmacroIbVrefDq_0, 72, 22:16, 20:14) \
|
||||
HANDLER(EmcPmacroIbVrefDq_0, 72, 30:24, 27:21) \
|
||||
HANDLER(EmcFbioCfg5, 72, 15:13, 30:28) \
|
||||
HANDLER(EmcCfg, 72, 6:6, 31:31) \
|
||||
HANDLER(EmcPmacroIbVrefDq_1, 73, 6:0, 6:0) \
|
||||
HANDLER(EmcPmacroIbVrefDq_1, 73, 14:8, 13:7) \
|
||||
HANDLER(EmcPmacroIbVrefDq_1, 73, 22:16, 20:14) \
|
||||
HANDLER(EmcPmacroIbVrefDq_1, 73, 30:24, 27:21) \
|
||||
HANDLER(EmcCfg2, 73, 5:3, 30:28) \
|
||||
HANDLER(EmcCfg, 73, 7:7, 31:31) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_0, 74, 6:0, 6:0) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_0, 74, 14:8, 13:7) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_0, 74, 22:16, 20:14) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_0, 74, 30:24, 27:21) \
|
||||
HANDLER(EmcCfg, 74, 17:16, 29:28) \
|
||||
HANDLER(EmcFbioCfg5, 74, 1:0, 31:30) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_1, 75, 6:0, 6:0) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_1, 75, 14:8, 13:7) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_1, 75, 22:16, 20:14) \
|
||||
HANDLER(EmcPmacroIbVrefDqs_1, 75, 30:24, 27:21) \
|
||||
HANDLER(EmcFbioCfg5, 75, 3:2, 29:28) \
|
||||
HANDLER(EmcCfg2, 75, 27:26, 31:30) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_0, 76, 6:0, 6:0) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_0, 76, 14:8, 13:7) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_0, 76, 22:16, 20:14) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_0, 76, 30:24, 27:21) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 76, 3:2, 29:28) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 76, 7:6, 31:30) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_1, 77, 6:0, 6:0) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_1, 77, 14:8, 13:7) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_1, 77, 22:16, 20:14) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_1, 77, 30:24, 27:21) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 77, 11:10, 29:28) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 77, 15:14, 31:30) \
|
||||
HANDLER(EmcAutoCalChannel, 78, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalChannel, 78, 11:8, 9:6) \
|
||||
HANDLER(EmcAutoCalChannel, 78, 27:16, 21:10) \
|
||||
HANDLER(EmcAutoCalChannel, 78, 31:29, 24:22) \
|
||||
HANDLER(EmcConfigSampleDelay, 78, 6:0, 31:25) \
|
||||
HANDLER(EmcPmacroRxTerm, 79, 5:0, 5:0) \
|
||||
HANDLER(EmcPmacroRxTerm, 79, 13:8, 11:6) \
|
||||
HANDLER(EmcPmacroRxTerm, 79, 21:16, 17:12) \
|
||||
HANDLER(EmcPmacroRxTerm, 79, 29:24, 23:18) \
|
||||
HANDLER(EmcRc, 79, 7:0, 31:24) \
|
||||
HANDLER(EmcPmacroDqTxDrv, 80, 5:0, 5:0) \
|
||||
HANDLER(EmcPmacroDqTxDrv, 80, 13:8, 11:6) \
|
||||
HANDLER(EmcPmacroDqTxDrv, 80, 21:16, 17:12) \
|
||||
HANDLER(EmcPmacroDqTxDrv, 80, 29:24, 23:18) \
|
||||
HANDLER(EmcSelDpdCtrl, 80, 5:2, 27:24) \
|
||||
HANDLER(EmcSelDpdCtrl, 80, 8:8, 28:28) \
|
||||
HANDLER(EmcSelDpdCtrl, 80, 18:16, 31:29) \
|
||||
HANDLER(EmcPmacroCaTxDrv, 81, 5:0, 5:0) \
|
||||
HANDLER(EmcPmacroCaTxDrv, 81, 13:8, 11:6) \
|
||||
HANDLER(EmcPmacroCaTxDrv, 81, 21:16, 17:12) \
|
||||
HANDLER(EmcPmacroCaTxDrv, 81, 29:24, 23:18) \
|
||||
HANDLER(EmcObdly, 81, 5:0, 29:24) \
|
||||
HANDLER(EmcObdly, 81, 29:28, 31:30) \
|
||||
HANDLER(EmcZcalInterval, 82, 23:10, 13:0) \
|
||||
HANDLER(EmcZcalInterval, 82, 9:0, 23:14) \
|
||||
HANDLER(EmcPmacroCmdRxTermMode, 82, 1:0, 25:24) \
|
||||
HANDLER(EmcPmacroCmdRxTermMode, 82, 5:4, 27:26) \
|
||||
HANDLER(EmcPmacroCmdRxTermMode, 82, 9:8, 29:28) \
|
||||
HANDLER(EmcPmacroCmdRxTermMode, 82, 13:12, 31:30) \
|
||||
HANDLER(EmcDataBrlshft0, 83, 23:0, 23:0) \
|
||||
HANDLER(EmcPmacroDataRxTermMode, 83, 1:0, 25:24) \
|
||||
HANDLER(EmcPmacroDataRxTermMode, 83, 5:4, 27:26) \
|
||||
HANDLER(EmcPmacroDataRxTermMode, 83, 9:8, 29:28) \
|
||||
HANDLER(EmcPmacroDataRxTermMode, 83, 13:12, 31:30) \
|
||||
HANDLER(EmcDataBrlshft1, 84, 23:0, 23:0) \
|
||||
HANDLER(McEmemArbTimingRc, 84, 7:0, 31:24) \
|
||||
HANDLER(EmcDqsBrlshft0, 85, 23:0, 23:0) \
|
||||
HANDLER(McEmemArbRsv, 85, 7:0, 31:24) \
|
||||
HANDLER(EmcDqsBrlshft1, 86, 23:0, 23:0) \
|
||||
HANDLER(EmcCfgPipe2, 87, 11:0, 11:0) \
|
||||
HANDLER(EmcCfgPipe2, 87, 27:16, 23:12) \
|
||||
HANDLER(EmcCfgPipe1, 88, 11:0, 11:0) \
|
||||
HANDLER(EmcCfgPipe1, 88, 27:16, 23:12) \
|
||||
HANDLER(EmcPmacroCmdCtrl0, 89, 5:0, 5:0) \
|
||||
HANDLER(EmcPmacroCmdCtrl0, 89, 13:8, 11:6) \
|
||||
HANDLER(EmcPmacroCmdCtrl0, 89, 21:16, 17:12) \
|
||||
HANDLER(EmcPmacroCmdCtrl0, 89, 29:24, 23:18) \
|
||||
HANDLER(EmcPmacroCmdCtrl1, 90, 5:0, 5:0) \
|
||||
HANDLER(EmcPmacroCmdCtrl1, 90, 13:8, 11:6) \
|
||||
HANDLER(EmcPmacroCmdCtrl1, 90, 21:16, 17:12) \
|
||||
HANDLER(EmcPmacroCmdCtrl1, 90, 29:24, 23:18) \
|
||||
HANDLER(EmcRas, 90, 6:0, 30:24) \
|
||||
HANDLER(EmcCfg, 90, 8:8, 31:31) \
|
||||
HANDLER(EmcPmacroVttgenCtrl2, 91, 23:0, 23:0) \
|
||||
HANDLER(EmcW2p, 91, 6:0, 30:24) \
|
||||
HANDLER(EmcCfg, 91, 9:9, 31:31) \
|
||||
HANDLER(EmcPmacroCmdPadRxCtrl, 92, 2:0, 2:0) \
|
||||
HANDLER(EmcPmacroCmdPadRxCtrl, 92, 5:4, 4:3) \
|
||||
HANDLER(EmcPmacroCmdPadRxCtrl, 92, 10:8, 7:5) \
|
||||
HANDLER(EmcPmacroCmdPadRxCtrl, 92, 22:12, 18:8) \
|
||||
HANDLER(EmcPmacroCmdPadRxCtrl, 92, 28:24, 23:19) \
|
||||
HANDLER(EmcQSafe, 92, 6:0, 30:24) \
|
||||
HANDLER(EmcCfg, 92, 18:18, 31:31) \
|
||||
HANDLER(EmcPmacroDataPadRxCtrl, 93, 2:0, 2:0) \
|
||||
HANDLER(EmcPmacroDataPadRxCtrl, 93, 5:4, 4:3) \
|
||||
HANDLER(EmcPmacroDataPadRxCtrl, 93, 10:8, 7:5) \
|
||||
HANDLER(EmcPmacroDataPadRxCtrl, 93, 22:12, 18:8) \
|
||||
HANDLER(EmcPmacroDataPadRxCtrl, 93, 28:24, 23:19) \
|
||||
HANDLER(EmcRdv, 93, 6:0, 30:24) \
|
||||
HANDLER(EmcCfg, 93, 21:21, 31:31) \
|
||||
HANDLER(McEmemArbDaCovers, 94, 23:0, 23:0) \
|
||||
HANDLER(EmcRw2Pden, 94, 6:0, 30:24) \
|
||||
HANDLER(EmcCfg, 94, 22:22, 31:31) \
|
||||
HANDLER(EmcPmacroCmdCtrl2, 95, 5:0, 5:0) \
|
||||
HANDLER(EmcPmacroCmdCtrl2, 95, 13:9, 10:6) \
|
||||
HANDLER(EmcPmacroCmdCtrl2, 95, 21:16, 16:11) \
|
||||
HANDLER(EmcPmacroCmdCtrl2, 95, 29:24, 22:17) \
|
||||
HANDLER(EmcRfcPb, 95, 8:0, 31:23) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_0, 96, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_0, 96, 26:16, 21:11) \
|
||||
HANDLER(EmcCfgUpdate, 96, 2:0, 24:22) \
|
||||
HANDLER(EmcCfgUpdate, 96, 10:8, 27:25) \
|
||||
HANDLER(EmcCfgUpdate, 96, 31:28, 31:28) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_1, 97, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_1, 97, 26:16, 21:11) \
|
||||
HANDLER(EmcRfc, 97, 9:0, 31:22) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_2, 98, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_2, 98, 26:16, 21:11) \
|
||||
HANDLER(EmcTxsr, 98, 9:0, 31:22) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_3, 99, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_3, 99, 26:16, 21:11) \
|
||||
HANDLER(EmcMc2EmcQ, 99, 2:0, 24:22) \
|
||||
HANDLER(EmcMc2EmcQ, 99, 10:8, 27:25) \
|
||||
HANDLER(EmcMc2EmcQ, 99, 27:24, 31:28) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_4, 100, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_4, 100, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbRing1Throttle, 100, 4:0, 26:22) \
|
||||
HANDLER(McEmemArbRing1Throttle, 100, 20:16, 31:27) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_5, 101, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank0_5, 101, 26:16, 21:11) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_0, 102, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_0, 102, 26:16, 21:11) \
|
||||
HANDLER(EmcAr2Pden, 102, 8:0, 30:22) \
|
||||
HANDLER(EmcCfg, 102, 23:23, 31:31) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_1, 103, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_1, 103, 26:16, 21:11) \
|
||||
HANDLER(EmcRfcSlr, 103, 8:0, 30:22) \
|
||||
HANDLER(EmcCfg, 103, 24:24, 31:31) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_2, 104, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_2, 104, 26:16, 21:11) \
|
||||
HANDLER(EmcIbdly, 104, 6:0, 28:22) \
|
||||
HANDLER(EmcIbdly, 104, 29:28, 30:29) \
|
||||
HANDLER(EmcCfg, 104, 25:25, 31:31) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_3, 105, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_3, 105, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingRFCPB, 105, 8:0, 30:22) \
|
||||
HANDLER(EmcCfg, 105, 26:26, 31:31) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_4, 106, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_4, 106, 26:16, 21:11) \
|
||||
HANDLER(EmcTfaw, 106, 6:0, 28:22) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 106, 3:2, 30:29) \
|
||||
HANDLER(EmcCfg, 106, 28:28, 31:31) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_5, 107, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroQuseDdllRank1_5, 107, 26:16, 21:11) \
|
||||
HANDLER(EmcTClkStable, 107, 6:0, 28:22) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 107, 7:6, 30:29) \
|
||||
HANDLER(EmcCfg, 107, 29:29, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_0, 108, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_0, 108, 26:16, 21:11) \
|
||||
HANDLER(EmcPdex2Mrr, 108, 6:0, 28:22) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 108, 11:10, 30:29) \
|
||||
HANDLER(EmcCfg, 108, 30:30, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_1, 109, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_1, 109, 26:16, 21:11) \
|
||||
HANDLER(EmcRdvMask, 109, 6:0, 28:22) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 109, 15:14, 30:29) \
|
||||
HANDLER(EmcCfg, 109, 31:31, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_2, 110, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_2, 110, 26:16, 21:11) \
|
||||
HANDLER(EmcRdvEarlyMask, 110, 6:0, 28:22) \
|
||||
HANDLER(EmcFbioCfg5, 110, 4:4, 29:29) \
|
||||
HANDLER(EmcFbioCfg5, 110, 8:8, 30:30) \
|
||||
HANDLER(EmcFbioCfg5, 110, 10:10, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_3, 111, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_3, 111, 26:16, 21:11) \
|
||||
HANDLER(EmcRdvEarly, 111, 6:0, 28:22) \
|
||||
HANDLER(EmcFbioCfg5, 111, 12:12, 29:29) \
|
||||
HANDLER(EmcFbioCfg5, 111, 25:24, 31:30) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_4, 112, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_4, 112, 26:16, 21:11) \
|
||||
HANDLER(EmcPmacroDdllShortCmd_2, 112, 6:0, 28:22) \
|
||||
HANDLER(EmcFbioCfg5, 112, 28:26, 31:29) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_5, 113, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank0_5, 113, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingRp, 113, 6:0, 28:22) \
|
||||
HANDLER(EmcFbioCfg5, 113, 31:30, 30:29) \
|
||||
HANDLER(EmcCfg2, 113, 0:0, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_0, 114, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_0, 114, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingRas, 114, 6:0, 28:22) \
|
||||
HANDLER(EmcCfg2, 114, 2:1, 30:29) \
|
||||
HANDLER(EmcCfg2, 114, 7:7, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_1, 115, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_1, 115, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingFaw, 115, 6:0, 28:22) \
|
||||
HANDLER(EmcCfg2, 115, 11:10, 30:29) \
|
||||
HANDLER(EmcCfg2, 115, 14:14, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_2, 123, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_2, 123, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingRap2Pre, 123, 6:0, 28:22) \
|
||||
HANDLER(EmcCfg2, 123, 16:15, 30:29) \
|
||||
HANDLER(EmcCfg2, 123, 20:20, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_3, 124, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_3, 124, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingWap2Pre, 124, 6:0, 28:22) \
|
||||
HANDLER(EmcCfg2, 124, 24:22, 31:29) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_4, 125, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_4, 125, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingR2W, 125, 6:0, 28:22) \
|
||||
HANDLER(EmcCfg2, 125, 25:25, 29:29) \
|
||||
HANDLER(EmcCfg2, 125, 29:28, 31:30) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_5, 126, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqRank1_5, 126, 26:16, 21:11) \
|
||||
HANDLER(McEmemArbTimingW2R, 126, 6:0, 28:22) \
|
||||
HANDLER(EmcCfg2, 126, 31:30, 30:29) \
|
||||
HANDLER(EmcCfgPipe, 126, 0:0, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_0, 127, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_0, 127, 26:16, 21:11) \
|
||||
HANDLER(EmcRp, 127, 5:0, 27:22) \
|
||||
HANDLER(EmcCfgPipe, 127, 4:1, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_1, 128, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_1, 128, 26:16, 21:11) \
|
||||
HANDLER(EmcR2w, 128, 5:0, 27:22) \
|
||||
HANDLER(EmcCfgPipe, 128, 8:5, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_2, 129, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_2, 129, 26:16, 21:11) \
|
||||
HANDLER(EmcW2r, 129, 5:0, 27:22) \
|
||||
HANDLER(EmcCfgPipe, 129, 11:9, 30:28) \
|
||||
HANDLER(EmcCfgPipe, 129, 16:16, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_3, 130, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_3, 130, 26:16, 21:11) \
|
||||
HANDLER(EmcR2p, 130, 5:0, 27:22) \
|
||||
HANDLER(EmcCfgPipe, 130, 20:17, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_4, 131, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_4, 131, 26:16, 21:11) \
|
||||
HANDLER(EmcCcdmw, 131, 5:0, 27:22) \
|
||||
HANDLER(EmcCfgPipe, 131, 24:21, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_5, 132, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank0_5, 132, 26:16, 21:11) \
|
||||
HANDLER(EmcRdRcd, 132, 5:0, 27:22) \
|
||||
HANDLER(EmcCfgPipe, 132, 27:25, 30:28) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 132, 0:0, 31:31) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_0, 133, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_0, 133, 26:16, 21:11) \
|
||||
HANDLER(EmcWrRcd, 133, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 133, 4:1, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_1, 134, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_1, 134, 26:16, 21:11) \
|
||||
HANDLER(EmcWdv, 134, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 134, 8:5, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_2, 135, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_2, 135, 26:16, 21:11) \
|
||||
HANDLER(EmcQUse, 135, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 135, 12:9, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_3, 136, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_3, 136, 26:16, 21:11) \
|
||||
HANDLER(EmcPdEx2Wr, 136, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 136, 13:13, 28:28) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 136, 18:16, 31:29) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_4, 137, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_4, 137, 26:16, 21:11) \
|
||||
HANDLER(EmcPdEx2Rd, 137, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 137, 22:19, 31:28) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_5, 138, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroObDdllLongDqsRank1_5, 138, 26:16, 21:11) \
|
||||
HANDLER(EmcPdex2Cke, 138, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 138, 26:23, 31:28) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_0, 139, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_0, 139, 26:16, 21:11) \
|
||||
HANDLER(EmcPChg2Pden, 139, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd0, 139, 29:27, 30:28) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 139, 0:0, 31:31) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_1, 140, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_1, 140, 26:16, 21:11) \
|
||||
HANDLER(EmcAct2Pden, 140, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 140, 4:1, 31:28) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_2, 141, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_2, 141, 26:16, 21:11) \
|
||||
HANDLER(EmcCke2Pden, 141, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 141, 8:5, 31:28) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_3, 142, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank0_3, 142, 26:16, 21:11) \
|
||||
HANDLER(EmcTcke, 142, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 142, 12:9, 31:28) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_0, 143, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_0, 143, 26:16, 21:11) \
|
||||
HANDLER(EmcTrpab, 143, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 143, 13:13, 28:28) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 143, 18:16, 31:29) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_1, 144, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_1, 144, 26:16, 21:11) \
|
||||
HANDLER(EmcClkenOverride, 144, 3:1, 24:22) \
|
||||
HANDLER(EmcClkenOverride, 144, 8:6, 27:25) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 144, 22:19, 31:28) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_2, 145, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_2, 145, 26:16, 21:11) \
|
||||
HANDLER(EmcEInput, 145, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 145, 26:23, 31:28) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_3, 146, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroIbDdllLongDqsRank1_3, 146, 26:16, 21:11) \
|
||||
HANDLER(EmcEInputDuration, 146, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd1, 146, 29:27, 30:28) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 146, 0:0, 31:31) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_0, 147, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_0, 147, 26:16, 21:11) \
|
||||
HANDLER(EmcPutermExtra, 147, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 147, 4:1, 31:28) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_1, 148, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_1, 148, 26:16, 21:11) \
|
||||
HANDLER(EmcTckesr, 148, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 148, 8:5, 31:28) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_2, 149, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_2, 149, 26:16, 21:11) \
|
||||
HANDLER(EmcTpd, 149, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 149, 12:9, 31:28) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_3, 150, 10:0, 10:0) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_3, 150, 26:16, 21:11) \
|
||||
HANDLER(EmcWdvMask, 150, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 150, 13:13, 28:28) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 150, 18:16, 31:29) \
|
||||
HANDLER(McEmemArbCfg, 151, 8:0, 8:0) \
|
||||
HANDLER(McEmemArbCfg, 151, 20:16, 13:9) \
|
||||
HANDLER(McEmemArbCfg, 151, 31:24, 21:14) \
|
||||
HANDLER(EmcWdvChk, 151, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 151, 22:19, 31:28) \
|
||||
HANDLER(McEmemArbMisc1, 152, 12:0, 12:0) \
|
||||
HANDLER(McEmemArbMisc1, 152, 25:21, 17:13) \
|
||||
HANDLER(McEmemArbMisc1, 152, 31:28, 21:18) \
|
||||
HANDLER(EmcCmdBrlshft0, 152, 5:0, 27:22) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 152, 26:23, 31:28) \
|
||||
HANDLER(EmcMrsWaitCnt2, 153, 9:0, 9:0) \
|
||||
HANDLER(EmcMrsWaitCnt2, 153, 26:16, 20:10) \
|
||||
HANDLER(EmcPmacroIbRxrt, 153, 10:0, 31:21) \
|
||||
HANDLER(EmcMrsWaitCnt, 154, 9:0, 9:0) \
|
||||
HANDLER(EmcMrsWaitCnt, 154, 26:16, 20:10) \
|
||||
HANDLER(EmcPmacroDdllLongCmd_4, 154, 10:0, 31:21) \
|
||||
HANDLER(EmcAutoCalInterval, 155, 20:0, 20:0) \
|
||||
HANDLER(McEmemArbOutstandingReq, 155, 8:0, 29:21) \
|
||||
HANDLER(McEmemArbOutstandingReq, 155, 31:30, 31:30) \
|
||||
HANDLER(McEmemArbRefpbHpCtrl, 156, 6:0, 6:0) \
|
||||
HANDLER(McEmemArbRefpbHpCtrl, 156, 14:8, 13:7) \
|
||||
HANDLER(McEmemArbRefpbHpCtrl, 156, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdBrlshft1, 156, 5:0, 26:21) \
|
||||
HANDLER(EmcRrd, 156, 4:0, 31:27) \
|
||||
HANDLER(EmcQuseBrlshft0, 157, 19:0, 19:0) \
|
||||
HANDLER(EmcFbioCfg8, 157, 27:16, 31:20) \
|
||||
HANDLER(EmcQuseBrlshft1, 158, 19:0, 19:0) \
|
||||
HANDLER(EmcTxsrDll, 158, 11:0, 31:20) \
|
||||
HANDLER(EmcQuseBrlshft2, 159, 19:0, 19:0) \
|
||||
HANDLER(EmcTxdsrvttgen, 159, 11:0, 31:20) \
|
||||
HANDLER(EmcQuseBrlshft3, 160, 19:0, 19:0) \
|
||||
HANDLER(EmcPmacroVttgenCtrl0, 160, 3:0, 23:20) \
|
||||
HANDLER(EmcPmacroVttgenCtrl0, 160, 11:8, 27:24) \
|
||||
HANDLER(EmcPmacroVttgenCtrl0, 160, 19:16, 31:28) \
|
||||
HANDLER(EmcPmacroVttgenCtrl1, 161, 19:0, 19:0) \
|
||||
HANDLER(EmcCmdBrlshft2, 161, 5:0, 25:20) \
|
||||
HANDLER(EmcCmdBrlshft3, 161, 5:0, 31:26) \
|
||||
HANDLER(EmcAutoCalConfig3, 162, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalConfig3, 162, 13:8, 11:6) \
|
||||
HANDLER(EmcAutoCalConfig3, 162, 18:16, 14:12) \
|
||||
HANDLER(EmcAutoCalConfig3, 162, 22:20, 17:15) \
|
||||
HANDLER(EmcTRefBw, 162, 13:0, 31:18) \
|
||||
HANDLER(EmcAutoCalConfig4, 163, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalConfig4, 163, 13:8, 11:6) \
|
||||
HANDLER(EmcAutoCalConfig4, 163, 18:16, 14:12) \
|
||||
HANDLER(EmcAutoCalConfig4, 163, 22:20, 17:15) \
|
||||
HANDLER(EmcQpop, 163, 6:0, 24:18) \
|
||||
HANDLER(EmcQpop, 163, 22:16, 31:25) \
|
||||
HANDLER(EmcAutoCalConfig5, 164, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalConfig5, 164, 13:8, 11:6) \
|
||||
HANDLER(EmcAutoCalConfig5, 164, 18:16, 14:12) \
|
||||
HANDLER(EmcAutoCalConfig5, 164, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroAutocalCfgCommon, 164, 5:0, 23:18) \
|
||||
HANDLER(EmcPmacroAutocalCfgCommon, 164, 13:8, 29:24) \
|
||||
HANDLER(EmcPmacroAutocalCfgCommon, 164, 16:16, 30:30) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 164, 27:27, 31:31) \
|
||||
HANDLER(EmcAutoCalConfig6, 165, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalConfig6, 165, 13:8, 11:6) \
|
||||
HANDLER(EmcAutoCalConfig6, 165, 18:16, 14:12) \
|
||||
HANDLER(EmcAutoCalConfig6, 165, 22:20, 17:15) \
|
||||
HANDLER(EmcWev, 165, 5:0, 23:18) \
|
||||
HANDLER(EmcWsv, 165, 5:0, 29:24) \
|
||||
HANDLER(EmcPmacroTxPwrd2, 165, 29:28, 31:30) \
|
||||
HANDLER(EmcAutoCalConfig7, 166, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalConfig7, 166, 13:8, 11:6) \
|
||||
HANDLER(EmcAutoCalConfig7, 166, 18:16, 14:12) \
|
||||
HANDLER(EmcAutoCalConfig7, 166, 22:20, 17:15) \
|
||||
HANDLER(EmcCfg3, 166, 2:0, 20:18) \
|
||||
HANDLER(EmcCfg3, 166, 6:4, 23:21) \
|
||||
HANDLER(EmcQuseWidth, 166, 3:0, 27:24) \
|
||||
HANDLER(EmcQuseWidth, 166, 29:28, 29:28) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 166, 1:0, 31:30) \
|
||||
HANDLER(EmcAutoCalConfig8, 167, 5:0, 5:0) \
|
||||
HANDLER(EmcAutoCalConfig8, 167, 13:8, 11:6) \
|
||||
HANDLER(EmcAutoCalConfig8, 167, 18:16, 14:12) \
|
||||
HANDLER(EmcAutoCalConfig8, 167, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroBgBiasCtrl0, 167, 2:0, 20:18) \
|
||||
HANDLER(EmcPmacroBgBiasCtrl0, 167, 6:4, 23:21) \
|
||||
HANDLER(McEmemArbTimingRcd, 167, 5:0, 29:24) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 167, 3:2, 31:30) \
|
||||
HANDLER(EmcXm2CompPadCtrl2, 168, 17:0, 17:0) \
|
||||
HANDLER(McEmemArbTimingCcdmw, 168, 5:0, 23:18) \
|
||||
HANDLER(McEmemArbOverride, 168, 27:27, 24:24) \
|
||||
HANDLER(McEmemArbOverride, 168, 26:26, 25:25) \
|
||||
HANDLER(McEmemArbOverride, 168, 16:16, 26:26) \
|
||||
HANDLER(McEmemArbOverride, 168, 10:10, 27:27) \
|
||||
HANDLER(McEmemArbOverride, 168, 4:4, 28:28) \
|
||||
HANDLER(McEmemArbOverride, 168, 3:3, 29:29) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 168, 5:4, 31:30) \
|
||||
HANDLER(EmcXm2CompPadCtrl3, 169, 17:0, 17:0) \
|
||||
HANDLER(EmcRext, 169, 4:0, 22:18) \
|
||||
HANDLER(EmcTClkStop, 169, 4:0, 27:23) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 169, 9:6, 31:28) \
|
||||
HANDLER(EmcZcalWaitCnt, 170, 10:0, 10:0) \
|
||||
HANDLER(EmcZcalWaitCnt, 170, 21:16, 16:11) \
|
||||
HANDLER(EmcZcalWaitCnt, 170, 31:31, 17:17) \
|
||||
HANDLER(EmcWext, 170, 4:0, 22:18) \
|
||||
HANDLER(EmcRefctrl2, 170, 0:0, 23:23) \
|
||||
HANDLER(EmcRefctrl2, 170, 26:24, 26:24) \
|
||||
HANDLER(EmcRefctrl2, 170, 31:31, 27:27) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 170, 13:10, 31:28) \
|
||||
HANDLER(EmcZcalMrwCmd, 171, 7:0, 7:0) \
|
||||
HANDLER(EmcZcalMrwCmd, 171, 23:16, 15:8) \
|
||||
HANDLER(EmcZcalMrwCmd, 171, 31:30, 17:16) \
|
||||
HANDLER(EmcWeDuration, 171, 4:0, 22:18) \
|
||||
HANDLER(EmcWsDuration, 171, 4:0, 27:23) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 171, 19:16, 31:28) \
|
||||
HANDLER(EmcSwizzleRank0Byte0, 172, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank0Byte0, 172, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank0Byte0, 172, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank0Byte0, 172, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank0Byte0, 172, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank0Byte0, 172, 22:20, 17:15) \
|
||||
HANDLER(EmcPutermWidth, 172, 31:31, 18:18) \
|
||||
HANDLER(EmcPutermWidth, 172, 3:0, 22:19) \
|
||||
HANDLER(McEmemArbTimingRrd, 172, 4:0, 27:23) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 172, 23:20, 31:28) \
|
||||
HANDLER(EmcSwizzleRank0Byte1, 173, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank0Byte1, 173, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank0Byte1, 173, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank0Byte1, 173, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank0Byte1, 173, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank0Byte1, 173, 22:20, 17:15) \
|
||||
HANDLER(McEmemArbTimingR2R, 173, 4:0, 22:18) \
|
||||
HANDLER(McEmemArbTimingW2W, 173, 4:0, 27:23) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 173, 27:24, 31:28) \
|
||||
HANDLER(EmcSwizzleRank0Byte2, 174, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank0Byte2, 174, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank0Byte2, 174, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank0Byte2, 174, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank0Byte2, 174, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank0Byte2, 174, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroTxPwrd3, 174, 29:28, 19:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc0, 174, 11:0, 31:20) \
|
||||
HANDLER(EmcSwizzleRank0Byte3, 175, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank0Byte3, 175, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank0Byte3, 175, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank0Byte3, 175, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank0Byte3, 175, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank0Byte3, 175, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc0, 175, 27:16, 29:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc1, 175, 1:0, 31:30) \
|
||||
HANDLER(EmcSwizzleRank1Byte0, 176, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank1Byte0, 176, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank1Byte0, 176, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank1Byte0, 176, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank1Byte0, 176, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank1Byte0, 176, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc1, 176, 11:2, 27:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc1, 176, 19:16, 31:28) \
|
||||
HANDLER(EmcSwizzleRank1Byte1, 177, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank1Byte1, 177, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank1Byte1, 177, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank1Byte1, 177, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank1Byte1, 177, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank1Byte1, 177, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc1, 177, 27:20, 25:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc3, 177, 5:0, 31:26) \
|
||||
HANDLER(EmcSwizzleRank1Byte2, 178, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank1Byte2, 178, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank1Byte2, 178, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank1Byte2, 178, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank1Byte2, 178, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank1Byte2, 178, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc3, 178, 11:6, 23:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc3, 178, 23:16, 31:24) \
|
||||
HANDLER(EmcSwizzleRank1Byte3, 179, 2:0, 2:0) \
|
||||
HANDLER(EmcSwizzleRank1Byte3, 179, 6:4, 5:3) \
|
||||
HANDLER(EmcSwizzleRank1Byte3, 179, 10:8, 8:6) \
|
||||
HANDLER(EmcSwizzleRank1Byte3, 179, 14:12, 11:9) \
|
||||
HANDLER(EmcSwizzleRank1Byte3, 179, 18:16, 14:12) \
|
||||
HANDLER(EmcSwizzleRank1Byte3, 179, 22:20, 17:15) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc3, 179, 27:24, 21:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc2, 179, 9:0, 31:22) \
|
||||
HANDLER(EmcPmacroCmdBrickCtrlFdpd, 180, 17:0, 17:0) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc2, 180, 11:10, 19:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc2, 180, 27:16, 31:20) \
|
||||
HANDLER(EmcPmacroDataBrickCtrlFdpd, 181, 17:0, 17:0) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc4, 181, 11:0, 29:18) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc4, 181, 17:16, 31:30) \
|
||||
HANDLER(EmcFbioCfg7, 182, 16:0, 16:0) \
|
||||
HANDLER(McEmemArbRefpbBankCtrl, 182, 6:0, 23:17) \
|
||||
HANDLER(McEmemArbRefpbBankCtrl, 182, 14:8, 30:24) \
|
||||
HANDLER(McEmemArbRefpbBankCtrl, 182, 31:31, 31:31) \
|
||||
HANDLER(EmcDynSelfRefControl, 183, 15:0, 15:0) \
|
||||
HANDLER(EmcDynSelfRefControl, 183, 31:31, 16:16) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc4, 183, 27:18, 26:17) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc5, 183, 4:0, 31:27) \
|
||||
HANDLER(EmcDllCfg1, 184, 16:0, 16:0) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc5, 184, 11:5, 23:17) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc5, 184, 23:16, 31:24) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 1:0, 1:0) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 6:5, 3:2) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 11:9, 6:4) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 13:13, 7:7) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 17:16, 9:8) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 21:20, 11:10) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 25:24, 13:12) \
|
||||
HANDLER(EmcPmacroPadCfgCtrl, 185, 30:28, 16:14) \
|
||||
HANDLER(EmcPmacroTxSelClkSrc5, 185, 27:24, 20:17) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 185, 1:0, 22:21) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 185, 5:4, 24:23) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 185, 9:8, 26:25) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 185, 13:12, 28:27) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 185, 16:16, 29:29) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 185, 21:20, 31:30) \
|
||||
HANDLER(EmcRefresh, 186, 15:0, 15:0) \
|
||||
HANDLER(EmcCmdQ, 186, 4:0, 20:16) \
|
||||
HANDLER(EmcCmdQ, 186, 10:8, 23:21) \
|
||||
HANDLER(EmcCmdQ, 186, 14:12, 26:24) \
|
||||
HANDLER(EmcCmdQ, 186, 28:24, 31:27) \
|
||||
HANDLER(EmcAcpdControl, 187, 15:0, 15:0) \
|
||||
HANDLER(EmcAutoCalVrefSel1, 187, 15:0, 31:16) \
|
||||
HANDLER(EmcXm2CompPadCtrl, 188, 1:0, 1:0) \
|
||||
HANDLER(EmcXm2CompPadCtrl, 188, 6:3, 5:2) \
|
||||
HANDLER(EmcXm2CompPadCtrl, 188, 9:9, 6:6) \
|
||||
HANDLER(EmcXm2CompPadCtrl, 188, 19:11, 15:7) \
|
||||
HANDLER(EmcCfgDigDllPeriod, 188, 15:0, 31:16) \
|
||||
HANDLER(EmcCfgDigDll_1, 189, 15:0, 15:0) \
|
||||
HANDLER(EmcPreRefreshReqCnt, 189, 15:0, 31:16) \
|
||||
HANDLER(EmcPmacroCmdPadTxCtrl, 190, 27:24, 19:16) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 1:0, 21:20) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 5:4, 23:22) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 9:8, 25:24) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 13:12, 27:26) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 16:16, 28:28) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 21:20, 30:29) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 190, 24:24, 31:31) \
|
||||
HANDLER(EmcPmacroDataPadTxCtrl, 191, 27:25, 2:0) \
|
||||
HANDLER(EmcPinGpio, 8, 1:0, 31:30) \
|
||||
HANDLER(EmcPinGpioEn, 9, 1:0, 31:30) \
|
||||
HANDLER(EmcDevSelect, 10, 1:0, 31:30) \
|
||||
HANDLER(EmcZcalWarmColdBootEnables, 11, 1:0, 31:30) \
|
||||
HANDLER(EmcCfgDigDllPeriodWarmBoot, 12, 1:0, 31:30) \
|
||||
HANDLER(EmcBctSpare13, 31, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare12, 32, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare7, 33, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare6, 40, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare5, 42, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare4, 44, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare3, 45, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare2, 46, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare1, 47, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare0, 48, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare9, 50, 31:0, 31:0) \
|
||||
HANDLER(EmcBctSpare8, 51, 31:0, 31:0) \
|
||||
HANDLER(BootRomPatchData, 56, 31:0, 31:0) \
|
||||
HANDLER(BootRomPatchControl, 57, 31:0, 31:0) \
|
||||
HANDLER(McClkenOverrideAllWarmBoot, 58, 0:0, 31:31) \
|
||||
HANDLER(EmcClkenOverrideAllWarmBoot, 59, 0:0, 30:30) \
|
||||
HANDLER(EmcMrsWarmBootEnable, 59, 0:0, 31:31) \
|
||||
HANDLER(ClearClk2Mc1, 60, 0:0, 30:30) \
|
||||
HANDLER(EmcWarmBootExtraModeRegWriteEnable, 60, 0:0, 31:31) \
|
||||
HANDLER(ClkRstControllerPllmMisc2OverrideEnable, 61, 0:0, 30:30) \
|
||||
HANDLER(EmcDbgWriteMux, 61, 0:0, 31:31) \
|
||||
HANDLER(EmcExtraRefreshNum, 62, 2:0, 31:29) \
|
||||
HANDLER(PmcIoDpd3ReqWait, 68, 2:0, 30:28) \
|
||||
HANDLER(AhbArbitrationXbarCtrlMemInitDone, 68, 0:0, 31:31) \
|
||||
HANDLER(MemoryType, 69, 2:0, 30:28) \
|
||||
HANDLER(PmcIoDpd4ReqWait, 70, 2:0, 30:28) \
|
||||
HANDLER(EmcTimingControlWait, 86, 7:0, 31:24) \
|
||||
HANDLER(EmcZcalWarmBootWait, 87, 7:0, 31:24) \
|
||||
HANDLER(WarmBootWait, 88, 7:0, 31:24) \
|
||||
HANDLER(EmcPinProgramWait, 89, 7:0, 31:24) \
|
||||
HANDLER(EmcAutoCalWait, 101, 9:0, 31:22) \
|
||||
HANDLER(SwizzleRankByteEncode, 190, 15:0, 15:0) \
|
||||
\
|
||||
/* PMC SCRATCH fields for LPDDR2. */ \
|
||||
HANDLER(EmcMrwLpddr2ZcalWarmBoot, 5, 23:16, 7:0) \
|
||||
HANDLER(EmcMrwLpddr2ZcalWarmBoot, 5, 7:0, 15:8) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 5, 23:16, 23:16) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 5, 7:0, 31:24) \
|
||||
HANDLER(EmcMrwLpddr2ZcalWarmBoot, 6, 31:30, 1:0) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 6, 31:30, 3:2) \
|
||||
HANDLER(EmcMrwLpddr2ZcalWarmBoot, 6, 27:26, 5:4) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 6, 27:26, 7:6) \
|
||||
HANDLER(EmcMrw6, 8, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw6, 8, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw8, 9, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw8, 9, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw9, 10, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw9, 10, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw10, 11, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw10, 11, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw12, 12, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw12, 12, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw13, 13, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw13, 13, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw14, 14, 27:0, 27:0) \
|
||||
HANDLER(EmcMrw14, 14, 31:30, 29:28) \
|
||||
HANDLER(EmcMrw1, 15, 7:0, 7:0) \
|
||||
HANDLER(EmcMrw1, 15, 23:16, 15:8) \
|
||||
HANDLER(EmcMrw1, 15, 27:26, 17:16) \
|
||||
HANDLER(EmcMrw1, 15, 31:30, 19:18) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 16, 7:0, 7:0) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 16, 23:16, 15:8) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 16, 27:26, 17:16) \
|
||||
HANDLER(EmcWarmBootMrwExtra, 16, 31:30, 19:18) \
|
||||
HANDLER(EmcMrw2, 17, 7:0, 7:0) \
|
||||
HANDLER(EmcMrw2, 17, 23:16, 15:8) \
|
||||
HANDLER(EmcMrw2, 17, 27:26, 17:16) \
|
||||
HANDLER(EmcMrw2, 17, 31:30, 19:18) \
|
||||
HANDLER(EmcMrw3, 18, 7:0, 7:0) \
|
||||
HANDLER(EmcMrw3, 18, 23:16, 15:8) \
|
||||
HANDLER(EmcMrw3, 18, 27:26, 17:16) \
|
||||
HANDLER(EmcMrw3, 18, 31:30, 19:18) \
|
||||
HANDLER(EmcMrw4, 19, 7:0, 7:0) \
|
||||
HANDLER(EmcMrw4, 19, 23:16, 15:8) \
|
||||
HANDLER(EmcMrw4, 19, 27:26, 17:16) \
|
||||
HANDLER(EmcMrw4, 19, 31:30, 19:18)
|
||||
|
||||
#define FOREACH_SDRAM_SECURE_SCRATCH_REGISTER_ERISTA(HANDLER) \
|
||||
/* PMC SECURE_SCRATCH fields. */ \
|
||||
HANDLER(EmcCmdMappingByte, 8, 31:0, 31:0) \
|
||||
HANDLER(EmcPmacroBrickMapping0, 9, 31:0, 31:0) \
|
||||
HANDLER(EmcPmacroBrickMapping1, 10, 31:0, 31:0) \
|
||||
HANDLER(EmcPmacroBrickMapping2, 11, 31:0, 31:0) \
|
||||
HANDLER(McVideoProtectGpuOverride0, 12, 31:0, 31:0) \
|
||||
HANDLER(EmcCmdMappingCmd0_0, 13, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd0_0, 13, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd0_0, 13, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd0_0, 13, 30:24, 27:21) \
|
||||
HANDLER(McVideoProtectBomAdrHi, 13, 1:0, 29:28) \
|
||||
HANDLER(McVideoProtectWriteAccess, 13, 1:0, 31:30) \
|
||||
HANDLER(EmcCmdMappingCmd0_1, 14, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd0_1, 14, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd0_1, 14, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd0_1, 14, 30:24, 27:21) \
|
||||
HANDLER(McSecCarveoutAdrHi, 14, 1:0, 29:28) \
|
||||
HANDLER(McMtsCarveoutAdrHi, 14, 1:0, 31:30) \
|
||||
HANDLER(EmcCmdMappingCmd1_0, 15, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd1_0, 15, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd1_0, 15, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd1_0, 15, 30:24, 27:21) \
|
||||
HANDLER(McGeneralizedCarveout5BomHi, 15, 1:0, 29:28) \
|
||||
HANDLER(McGeneralizedCarveout3BomHi, 15, 1:0, 31:30) \
|
||||
HANDLER(EmcCmdMappingCmd1_1, 16, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd1_1, 16, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd1_1, 16, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd1_1, 16, 30:24, 27:21) \
|
||||
HANDLER(McGeneralizedCarveout2BomHi, 16, 1:0, 29:28) \
|
||||
HANDLER(McGeneralizedCarveout4BomHi, 16, 1:0, 31:30) \
|
||||
HANDLER(EmcCmdMappingCmd2_0, 17, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd2_0, 17, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd2_0, 17, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd2_0, 17, 30:24, 27:21) \
|
||||
HANDLER(McGeneralizedCarveout1BomHi, 17, 1:0, 29:28) \
|
||||
HANDLER(EmcAdrCfg, 17, 0:0, 30:30) \
|
||||
HANDLER(EmcFbioSpare, 17, 1:1, 31:31) \
|
||||
HANDLER(EmcCmdMappingCmd2_1, 18, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd2_1, 18, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd2_1, 18, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd2_1, 18, 30:24, 27:21) \
|
||||
HANDLER(EmcFbioCfg8, 18, 15:15, 28:28) \
|
||||
HANDLER(McEmemAdrCfg, 18, 0:0, 29:29) \
|
||||
HANDLER(McSecCarveoutProtectWriteAccess, 18, 0:0, 30:30) \
|
||||
HANDLER(McMtsCarveoutRegCtrl, 18, 0:0, 31:31) \
|
||||
HANDLER(EmcCmdMappingCmd3_0, 19, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd3_0, 19, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd3_0, 19, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd3_0, 19, 30:24, 27:21) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 19, 6:3, 31:28) \
|
||||
HANDLER(EmcCmdMappingCmd3_1, 20, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd3_1, 20, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd3_1, 20, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd3_1, 20, 30:24, 27:21) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 20, 10:7, 31:28) \
|
||||
HANDLER(McGeneralizedCarveout4Cfg0, 39, 26:0, 26:0) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 39, 17:14, 30:27) \
|
||||
HANDLER(McVideoProtectVprOverride, 39, 0:0, 31:31) \
|
||||
HANDLER(McGeneralizedCarveout5Cfg0, 40, 26:0, 26:0) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 40, 21:18, 30:27) \
|
||||
HANDLER(McVideoProtectVprOverride, 40, 1:1, 31:31) \
|
||||
HANDLER(EmcCmdMappingCmd0_2, 41, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd0_2, 41, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd0_2, 41, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd0_2, 41, 27:24, 24:21) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 41, 6:3, 28:25) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 41, 13:11, 31:29) \
|
||||
HANDLER(EmcCmdMappingCmd1_2, 42, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd1_2, 42, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd1_2, 42, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd1_2, 42, 27:24, 24:21) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 42, 13:7, 31:25) \
|
||||
HANDLER(EmcCmdMappingCmd2_2, 43, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd2_2, 43, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd2_2, 43, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd2_2, 43, 27:24, 24:21) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 43, 17:14, 28:25) \
|
||||
HANDLER(McGeneralizedCarveout3Cfg0, 43, 13:11, 31:29) \
|
||||
HANDLER(EmcCmdMappingCmd3_2, 44, 6:0, 6:0) \
|
||||
HANDLER(EmcCmdMappingCmd3_2, 44, 14:8, 13:7) \
|
||||
HANDLER(EmcCmdMappingCmd3_2, 44, 22:16, 20:14) \
|
||||
HANDLER(EmcCmdMappingCmd3_2, 44, 27:24, 24:21) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 44, 21:18, 28:25) \
|
||||
HANDLER(McVideoProtectVprOverride, 44, 3:2, 30:29) \
|
||||
HANDLER(McVideoProtectVprOverride, 44, 6:6, 31:31) \
|
||||
HANDLER(McEmemAdrCfgChannelMask, 45, 31:9, 22:0) \
|
||||
HANDLER(McEmemAdrCfgDev0, 45, 2:0, 25:23) \
|
||||
HANDLER(McEmemAdrCfgDev0, 45, 9:8, 27:26) \
|
||||
HANDLER(McEmemAdrCfgDev0, 45, 19:16, 31:28) \
|
||||
HANDLER(McEmemAdrCfgBankMask0, 46, 31:10, 21:0) \
|
||||
HANDLER(McEmemAdrCfgDev1, 46, 2:0, 24:22) \
|
||||
HANDLER(McEmemAdrCfgDev1, 46, 9:8, 26:25) \
|
||||
HANDLER(McEmemAdrCfgDev1, 46, 19:16, 30:27) \
|
||||
HANDLER(McVideoProtectVprOverride, 46, 7:7, 31:31) \
|
||||
HANDLER(McEmemAdrCfgBankMask1, 47, 31:10, 21:0) \
|
||||
HANDLER(McGeneralizedCarveout3Cfg0, 47, 10:3, 29:22) \
|
||||
HANDLER(McVideoProtectVprOverride, 47, 9:8, 31:30) \
|
||||
HANDLER(McEmemAdrCfgBankMask2, 48, 31:10, 21:0) \
|
||||
HANDLER(McGeneralizedCarveout3Cfg0, 48, 21:14, 29:22) \
|
||||
HANDLER(McVideoProtectVprOverride, 48, 11:11, 30:30) \
|
||||
HANDLER(McVideoProtectVprOverride, 48, 14:14, 31:31) \
|
||||
HANDLER(McVideoProtectGpuOverride1, 49, 15:0, 15:0) \
|
||||
HANDLER(McEmemCfg, 49, 13:0, 29:16) \
|
||||
HANDLER(McEmemCfg, 49, 31:31, 30:30) \
|
||||
HANDLER(McVideoProtectVprOverride, 49, 15:15, 31:31) \
|
||||
HANDLER(McGeneralizedCarveout3Bom, 50, 31:17, 14:0) \
|
||||
HANDLER(McGeneralizedCarveout1Bom, 50, 31:17, 29:15) \
|
||||
HANDLER(McVideoProtectVprOverride, 50, 18:17, 31:30) \
|
||||
HANDLER(McGeneralizedCarveout4Bom, 51, 31:17, 14:0) \
|
||||
HANDLER(McGeneralizedCarveout2Bom, 51, 31:17, 29:15) \
|
||||
HANDLER(McVideoProtectVprOverride, 51, 20:19, 31:30) \
|
||||
HANDLER(McGeneralizedCarveout5Bom, 52, 31:17, 14:0) \
|
||||
HANDLER(McVideoProtectBom, 52, 31:20, 26:15) \
|
||||
HANDLER(McVideoProtectVprOverride, 52, 23:21, 29:27) \
|
||||
HANDLER(McVideoProtectVprOverride, 52, 26:26, 30:30) \
|
||||
HANDLER(McVideoProtectVprOverride, 52, 29:29, 31:31) \
|
||||
HANDLER(McVideoProtectSizeMb, 53, 11:0, 11:0) \
|
||||
HANDLER(McSecCarveoutBom, 53, 31:20, 23:12) \
|
||||
HANDLER(McVideoProtectVprOverride, 53, 31:30, 25:24) \
|
||||
HANDLER(McVideoProtectVprOverride1, 53, 1:0, 27:26) \
|
||||
HANDLER(McVideoProtectVprOverride1, 53, 7:4, 31:28) \
|
||||
HANDLER(McSecCarveoutSizeMb, 54, 11:0, 11:0) \
|
||||
HANDLER(McMtsCarveoutBom, 54, 31:20, 23:12) \
|
||||
HANDLER(McVideoProtectVprOverride1, 54, 15:8, 31:24) \
|
||||
HANDLER(McMtsCarveoutSizeMb, 55, 11:0, 11:0) \
|
||||
HANDLER(McGeneralizedCarveout4Size128kb, 55, 11:0, 23:12) \
|
||||
HANDLER(McVideoProtectVprOverride1, 55, 16:16, 24:24) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 55, 2:0, 27:25) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 55, 25:22, 31:28) \
|
||||
HANDLER(McGeneralizedCarveout3Size128kb, 56, 11:0, 11:0) \
|
||||
HANDLER(McGeneralizedCarveout2Size128kb, 56, 11:0, 23:12) \
|
||||
HANDLER(McGeneralizedCarveout2Cfg0, 56, 26:26, 24:24) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 56, 2:0, 27:25) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 56, 25:22, 31:28) \
|
||||
HANDLER(McGeneralizedCarveout1Size128kb, 57, 11:0, 11:0) \
|
||||
HANDLER(McGeneralizedCarveout5Size128kb, 57, 11:0, 23:12) \
|
||||
HANDLER(McGeneralizedCarveout1Cfg0, 57, 26:26, 24:24) \
|
||||
HANDLER(McGeneralizedCarveout3Cfg0, 57, 2:0, 27:25) \
|
||||
HANDLER(McGeneralizedCarveout3Cfg0, 57, 25:22, 31:28) \
|
||||
HANDLER(McGeneralizedCarveout3Cfg0, 58, 26:26, 0:0) \
|
||||
HANDLER(McGeneralizedCarveout1Access0, 59, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1Access1, 60, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1Access2, 61, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1Access3, 62, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1Access4, 63, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2Access0, 64, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2Access1, 65, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2Access2, 66, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2Access3, 67, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2Access4, 68, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3Access0, 69, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3Access1, 70, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3Access2, 71, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3Access3, 72, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3Access4, 73, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4Access0, 74, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4Access1, 75, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4Access2, 76, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4Access3, 77, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4Access4, 78, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5Access0, 79, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5Access1, 80, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5Access2, 81, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5Access3, 82, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1ForceInternalAccess0, 84, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1ForceInternalAccess1, 85, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1ForceInternalAccess2, 86, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1ForceInternalAccess3, 87, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout1ForceInternalAccess4, 88, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2ForceInternalAccess0, 89, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2ForceInternalAccess1, 90, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2ForceInternalAccess2, 91, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2ForceInternalAccess3, 92, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout2ForceInternalAccess4, 93, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3ForceInternalAccess0, 94, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3ForceInternalAccess1, 95, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3ForceInternalAccess2, 96, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3ForceInternalAccess3, 97, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout3ForceInternalAccess4, 98, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4ForceInternalAccess0, 99, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4ForceInternalAccess1, 100, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4ForceInternalAccess2, 101, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4ForceInternalAccess3, 102, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout4ForceInternalAccess4, 103, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5ForceInternalAccess0, 104, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5ForceInternalAccess1, 105, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5ForceInternalAccess2, 106, 31:0, 31:0) \
|
||||
HANDLER(McGeneralizedCarveout5ForceInternalAccess3, 107, 31:0, 31:0)
|
||||
1037
fusee/program/source/sdram/fusee_sdram_params_lp0_mariko.inc
Normal file
1037
fusee/program/source/sdram/fusee_sdram_params_lp0_mariko.inc
Normal file
File diff suppressed because it is too large
Load Diff
373
fusee/program/source/sein/fusee_secure_initialize.cpp
Normal file
373
fusee/program/source/sein/fusee_secure_initialize.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "fusee_secure_initialize.hpp"
|
||||
#include "../fusee_registers_di.hpp"
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t MC = secmon::MemoryRegionPhysicalDeviceMemoryController.GetAddress();
|
||||
constexpr inline const uintptr_t APB = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress();
|
||||
constexpr inline const uintptr_t AHB = AHB_ARBC(0);
|
||||
constexpr inline const uintptr_t I2S = I2S_REG(0);
|
||||
constexpr inline const uintptr_t DISP1 = secmon::MemoryRegionPhysicalDeviceDisp1.GetAddress();
|
||||
constexpr inline const uintptr_t VIC = secmon::MemoryRegionPhysicalDeviceDsi.GetAddress() + 0x40000;
|
||||
constexpr inline const uintptr_t TIMER = secmon::MemoryRegionPhysicalDeviceTimer.GetAddress();
|
||||
constexpr inline const uintptr_t SYSCTR0 = secmon::MemoryRegionPhysicalDeviceSysCtr0.GetAddress();
|
||||
|
||||
void DoRcmWorkaround(const void *sbk, size_t sbk_size) {
|
||||
/* Set the SBK inside the security engine. */
|
||||
se::SetAesKey(pkg1::AesKeySlot_SecureBoot, sbk, sbk_size);
|
||||
|
||||
/* Lock the SBK/SSK as unreadable. */
|
||||
se::LockAesKeySlot(pkg1::AesKeySlot_SecureBoot, se::KeySlotLockFlags_KeyRead);
|
||||
se::LockAesKeySlot(pkg1::AesKeySlot_SecureStorage, se::KeySlotLockFlags_KeyRead);
|
||||
|
||||
/* Clear TZRAM. */
|
||||
std::memset(secmon::MemoryRegionPhysicalTzram.GetPointer(), 0, secmon::MemoryRegionPhysicalTzram.GetSize());
|
||||
|
||||
/* Clear APBDEV_PMC_CRYPTO_OP. */
|
||||
reg::Write(PMC + APBDEV_PMC_CRYPTO_OP, 0);
|
||||
|
||||
/* Clear the boot reason. */
|
||||
reg::Write(PMC + APBDEV_PMC_SCRATCH200, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_CRYPTO_OP, 0);
|
||||
|
||||
/* Clear OBS_OVERRIDE/APB2JTAG_OVERRIDE */
|
||||
reg::ReadWrite(AHB + AHB_AHB_SPARE_REG, AHB_REG_BITS_ENUM(AHB_SPARE_REG_OBS_OVERRIDE_EN, DISABLE),
|
||||
AHB_REG_BITS_ENUM(AHB_SPARE_REG_APB2JTAG_OVERRIDE_EN, DISABLE));
|
||||
|
||||
/* Clear low bits of APBDEV_PMC_SCRATCH49 */
|
||||
reg::ClearBits(PMC + APBDEV_PMC_SCRATCH49, 0x3);
|
||||
}
|
||||
|
||||
void DoMbistWorkaround() {
|
||||
/* Configure CLK_RST_CONTROLLER_CLK_SOURCE_SOR1. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL0, MUX),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL1, SOR1_CLOCK_SWITCH));
|
||||
|
||||
/* Set CSI clock source as PLLD. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLD_BASE, CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_ENABLE, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(PLLD_BASE_CSI_CLK_SRC, PLL_D));
|
||||
|
||||
/* Clear APE, VIC, HOST1X, DISP1 reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_Y_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_Y_APE_RST, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_X_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_X_VIC_RST, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_L_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_L_DISP1_RST, ENABLE), CLK_RST_REG_BITS_ENUM(RST_DEV_L_HOST1X_RST, ENABLE));
|
||||
|
||||
/* Wait two microseconds for the devices to come out of reset. */
|
||||
util::WaitMicroSeconds(2);
|
||||
|
||||
/* Set I2S_CTRL.MASTER and clear I2S_CG.SCLG_ENABLE for all I2S registers. */
|
||||
reg::ReadWrite(I2S + I2S0_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
|
||||
reg::ReadWrite(I2S + I2S0_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
|
||||
reg::ReadWrite(I2S + I2S1_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
|
||||
reg::ReadWrite(I2S + I2S1_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
|
||||
reg::ReadWrite(I2S + I2S2_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
|
||||
reg::ReadWrite(I2S + I2S2_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
|
||||
reg::ReadWrite(I2S + I2S3_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
|
||||
reg::ReadWrite(I2S + I2S3_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
|
||||
reg::ReadWrite(I2S + I2S4_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
|
||||
reg::ReadWrite(I2S + I2S4_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
|
||||
|
||||
/* Set DC_COM_DSC_TOP_CTL.DSC_SLG_OVERRIDE */
|
||||
reg::SetBits(DISP1 + DC_COM_DSC_TOP_CTL * sizeof(u32), 0x4);
|
||||
|
||||
/* Set NV_PVIC_THI_SLCG_OVERRIDE_LOW_A */
|
||||
reg::SetBits(VIC + NV_PVIC_THI_SLCG_OVERRIDE_LOW_A, 0xFFFFFFFF);
|
||||
|
||||
/* Wait two microseconds for configuration to take. */
|
||||
util::WaitMicroSeconds(2);
|
||||
|
||||
/* Set APE, VIC, HOST1X, DISP1 reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_Y_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_Y_APE_RST, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_L_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_L_DISP1_RST, ENABLE), CLK_RST_REG_BITS_ENUM(RST_DEV_L_HOST1X_RST, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_X_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_X_VIC_RST, ENABLE));
|
||||
|
||||
/* Set clock enable for a select few devices. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_FUSE, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_PMC, ENABLE));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_CACHE2, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_GPIO, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_TMR, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_RTC, ENABLE));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_CRAM2, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMD, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMC, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMB, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMA, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_CSITE, ENABLE));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_SE, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_SPDIF_DOUBLER, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_APB2APE, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_MSELECT, ENABLE));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_MC1, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_ENTROPY, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX5, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX4, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX3, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX2, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX1, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX0, ENABLE));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_PLLG_REF, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_DBGAPB, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_GPU, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_BBC, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_CPU, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_CBPA, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_CAPA, ENABLE));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_REG_BITS_ENUM(CLK_ENB_Y_CLK_ENB_MC_CDPA, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_ENB_Y_CLK_ENB_MC_CCPA, ENABLE));
|
||||
|
||||
/* Clear all LVL2 clock gate overrides to zero. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE, 0);
|
||||
|
||||
/* Reset CSI clock source. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLD_BASE, CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_BYPASS, DISABLE),
|
||||
CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_ENABLE, DISABLE),
|
||||
CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_REF_DIS, REF_ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(PLLD_BASE_CSI_CLK_SRC, BRICK));
|
||||
|
||||
/* Configure CLK_RST_CONTROLLER_CLK_SOURCE_SOR1. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL0, MUX),
|
||||
CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL1, SAFE_CLOCK));
|
||||
|
||||
/* Configure VI, HOST1X, NVENC clock sources. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_VI, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_VI_VI_CLK_SRC, PLLP_OUT0));
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_HOST1X_HOST1X_CLK_SRC, PLLP_OUT0));
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_NVENC, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_NVENC_NVENC_CLK_SRC, PLLP_OUT0));
|
||||
}
|
||||
|
||||
void EnableArc() {
|
||||
/* Enable clocks for EMC/MC, using PLLP_OUT0. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_EMC, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_EMC_EMC_2X_CLK_SRC, PLLP_OUT0));
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_EMC, ENABLE));
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_MEM, ENABLE));
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_X_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_EMC_DLL, ENABLE));
|
||||
|
||||
/* Clear reset for MEM/EMC. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_H_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_H_EMC_RST, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_DEV_H_MEM_RST, ENABLE));
|
||||
|
||||
/* Wait 5 microseconds for configuration to take. */
|
||||
util::WaitMicroSeconds(5);
|
||||
|
||||
/* Enable ARC_CLK_OVR_ON. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD, CLK_RST_REG_BITS_ENUM(LVL2_CLK_GATE_OVRD_ARC_CLK_OVR_ON, ON));
|
||||
|
||||
/* Enable the ARC. */
|
||||
reg::ReadWrite(MC + MC_IRAM_REG_CTRL, MC_REG_BITS_ENUM(IRAM_REG_CTRL_IRAM_CFG_WRITE_ACCESS, ENABLED));
|
||||
|
||||
/* Set IRAM BOM/TOP to open up access to all mmio. */
|
||||
reg::Write(MC + MC_IRAM_BOM, 0x40000000);
|
||||
reg::Write(MC + MC_IRAM_TOM, 0x80000000);
|
||||
|
||||
/* Read to ensure our configuration takes. */
|
||||
reg::Read(MC + MC_IRAM_REG_CTRL);
|
||||
}
|
||||
|
||||
void InitializeClock() {
|
||||
/* Set SPARE_REG0 clock divisor 2. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_SPARE_REG0, CLK_RST_REG_BITS_ENUM(SPARE_REG0_CLK_M_DIVISOR, CLK_M_DIVISOR2));
|
||||
|
||||
/* Set system counter frequency. */
|
||||
reg::Write(SYSCTR0 + SYSCTR0_CNTFID0, 19'200'000);
|
||||
|
||||
/* Restore TIMERUS config to 19.2 MHz. */
|
||||
reg::Write(TIMER + TIMERUS_USEC_CFG, TIMER_REG_BITS_VALUE(USEC_CFG_USEC_DIVIDEND, 5 - 1),
|
||||
TIMER_REG_BITS_VALUE(USEC_CFG_USEC_DIVISOR, 96 - 1));
|
||||
|
||||
/* Enable the crystal oscillator, and copy the drive strength from pmc. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_OSC_CTRL, CLK_RST_REG_BITS_ENUM (OSC_CTRL_OSC_FREQ, OSC38P4),
|
||||
CLK_RST_REG_BITS_ENUM (OSC_CTRL_XOE, ENABLE),
|
||||
CLK_RST_REG_BITS_VALUE(OSC_CTRL_XOFS, 7));
|
||||
|
||||
/* Set the crystal oscillator value in PMC. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_OSC_EDPD_OVER, PMC_REG_BITS_VALUE(OSC_EDPD_OVER_XOFS, 7));
|
||||
|
||||
/* Configure the crystal oscillator to use PMC value on warmboot. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_OSC_EDPD_OVER, PMC_REG_BITS_ENUM(OSC_EDPD_OVER_OSC_CTRL_SELECT, PMC));
|
||||
|
||||
/* Set HOLD_CKE_LOW_EN. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_CNTRL2, PMC_REG_BITS_ENUM(CNTRL2_HOLD_CKE_LOW_EN, ENABLE));
|
||||
|
||||
/* Set CFG2TMC_RAM_SVOP_PDP to 2. */
|
||||
/* NOTE: Nintendo acidentally writes this to the PMC instead of the APB due to a bug. */
|
||||
reg::ReadWrite(APB + APB_MISC_GP_ASDBGREG, APB_MISC_REG_BITS_VALUE(GP_ASDBGREG_CFG2TMC_RAM_SVOP_PDP, 2));
|
||||
|
||||
/* Set CLK_SYSTEM_RATE. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SYSTEM_RATE, CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_HCLK_DIS, 0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_AHB_RATE, 1),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_PCLK_DIS, 0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_APB_RATE, 0));
|
||||
|
||||
/* Configure PLLMB_BASE. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLMB_BASE, CLK_RST_REG_BITS_ENUM(PLLMB_BASE_PLLMB_ENABLE, DISABLE));
|
||||
|
||||
/* Configure TSC_MULT. */
|
||||
constexpr u32 TscMultValue = 19'200'000 * 16 / 32768;
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_TSC_MULT, PMC_REG_BITS_VALUE(TSC_MULT_MULT_VAL, TscMultValue));
|
||||
|
||||
/* Configure SCLK_BURST_POLICY */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_SCLK_BURST_POLICY, CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SYS_STATE, RUN),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_COP_AUTO_SWAKEUP_FROM_FIQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_CPU_AUTO_SWAKEUP_FROM_FIQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_COP_AUTO_SWAKEUP_FROM_IRQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_CPU_AUTO_SWAKEUP_FROM_IRQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_FIQ_SOURCE, PLLP_OUT2),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_IRQ_SOURCE, PLLP_OUT2),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE, PLLP_OUT2),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_IDLE_SOURCE, PLLP_OUT2));
|
||||
|
||||
/* Configure SUPER_SCLK_DIVIDER */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER, CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_ENB, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_COP_FIQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_CPU_FIQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_COP_IRQ, NOP),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_CPU_IRQ, NOP),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIVIDEND, 0),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIVISOR, 0));
|
||||
|
||||
/* Set CLK_SYSTEM_RATE */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SYSTEM_RATE, CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_HCLK_DIS, 0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_AHB_RATE, 0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_PCLK_DIS, 0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_APB_RATE, 2));
|
||||
}
|
||||
|
||||
void InitializePinmux(fuse::HardwareType hw_type) {
|
||||
/* Clear global pinmux control register */
|
||||
reg::Write(APB + APB_MISC_PP_PINMUX_GLOBAL_0, 0);
|
||||
|
||||
/* Perform initial pinmux setup. */
|
||||
pinmux::SetupFirst(hw_type);
|
||||
|
||||
/* Setup important pinmux devices. */
|
||||
pinmux::SetupI2c1();
|
||||
pinmux::SetupI2c5();
|
||||
pinmux::SetupUartA();
|
||||
pinmux::SetupVolumeButton();
|
||||
pinmux::SetupHomeButton();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SecureInitialize(bool enable_log) {
|
||||
/* Get SoC type/hardware type. */
|
||||
const auto soc_type = fuse::GetSocType();
|
||||
const auto hw_type = fuse::GetHardwareType();
|
||||
|
||||
/* If Erista, perform bootrom logic (to compensate for RCM exploit) and MBIST workaround. */
|
||||
if (soc_type == fuse::SocType_Erista) {
|
||||
/* Potentially perform bootrom compensation. */
|
||||
{
|
||||
u32 sbk[4];
|
||||
if (fuse::GetSecureBootKey(sbk)) {
|
||||
DoRcmWorkaround(sbk, sizeof(sbk));
|
||||
}
|
||||
}
|
||||
DoMbistWorkaround();
|
||||
}
|
||||
|
||||
/* Initialize security engine clock. */
|
||||
clkrst::EnableSeClock();
|
||||
|
||||
/* Set fuse visibility. */
|
||||
clkrst::SetFuseVisibility(true);
|
||||
|
||||
/* Disable fuse programming. */
|
||||
fuse::Lockout();
|
||||
|
||||
/* Initialize the security engine. */
|
||||
se::Initialize();
|
||||
|
||||
/* Enable the arc. */
|
||||
EnableArc();
|
||||
|
||||
/* Setup initial clocks. */
|
||||
InitializeClock();
|
||||
|
||||
/* Setup initial pinmux. */
|
||||
InitializePinmux(hw_type);
|
||||
|
||||
/* Initialize logging. */
|
||||
if (enable_log) {
|
||||
clkrst::EnableUartAClock();
|
||||
}
|
||||
|
||||
/* Enable various clocks. */
|
||||
clkrst::EnableCldvfsClock();
|
||||
clkrst::EnableI2c1Clock();
|
||||
clkrst::EnableI2c5Clock();
|
||||
clkrst::EnableTzramClock();
|
||||
|
||||
/* Ensure avp cache is enabled, since we'll be using it. */
|
||||
clkrst::EnableCache2Clock();
|
||||
clkrst::EnableCram2Clock();
|
||||
|
||||
/* Initialize I2C5. */
|
||||
i2c::Initialize(i2c::Port_5);
|
||||
|
||||
/* Configure pmic system setting. */
|
||||
pmic::SetSystemSetting(soc_type);
|
||||
|
||||
/* Enable VDD core */
|
||||
pmic::EnableVddCore(soc_type);
|
||||
|
||||
/* On hoag, enable Ldo8 */
|
||||
if (hw_type == fuse::HardwareType_Hoag) {
|
||||
pmic::EnableLdo8();
|
||||
}
|
||||
|
||||
/* Initialize I2C1. */
|
||||
i2c::Initialize(i2c::Port_1);
|
||||
|
||||
/* Configure SCLK_BURST_POLICY. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_SCLK_BURST_POLICY, CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_FIQ_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_IRQ_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_IDLE_SOURCE, PLLP_OUT0));
|
||||
|
||||
/* Do mariko-only TZRAM configuration. */
|
||||
if (soc_type == fuse::SocType_Mariko) {
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_TZRAM_PWR_CNTRL, PMC_REG_BITS_VALUE(TZRAM_PWR_CNTRL_TZRAM_SD, 0));
|
||||
|
||||
reg::Write(PMC + APBDEV_PMC_TZRAM_NON_SEC_DISABLE, PMC_REG_BITS_ENUM(TZRAM_NON_SEC_DISABLE_SD_WRITE, ON),
|
||||
PMC_REG_BITS_ENUM(TZRAM_NON_SEC_DISABLE_SD_READ, ON));
|
||||
|
||||
reg::Write(PMC + APBDEV_PMC_TZRAM_SEC_DISABLE, PMC_REG_BITS_ENUM(TZRAM_SEC_DISABLE_SD_WRITE, ON),
|
||||
PMC_REG_BITS_ENUM(TZRAM_SEC_DISABLE_SD_READ, ON));
|
||||
}
|
||||
|
||||
/* Hold certain devices in reset. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_REG_BITS_ENUM(RST_DEVICES_L_SWR_USBD_RST, ENABLE));
|
||||
}
|
||||
|
||||
}
|
||||
23
fusee/program/source/sein/fusee_secure_initialize.hpp
Normal file
23
fusee/program/source/sein/fusee_secure_initialize.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#pragma once
|
||||
|
||||
namespace ams::nxboot {
|
||||
|
||||
void SecureInitialize(bool enable_log);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user