1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2000 4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 5 */ 6 7/* 8 * Support for harddisk partitions. 9 * 10 * To be compatible with LinuxPPC and Apple we use the standard Apple 11 * SCSI disk partitioning scheme. For more information see: 12 * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 13 */ 14 15#include <common.h> 16#include <command.h> 17#include <log.h> 18#include <memalign.h> 19#include <ide.h> 20#include "part_mac.h" 21#include <part.h> 22 23/* stdlib.h causes some compatibility problems; should fixe these! -- wd */ 24#ifndef __ldiv_t_defined 25typedef struct { 26 long int quot; /* Quotient */ 27 long int rem; /* Remainder */ 28} ldiv_t; 29extern ldiv_t ldiv (long int __numer, long int __denom); 30# define __ldiv_t_defined 1 31#endif 32 33 34static int part_mac_read_ddb(struct blk_desc *desc, mac_driver_desc_t *ddb_p); 35static int part_mac_read_pdb(struct blk_desc *desc, int part, 36 mac_partition_t *pdb_p); 37 38/* 39 * Test for a valid MAC partition 40 */ 41static int part_test_mac(struct blk_desc *desc) 42{ 43 ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); 44 ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); 45 ulong i, n; 46 47 if (part_mac_read_ddb(desc, ddesc)) { 48 /* 49 * error reading Driver Descriptor Block, 50 * or no valid Signature 51 */ 52 return (-1); 53 } 54 55 n = 1; /* assuming at least one partition */ 56 for (i=1; i<=n; ++i) { 57 if ((blk_dread(desc, i, 1, (ulong *)mpart) != 1) || 58 mpart->signature != MAC_PARTITION_MAGIC) { 59 return (-1); 60 } 61 /* update partition count */ 62 n = mpart->map_count; 63 } 64 return (0); 65} 66 67static void part_print_mac(struct blk_desc *desc) 68{ 69 ulong i, n; 70 ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); 71 ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); 72 ldiv_t mb, gb; 73 74 if (part_mac_read_ddb(desc, ddesc)) { 75 /* 76 * error reading Driver Descriptor Block, 77 * or no valid Signature 78 */ 79 return; 80 } 81 82 n = ddesc->blk_count; 83 84 mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */ 85 /* round to 1 digit */ 86 mb.rem *= 10 * ddesc->blk_size; 87 mb.rem += 512 * 1024; 88 mb.rem /= 1024 * 1024; 89 90 gb = ldiv(10 * mb.quot + mb.rem, 10240); 91 gb.rem += 512; 92 gb.rem /= 1024; 93 94 95 printf ("Block Size=%d, Number of Blocks=%d, " 96 "Total Capacity: %ld.%ld MB = %ld.%ld GB\n" 97 "DeviceType=0x%x, DeviceId=0x%x\n\n" 98 " #: type name" 99 " length base (size)\n", 100 ddesc->blk_size, 101 ddesc->blk_count, 102 mb.quot, mb.rem, gb.quot, gb.rem, 103 ddesc->dev_type, ddesc->dev_id 104 ); 105 106 n = 1; /* assuming at least one partition */ 107 for (i=1; i<=n; ++i) { 108 ulong bytes; 109 char c; 110 111 printf ("%4ld: ", i); 112 if (blk_dread(desc, i, 1, (ulong *)mpart) != 1) { 113 printf ("** Can't read Partition Map on %d:%ld **\n", 114 desc->devnum, i); 115 return; 116 } 117 118 if (mpart->signature != MAC_PARTITION_MAGIC) { 119 printf("** Bad Signature on %d:%ld - expected 0x%04x, got 0x%04x\n", 120 desc->devnum, i, MAC_PARTITION_MAGIC, 121 mpart->signature); 122 return; 123 } 124 125 /* update partition count */ 126 n = mpart->map_count; 127 128 c = 'k'; 129 bytes = mpart->block_count; 130 bytes /= (1024 / ddesc->blk_size); /* kB; assumes blk_size == 512 */ 131 if (bytes >= 1024) { 132 bytes >>= 10; 133 c = 'M'; 134 } 135 if (bytes >= 1024) { 136 bytes >>= 10; 137 c = 'G'; 138 } 139 140 printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", 141 mpart->type, 142 mpart->name, 143 mpart->block_count, 144 mpart->start_block, 145 bytes, c 146 ); 147 } 148 149 return; 150} 151 152 153/* 154 * Read Device Descriptor Block 155 */ 156static int part_mac_read_ddb(struct blk_desc *desc, mac_driver_desc_t *ddb_p) 157{ 158 if (blk_dread(desc, 0, 1, (ulong *)ddb_p) != 1) { 159 debug("** Can't read Driver Descriptor Block **\n"); 160 return (-1); 161 } 162 163 if (ddb_p->signature != MAC_DRIVER_MAGIC) { 164 return (-1); 165 } 166 return (0); 167} 168 169/* 170 * Read Partition Descriptor Block 171 */ 172static int part_mac_read_pdb(struct blk_desc *desc, int part, 173 mac_partition_t *pdb_p) 174{ 175 int n = 1; 176 177 for (;;) { 178 /* 179 * We must always read the descritpor block for 180 * partition 1 first since this is the only way to 181 * know how many partitions we have. 182 */ 183 if (blk_dread(desc, n, 1, (ulong *)pdb_p) != 1) { 184 printf("** Can't read Partition Map on %d:%d **\n", 185 desc->devnum, n); 186 return (-1); 187 } 188 189 if (pdb_p->signature != MAC_PARTITION_MAGIC) { 190 printf("** Bad Signature on %d:%d: expected 0x%04x, got 0x%04x\n", 191 desc->devnum, n, MAC_PARTITION_MAGIC, 192 pdb_p->signature); 193 return (-1); 194 } 195 196 if (n == part) 197 return (0); 198 199 if ((part < 1) || (part > pdb_p->map_count)) { 200 printf("** Invalid partition %d:%d [%d:1...%d:%d only]\n", 201 desc->devnum, part, desc->devnum, desc->devnum, 202 pdb_p->map_count); 203 return (-1); 204 } 205 206 /* update partition count */ 207 n = part; 208 } 209 210 /* NOTREACHED */ 211} 212 213static int part_get_info_mac(struct blk_desc *desc, int part, 214 struct disk_partition *info) 215{ 216 ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); 217 ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); 218 219 if (part_mac_read_ddb(desc, ddesc)) 220 return -1; 221 222 info->blksz = ddesc->blk_size; 223 224 if (part_mac_read_pdb(desc, part, mpart)) 225 return -1; 226 227 info->start = mpart->start_block; 228 info->size = mpart->block_count; 229 memcpy (info->type, mpart->type, sizeof(info->type)); 230 memcpy (info->name, mpart->name, sizeof(info->name)); 231 232 return (0); 233} 234 235U_BOOT_PART_TYPE(mac) = { 236 .name = "MAC", 237 .part_type = PART_TYPE_MAC, 238 .max_entries = MAC_ENTRY_NUMBERS, 239 .get_info = part_get_info_mac, 240 .print = part_print_mac, 241 .test = part_test_mac, 242}; 243