This commit was manufactured by cvs2svn to create branch
[external/binutils.git] / sim / ppc / pk_disklabel.c
index ec006b0..91dcf7c 100644 (file)
@@ -1,6 +1,6 @@
 /*  This file is part of the program psim.
     
-    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
     
     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
@@ -174,7 +174,7 @@ static const device_instance_callbacks package_disklabel_callbacks = {
 /* Reconize different types of boot block */
 
 static int
-block_is_bpb(const unsigned8 block[])
+block0_is_bpb(const unsigned8 block[])
 {
   const char ebdic_ibma[] = { 0xc9, 0xc2, 0xd4, 0xc1 };
   /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
@@ -194,46 +194,97 @@ block_is_bpb(const unsigned8 block[])
   return 1;
 }
 
-/* is_iso9660() later ... */
+
+/* Verify that the device contains an ISO-9660 File system */
 
 static int
-block_is_fdisk(const unsigned8 block[])
+is_iso9660(device_instance *raw_disk)
 {
-  const int partition_type_fields[] = { 0x1c2, 0x1d2, 0x1e2, 0x1f2, 0 };
+  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
+  unsigned8 block[512];
+  if (device_instance_seek(raw_disk, 0, 512 * 64) < 0)
+    return 0;
+  if (device_instance_read(raw_disk, block, sizeof(block)) != sizeof(block))
+    return 0;
+  if (block[0] == 0x01
+      && block[1] == 'C'
+      && block[2] == 'D'
+      && block[3] == '0'
+      && block[4] == '0'
+      && block[5] == '1')
+    return 1;
+  return 0;
+}
+
+
+/* Verify that the disk block contains a valid DOS partition table.
+   While we're at it have a look around for active partitions etc.
+
+   Return 0: invalid
+   Return 1..4: valid, value returned is the first active partition
+   Return -1: no active partition */
+
+static int
+block0_is_fdisk(const unsigned8 block[])
+{
+  const int partition_type_fields[] = { 0, 0x1c2, 0x1d2, 0x1e2, 0x1f2 };
+  const int partition_active_fields[] = { 0, 0x1be, 0x1ce, 0x1de, 0xee };
   int partition;
+  int active = -1;
   /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
   /* must have LE 0xAA55 signature at offset 510 */
-  if (block[511] != 0xAA && block[510] != 0x55)
+  if (block[511/*0x1ff*/] != 0xAA && block[510/*0x1fe*/] != 0x55)
     return 0;
   /* must contain valid partition types */
-  for (partition = 0;
-       partition_type_fields[partition] != 0;
-       partition++) {
-    switch (block[partition_type_fields[partition]]) {
-    case 4: case 0x41: case 0x96:
+  for (partition = 1; partition <= 4 && active != 0; partition++) {
+    int partition_type = block[partition_type_fields[partition]];
+    int is_active = block[partition_active_fields[partition]] == 0x80;
+    const char *type;
+    switch (partition_type) {
+    case 0x00:
+      type = "UNUSED";
       break;
-    case 5: case 6:
-      PTRACE(disklabel, ("extended partition types not supported\n"));
-      return 0;
-    case 0x82:
-      PTRACE(disklabel, ("warning - partition %d of type 0x82 - Solaris?\n", partition));
+    case 0x01:
+      type = "FAT 12 File system";
+      break;
+    case 0x04:
+      type = "FAT 16 File system";
       break;
-    case 0x1:
-      PTRACE(disklabel, ("warning - partition %d of type 1 - DOS12\n", partition));
+    case 0x05:
+    case 0x06:
+      type = "rejected - extended/chained partition not supported";
+      active = 0;
       break;
-    case 0:
+    case 0x41:
+      type = "Single program image";
+      break;
+    case 0x82:
+      type = "Solaris?";
+      break;
+    case 0x96:
+      type = "ISO 9660 File system";
       break;
     default:
-      PTRACE(disklabel, ("rejecting partition %d of type 0x%x\n", partition,
-                        block[partition_type_fields[partition]]));
-      return 0;
+      type = "rejected - unknown type";
+      active = 0;
+      break;
     }
+    PTRACE(disklabel, ("partition %d of type 0x%02x - %s%s\n",
+                      partition,
+                      partition_type,
+                      type,
+                      is_active && active != 0 ? " (active)" : ""));
+    if (partition_type != 0 && is_active && active < 0)
+      active = partition;
   }
-  return 1;
+  return active;
 }
 
+
+/* Verify that block0 corresponds to a MAC disk */
+
 static int
-block_is_mac_disk(const unsigned8 block[])
+block0_is_mac_disk(const unsigned8 block[])
 {
   /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
   /* signature - BEx4552 at offset 0 */
@@ -251,7 +302,6 @@ pk_disklabel_create_instance(device_instance *raw_disk,
 {
   int partition;
   char *filename;
-  unsigned8 boot_block[512];
 
   /* parse the arguments */
   if (args == NULL) {
@@ -268,68 +318,84 @@ pk_disklabel_create_instance(device_instance *raw_disk,
       filename = NULL; /* easier */
   }
 
-  if (device_instance_seek(raw_disk, 0, 0) < 0)
-    device_error(device_instance_device(raw_disk),
-                "Problem seeking on raw disk\n");
-
-  if (partition < 0) {
-    /* select the active partition */
-    if (device_instance_read(raw_disk, &boot_block, sizeof(boot_block))
-       != sizeof(boot_block))
-      return raw_disk;
-    device_error(device_instance_device(raw_disk),
-                "selection of the active partition unimplemented\n");
-    return (device_instance *)0;       /* silence warnings */
-  }
-  else if (partition == 0) {
+  if (partition == 0) {
     /* select the raw disk */
     return raw_disk;
   }
   else {
-    /* select the specified disk partition */
-    /* read in the boot record */
+    unsigned8 boot_block[512];
+    /* get the boot block for examination */
+    if (device_instance_seek(raw_disk, 0, 0) < 0)
+      device_error(device_instance_device(raw_disk),
+                  "Problem seeking on raw disk");
     if (device_instance_read(raw_disk, &boot_block, sizeof(boot_block))
        != sizeof(boot_block))
-      return raw_disk;
-    if (block_is_bpb(boot_block)) {
-      device_error(device_instance_device(raw_disk), "Unimplemented\n");
-    }
-    else if (block_is_fdisk(boot_block)) {
-      /* return an instance */
-      ppcboot_partition_t *partition_table = (ppcboot_partition_t*) &boot_block[446];
-      ppcboot_partition_t *partition_entry;
-      disklabel *label;
-      if (partition > 3)
-       device_error(device_instance_device(raw_disk),
-                    "Invalid fdisk partition number %d\n", partition);
-      partition_entry = &partition_table[partition-1];
-      label = ZALLOC(disklabel);
-      label->raw_disk = raw_disk;
-      label->pos = 0;
-      label->sector_begin = 512 * sector2uw(partition_entry->sector_begin);
-      label->sector_length = 512 * sector2uw(partition_entry->sector_length);
-      PTRACE(disklabel, ("partition %ld, sector-begin %ld, length %ld\n",
-                        (long)partition, (long)label->sector_begin, (long)label->sector_length));
-      if (filename != NULL)
-       device_error(device_instance_device(raw_disk),
-                    "File names not yet supported\n");
-      return device_create_instance_from(NULL, raw_disk,
-                                        label,
-                                        NULL, args,
-                                        &package_disklabel_callbacks);
-    }
-    else if (block_is_mac_disk(boot_block)) {
-      device_error(device_instance_device(raw_disk), "Unimplemented\n");
+      device_error(device_instance_device(raw_disk), "Problem reading boot block");
+
+    if (partition < 0) {
+      /* select the active partition */
+      if (block0_is_bpb(boot_block)) {
+       device_error(device_instance_device(raw_disk), "Unimplemented active BPB");
+      }
+      else if (block0_is_fdisk(boot_block)) {
+       int active = block0_is_fdisk(boot_block);
+       device_error(device_instance_device(raw_disk), "Unimplemented active FDISK (%d)",
+                    active);
+      }
+      else if (is_iso9660(raw_disk)) {
+       device_error(device_instance_device(raw_disk), "Unimplemented active ISO9660");
+      }
+      else if (block0_is_mac_disk(boot_block)) {
+       device_error(device_instance_device(raw_disk), "Unimplemented active MAC DISK");
+      }
+      else {
+       device_error(device_instance_device(raw_disk), "Unreconized bootblock");
+      }
     }
     else {
-      device_error(device_instance_device(raw_disk),
-                  "Unreconized bootblock\n");
+      /* select the specified disk partition */
+      if (block0_is_bpb(boot_block)) {
+       device_error(device_instance_device(raw_disk), "Unimplemented BPB");
+      }
+      else if (block0_is_fdisk(boot_block)) {
+       /* return an instance */
+       ppcboot_partition_t *partition_table = (ppcboot_partition_t*) &boot_block[446];
+       ppcboot_partition_t *partition_entry;
+       disklabel *label;
+       if (partition > 4)
+         device_error(device_instance_device(raw_disk),
+                      "Only FDISK partitions 1..4 supported");
+       partition_entry = &partition_table[partition - 1];
+       label = ZALLOC(disklabel);
+       label->raw_disk = raw_disk;
+       label->pos = 0;
+       label->sector_begin = 512 * sector2uw(partition_entry->sector_begin);
+       label->sector_length = 512 * sector2uw(partition_entry->sector_length);
+       PTRACE(disklabel, ("partition %ld, sector-begin %ld, length %ld\n",
+                          (long)partition,
+                          (long)label->sector_begin,
+                          (long)label->sector_length));
+       if (filename != NULL)
+         device_error(device_instance_device(raw_disk),
+                      "FDISK file names not yet supported");
+       return device_create_instance_from(NULL, raw_disk,
+                                          label,
+                                          NULL, args,
+                                          &package_disklabel_callbacks);
+      }
+      else if (block0_is_mac_disk(boot_block)) {
+       device_error(device_instance_device(raw_disk), "Unimplemented MAC DISK");
+      }
+      else {
+       device_error(device_instance_device(raw_disk),
+                    "Unreconized bootblock");
+      }
     }
-    return raw_disk;
   }
-
+  
+  return NULL;
 }
-
-
+  
+  
 #endif /* _PK_DISKLABEL_C_ */