mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 06:30:39 +00:00
75eb82ec7c
Mflash is fusion memory device mainly targeted consumer eletronic and mobile phone. Internally, it have nand flash and other hardware logics and supports some different operation (ATA, IO, XIP) modes. IO mode is custom mode for the host that doesn't have IDE interface. (Many mobile targeted SoC doesn't have IDE bus) This driver support mflash IO mode. Followings are brief descriptions about IO mode. 1. IO mode based on ATA protocol and uses some custom command. (read confirm, write confirm) 2. IO mode uses SRAM bus interface. Signed-off-by: unsik Kim <donari75@gmail.com>
256 lines
6.1 KiB
C
256 lines
6.1 KiB
C
/*
|
|
* (C) Copyright 2000
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*/
|
|
|
|
/*
|
|
* Support for harddisk partitions.
|
|
*
|
|
* To be compatible with LinuxPPC and Apple we use the standard Apple
|
|
* SCSI disk partitioning scheme. For more information see:
|
|
* http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <ide.h>
|
|
#include "part_mac.h"
|
|
|
|
#if defined(CONFIG_CMD_IDE) || \
|
|
defined(CONFIG_CMD_MG_DISK) || \
|
|
defined(CONFIG_CMD_SCSI) || \
|
|
defined(CONFIG_CMD_SATA) || \
|
|
defined(CONFIG_CMD_USB) || \
|
|
defined(CONFIG_MMC) || \
|
|
defined(CONFIG_SYSTEMACE)
|
|
|
|
/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
|
|
#ifndef __ldiv_t_defined
|
|
typedef struct {
|
|
long int quot; /* Quotient */
|
|
long int rem; /* Remainder */
|
|
} ldiv_t;
|
|
extern ldiv_t ldiv (long int __numer, long int __denom);
|
|
# define __ldiv_t_defined 1
|
|
#endif
|
|
|
|
|
|
static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p);
|
|
static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p);
|
|
|
|
/*
|
|
* Test for a valid MAC partition
|
|
*/
|
|
int test_part_mac (block_dev_desc_t *dev_desc)
|
|
{
|
|
mac_driver_desc_t ddesc;
|
|
mac_partition_t mpart;
|
|
ulong i, n;
|
|
|
|
if (part_mac_read_ddb (dev_desc, &ddesc)) {
|
|
/* error reading Driver Desriptor Block, or no valid Signature */
|
|
return (-1);
|
|
}
|
|
|
|
n = 1; /* assuming at least one partition */
|
|
for (i=1; i<=n; ++i) {
|
|
if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) ||
|
|
(mpart.signature != MAC_PARTITION_MAGIC) ) {
|
|
return (-1);
|
|
}
|
|
/* update partition count */
|
|
n = mpart.map_count;
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
|
|
void print_part_mac (block_dev_desc_t *dev_desc)
|
|
{
|
|
ulong i, n;
|
|
mac_driver_desc_t ddesc;
|
|
mac_partition_t mpart;
|
|
ldiv_t mb, gb;
|
|
|
|
if (part_mac_read_ddb (dev_desc, &ddesc)) {
|
|
/* error reading Driver Desriptor Block, or no valid Signature */
|
|
return;
|
|
}
|
|
|
|
n = ddesc.blk_count;
|
|
|
|
mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */
|
|
/* round to 1 digit */
|
|
mb.rem *= 10 * ddesc.blk_size;
|
|
mb.rem += 512 * 1024;
|
|
mb.rem /= 1024 * 1024;
|
|
|
|
gb = ldiv(10 * mb.quot + mb.rem, 10240);
|
|
gb.rem += 512;
|
|
gb.rem /= 1024;
|
|
|
|
|
|
printf ("Block Size=%d, Number of Blocks=%d, "
|
|
"Total Capacity: %ld.%ld MB = %ld.%ld GB\n"
|
|
"DeviceType=0x%x, DeviceId=0x%x\n\n"
|
|
" #: type name"
|
|
" length base (size)\n",
|
|
ddesc.blk_size,
|
|
ddesc.blk_count,
|
|
mb.quot, mb.rem, gb.quot, gb.rem,
|
|
ddesc.dev_type, ddesc.dev_id
|
|
);
|
|
|
|
n = 1; /* assuming at least one partition */
|
|
for (i=1; i<=n; ++i) {
|
|
ulong bytes;
|
|
char c;
|
|
|
|
printf ("%4ld: ", i);
|
|
if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) {
|
|
printf ("** Can't read Partition Map on %d:%ld **\n",
|
|
dev_desc->dev, i);
|
|
return;
|
|
}
|
|
|
|
if (mpart.signature != MAC_PARTITION_MAGIC) {
|
|
printf ("** Bad Signature on %d:%ld - "
|
|
"expected 0x%04x, got 0x%04x\n",
|
|
dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature);
|
|
return;
|
|
}
|
|
|
|
/* update partition count */
|
|
n = mpart.map_count;
|
|
|
|
c = 'k';
|
|
bytes = mpart.block_count;
|
|
bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */
|
|
if (bytes >= 1024) {
|
|
bytes >>= 10;
|
|
c = 'M';
|
|
}
|
|
if (bytes >= 1024) {
|
|
bytes >>= 10;
|
|
c = 'G';
|
|
}
|
|
|
|
printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n",
|
|
mpart.type,
|
|
mpart.name,
|
|
mpart.block_count,
|
|
mpart.start_block,
|
|
bytes, c
|
|
);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* Read Device Descriptor Block
|
|
*/
|
|
static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p)
|
|
{
|
|
if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) {
|
|
printf ("** Can't read Driver Desriptor Block **\n");
|
|
return (-1);
|
|
}
|
|
|
|
if (ddb_p->signature != MAC_DRIVER_MAGIC) {
|
|
#if 0
|
|
printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n",
|
|
MAC_DRIVER_MAGIC, ddb_p->signature);
|
|
#endif
|
|
return (-1);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Read Partition Descriptor Block
|
|
*/
|
|
static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p)
|
|
{
|
|
int n = 1;
|
|
|
|
for (;;) {
|
|
/*
|
|
* We must always read the descritpor block for
|
|
* partition 1 first since this is the only way to
|
|
* know how many partitions we have.
|
|
*/
|
|
if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) {
|
|
printf ("** Can't read Partition Map on %d:%d **\n",
|
|
dev_desc->dev, n);
|
|
return (-1);
|
|
}
|
|
|
|
if (pdb_p->signature != MAC_PARTITION_MAGIC) {
|
|
printf ("** Bad Signature on %d:%d: "
|
|
"expected 0x%04x, got 0x%04x\n",
|
|
dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);
|
|
return (-1);
|
|
}
|
|
|
|
if (n == part)
|
|
return (0);
|
|
|
|
if ((part < 1) || (part > pdb_p->map_count)) {
|
|
printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
|
|
dev_desc->dev, part,
|
|
dev_desc->dev,
|
|
dev_desc->dev, pdb_p->map_count);
|
|
return (-1);
|
|
}
|
|
|
|
/* update partition count */
|
|
n = part;
|
|
}
|
|
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
|
|
{
|
|
mac_driver_desc_t ddesc;
|
|
mac_partition_t mpart;
|
|
|
|
if (part_mac_read_ddb (dev_desc, &ddesc)) {
|
|
return (-1);
|
|
}
|
|
|
|
info->blksz = ddesc.blk_size;
|
|
|
|
if (part_mac_read_pdb (dev_desc, part, &mpart)) {
|
|
return (-1);
|
|
}
|
|
|
|
info->start = mpart.start_block;
|
|
info->size = mpart.block_count;
|
|
memcpy (info->type, mpart.type, sizeof(info->type));
|
|
memcpy (info->name, mpart.name, sizeof(info->name));
|
|
|
|
return (0);
|
|
}
|
|
|
|
#endif
|