Blame view
disk/part_amiga.c
8.79 KB
c7de829c7 * Patch by Thomas... |
1 2 |
/* * (C) Copyright 2001 |
8bde7f776 * Code cleanup: |
3 |
* Hans-Joerg Frieden, Hyperion Entertainment |
c7de829c7 * Patch by Thomas... |
4 5 |
* Hans-JoergF@hyperion-entertainment.com * |
1a4596601 Add GPL-2.0+ SPDX... |
6 |
* SPDX-License-Identifier: GPL-2.0+ |
c7de829c7 * Patch by Thomas... |
7 8 9 10 |
*/ #include <common.h> #include <command.h> #include <ide.h> |
c7de829c7 * Patch by Thomas... |
11 |
#include "part_amiga.h" |
1811a928c Move most CONFIG_... |
12 |
#ifdef CONFIG_HAVE_BLOCK_DEVICE |
c7de829c7 * Patch by Thomas... |
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#undef AMIGA_DEBUG #ifdef AMIGA_DEBUG #define PRINTF(fmt, args...) printf(fmt ,##args) #else #define PRINTF(fmt, args...) #endif struct block_header { u32 id; u32 summed_longs; s32 chk_sum; }; static unsigned char block_buffer[DEFAULT_SECTOR_SIZE]; static struct rigid_disk_block rdb = {0}; static struct bootcode_block bootcode = {0}; /* * Copy a bcpl to a c string */ static void bcpl_strcpy(char *to, char *from) { int len = *from++; while (len) { *to++ = *from++; len--; } *to = 0; } /* * Print a BCPL String. BCPL strings start with a byte with the length * of the string, and don't contain a terminating nul character */ static void bstr_print(char *string) { int len = *string++; char buffer[256]; int i; |
8bde7f776 * Code cleanup: |
57 |
|
c7de829c7 * Patch by Thomas... |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
i = 0; while (len) { buffer[i++] = *string++; len--; } buffer[i] = 0; printf("%-10s", buffer); } /* * Sum a block. The checksum of a block must end up at zero * to be valid. The chk_sum field is selected so that adding * it yields zero. */ int sum_block(struct block_header *header) { s32 *block = (s32 *)header; u32 i; s32 sum = 0; for (i = 0; i < header->summed_longs; i++) sum += *block++; |
8bde7f776 * Code cleanup: |
82 |
|
c7de829c7 * Patch by Thomas... |
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
return (sum != 0); } /* * Print an AmigaOS disk type. Disk types are a four-byte identifier * describing the file system. They are usually written as a three-letter * word followed by a backslash and a version number. For example, * DOS\0 would be the original file system. SFS\0 would be SmartFileSystem. * DOS\1 is FFS. */ static void print_disk_type(u32 disk_type) { char buffer[6]; buffer[0] = (disk_type & 0xFF000000)>>24; buffer[1] = (disk_type & 0x00FF0000)>>16; buffer[2] = (disk_type & 0x0000FF00)>>8; buffer[3] = '\\'; buffer[4] = (disk_type & 0x000000FF) + '0'; buffer[5] = 0; printf("%s", buffer); } /* * Print the info contained within the given partition block */ static void print_part_info(struct partition_block *p) { struct amiga_part_geometry *g; |
8bde7f776 * Code cleanup: |
111 |
|
c7de829c7 * Patch by Thomas... |
112 113 114 |
g = (struct amiga_part_geometry *)&(p->environment); bstr_print(p->drive_name); |
8bde7f776 * Code cleanup: |
115 116 |
printf("%6d\t%6d\t", g->low_cyl * g->block_per_track * g->surfaces , |
c7de829c7 * Patch by Thomas... |
117 118 119 120 121 122 123 124 125 126 127 128 |
(g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1); print_disk_type(g->dos_type); printf("\t%5d ", g->boot_priority); } /* * Search for the Rigid Disk Block. The rigid disk block is required * to be within the first 16 blocks of a drive, needs to have * the ID AMIGA_ID_RDISK ('RDSK') and needs to have a valid * sum-to-zero checksum */ |
4101f6879 dm: Drop the bloc... |
129 |
struct rigid_disk_block *get_rdisk(struct blk_desc *dev_desc) |
c7de829c7 * Patch by Thomas... |
130 131 132 133 |
{ int i; int limit; char *s; |
00caae6d4 env: Rename geten... |
134 |
s = env_get("amiga_scanlimit"); |
c7de829c7 * Patch by Thomas... |
135 |
if (s) |
75eb82ec7 mflash: Initial m... |
136 |
limit = simple_strtoul(s, NULL, 10); |
c7de829c7 * Patch by Thomas... |
137 138 139 140 141 |
else limit = AMIGA_BLOCK_LIMIT; for (i=0; i<limit; i++) { |
2a981dc2c dm: block: Adjust... |
142 |
ulong res = blk_dread(dev_desc, i, 1, (ulong *)block_buffer); |
c7de829c7 * Patch by Thomas... |
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
if (res == 1) { struct rigid_disk_block *trdb = (struct rigid_disk_block *)block_buffer; if (trdb->id == AMIGA_ID_RDISK) { PRINTF("Rigid disk block suspect at %d, checking checksum ",i); if (sum_block((struct block_header *)block_buffer) == 0) { PRINTF("FOUND "); memcpy(&rdb, trdb, sizeof(struct rigid_disk_block)); return (struct rigid_disk_block *)&rdb; } } } } PRINTF("Done scanning, no RDB found "); return NULL; } |
8bde7f776 * Code cleanup: |
164 |
/* |
c7de829c7 * Patch by Thomas... |
165 166 167 168 |
* Search for boot code * Again, the first boot block must be located somewhere in the first 16 blocks, or rooted in the * Ridgid disk block */ |
4101f6879 dm: Drop the bloc... |
169 |
struct bootcode_block *get_bootcode(struct blk_desc *dev_desc) |
c7de829c7 * Patch by Thomas... |
170 171 172 173 |
{ int i; int limit; char *s; |
00caae6d4 env: Rename geten... |
174 |
s = env_get("amiga_scanlimit"); |
c7de829c7 * Patch by Thomas... |
175 |
if (s) |
75eb82ec7 mflash: Initial m... |
176 |
limit = simple_strtoul(s, NULL, 10); |
c7de829c7 * Patch by Thomas... |
177 178 179 180 181 182 183 184 |
else limit = AMIGA_BLOCK_LIMIT; PRINTF("Scanning for BOOT from 0 to %d ", limit); for (i = 0; i < limit; i++) { |
2a981dc2c dm: block: Adjust... |
185 |
ulong res = blk_dread(dev_desc, i, 1, (ulong *)block_buffer); |
c7de829c7 * Patch by Thomas... |
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
if (res == 1) { struct bootcode_block *boot = (struct bootcode_block *)block_buffer; if (boot->id == AMIGA_ID_BOOT) { PRINTF("BOOT block at %d, checking checksum ", i); if (sum_block((struct block_header *)block_buffer) == 0) { PRINTF("Found valid bootcode block "); memcpy(&bootcode, boot, sizeof(struct bootcode_block)); return &bootcode; } } } } PRINTF("No boot code found on disk "); return 0; } |
8bde7f776 * Code cleanup: |
208 |
/* |
c7de829c7 * Patch by Thomas... |
209 210 211 |
* Test if the given partition has an Amiga partition table/Rigid * Disk block */ |
084bf4c24 part: Rename test... |
212 |
static int part_test_amiga(struct blk_desc *dev_desc) |
c7de829c7 * Patch by Thomas... |
213 214 215 |
{ struct rigid_disk_block *rdb; struct bootcode_block *bootcode; |
084bf4c24 part: Rename test... |
216 217 |
PRINTF("part_test_amiga: Testing for an Amiga RDB partition "); |
8bde7f776 * Code cleanup: |
218 |
|
c7de829c7 * Patch by Thomas... |
219 220 221 222 223 |
rdb = get_rdisk(dev_desc); if (rdb) { bootcode = get_bootcode(dev_desc); if (bootcode) |
084bf4c24 part: Rename test... |
224 225 |
PRINTF("part_test_amiga: bootable Amiga disk "); |
c7de829c7 * Patch by Thomas... |
226 |
else |
084bf4c24 part: Rename test... |
227 228 |
PRINTF("part_test_amiga: non-bootable Amiga disk "); |
c7de829c7 * Patch by Thomas... |
229 230 231 |
return 0; } |
8bde7f776 * Code cleanup: |
232 |
else |
c7de829c7 * Patch by Thomas... |
233 |
{ |
084bf4c24 part: Rename test... |
234 235 |
PRINTF("part_test_amiga: no RDB found "); |
c7de829c7 * Patch by Thomas... |
236 237 238 239 |
return -1; } } |
8bde7f776 * Code cleanup: |
240 |
/* |
c7de829c7 * Patch by Thomas... |
241 242 |
* Find partition number partnum on the given drive. */ |
4101f6879 dm: Drop the bloc... |
243 244 |
static struct partition_block *find_partition(struct blk_desc *dev_desc, int partnum) |
c7de829c7 * Patch by Thomas... |
245 246 247 248 249 250 251 252 |
{ struct rigid_disk_block *rdb; struct partition_block *p; u32 block; PRINTF("Trying to find partition block %d ", partnum); rdb = get_rdisk(dev_desc); |
8bde7f776 * Code cleanup: |
253 |
if (!rdb) |
c7de829c7 * Patch by Thomas... |
254 255 256 257 258 |
{ PRINTF("find_partition: no rdb found "); return NULL; } |
8bde7f776 * Code cleanup: |
259 |
|
c7de829c7 * Patch by Thomas... |
260 261 262 263 264 265 266 267 268 |
PRINTF("find_partition: Scanning partition list "); block = rdb->partition_list; PRINTF("find_partition: partition list at 0x%x ", block); while (block != 0xFFFFFFFF) { |
2a981dc2c dm: block: Adjust... |
269 |
ulong res = blk_dread(dev_desc, block, 1, (ulong *)block_buffer); |
c7de829c7 * Patch by Thomas... |
270 271 272 273 274 275 276 277 278 279 |
if (res == 1) { p = (struct partition_block *)block_buffer; if (p->id == AMIGA_ID_PART) { PRINTF("PART block suspect at 0x%x, checking checksum ",block); if (sum_block((struct block_header *)p) == 0) { if (partnum == 0) break; |
8bde7f776 * Code cleanup: |
280 |
else |
c7de829c7 * Patch by Thomas... |
281 282 283 284 285 286 287 288 |
{ partnum--; block = p->next; } } } else block = 0xFFFFFFFF; } else block = 0xFFFFFFFF; } |
8bde7f776 * Code cleanup: |
289 |
if (block == 0xFFFFFFFF) |
c7de829c7 * Patch by Thomas... |
290 291 292 293 294 295 296 297 |
{ PRINTF("PART block not found "); return NULL; } return (struct partition_block *)block_buffer; } |
8bde7f776 * Code cleanup: |
298 |
/* |
c7de829c7 * Patch by Thomas... |
299 300 |
* Get info about a partition */ |
3e8bd4695 dm: part: Rename ... |
301 |
static int part_get_info_amiga(struct blk_desc *dev_desc, int part, |
96e5b03c8 dm: part: Convert... |
302 |
disk_partition_t *info) |
c7de829c7 * Patch by Thomas... |
303 304 305 306 307 308 309 310 311 312 313 |
{ struct partition_block *p = find_partition(dev_desc, part-1); struct amiga_part_geometry *g; u32 disk_type; if (!p) return -1; g = (struct amiga_part_geometry *)&(p->environment); info->start = g->low_cyl * g->block_per_track * g->surfaces; info->size = (g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1; info->blksz = rdb.block_bytes; |
95a6f9dfc dm: part: Add a c... |
314 |
bcpl_strcpy((char *)info->name, p->drive_name); |
8bde7f776 * Code cleanup: |
315 |
|
c7de829c7 * Patch by Thomas... |
316 317 318 319 320 321 322 323 324 |
disk_type = g->dos_type; info->type[0] = (disk_type & 0xFF000000)>>24; info->type[1] = (disk_type & 0x00FF0000)>>16; info->type[2] = (disk_type & 0x0000FF00)>>8; info->type[3] = '\\'; info->type[4] = (disk_type & 0x000000FF) + '0'; info->type[5] = 0; |
8bde7f776 * Code cleanup: |
325 |
|
c7de829c7 * Patch by Thomas... |
326 327 |
return 0; } |
084bf4c24 part: Rename test... |
328 |
static void part_print_amiga(struct blk_desc *dev_desc) |
8bde7f776 * Code cleanup: |
329 |
{ |
c7de829c7 * Patch by Thomas... |
330 331 332 333 334 335 336 |
struct rigid_disk_block *rdb; struct bootcode_block *boot; struct partition_block *p; u32 block; int i = 1; rdb = get_rdisk(dev_desc); |
8bde7f776 * Code cleanup: |
337 |
if (!rdb) |
c7de829c7 * Patch by Thomas... |
338 |
{ |
084bf4c24 part: Rename test... |
339 340 |
PRINTF("part_print_amiga: no rdb found "); |
c7de829c7 * Patch by Thomas... |
341 342 |
return; } |
8bde7f776 * Code cleanup: |
343 |
|
084bf4c24 part: Rename test... |
344 345 |
PRINTF("part_print_amiga: Scanning partition list "); |
c7de829c7 * Patch by Thomas... |
346 347 |
block = rdb->partition_list; |
084bf4c24 part: Rename test... |
348 349 |
PRINTF("part_print_amiga: partition list at 0x%x ", block); |
c7de829c7 * Patch by Thomas... |
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
printf("Summary: DiskBlockSize: %d " " Cylinders : %d " " Sectors/Track: %d " " Heads : %d ", rdb->block_bytes, rdb->cylinders, rdb->sectors, rdb->heads); printf(" First Num. " "Nr. Part. Name Block Block Type Boot Priority "); while (block != 0xFFFFFFFF) { ulong res; PRINTF("Trying to load block #0x%X ", block); |
8bde7f776 * Code cleanup: |
374 |
|
2a981dc2c dm: block: Adjust... |
375 |
res = blk_dread(dev_desc, block, 1, (ulong *)block_buffer); |
c7de829c7 * Patch by Thomas... |
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
if (res == 1) { p = (struct partition_block *)block_buffer; if (p->id == AMIGA_ID_PART) { PRINTF("PART block suspect at 0x%x, checking checksum ",block); if (sum_block((struct block_header *)p) == 0) { printf("%-4d ", i); i++; print_part_info(p); block = p->next; } } else block = 0xFFFFFFFF; } else block = 0xFFFFFFFF; } boot = get_bootcode(dev_desc); if (boot) { printf("Disk is bootable "); } } |
96e5b03c8 dm: part: Convert... |
400 401 402 |
U_BOOT_PART_TYPE(amiga) = { .name = "AMIGA", .part_type = PART_TYPE_AMIGA, |
87b8530fe disk: part: imple... |
403 |
.max_entries = AMIGA_ENTRY_NUMBERS, |
3e8bd4695 dm: part: Rename ... |
404 |
.get_info = part_get_info_amiga, |
084bf4c24 part: Rename test... |
405 406 |
.print = part_print_amiga, .test = part_test_amiga, |
96e5b03c8 dm: part: Convert... |
407 |
}; |
c7de829c7 * Patch by Thomas... |
408 |
#endif |