Print this page
10570 Need workaround to EFI boot on AMI BIOS


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  24  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  * Copyright 2016 Toomas Soome <tsoome@me.com>

  27  */
  28 
  29 /*
  30  * This module provides support for labeling operations for target
  31  * drivers.
  32  */
  33 
  34 #include <sys/scsi/scsi.h>
  35 #include <sys/sunddi.h>
  36 #include <sys/dklabel.h>
  37 #include <sys/dkio.h>
  38 #include <sys/vtoc.h>
  39 #include <sys/dktp/fdisk.h>
  40 #include <sys/vtrace.h>
  41 #include <sys/efi_partition.h>
  42 #include <sys/cmlb.h>
  43 #include <sys/cmlb_impl.h>
  44 #if defined(__i386) || defined(__amd64)
  45 #include <sys/fs/dv_node.h>
  46 #endif


2730 static void
2731 cmlb_swap_efi_gpe(int nparts, efi_gpe_t *p)
2732 {
2733         int i;
2734 
2735         _NOTE(ASSUMING_PROTECTED(*p))
2736         for (i = 0; i < nparts; i++) {
2737                 UUID_LE_CONVERT(p[i].efi_gpe_PartitionTypeGUID,
2738                     p[i].efi_gpe_PartitionTypeGUID);
2739                 p[i].efi_gpe_StartingLBA = LE_64(p[i].efi_gpe_StartingLBA);
2740                 p[i].efi_gpe_EndingLBA = LE_64(p[i].efi_gpe_EndingLBA);
2741                 /* PartitionAttrs */
2742         }
2743 }
2744 
2745 static int
2746 cmlb_validate_efi(efi_gpt_t *labp)
2747 {
2748         if (labp->efi_gpt_Signature != EFI_SIGNATURE)
2749                 return (EINVAL);
2750         /* at least 96 bytes in this version of the spec. */
2751         if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
2752             labp->efi_gpt_HeaderSize)
2753                 return (EINVAL);
2754         /* this should be 128 bytes */
2755         if (labp->efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t))
2756                 return (EINVAL);
2757         return (0);
2758 }
2759 
2760 /*
2761  * This function returns B_FALSE if there is a valid MBR signature and no
2762  * partition table entries of type EFI_PMBR (0xEE). Otherwise it returns B_TRUE.
2763  *
2764  * The EFI spec (1.10 and later) requires having a Protective MBR (PMBR) to
2765  * recognize the disk as GPT partitioned. However, some other OS creates an MBR
2766  * where a PMBR entry is not the only one. Also, if the first block has been
2767  * corrupted, currently best attempt to allow data access would be to try to
2768  * check for GPT headers. Hence in case of more than one partition entry, but
2769  * at least one EFI_PMBR partition type or no valid magic number, the function
2770  * returns B_TRUE to continue with looking for GPT header.




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  24  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  * Copyright 2016 Toomas Soome <tsoome@me.com>
  27  * Copyright (c) 2019, Joyent, Inc.
  28  */
  29 
  30 /*
  31  * This module provides support for labeling operations for target
  32  * drivers.
  33  */
  34 
  35 #include <sys/scsi/scsi.h>
  36 #include <sys/sunddi.h>
  37 #include <sys/dklabel.h>
  38 #include <sys/dkio.h>
  39 #include <sys/vtoc.h>
  40 #include <sys/dktp/fdisk.h>
  41 #include <sys/vtrace.h>
  42 #include <sys/efi_partition.h>
  43 #include <sys/cmlb.h>
  44 #include <sys/cmlb_impl.h>
  45 #if defined(__i386) || defined(__amd64)
  46 #include <sys/fs/dv_node.h>
  47 #endif


2731 static void
2732 cmlb_swap_efi_gpe(int nparts, efi_gpe_t *p)
2733 {
2734         int i;
2735 
2736         _NOTE(ASSUMING_PROTECTED(*p))
2737         for (i = 0; i < nparts; i++) {
2738                 UUID_LE_CONVERT(p[i].efi_gpe_PartitionTypeGUID,
2739                     p[i].efi_gpe_PartitionTypeGUID);
2740                 p[i].efi_gpe_StartingLBA = LE_64(p[i].efi_gpe_StartingLBA);
2741                 p[i].efi_gpe_EndingLBA = LE_64(p[i].efi_gpe_EndingLBA);
2742                 /* PartitionAttrs */
2743         }
2744 }
2745 
2746 static int
2747 cmlb_validate_efi(efi_gpt_t *labp)
2748 {
2749         if (labp->efi_gpt_Signature != EFI_SIGNATURE)
2750                 return (EINVAL);
2751         /* at least 92 bytes in this version of the spec. */
2752         if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
2753             labp->efi_gpt_HeaderSize)
2754                 return (EINVAL);
2755         /* this should be 128 bytes */
2756         if (labp->efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t))
2757                 return (EINVAL);
2758         return (0);
2759 }
2760 
2761 /*
2762  * This function returns B_FALSE if there is a valid MBR signature and no
2763  * partition table entries of type EFI_PMBR (0xEE). Otherwise it returns B_TRUE.
2764  *
2765  * The EFI spec (1.10 and later) requires having a Protective MBR (PMBR) to
2766  * recognize the disk as GPT partitioned. However, some other OS creates an MBR
2767  * where a PMBR entry is not the only one. Also, if the first block has been
2768  * corrupted, currently best attempt to allow data access would be to try to
2769  * check for GPT headers. Hence in case of more than one partition entry, but
2770  * at least one EFI_PMBR partition type or no valid magic number, the function
2771  * returns B_TRUE to continue with looking for GPT header.