mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-06-18 16:55:31 -04:00
(shirait)
忘れ物 git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@258 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
parent
8d4eb3a702
commit
f0406ca817
848
trunk/firmware/build/libraries/fatfs/common/src/drnand.c
Normal file
848
trunk/firmware/build/libraries/fatfs/common/src/drnand.c
Normal file
@ -0,0 +1,848 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TWL - rtfs interface for SD Memory Card
|
||||
File: drnand.h
|
||||
|
||||
Copyright 2006-2008 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: #$
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <rtfs.h>
|
||||
#include <portconf.h>
|
||||
//#if (INCLUDE_SD)
|
||||
|
||||
//#include "sdmc_config.h"
|
||||
#include <brom/nand/nand.h>
|
||||
#include <sdmc.h>
|
||||
|
||||
#define PRINTDEBUG( ...) ((void)0)
|
||||
/*
|
||||
#if (SD_DEBUG_PRINT_ON == 1)
|
||||
#define PRINTDEBUG osTPrintf
|
||||
#else
|
||||
#define PRINTDEBUG( ...) ((void)0)
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
定数
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define NUM_SD_PAGES
|
||||
#define SD_PAGE_SIZE
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
extern変数
|
||||
*---------------------------------------------------------------------------*/
|
||||
/*SDメモリカードのスペック構造体*/
|
||||
SdmcSpec sdmc_current_spec;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
extern関数
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern void nandReset( void);
|
||||
void i_nandCalcSize( void); //TODO:sdmc_current_specを構造体に入れること
|
||||
BOOL nandCrashBootSectors( u32* buf);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
static変数
|
||||
*---------------------------------------------------------------------------*/
|
||||
static FATSpec NandFatSpec[4]; //FATパラメータ(パーティション0~3個別)
|
||||
static int nand_calculated_fat_params = 0;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
static関数
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL sdi_get_CHS_params( void);
|
||||
static u32 sdi_get_ceil( u32 cval, u32 mval);
|
||||
static BOOL sdi_get_nom( u32 min_nom);
|
||||
static void sdi_get_fatparams( void);
|
||||
static void sdi_build_partition_table( int driveno, DDRIVE *pdr);
|
||||
BOOL nandFillPartition( int partition_no, u32* buf, u32 blocks);
|
||||
void i_nandCalcSize( void);
|
||||
|
||||
|
||||
#if 1 //アプリケーションでパーティション構成を決めたいとき
|
||||
|
||||
u32 NAND_FAT_PARTITION_COUNT;
|
||||
u32 NAND_RAW_SECTORS;
|
||||
u32 NAND_FAT0_SECTORS = 0;
|
||||
u32 NAND_FAT1_SECTORS;
|
||||
u32 NAND_FAT2_SECTORS;
|
||||
u32 NAND_FAT3_SECTORS;
|
||||
|
||||
void nandSetFormatRequest( u16 partition_num, u32* partition_sectors);
|
||||
void nandSetFormatRequest( u16 partition_num, u32* partition_sectors)
|
||||
{
|
||||
NAND_RAW_SECTORS = partition_sectors[0];
|
||||
NAND_FAT0_SECTORS = partition_sectors[1] + NAND_RAW_SECTORS;
|
||||
NAND_FAT1_SECTORS = partition_sectors[2];
|
||||
NAND_FAT2_SECTORS = partition_sectors[3];
|
||||
NAND_FAT3_SECTORS = partition_sectors[4];
|
||||
NAND_FAT_PARTITION_COUNT = partition_num;
|
||||
}
|
||||
|
||||
#else //パーティション構成を決め打ちするとき
|
||||
/* RAW:1MB, FAT0:206MB, FAT1:32.75MB */
|
||||
#define NAND_FAT_PARTITION_COUNT (3)
|
||||
#define NAND_RAW_SECTORS (( 1*1024*1024)/512);
|
||||
#define NAND_FAT0_SECTORS (((206*1024*1024)/512) + NAND_RAW_SECTORS); //計算上RAWを含めておく
|
||||
#define NAND_FAT1_SECTORS ((33536*1024)/512);
|
||||
#define NAND_FAT2_SECTORS (( 1*1024*1024)/512);
|
||||
#define NAND_FAT3_SECTORS (0);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandCheckMedia
|
||||
|
||||
Description: MBRのシグネチャおよび
|
||||
パーティションのフォーマット種別をチェックする
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns: TRUE/FALSE
|
||||
(FALSEなら pc_format_media が必要)
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL nandCheckMedia( void) //TODO:nand partition仕様に対応させること
|
||||
{
|
||||
u8* bufp;
|
||||
u32 buffer[512/4];
|
||||
u8 systemid;
|
||||
|
||||
/**/
|
||||
nandReadSector( buffer, 0, 1);
|
||||
|
||||
bufp = (u8*)buffer;
|
||||
|
||||
/* Check the Signature Word. */
|
||||
if( (bufp[510]!=0x55) || (bufp[511]!=0xAA)) {
|
||||
return( FALSE);
|
||||
}
|
||||
/* Check the System ID of partition. */
|
||||
systemid = bufp[450];
|
||||
if( (systemid!=0x01) && (systemid!=0x04) && (systemid!=0x06) &&
|
||||
(systemid!=0x0B) && (systemid!=0x0C)) {
|
||||
return( FALSE);
|
||||
}
|
||||
|
||||
return( TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsIo
|
||||
|
||||
Description: 上位層からのセクタリード/ライト要求を受ける
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
block : 開始ブロック番号
|
||||
buffer :
|
||||
count : ブロック数
|
||||
reading : リード要求時にTRUE
|
||||
|
||||
Returns: TRUE/FALSE
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL nandRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading)
|
||||
{
|
||||
if( reading) {
|
||||
PRINTDEBUG( "DEVCTL_IO_READ ... block:%x, count:%x -> buf:%x\n", block, count, buffer);
|
||||
nandReadSector( buffer, block, count);
|
||||
}else{
|
||||
PRINTDEBUG( "DEVCTL_IO_WRITE ... block:%x, count:%x <- buf:%x\n", block, count, buffer);
|
||||
nandWriteSector( buffer, block, count);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsCtrl
|
||||
|
||||
Description: 上位層からのコントロール要求を受ける
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
opcode : 要求の種類
|
||||
pargs :
|
||||
|
||||
Returns:
|
||||
Memo : DRIVE_FLAGS_REMOVABLEの場合、ドライバのIO関数を呼ぶ前に
|
||||
CTRL関数のDEVCTL_CHECK_STATUSが呼ばれる。
|
||||
DEVTEST_CHANGED→DEVTEST_NOCHANGEが確認されるとRTFSはセクタ0を
|
||||
読みに行き、FATパラメータを取得した上で目的のセクタを読みに行く。
|
||||
CTRL関数の前にはDEVCTL_CHECK_STATUSが呼ばれないので、DEVCTL_
|
||||
GET_GEOMETRYでは自前で再挿入をチェックする必要がある。
|
||||
*---------------------------------------------------------------------------*/
|
||||
int nandRtfsCtrl( int driveno, int opcode, void* pargs)
|
||||
{
|
||||
DDRIVE *pdr;
|
||||
DEV_GEOMETRY gc;
|
||||
|
||||
pdr = pc_drno_to_drive_struct( driveno);
|
||||
|
||||
switch( opcode) {
|
||||
case DEVCTL_GET_GEOMETRY: //formatまたはpartirionするときにRTFSが使うパラメータ
|
||||
PRINTDEBUG( "DEVCTL_GET_GEOMETRY\n");
|
||||
|
||||
if( NAND_FAT0_SECTORS == 0) { /* フォーマットパラメータ未設定のときは失敗する */
|
||||
return( -1);
|
||||
}
|
||||
|
||||
rtfs_memset( &gc, (byte)0, sizeof(gc));
|
||||
|
||||
if( nand_calculated_fat_params == 0) {
|
||||
i_nandCalcSize(); //TODO:sdmc_current_specを構造体に入れること
|
||||
if( sdi_get_CHS_params() == FALSE) { //最初に呼ぶこと
|
||||
return( -1);
|
||||
}
|
||||
sdi_get_fatparams();
|
||||
if( sdi_get_nom( NAND_RAW_SECTORS) == FALSE) {
|
||||
return( -1);
|
||||
}
|
||||
nand_calculated_fat_params = 1;
|
||||
}
|
||||
|
||||
PRINTDEBUG( "memory capacity : 0x%x\n", NandFatSpec[pdr->partition_number].memory_capacity);
|
||||
PRINTDEBUG( "device capacity : 0x%x\n", NandFatSpec[pdr->partition_number].device_capacity);
|
||||
PRINTDEBUG( "adjusted capacity : 0x%x\n", NandFatSpec[pdr->partition_number].adjusted_memory_capacity);
|
||||
PRINTDEBUG( "volume cylinders : 0x%x\n", NandFatSpec[pdr->partition_number].volume_cylinders);
|
||||
PRINTDEBUG( "\n");
|
||||
PRINTDEBUG( "heads : 0x%x\n", NandFatSpec[pdr->partition_number].heads);
|
||||
PRINTDEBUG( "secptrack : 0x%x\n", NandFatSpec[pdr->partition_number].secptrack);
|
||||
PRINTDEBUG( "cylinders : 0x%x\n", NandFatSpec[pdr->partition_number].cylinders);
|
||||
PRINTDEBUG( "SC : 0x%x\n", NandFatSpec[pdr->partition_number].SC);
|
||||
PRINTDEBUG( "BU : 0x%x\n", NandFatSpec[pdr->partition_number].BU);
|
||||
PRINTDEBUG( "RDE : 0x%x\n", NandFatSpec[pdr->partition_number].RDE);
|
||||
PRINTDEBUG( "SS : 0x%x\n", NandFatSpec[pdr->partition_number].SS);
|
||||
PRINTDEBUG( "RSC : 0x%x\n", NandFatSpec[pdr->partition_number].RSC);
|
||||
PRINTDEBUG( "FATBITS : 0x%x\n", NandFatSpec[pdr->partition_number].FATBITS);
|
||||
PRINTDEBUG( "SF : 0x%x\n", NandFatSpec[pdr->partition_number].SF);
|
||||
PRINTDEBUG( "SSA : 0x%x\n", NandFatSpec[pdr->partition_number].SSA);
|
||||
PRINTDEBUG( "NOM : 0x%x\n", NandFatSpec[pdr->partition_number].NOM);
|
||||
|
||||
/*デバイスの先頭から現在のパーティションの領域までを含む容量分をセットする*/
|
||||
gc.dev_geometry_lbas = (NandFatSpec[pdr->partition_number].begin_sect +
|
||||
NandFatSpec[pdr->partition_number].memory_capacity);
|
||||
gc.dev_geometry_heads = NandFatSpec[pdr->partition_number].heads;
|
||||
gc.dev_geometry_secptrack = NandFatSpec[pdr->partition_number].secptrack;
|
||||
|
||||
/*デバイスの先頭から現在のパーティションの領域までを含む容量分をセットする*/
|
||||
gc.dev_geometry_cylinders = gc.dev_geometry_lbas /
|
||||
(gc.dev_geometry_heads * gc.dev_geometry_secptrack);
|
||||
/**/
|
||||
gc.fmt_parms_valid = TRUE;
|
||||
gc.fmt.oemname[0] = 'T';
|
||||
gc.fmt.oemname[1] = 'W';
|
||||
gc.fmt.oemname[2] = 'L';
|
||||
gc.fmt.oemname[3] = '\0';
|
||||
gc.fmt.secpalloc = (u8)(NandFatSpec[pdr->partition_number].SC); /*sectors per cluster(FIX by capacity)*/
|
||||
gc.fmt.secreserved = (u16)(NandFatSpec[pdr->partition_number].RSC);//sdmc_current_spec.RSC;/*reserved sectors(FIX 1 at FAT12,16)*/
|
||||
gc.fmt.numfats = 2;
|
||||
gc.fmt.secpfat = NandFatSpec[pdr->partition_number].SF;
|
||||
gc.fmt.numhide = NandFatSpec[pdr->partition_number].NOM; /**/
|
||||
gc.fmt.numroot = NandFatSpec[pdr->partition_number].RDE; /*FIX*/
|
||||
gc.fmt.mediadesc = 0xF8;
|
||||
gc.fmt.secptrk = NandFatSpec[pdr->partition_number].secptrack; //CHS Recommendation
|
||||
gc.fmt.numhead = NandFatSpec[pdr->partition_number].heads;
|
||||
gc.fmt.numcyl = (u16)(gc.dev_geometry_cylinders);//NandFatSpec[pdr->partition_number].cylinders;
|
||||
gc.fmt.physical_drive_no = (u8)driveno;
|
||||
gc.fmt.binary_volume_label = BIN_VOL_LABEL;
|
||||
gc.fmt.text_volume_label[0] = '\0';
|
||||
|
||||
PRINTDEBUG( "heads : 0x%x, secptrack : 0x%x, cylinders : 0x%x\n", gc.dev_geometry_heads, gc.dev_geometry_secptrack, gc.dev_geometry_cylinders);
|
||||
|
||||
miCpuCopy8( &gc, pargs, sizeof(gc));
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_FORMAT:
|
||||
PRINTDEBUG( "DEVCTL_FORMAT\n");
|
||||
sdi_build_partition_table( driveno, pdr); //MBRセクタ(パーティションテーブル含む)書き込み
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_REPORT_REMOVE: //抜かれたとき
|
||||
PRINTDEBUG( "DEVCTL_REPORT_REMOVE\n");
|
||||
pdr->drive_flags &= ~DRIVE_FLAGS_INSERTED;
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_CHECKSTATUS: //REMOVABLEの場合、毎回R/W前に呼ばれる
|
||||
PRINTDEBUG( "DEVCTL_CHECKSTATUS\n");
|
||||
// if (!(pdr->drive_flags & DRIVE_FLAGS_REMOVABLE)) { //リムーバブルでない場合
|
||||
return(DEVTEST_NOCHANGE);
|
||||
// }
|
||||
|
||||
case DEVCTL_WARMSTART: //attachのときしか呼ばれない
|
||||
PRINTDEBUG( "DEVCTL_WARMSTART\n");
|
||||
/*-- NANDのみ初期化 --*/
|
||||
// nandReset();
|
||||
/*--------------------*/
|
||||
pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_PARTITIONED); //| DRIVE_FLAGS_REMOVABLE
|
||||
pdr->drive_flags |= DRIVE_FLAGS_INSERTED;
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_POWER_RESTORE:
|
||||
PRINTDEBUG( "DEVCTL_POWER_RESTORE\n");
|
||||
break;
|
||||
|
||||
case DEVCTL_POWER_LOSS:
|
||||
PRINTDEBUG( "DEVCTL_POWER_LOSS\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTDEBUG( "DEVCTL_unknown\n");
|
||||
break;
|
||||
}
|
||||
return( 0);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsAttach
|
||||
|
||||
Description: nandドライバをドライブに割り当てる
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
|
||||
Returns:
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL nandRtfsAttach( int driveno, int partition_no)
|
||||
{
|
||||
BOOLEAN result;
|
||||
DDRIVE pdr;
|
||||
|
||||
#if 0 /*----- フォーマットパラメータ依存部 -----*/
|
||||
if( partition_no >= NAND_FAT_PARTITION_COUNT) {
|
||||
return( FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
pdr.dev_table_drive_io = nandRtfsIo;
|
||||
pdr.dev_table_perform_device_ioctl = nandRtfsCtrl;
|
||||
pdr.register_file_address = (dword) 0; /* Not used */
|
||||
pdr.interrupt_number = 0; /* Not used */
|
||||
pdr.drive_flags = (DRIVE_FLAGS_VALID | DRIVE_FLAGS_PARTITIONED);//DRIVE_FLAGS_FAILSAFE;
|
||||
pdr.partition_number = partition_no; /* Not used */
|
||||
pdr.pcmcia_slot_number = 0; /* Not used */
|
||||
pdr.controller_number = 0;
|
||||
pdr.logical_unit_number = 0;
|
||||
|
||||
switch( partition_no) {
|
||||
case 0:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p0"); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
case 1:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p1"); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
case 2:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p2"); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
case 3:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p3"); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
default:
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return( result);
|
||||
}
|
||||
|
||||
|
||||
/*SD File System Specification(仕様書)に基づいた値を出す*/
|
||||
static BOOL sdi_get_CHS_params( void)
|
||||
{
|
||||
u32 i;
|
||||
u32 mbytes;
|
||||
u32 cumulative_capacity; //累計
|
||||
|
||||
/**/
|
||||
NandFatSpec[0].memory_capacity = NAND_FAT0_SECTORS;
|
||||
NandFatSpec[1].memory_capacity = NAND_FAT1_SECTORS;
|
||||
NandFatSpec[2].memory_capacity = NAND_FAT2_SECTORS;
|
||||
NandFatSpec[3].memory_capacity = NAND_FAT3_SECTORS;
|
||||
|
||||
|
||||
cumulative_capacity = 0;
|
||||
for( i=0; i<(NAND_FAT_PARTITION_COUNT - 1); i++) {
|
||||
cumulative_capacity += NandFatSpec[i].memory_capacity;
|
||||
}
|
||||
/*容量破綻チェック*/
|
||||
// osTPrintf( "cumulative:0x%x, memory:0x%x\n", cumulative_capacity, sdmc_current_spec.memory_capacity);
|
||||
if( cumulative_capacity >= sdmc_current_spec.memory_capacity) {
|
||||
return( FALSE);
|
||||
}
|
||||
|
||||
/*最終パーティションは残りのセクタ全部*/
|
||||
NandFatSpec[NAND_FAT_PARTITION_COUNT -1].memory_capacity =
|
||||
sdmc_current_spec.memory_capacity - cumulative_capacity;
|
||||
|
||||
/*無効なパーティションにサイズ0を設定*/
|
||||
for( i=NAND_FAT_PARTITION_COUNT; i<4; i++) {
|
||||
NandFatSpec[i].memory_capacity = 0;
|
||||
}
|
||||
|
||||
|
||||
// mbytes = (sdmc_current_spec.card_capacity / (1024 * 1024)) * 512;
|
||||
mbytes = (sdmc_current_spec.card_capacity >> 11); //TODO:forの中に入れてパーティション毎の値にするテストをすること
|
||||
|
||||
for( i=0; i<NAND_FAT_PARTITION_COUNT; i++) {
|
||||
while( 1) {
|
||||
if( mbytes <= 2) {
|
||||
NandFatSpec[i].heads = 2;
|
||||
NandFatSpec[i].secptrack = 16;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 16) {
|
||||
NandFatSpec[i].heads = 2;
|
||||
NandFatSpec[i].secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 32) {
|
||||
NandFatSpec[i].heads = 4;
|
||||
NandFatSpec[i].secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 128) {
|
||||
NandFatSpec[i].heads = 8;
|
||||
NandFatSpec[i].secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 256) {
|
||||
NandFatSpec[i].heads = 16;
|
||||
NandFatSpec[i].secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 504) {
|
||||
NandFatSpec[i].heads = 16;
|
||||
NandFatSpec[i].secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 1008) {
|
||||
NandFatSpec[i].heads = 32;
|
||||
NandFatSpec[i].secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 2016) {
|
||||
NandFatSpec[i].heads = 64;
|
||||
NandFatSpec[i].secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 2048) {
|
||||
NandFatSpec[i].heads = 128;
|
||||
NandFatSpec[i].secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 4032) {
|
||||
NandFatSpec[i].heads = 128;
|
||||
NandFatSpec[i].secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 32768) {
|
||||
NandFatSpec[i].heads = 255;
|
||||
NandFatSpec[i].secptrack = 63;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*デバイス容量設定*/
|
||||
NandFatSpec[i].device_capacity = sdmc_current_spec.memory_capacity;
|
||||
|
||||
/*---------- デバイス全体 ----------*/
|
||||
NandFatSpec[i].cylinders = (u16) /*シリンダ数を計算*/
|
||||
(NandFatSpec[i].device_capacity /
|
||||
(NandFatSpec[i].heads * NandFatSpec[i].secptrack));
|
||||
|
||||
/*memory_capacityを再計算してadjusted_memory_capacityに格納*/
|
||||
NandFatSpec[i].adjusted_device_capacity = (u32)
|
||||
(NandFatSpec[i].cylinders *
|
||||
(NandFatSpec[i].heads * NandFatSpec[i].secptrack));
|
||||
/*----------------------------------*/
|
||||
|
||||
/*---------- ボリューム ----------*/
|
||||
NandFatSpec[i].volume_cylinders = (u16) /*シリンダ数を計算*/
|
||||
(NandFatSpec[i].memory_capacity /
|
||||
(NandFatSpec[i].heads * NandFatSpec[i].secptrack));
|
||||
|
||||
/*memory_capacityを再計算してadjusted_memory_capacityに格納*/
|
||||
NandFatSpec[i].adjusted_memory_capacity = (u32)
|
||||
(NandFatSpec[i].volume_cylinders *
|
||||
(NandFatSpec[i].heads * NandFatSpec[i].secptrack));
|
||||
/*--------------------------------*/
|
||||
}
|
||||
|
||||
PRINTDEBUG( "device_capacity:0x%x, adjusted:0x%x\n",
|
||||
NandFatSpec[0].device_capacity,
|
||||
NandFatSpec[0].adjusted_device_capacity);
|
||||
|
||||
for( i=0; i<NAND_FAT_PARTITION_COUNT; i++) {
|
||||
PRINTDEBUG( "partition %d memory_capacity:0x%x, adjusted:0x%x\n",
|
||||
i, NandFatSpec[i].memory_capacity,
|
||||
NandFatSpec[i].adjusted_memory_capacity);
|
||||
}
|
||||
return( TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*引数を超える最も小さい整数を算出する*/
|
||||
static u32 sdi_get_ceil( u32 cval, u32 mval)
|
||||
{
|
||||
return( (cval / mval) + (1 * (cval % mval != 0)));
|
||||
}
|
||||
|
||||
|
||||
/*マスターブートセクタのセクタ数を返す*/
|
||||
static BOOL sdi_get_nom( u32 MIN_NOM)
|
||||
{
|
||||
u32 RSC[4];
|
||||
u32 TS[4];
|
||||
u32 RDE = 512; //ルートディレクトリエントリ(FIX)
|
||||
u32 SS = 512; //セクタサイズ(FIX)
|
||||
u32 SC, n, MAX, SFdash;
|
||||
u16 i;
|
||||
|
||||
RSC[0] = 1; //FAT12,16では1
|
||||
RSC[1] = 1;
|
||||
RSC[2] = 1;
|
||||
RSC[3] = 1;
|
||||
|
||||
TS[0] = NandFatSpec[0].adjusted_memory_capacity;
|
||||
TS[1] = NandFatSpec[1].adjusted_memory_capacity;
|
||||
TS[2] = NandFatSpec[2].adjusted_memory_capacity;
|
||||
TS[3] = NandFatSpec[3].adjusted_memory_capacity;
|
||||
|
||||
NandFatSpec[0].begin_sect = 0;
|
||||
NandFatSpec[1].begin_sect = NandFatSpec[0].begin_sect + NandFatSpec[0].memory_capacity;
|
||||
NandFatSpec[2].begin_sect = NandFatSpec[1].begin_sect + NandFatSpec[1].memory_capacity;
|
||||
NandFatSpec[3].begin_sect = NandFatSpec[2].begin_sect + NandFatSpec[2].memory_capacity;
|
||||
|
||||
|
||||
for( i=0; i<NAND_FAT_PARTITION_COUNT; i++) {
|
||||
|
||||
SC = NandFatSpec[i].SC;
|
||||
|
||||
NandFatSpec[i].SF = (u16)sdi_get_ceil( TS[i]/SC * NandFatSpec[i].FATBITS, SS*8);
|
||||
|
||||
/*-----------------------SDHCのとき----------------------------*/
|
||||
if( sdmc_current_spec.csd_ver2_flag) {
|
||||
PRINTDEBUG( "ERR! enter SDHC branch\n");
|
||||
/*nandの場合、NOMは少なくともMIN_NOM以上*/
|
||||
if( i==0) {
|
||||
NandFatSpec[i].NOM = sdi_get_ceil( MIN_NOM, NandFatSpec[i].BU) *
|
||||
NandFatSpec[i].BU;
|
||||
}else{
|
||||
sdmc_current_spec.NOM = sdmc_current_spec.BU;
|
||||
}
|
||||
do {
|
||||
n = sdi_get_ceil( (u32)(2*NandFatSpec[i].SF), (u32)(NandFatSpec[i].BU));
|
||||
NandFatSpec[i].RSC = (NandFatSpec[i].BU * n) - ( 2 * NandFatSpec[i].SF);
|
||||
if( NandFatSpec[i].RSC < 9) {
|
||||
NandFatSpec[i].RSC += NandFatSpec[i].BU;
|
||||
}
|
||||
NandFatSpec[i].SSA = NandFatSpec[i].RSC + (2 * NandFatSpec[i].SF);
|
||||
do {
|
||||
MAX = ((TS[i] - NandFatSpec[i].NOM - NandFatSpec[i].SSA) / SC) + 1;
|
||||
SFdash = sdi_get_ceil( (2+(MAX-1)) * NandFatSpec[i].FATBITS, SS*8);
|
||||
if( SFdash > NandFatSpec[i].SF) {
|
||||
NandFatSpec[i].SSA += NandFatSpec[i].BU;
|
||||
NandFatSpec[i].RSC += NandFatSpec[i].BU;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while( 1);
|
||||
if( SFdash != NandFatSpec[i].SF) {
|
||||
NandFatSpec[i].SF -= 1;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while( 1);
|
||||
}else{ /*-------------------------SDのとき-------------------------------*/
|
||||
do {
|
||||
NandFatSpec[i].SSA = RSC[i] + ( 2 * NandFatSpec[i].SF) + sdi_get_ceil( 32*RDE, SS);
|
||||
n = sdi_get_ceil( NandFatSpec[i].SSA, NandFatSpec[i].BU);
|
||||
|
||||
/*nand パーティション0の場合、NOMは少なくともMIN_NOM以上*/
|
||||
if( i==0) {
|
||||
n+= sdi_get_ceil( MIN_NOM, NandFatSpec[i].BU);
|
||||
}
|
||||
|
||||
NandFatSpec[i].NOM = (NandFatSpec[i].BU * n) - NandFatSpec[i].SSA;
|
||||
if( NandFatSpec[i].NOM != NandFatSpec[i].BU) {
|
||||
NandFatSpec[i].NOM += NandFatSpec[i].BU;
|
||||
}
|
||||
do {
|
||||
if( NandFatSpec[i].NOM >= sdmc_current_spec.memory_capacity) {
|
||||
return( FALSE);
|
||||
}
|
||||
MAX = ((TS[i] - NandFatSpec[i].NOM - NandFatSpec[i].SSA) / SC) + 1;
|
||||
SFdash = sdi_get_ceil( (2+(MAX-1)) * NandFatSpec[i].FATBITS, SS*8);
|
||||
if( SFdash > NandFatSpec[i].SF) {
|
||||
NandFatSpec[i].NOM += NandFatSpec[i].BU;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while( 1);
|
||||
if( SFdash != NandFatSpec[i].SF) {
|
||||
NandFatSpec[i].SF = (u16)SFdash;
|
||||
}else{
|
||||
break; //complete
|
||||
}
|
||||
}while( 1);
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<NAND_FAT_PARTITION_COUNT; i++) {
|
||||
NandFatSpec[i].NOM += NandFatSpec[i].begin_sect; //各パーティションの先頭
|
||||
PRINTDEBUG( "before NOM:0x%x, begin_sect:0x%x\n", NandFatSpec[i].NOM, NandFatSpec[i].begin_sect);
|
||||
PRINTDEBUG( "partition %d NOM:0x%x, SSA:0x%x, begin_sect:0x%x\n",
|
||||
i, NandFatSpec[i].NOM, NandFatSpec[i].SSA, NandFatSpec[i].begin_sect);
|
||||
}
|
||||
|
||||
return( TRUE);
|
||||
}
|
||||
|
||||
/*FATのビット数を返す*/
|
||||
static void sdi_get_fatparams( void)
|
||||
{
|
||||
u32 i, mbytes;
|
||||
|
||||
for( i=0; i<NAND_FAT_PARTITION_COUNT; i++) {
|
||||
// mbytes = (sdmc_current_spec.card_capacity / (1024 * 1024)) * 512;
|
||||
mbytes = (sdmc_current_spec.card_capacity >> 11);
|
||||
|
||||
if( mbytes <= 64) {
|
||||
NandFatSpec[i].FATBITS = 12;
|
||||
NandFatSpec[i].RDE = 512;
|
||||
NandFatSpec[i].RSC = 1;
|
||||
}else{
|
||||
if( mbytes <= 2048) {
|
||||
NandFatSpec[i].FATBITS = 16;
|
||||
NandFatSpec[i].RDE = 512;
|
||||
NandFatSpec[i].RSC = 1;
|
||||
}else{
|
||||
NandFatSpec[i].FATBITS = 32;
|
||||
NandFatSpec[i].RDE = 0; //FAT32のときは未使用。0にしておかないとRTFSが BAD FORMAT を返す。
|
||||
NandFatSpec[i].RSC = 1;
|
||||
}
|
||||
}
|
||||
|
||||
while( 1) {
|
||||
if( mbytes <= 8) {
|
||||
NandFatSpec[i].SC = 16;
|
||||
NandFatSpec[i].BU = 16;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 64) {
|
||||
NandFatSpec[i].SC = 32;
|
||||
NandFatSpec[i].BU = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 256) {
|
||||
NandFatSpec[i].SC = 32;
|
||||
NandFatSpec[i].BU = 64;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 1024) {
|
||||
NandFatSpec[i].SC = 32;
|
||||
NandFatSpec[i].BU = 128;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 2048) {
|
||||
NandFatSpec[i].SC = 64;
|
||||
NandFatSpec[i].BU = 128;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 32768) {
|
||||
NandFatSpec[i].SC = 64;
|
||||
NandFatSpec[i].BU = 8192;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*MBRセクタ(パーティションセクタ含む)を生成して書き込む*/
|
||||
static void sdi_build_partition_table( int driveno, DDRIVE *pdr)
|
||||
{
|
||||
u16 MbrSectDat[512/2];
|
||||
u32 starting_head[4], starting_sect[4], starting_cyl[4];
|
||||
u32 ending_head[4], ending_sect[4], ending_cyl[4];
|
||||
u32 total_sect[4];
|
||||
// u32 starting_data[4], ending_data[4];
|
||||
u32 systemid[4];
|
||||
u16 i;
|
||||
|
||||
for( i=0; i<4; i++) {
|
||||
if( i < NAND_FAT_PARTITION_COUNT) {
|
||||
/**/
|
||||
starting_head[i] = NandFatSpec[i].NOM % (NandFatSpec[i].heads *
|
||||
NandFatSpec[i].secptrack);
|
||||
starting_head[i] /= NandFatSpec[i].secptrack;
|
||||
|
||||
/**/
|
||||
starting_sect[i] = (NandFatSpec[i].NOM % NandFatSpec[i].secptrack) + 1;
|
||||
|
||||
/**/
|
||||
starting_cyl[i] = NandFatSpec[i].NOM / (NandFatSpec[i].heads *
|
||||
NandFatSpec[i].secptrack);
|
||||
|
||||
/**/
|
||||
// total_sect[i] = (NandFatSpec[i].adjusted_memory_capacity - NandFatSpec[i].NOM);
|
||||
total_sect[i] = (NandFatSpec[i].begin_sect +
|
||||
NandFatSpec[i].adjusted_memory_capacity - NandFatSpec[i].NOM);
|
||||
|
||||
ending_head[i] = (NandFatSpec[i].NOM + total_sect[i] - 1) %
|
||||
(NandFatSpec[i].heads * NandFatSpec[i].secptrack);
|
||||
ending_head[i] /= NandFatSpec[i].secptrack;
|
||||
|
||||
/**/
|
||||
ending_sect[i] = ((NandFatSpec[i].NOM + total_sect[i] - 1) %
|
||||
NandFatSpec[i].secptrack) + 1;
|
||||
|
||||
/**/
|
||||
ending_cyl[i] = (NandFatSpec[i].NOM + total_sect[i] - 1) /
|
||||
(NandFatSpec[i].heads * NandFatSpec[i].secptrack);
|
||||
|
||||
/**/
|
||||
if( NandFatSpec[i].FATBITS == 32) { //FAT32のとき
|
||||
if( total_sect[i] < 0xFB0400) { //8032.5MBが閾値(SD FileSystemSpec2.00参照)
|
||||
systemid[i] = 0x0B; /* FAT32 */
|
||||
}else{
|
||||
systemid[i] = 0x0C; /* FAT32(拡張INT13対応) */
|
||||
}
|
||||
}else{ //FAT12,FAT16のとき
|
||||
if( total_sect[i] < 32680) {
|
||||
systemid[i] = 0x01; /* FAT12 */
|
||||
}else if( total_sect[i] < 65536) {
|
||||
systemid[i] = 0x04; /* FAT16(16MB~32MB未満) */
|
||||
}else{
|
||||
systemid[i] = 0x06; /* FAT16(32MB~4GB) */
|
||||
}
|
||||
}
|
||||
}else{
|
||||
starting_head[i] = 0;
|
||||
starting_sect[i] = 0;
|
||||
starting_cyl[i] = 0;
|
||||
total_sect[i] = 0;
|
||||
ending_head[i] = 0;
|
||||
ending_sect[i] = 0;
|
||||
ending_cyl[i] = 0;
|
||||
systemid[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*MBRセクタ(パーティションテーブル含む)作成*/
|
||||
miCpuFill8( MbrSectDat, 0, sizeof(MbrSectDat));
|
||||
|
||||
for( i=0; i<4; i++) {
|
||||
MbrSectDat[(446+(i*16))/2] = (u16)(starting_head[i]<<8);
|
||||
//上位8bit:starting_cylの下位8bit, 下位8bit:starting_cylの上位2bit + starting_sect 6bit.
|
||||
MbrSectDat[(448+(i*16))/2] = (u16)((starting_cyl[i]<<8) +
|
||||
((starting_cyl[i]>>2) & 0xC0) + starting_sect[i]);
|
||||
MbrSectDat[(450+(i*16))/2] = (u16)((ending_head[i]<<8) + systemid[i]);
|
||||
//上位8bit:ending_cylの下位8bit, 下位8bit:ending_cylの上位2bit + ending_sect 6bit.
|
||||
MbrSectDat[(452+(i*16))/2] = (u16)((ending_cyl[i]<<8) +
|
||||
((ending_cyl[i]>>2) & 0xC0) + ending_sect[i]);
|
||||
MbrSectDat[(454+(i*16))/2] = (u16)(NandFatSpec[i].NOM);
|
||||
MbrSectDat[(456+(i*16))/2] = (u16)(NandFatSpec[i].NOM>>16);
|
||||
MbrSectDat[(458+(i*16))/2] = (u16)(total_sect[i]);
|
||||
MbrSectDat[(460+(i*16))/2] = (u16)(total_sect[i]>>16);
|
||||
}
|
||||
MbrSectDat[510/2] = 0xAA55;
|
||||
/*セクタ0に書き込み*/
|
||||
pdr->dev_table_drive_io( driveno, 0, MbrSectDat, 1, FALSE);
|
||||
// sdmcWriteFifo( MbrSectDat, 1, 0, NULL, &SdResult);//MbrSectDatは2Byte alignかも知れないので危険
|
||||
nandWriteSector( MbrSectDat, 0, 1);
|
||||
|
||||
/**/
|
||||
for( i=0; i<4; i++) {
|
||||
PRINTDEBUG( "---partition %d---\n", i);
|
||||
PRINTDEBUG( "total sect : 0x%x\n", total_sect[i]);
|
||||
PRINTDEBUG( "starting head : 0x%x\n", starting_head[i]);
|
||||
PRINTDEBUG( "starting sect : 0x%x\n", starting_sect[i]);
|
||||
PRINTDEBUG( "starting cyl : 0x%x\n", starting_cyl[i]);
|
||||
PRINTDEBUG( "ending head : 0x%x\n", ending_head[i]);
|
||||
PRINTDEBUG( "ending sect : 0x%x\n", ending_sect[i]);
|
||||
PRINTDEBUG( "ending cyl : 0x%x\n", ending_cyl[i]);
|
||||
PRINTDEBUG( "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL nandFillPartition( int partition_no, u32* buf, u32 blocks)
|
||||
{
|
||||
u32 user_sect;
|
||||
u32 user_size;
|
||||
u32 done_size = 0;
|
||||
u32 ofs, len;
|
||||
|
||||
ofs = NandFatSpec[partition_no].NOM - NandFatSpec[partition_no].begin_sect;
|
||||
user_sect = NandFatSpec[partition_no].NOM;
|
||||
user_size = NandFatSpec[partition_no].adjusted_memory_capacity - ofs;
|
||||
|
||||
/* osTPrintf( "partition:0x%x ... user_sect:0x%x, user_size:0x%x\n",
|
||||
partition_no, user_sect, user_size);
|
||||
*/
|
||||
osTPrintf( "partition:0x%x fill\n", partition_no);
|
||||
#if 1
|
||||
while( 1) {
|
||||
len = (user_size > blocks) ? (u32)blocks : (u32)user_size;
|
||||
if( nandRtfsIo( 5, user_sect+done_size, buf, (u16)len, FALSE) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
done_size += len;
|
||||
user_size -= len;
|
||||
if( user_size == 0) {
|
||||
break;
|
||||
}
|
||||
if( ((done_size % 2048) == 0)&&(done_size!=0)) {
|
||||
osTPrintf( ".");
|
||||
}
|
||||
if( ((done_size % (2048*40)) == 0)&&(done_size!=0)) {
|
||||
osTPrintf( "\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
osTPrintf( "\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL nandCrashBootSectors( u32* buf)
|
||||
{
|
||||
/* MBR上書き */
|
||||
nandWriteSector( buf, 0, 1);
|
||||
return( TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: i_nandCalcSize
|
||||
|
||||
Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void i_nandCalcSize( void)
|
||||
{
|
||||
sdmc_current_spec.csd_ver2_flag = 0;
|
||||
sdmc_current_spec.protected_capacity = (20*256); //20Blocks
|
||||
sdmc_current_spec.card_capacity = NAND_GUARANTEED_SECTORS;
|
||||
sdmc_current_spec.memory_capacity = sdmc_current_spec.card_capacity -
|
||||
sdmc_current_spec.protected_capacity;
|
||||
}
|
||||
|
||||
|
||||
//#endif /*(INCLUDE_SD)*/
|
Loading…
Reference in New Issue
Block a user