]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - disk/part_amiga.c
1 // SPDX-License-Identifier: GPL-2.0+
4 * Hans-Joerg Frieden, Hyperion Entertainment
5 * Hans-JoergF@hyperion-entertainment.com
11 #include "part_amiga.h"
17 #define PRINTF(fmt, args...) printf(fmt ,##args)
19 #define PRINTF(fmt, args...)
29 static unsigned char block_buffer
[DEFAULT_SECTOR_SIZE
];
30 static struct rigid_disk_block rdb
= {0};
31 static struct bootcode_block bootcode
= {0};
34 * Copy a bcpl to a c string
36 static void bcpl_strcpy(char *to
, char *from
)
49 * Print a BCPL String. BCPL strings start with a byte with the length
50 * of the string, and don't contain a terminating nul character
52 static void bstr_print(char *string
)
61 buffer
[i
++] = *string
++;
66 printf("%-10s", buffer
);
70 * Sum a block. The checksum of a block must end up at zero
71 * to be valid. The chk_sum field is selected so that adding
74 int sum_block(struct block_header
*header
)
76 s32
*block
= (s32
*)header
;
80 for (i
= 0; i
< header
->summed_longs
; i
++)
87 * Print an AmigaOS disk type. Disk types are a four-byte identifier
88 * describing the file system. They are usually written as a three-letter
89 * word followed by a backslash and a version number. For example,
90 * DOS\0 would be the original file system. SFS\0 would be SmartFileSystem.
93 static void print_disk_type(u32 disk_type
)
96 buffer
[0] = (disk_type
& 0xFF000000)>>24;
97 buffer
[1] = (disk_type
& 0x00FF0000)>>16;
98 buffer
[2] = (disk_type
& 0x0000FF00)>>8;
100 buffer
[4] = (disk_type
& 0x000000FF) + '0';
102 printf("%s", buffer
);
106 * Print the info contained within the given partition block
108 static void print_part_info(struct partition_block
*p
)
110 struct amiga_part_geometry
*g
;
112 g
= (struct amiga_part_geometry
*)&(p
->environment
);
114 bstr_print(p
->drive_name
);
116 g
->low_cyl
* g
->block_per_track
* g
->surfaces
,
117 (g
->high_cyl
- g
->low_cyl
+ 1) * g
->block_per_track
* g
->surfaces
- 1);
118 print_disk_type(g
->dos_type
);
119 printf("\t%5d\n", g
->boot_priority
);
123 * Search for the Rigid Disk Block. The rigid disk block is required
124 * to be within the first 16 blocks of a drive, needs to have
125 * the ID AMIGA_ID_RDISK ('RDSK') and needs to have a valid
126 * sum-to-zero checksum
128 struct rigid_disk_block
*get_rdisk(struct blk_desc
*desc
)
134 s
= env_get("amiga_scanlimit");
136 limit
= dectoul(s
, NULL
);
138 limit
= AMIGA_BLOCK_LIMIT
;
140 for (i
=0; i
<limit
; i
++)
142 ulong res
= blk_dread(desc
, i
, 1, (ulong
*)block_buffer
);
145 struct rigid_disk_block
*trdb
= (struct rigid_disk_block
*)block_buffer
;
146 if (trdb
->id
== AMIGA_ID_RDISK
)
148 PRINTF("Rigid disk block suspect at %d, checking checksum\n",i
);
149 if (sum_block((struct block_header
*)block_buffer
) == 0)
152 memcpy(&rdb
, trdb
, sizeof(struct rigid_disk_block
));
153 return (struct rigid_disk_block
*)&rdb
;
158 PRINTF("Done scanning, no RDB found\n");
163 * Search for boot code
164 * Again, the first boot block must be located somewhere in the first 16 blocks, or rooted in the
168 struct bootcode_block
*get_bootcode(struct blk_desc
*desc
)
174 s
= env_get("amiga_scanlimit");
176 limit
= dectoul(s
, NULL
);
178 limit
= AMIGA_BLOCK_LIMIT
;
180 PRINTF("Scanning for BOOT from 0 to %d\n", limit
);
182 for (i
= 0; i
< limit
; i
++)
184 ulong res
= blk_dread(desc
, i
, 1, (ulong
*)block_buffer
);
187 struct bootcode_block
*boot
= (struct bootcode_block
*)block_buffer
;
188 if (boot
->id
== AMIGA_ID_BOOT
)
190 PRINTF("BOOT block at %d, checking checksum\n", i
);
191 if (sum_block((struct block_header
*)block_buffer
) == 0)
193 PRINTF("Found valid bootcode block\n");
194 memcpy(&bootcode
, boot
, sizeof(struct bootcode_block
));
201 PRINTF("No boot code found on disk\n");
206 * Test if the given partition has an Amiga partition table/Rigid
209 static int part_test_amiga(struct blk_desc
*desc
)
211 struct rigid_disk_block
*rdb
;
212 struct bootcode_block
*bootcode
;
214 PRINTF("part_test_amiga: Testing for an Amiga RDB partition\n");
216 rdb
= get_rdisk(desc
);
219 bootcode
= get_bootcode(desc
);
221 PRINTF("part_test_amiga: bootable Amiga disk\n");
223 PRINTF("part_test_amiga: non-bootable Amiga disk\n");
229 PRINTF("part_test_amiga: no RDB found\n");
236 * Find partition number partnum on the given drive.
238 static struct partition_block
*find_partition(struct blk_desc
*desc
,
241 struct rigid_disk_block
*rdb
;
242 struct partition_block
*p
;
245 PRINTF("Trying to find partition block %d\n", partnum
);
246 rdb
= get_rdisk(desc
);
249 PRINTF("find_partition: no rdb found\n");
253 PRINTF("find_partition: Scanning partition list\n");
255 block
= rdb
->partition_list
;
256 PRINTF("find_partition: partition list at 0x%x\n", block
);
258 while (block
!= 0xFFFFFFFF)
260 ulong res
= blk_dread(desc
, block
, 1, (ulong
*)block_buffer
);
263 p
= (struct partition_block
*)block_buffer
;
264 if (p
->id
== AMIGA_ID_PART
)
266 PRINTF("PART block suspect at 0x%x, checking checksum\n",block
);
267 if (sum_block((struct block_header
*)p
) == 0)
269 if (partnum
== 0) break;
276 } else block
= 0xFFFFFFFF;
277 } else block
= 0xFFFFFFFF;
280 if (block
== 0xFFFFFFFF)
282 PRINTF("PART block not found\n");
286 return (struct partition_block
*)block_buffer
;
290 * Get info about a partition
292 static int part_get_info_amiga(struct blk_desc
*desc
, int part
,
293 struct disk_partition
*info
)
295 struct partition_block
*p
= find_partition(desc
, part
- 1);
296 struct amiga_part_geometry
*g
;
301 g
= (struct amiga_part_geometry
*)&(p
->environment
);
302 info
->start
= g
->low_cyl
* g
->block_per_track
* g
->surfaces
;
303 info
->size
= (g
->high_cyl
- g
->low_cyl
+ 1) * g
->block_per_track
* g
->surfaces
- 1;
304 info
->blksz
= rdb
.block_bytes
;
305 bcpl_strcpy((char *)info
->name
, p
->drive_name
);
308 disk_type
= g
->dos_type
;
310 info
->type
[0] = (disk_type
& 0xFF000000)>>24;
311 info
->type
[1] = (disk_type
& 0x00FF0000)>>16;
312 info
->type
[2] = (disk_type
& 0x0000FF00)>>8;
313 info
->type
[3] = '\\';
314 info
->type
[4] = (disk_type
& 0x000000FF) + '0';
320 static void part_print_amiga(struct blk_desc
*desc
)
322 struct rigid_disk_block
*rdb
;
323 struct bootcode_block
*boot
;
324 struct partition_block
*p
;
328 rdb
= get_rdisk(desc
);
331 PRINTF("part_print_amiga: no rdb found\n");
335 PRINTF("part_print_amiga: Scanning partition list\n");
337 block
= rdb
->partition_list
;
338 PRINTF("part_print_amiga: partition list at 0x%x\n", block
);
340 printf("Summary: DiskBlockSize: %d\n"
342 " Sectors/Track: %d\n"
344 rdb
->block_bytes
, rdb
->cylinders
, rdb
->sectors
,
347 printf(" First Num. \n"
348 "Nr. Part. Name Block Block Type Boot Priority\n");
350 while (block
!= 0xFFFFFFFF)
354 PRINTF("Trying to load block #0x%X\n", block
);
356 res
= blk_dread(desc
, block
, 1, (ulong
*)block_buffer
);
359 p
= (struct partition_block
*)block_buffer
;
360 if (p
->id
== AMIGA_ID_PART
)
362 PRINTF("PART block suspect at 0x%x, checking checksum\n",block
);
363 if (sum_block((struct block_header
*)p
) == 0)
365 printf("%-4d ", i
); i
++;
369 } else block
= 0xFFFFFFFF;
370 } else block
= 0xFFFFFFFF;
373 boot
= get_bootcode(desc
);
376 printf("Disk is bootable\n");
380 U_BOOT_PART_TYPE(amiga
) = {
382 .part_type
= PART_TYPE_AMIGA
,
383 .max_entries
= AMIGA_ENTRY_NUMBERS
,
384 .get_info
= part_get_info_amiga
,
385 .print
= part_print_amiga
,
386 .test
= part_test_amiga
,