Przeglądaj źródła

[int13] Add infrastructure to support EDD version 4.0

Support the extensions mandated by EDD 4.0, including:

 o  the ability to specify a flat physical address in a disk address
    packet,

 o  the ability to specify a sector count greater than 127 in a disk
    address packet,

 o  support for all functions within the Fixed Disk Access and EDD
    Support subsets,

 o  the ability to describe a device using EDD Device Path Information.

This implementation is based on draft revision 3 of the EDD 4.0
specification, with reference to the EDD 3.0 specification.  It is
possible that this implementation may need to change in order to
conform to the final published EDD 4.0 specification.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 lat temu
rodzic
commit
3c35ae2f3b

+ 27
- 4
src/arch/i386/include/int13.h Wyświetl plik

@@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 12
 #include <stdint.h>
13 13
 #include <ipxe/list.h>
14
+#include <ipxe/edd.h>
14 15
 #include <realmode.h>
15 16
 
16 17
 /**
@@ -36,6 +37,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
36 37
 #define INT13_EXTENDED_READ		0x42
37 38
 /** Extended write */
38 39
 #define INT13_EXTENDED_WRITE		0x43
40
+/** Verify sectors */
41
+#define INT13_EXTENDED_VERIFY		0x44
42
+/** Extended seek */
43
+#define INT13_EXTENDED_SEEK		0x47
39 44
 /** Get extended drive parameters */
40 45
 #define INT13_GET_EXTENDED_PARAMETERS	0x48
41 46
 /** Get CD-ROM status / terminate emulation */
@@ -68,16 +73,22 @@ FILE_LICENCE ( GPL2_OR_LATER );
68 73
 struct int13_disk_address {
69 74
 	/** Size of the packet, in bytes */
70 75
 	uint8_t bufsize;
71
-	/** Reserved, must be zero */
72
-	uint8_t reserved;
76
+	/** Reserved */
77
+	uint8_t reserved_a;
73 78
 	/** Block count */
74
-	uint16_t count;
79
+	uint8_t count;
80
+	/** Reserved */
81
+	uint8_t reserved_b;
75 82
 	/** Data buffer */
76 83
 	struct segoff buffer;
77 84
 	/** Starting block number */
78 85
 	uint64_t lba;
79
-	/** Data buffer (EDD-3.0 only) */
86
+	/** Data buffer (EDD 3.0+ only) */
80 87
 	uint64_t buffer_phys;
88
+	/** Block count (EDD 4.0+ only) */
89
+	uint32_t long_count;
90
+	/** Reserved */
91
+	uint32_t reserved_c;
81 92
 } __attribute__ (( packed ));
82 93
 
83 94
 /** INT 13 disk parameters */
@@ -96,6 +107,10 @@ struct int13_disk_parameters {
96 107
 	uint64_t sectors;
97 108
 	/** Bytes per sector */
98 109
 	uint16_t sector_size;
110
+	/** Device parameter table extension */
111
+	struct segoff dpte;
112
+	/** Device path information */
113
+	struct edd_device_path_information dpi;
99 114
 } __attribute__ (( packed ));
100 115
 
101 116
 /**
@@ -147,6 +162,8 @@ struct int13_disk_parameters {
147 162
 #define INT13_EXTENSION_REMOVABLE	0x02
148 163
 /** EDD functions supported */
149 164
 #define INT13_EXTENSION_EDD		0x04
165
+/** 64-bit extensions are present */
166
+#define INT13_EXTENSION_64BIT		0x08
150 167
 
151 168
 /** @} */
152 169
 
@@ -166,6 +183,12 @@ struct int13_disk_parameters {
166 183
 
167 184
 /** @} */ 
168 185
 
186
+/** Maximum number of sectors for which CHS geometry is allowed to be valid
187
+ *
188
+ * This number is taken from the EDD specification.
189
+ */
190
+#define INT13_MAX_CHS_SECTORS		15482880
191
+
169 192
 /** Bootable CD-ROM specification packet */
170 193
 struct int13_cdrom_specification {
171 194
 	/** Size of packet in bytes */

+ 216
- 23
src/arch/i386/interface/pcbios/int13.c Wyświetl plik

@@ -35,6 +35,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
35 35
 #include <ipxe/timer.h>
36 36
 #include <ipxe/acpi.h>
37 37
 #include <ipxe/sanboot.h>
38
+#include <ipxe/device.h>
39
+#include <ipxe/pci.h>
38 40
 #include <realmode.h>
39 41
 #include <bios.h>
40 42
 #include <biosint.h>
@@ -654,8 +656,10 @@ static int int13_extension_check ( struct int13_drive *int13 __unused,
654 656
 	if ( ix86->regs.bx == 0x55aa ) {
655 657
 		DBGC2 ( int13, "INT13 extensions installation check\n" );
656 658
 		ix86->regs.bx = 0xaa55;
657
-		ix86->regs.cx = INT13_EXTENSION_LINEAR;
658
-		return INT13_EXTENSION_VER_1_X;
659
+		ix86->regs.cx = ( INT13_EXTENSION_LINEAR |
660
+				  INT13_EXTENSION_EDD |
661
+				  INT13_EXTENSION_64BIT );
662
+		return INT13_EXTENSION_VER_3_0;
659 663
 	} else {
660 664
 		return -INT13_STATUS_INVALID;
661 665
 	}
@@ -678,25 +682,56 @@ static int int13_extended_rw ( struct int13_drive *int13,
678 682
 						    userptr_t buffer,
679 683
 						    size_t len ) ) {
680 684
 	struct int13_disk_address addr;
685
+	uint8_t bufsize;
681 686
 	uint64_t lba;
682 687
 	unsigned long count;
683 688
 	userptr_t buffer;
684 689
 	int rc;
685 690
 
691
+	/* Get buffer size */
692
+	get_real ( bufsize, ix86->segs.ds,
693
+		   ( ix86->regs.si + offsetof ( typeof ( addr ), bufsize ) ) );
694
+	if ( bufsize < offsetof ( typeof ( addr ), buffer_phys ) ) {
695
+		DBGC2 ( int13, "<invalid buffer size %#02x\n>\n", bufsize );
696
+		return -INT13_STATUS_INVALID;
697
+	}
698
+
686 699
 	/* Read parameters from disk address structure */
687
-	copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, sizeof ( addr ));
700
+	memset ( &addr, 0, sizeof ( addr ) );
701
+	copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, bufsize );
688 702
 	lba = addr.lba;
689
-	count = addr.count;
690
-	buffer = real_to_user ( addr.buffer.segment, addr.buffer.offset );
703
+	DBGC2 ( int13, "LBA %08llx <-> ", ( ( unsigned long long ) lba ) );
704
+	if ( ( addr.count == 0xff ) ||
705
+	     ( ( addr.buffer.segment == 0xffff ) &&
706
+	       ( addr.buffer.offset == 0xffff ) ) ) {
707
+		buffer = phys_to_user ( addr.buffer_phys );
708
+		DBGC2 ( int13, "%08llx",
709
+			( ( unsigned long long ) addr.buffer_phys ) );
710
+	} else {
711
+		buffer = real_to_user ( addr.buffer.segment,
712
+					addr.buffer.offset );
713
+		DBGC2 ( int13, "%04x:%04x", addr.buffer.segment,
714
+			addr.buffer.offset );
715
+	}
716
+	if ( addr.count <= 0x7f ) {
717
+		count = addr.count;
718
+	} else if ( addr.count == 0xff ) {
719
+		count = addr.long_count;
720
+	} else {
721
+		DBGC2 ( int13, " <invalid count %#02x>\n", addr.count );
722
+		return -INT13_STATUS_INVALID;
723
+	}
724
+	DBGC2 ( int13, " (count %ld)\n", count );
691 725
 
692
-	DBGC2 ( int13, "LBA %08llx <-> %04x:%04x (count %ld)\n",
693
-		( ( unsigned long long ) lba ), addr.buffer.segment,
694
-		addr.buffer.offset, count );
695
-	
696 726
 	/* Read from / write to block device */
697 727
 	if ( ( rc = int13_rw ( int13, lba, count, buffer, block_rw ) ) != 0 ) {
698 728
 		DBGC ( int13, "INT13 drive %02x extended I/O failed: %s\n",
699 729
 		       int13->drive, strerror ( rc ) );
730
+		/* Record that no blocks were transferred successfully */
731
+		addr.count = 0;
732
+		put_real ( addr.count, ix86->segs.ds,
733
+			   ( ix86->regs.si +
734
+			     offsetof ( typeof ( addr ), count ) ) );
700 735
 		return -INT13_STATUS_READ_ERROR;
701 736
 	}
702 737
 
@@ -729,6 +764,117 @@ static int int13_extended_write ( struct int13_drive *int13,
729 764
 	return int13_extended_rw ( int13, ix86, block_write );
730 765
 }
731 766
 
767
+/**
768
+ * INT 13, 44 - Verify sectors
769
+ *
770
+ * @v int13		Emulated drive
771
+ * @v ds:si		Disk address packet
772
+ * @ret status		Status code
773
+ */
774
+static int int13_extended_verify ( struct int13_drive *int13,
775
+				   struct i386_all_regs *ix86 ) {
776
+	struct int13_disk_address addr;
777
+	uint64_t lba;
778
+	unsigned long count;
779
+
780
+	/* Read parameters from disk address structure */
781
+	if ( DBG_EXTRA ) {
782
+		copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si,
783
+				 sizeof ( addr ));
784
+		lba = addr.lba;
785
+		count = addr.count;
786
+		DBGC2 ( int13, "Verify: LBA %08llx (count %ld)\n",
787
+			( ( unsigned long long ) lba ), count );
788
+	}
789
+
790
+	/* We have no mechanism for verifying sectors */
791
+	return -INT13_STATUS_INVALID;
792
+}
793
+
794
+/**
795
+ * INT 13, 44 - Extended seek
796
+ *
797
+ * @v int13		Emulated drive
798
+ * @v ds:si		Disk address packet
799
+ * @ret status		Status code
800
+ */
801
+int int13_extended_seek ( struct int13_drive *int13,
802
+			  struct i386_all_regs *ix86 ) {
803
+	struct int13_disk_address addr;
804
+	uint64_t lba;
805
+	unsigned long count;
806
+
807
+	/* Read parameters from disk address structure */
808
+	if ( DBG_EXTRA ) {
809
+		copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si,
810
+				 sizeof ( addr ));
811
+		lba = addr.lba;
812
+		count = addr.count;
813
+		DBGC2 ( int13, "Seek: LBA %08llx (count %ld)\n",
814
+			( ( unsigned long long ) lba ), count );
815
+	}
816
+
817
+	/* Ignore and return success */
818
+	return 0;
819
+}
820
+
821
+/**
822
+ * Build device path information
823
+ *
824
+ * @v int13		Emulated drive
825
+ * @v dpi		Device path information
826
+ * @ret rc		Return status code
827
+ */
828
+static int int13_device_path_info ( struct int13_drive *int13,
829
+				    struct edd_device_path_information *dpi ) {
830
+	struct device *device;
831
+	struct device_description *desc;
832
+	unsigned int i;
833
+	uint8_t sum = 0;
834
+	int rc;
835
+
836
+	/* Get underlying hardware device */
837
+	device = identify_device ( &int13->block );
838
+	if ( ! device ) {
839
+		DBGC ( int13, "INT13 drive %02x cannot identify hardware "
840
+		       "device\n", int13->drive );
841
+		return -ENODEV;
842
+	}
843
+
844
+	/* Fill in bus type and interface path */
845
+	desc = &device->desc;
846
+	switch ( desc->bus_type ) {
847
+	case BUS_TYPE_PCI:
848
+		dpi->host_bus_type.type = EDD_BUS_TYPE_PCI;
849
+		dpi->interface_path.pci.bus = PCI_BUS ( desc->location );
850
+		dpi->interface_path.pci.slot = PCI_SLOT ( desc->location );
851
+		dpi->interface_path.pci.function = PCI_FUNC ( desc->location );
852
+		dpi->interface_path.pci.channel = 0xff; /* unused */
853
+		break;
854
+	default:
855
+		DBGC ( int13, "INT13 drive %02x unrecognised bus type %d\n",
856
+		       int13->drive, desc->bus_type );
857
+		return -ENOTSUP;
858
+	}
859
+
860
+	/* Get EDD block device description */
861
+	if ( ( rc = edd_describe ( &int13->block, &dpi->interface_type,
862
+				   &dpi->device_path ) ) != 0 ) {
863
+		DBGC ( int13, "INT13 drive %02x cannot identify block device: "
864
+		       "%s\n", int13->drive, strerror ( rc ) );
865
+		return rc;
866
+	}
867
+
868
+	/* Fill in common fields and fix checksum */
869
+	dpi->key = EDD_DEVICE_PATH_INFO_KEY;
870
+	dpi->len = sizeof ( *dpi );
871
+	for ( i = 0 ; i < sizeof ( *dpi ) ; i++ )
872
+		sum += *( ( ( uint8_t * ) dpi ) + i );
873
+	dpi->checksum -= sum;
874
+
875
+	return 0;
876
+}
877
+
732 878
 /**
733 879
  * INT 13, 48 - Get extended parameters
734 880
  *
@@ -738,21 +884,62 @@ static int int13_extended_write ( struct int13_drive *int13,
738 884
  */
739 885
 static int int13_get_extended_parameters ( struct int13_drive *int13,
740 886
 					   struct i386_all_regs *ix86 ) {
741
-	struct int13_disk_parameters params = {
742
-		.bufsize = sizeof ( params ),
743
-		.flags = INT13_FL_DMA_TRANSPARENT,
744
-		.cylinders = int13->cylinders,
745
-		.heads = int13->heads,
746
-		.sectors_per_track = int13->sectors_per_track,
747
-		.sectors = int13->capacity.blocks,
748
-		.sector_size = int13->capacity.blksize,
749
-	};
750
-	
751
-	DBGC2 ( int13, "Get extended drive parameters to %04x:%04x\n",
752
-		ix86->segs.ds, ix86->regs.si );
887
+	struct int13_disk_parameters params;
888
+	struct segoff address;
889
+	size_t len = sizeof ( params );
890
+	uint16_t bufsize;
891
+	int rc;
892
+
893
+	/* Get buffer size */
894
+	get_real ( bufsize, ix86->segs.ds,
895
+		   ( ix86->regs.si + offsetof ( typeof ( params ), bufsize )));
896
+
897
+	DBGC2 ( int13, "Get extended drive parameters to %04x:%04x+%02x\n",
898
+		ix86->segs.ds, ix86->regs.si, bufsize );
899
+
900
+	/* Build drive parameters */
901
+	memset ( &params, 0, sizeof ( params ) );
902
+	params.flags = INT13_FL_DMA_TRANSPARENT;
903
+	if ( ( int13->cylinders < 1024 ) &&
904
+	     ( int13->capacity.blocks <= INT13_MAX_CHS_SECTORS ) ) {
905
+		params.flags |= INT13_FL_CHS_VALID;
906
+	}
907
+	params.cylinders = int13->cylinders;
908
+	params.heads = int13->heads;
909
+	params.sectors_per_track = int13->sectors_per_track;
910
+	params.sectors = int13->capacity.blocks;
911
+	params.sector_size = int13->capacity.blksize;
912
+	memset ( &params.dpte, 0xff, sizeof ( params.dpte ) );
913
+	if ( ( rc = int13_device_path_info ( int13, &params.dpi ) ) != 0 ) {
914
+		DBGC ( int13, "INT13 drive %02x could not provide device "
915
+		       "path information: %s\n",
916
+		       int13->drive, strerror ( rc ) );
917
+		len = offsetof ( typeof ( params ), dpi );
918
+	}
919
+
920
+	/* Calculate returned "buffer size" (which will be less than
921
+	 * the length actually copied if device path information is
922
+	 * present).
923
+	 */
924
+	if ( bufsize < offsetof ( typeof ( params ), dpte ) )
925
+		return -INT13_STATUS_INVALID;
926
+	if ( bufsize < offsetof ( typeof ( params ), dpi ) ) {
927
+		params.bufsize = offsetof ( typeof ( params ), dpte );
928
+	} else {
929
+		params.bufsize = offsetof ( typeof ( params ), dpi );
930
+	}
931
+
932
+	DBGC ( int13, "INT 13 drive %02x described using extended "
933
+	       "parameters:\n", int13->drive );
934
+	address.segment = ix86->segs.ds;
935
+	address.offset = ix86->regs.si;
936
+	DBGC_HDA ( int13, address, &params, len );
937
+
938
+	/* Return drive parameters */
939
+	if ( len > bufsize )
940
+		len = bufsize;
941
+	copy_to_real ( ix86->segs.ds, ix86->regs.si, &params, len );
753 942
 
754
-	copy_to_real ( ix86->segs.ds, ix86->regs.si, &params,
755
-		       sizeof ( params ) );
756 943
 	return 0;
757 944
 }
758 945
 
@@ -814,6 +1001,12 @@ static __asmcall void int13 ( struct i386_all_regs *ix86 ) {
814 1001
 		case INT13_EXTENDED_WRITE:
815 1002
 			status = int13_extended_write ( int13, ix86 );
816 1003
 			break;
1004
+		case INT13_EXTENDED_VERIFY:
1005
+			status = int13_extended_verify ( int13, ix86 );
1006
+			break;
1007
+		case INT13_EXTENDED_SEEK:
1008
+			status = int13_extended_seek ( int13, ix86 );
1009
+			break;
817 1010
 		case INT13_GET_EXTENDED_PARAMETERS:
818 1011
 			status = int13_get_extended_parameters ( int13, ix86 );
819 1012
 			break;

+ 26
- 1
src/core/device.c Wyświetl plik

@@ -21,8 +21,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
21 21
 #include <string.h>
22 22
 #include <ipxe/list.h>
23 23
 #include <ipxe/tables.h>
24
-#include <ipxe/device.h>
25 24
 #include <ipxe/init.h>
25
+#include <ipxe/interface.h>
26
+#include <ipxe/device.h>
26 27
 
27 28
 /**
28 29
  * @file
@@ -105,3 +106,27 @@ struct startup_fn startup_devices __startup_fn ( STARTUP_NORMAL ) = {
105 106
 	.startup = probe_devices,
106 107
 	.shutdown = remove_devices,
107 108
 };
109
+
110
+/**
111
+ * Identify a device behind an interface
112
+ *
113
+ * @v intf		Interface
114
+ * @ret device		Device, or NULL
115
+ */
116
+struct device * identify_device ( struct interface *intf ) {
117
+	struct interface *dest;
118
+	identify_device_TYPE ( void * ) *op =
119
+		intf_get_dest_op ( intf, identify_device, &dest );
120
+	void *object = intf_object ( dest );
121
+	void *device;
122
+
123
+	if ( op ) {
124
+		device = op ( object );
125
+	} else {
126
+		/* Default is to return NULL */
127
+		device = NULL;
128
+	}
129
+
130
+	intf_put ( dest );
131
+	return device;
132
+}

+ 56
- 0
src/core/edd.c Wyświetl plik

@@ -0,0 +1,56 @@
1
+/*
2
+ * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <errno.h>
22
+#include <ipxe/interface.h>
23
+#include <ipxe/edd.h>
24
+
25
+/** @file
26
+ *
27
+ * Enhanced Disk Drive specification
28
+ *
29
+ */
30
+
31
+/**
32
+ * Describe a disk device using EDD
33
+ *
34
+ * @v intf		Interface
35
+ * @v type		EDD interface type
36
+ * @v path		EDD device path
37
+ * @ret rc		Return status code
38
+ */
39
+int edd_describe ( struct interface *intf, struct edd_interface_type *type,
40
+		   union edd_device_path *path ) {
41
+	struct interface *dest;
42
+	edd_describe_TYPE ( void * ) *op =
43
+		intf_get_dest_op ( intf, edd_describe, &dest );
44
+	void *object = intf_object ( dest );
45
+	int rc;
46
+
47
+	if ( op ) {
48
+		rc = op ( object, type, path );
49
+	} else {
50
+		/* Default is to not support this operation */
51
+		rc = -ENOTSUP;
52
+	}
53
+
54
+	intf_put ( dest );
55
+	return rc;
56
+}

+ 6
- 0
src/include/ipxe/device.h Wyświetl plik

@@ -13,6 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
13 13
 #include <ipxe/list.h>
14 14
 #include <ipxe/tables.h>
15 15
 
16
+struct interface;
17
+
16 18
 /** A hardware device description */
17 19
 struct device_description {
18 20
 	/** Bus type
@@ -110,4 +112,8 @@ struct root_driver {
110 112
 /** Declare a root device */
111 113
 #define __root_device __table_entry ( ROOT_DEVICES, 01 )
112 114
 
115
+extern struct device * identify_device ( struct interface *intf );
116
+#define identify_device_TYPE( object_type ) \
117
+	typeof ( struct device * ( object_type ) )
118
+
113 119
 #endif /* _IPXE_DEVICE_H */

+ 193
- 0
src/include/ipxe/edd.h Wyświetl plik

@@ -0,0 +1,193 @@
1
+#ifndef _IPXE_EDD_H
2
+#define _IPXE_EDD_H
3
+
4
+/** @file
5
+ *
6
+ * Enhanced Disk Drive specification
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <stdint.h>
13
+#include <ipxe/interface.h>
14
+
15
+/** An EDD host bus type */
16
+struct edd_host_bus_type {
17
+	/** Type */
18
+	uint32_t type;
19
+} __attribute__ (( packed ));
20
+
21
+/** EDD bus type */
22
+#define EDD_BUS_TYPE_FIXED( a, b, c, d, ... )				    \
23
+	( ( (a) << 0 ) | ( (b) << 8 ) | ( (c) << 16 ) | ( (d) << 24 ) )
24
+#define EDD_BUS_TYPE( ... )						    \
25
+	EDD_BUS_TYPE_FIXED ( __VA_ARGS__, ' ', ' ', ' ', ' ' )
26
+/** EDD PCI bus type */
27
+#define EDD_BUS_TYPE_PCI EDD_BUS_TYPE ( 'P', 'C', 'I' )
28
+/** EDD ISA bus type */
29
+#define EDD_BUS_TYPE_ISA EDD_BUS_TYPE ( 'I', 'S', 'A' )
30
+/** EDD PCI-X bus type */
31
+#define EDD_BUS_TYPE_PCIX EDD_BUS_TYPE ( 'P', 'C', 'I', 'X' )
32
+/** EDD Infiniband bus type */
33
+#define EDD_BUS_TYPE_IBND EDD_BUS_TYPE ( 'I', 'B', 'N', 'D' )
34
+/** EDD PCI Express bus type */
35
+#define EDD_BUS_TYPE_XPRS EDD_BUS_TYPE ( 'X', 'P', 'R', 'S' )
36
+/** EDD HyperTransport bus type */
37
+#define EDD_BUS_TYPE_HTPT EDD_BUS_TYPE ( 'H', 'T', 'P', 'T' )
38
+
39
+/** An EDD interface type */
40
+struct edd_interface_type {
41
+	/** Type */
42
+	uint64_t type;
43
+} __attribute__ (( packed ));
44
+
45
+/** EDD interface type */
46
+#define EDD_INTF_TYPE_FIXED( a, b, c, d, e, f, g, h, ... )		    \
47
+	( ( ( ( uint64_t ) (a) ) <<  0 ) | ( ( ( uint64_t ) (b) ) <<  8 ) | \
48
+	  ( ( ( uint64_t ) (c) ) << 16 ) | ( ( ( uint64_t ) (d) ) << 24 ) | \
49
+	  ( ( ( uint64_t ) (e) ) << 32 ) | ( ( ( uint64_t ) (f) ) << 40 ) | \
50
+	  ( ( ( uint64_t ) (g) ) << 48 ) | ( ( ( uint64_t ) (h) ) << 56 ) )
51
+#define EDD_INTF_TYPE( ... )						    \
52
+	EDD_INTF_TYPE_FIXED ( __VA_ARGS__,				    \
53
+			      ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' )
54
+/** EDD ATA interface type */
55
+#define EDD_INTF_TYPE_ATA EDD_INTF_TYPE ( 'A', 'T', 'A' )
56
+/** EDD ATAPI interface type */
57
+#define EDD_INTF_TYPE_ATAPI EDD_INTF_TYPE ( 'A', 'T', 'A', 'P', 'I' )
58
+/** EDD SCSI interface type */
59
+#define EDD_INTF_TYPE_SCSI EDD_INTF_TYPE ( 'S', 'C', 'S', 'I' )
60
+/** EDD USB interface type */
61
+#define EDD_INTF_TYPE_USB EDD_INTF_TYPE ( 'U', 'S', 'B' )
62
+/** EDD 1394 interface type */
63
+#define EDD_INTF_TYPE_1394 EDD_INTF_TYPE ( '1', '3', '9', '4' )
64
+/** EDD Fibre Channel interface type */
65
+#define EDD_INTF_TYPE_FIBRE EDD_INTF_TYPE ( 'F', 'I', 'B', 'R', 'E' )
66
+/** EDD I2O interface type */
67
+#define EDD_INTF_TYPE_I2O EDD_INTF_TYPE ( 'I', '2', 'O' )
68
+/** EDD RAID interface type */
69
+#define EDD_INTF_TYPE_RAID EDD_INTF_TYPE ( 'R', 'A', 'I', 'D' )
70
+/** EDD SATA interface type */
71
+#define EDD_INTF_TYPE_SATA EDD_INTF_TYPE ( 'S', 'A', 'T', 'A' )
72
+/** EDD SAS interface type */
73
+#define EDD_INTF_TYPE_SAS EDD_INTF_TYPE ( 'S', 'A', 'S' )
74
+
75
+/** An EDD interface path */
76
+union edd_interface_path {
77
+	/** Legacy bus type */
78
+	struct {
79
+		/** Base address */
80
+		uint16_t base;
81
+	} __attribute__ (( packed )) legacy;
82
+	/** PCI, PCI-X, PCI Express, or HyperTransport bus type */
83
+	struct {
84
+		/** Bus */
85
+		uint8_t bus;
86
+		/** Slot */
87
+		uint8_t slot;
88
+		/** Function */
89
+		uint8_t function;
90
+		/** Channel number */
91
+		uint8_t channel;
92
+	} __attribute__ (( packed )) pci;
93
+	/** Padding */
94
+	uint8_t pad[8];
95
+} __attribute__ (( packed ));
96
+
97
+/** An EDD device path */
98
+union edd_device_path {
99
+	/** ATA interface type */
100
+	struct {
101
+		/** Slave */
102
+		uint8_t slave;
103
+	} __attribute__ (( packed )) ata;
104
+	/** ATAPI interface type */
105
+	struct {
106
+		/** Slave */
107
+		uint8_t slave;
108
+		/** Logical Unit Number */
109
+		uint8_t lun;
110
+	} __attribute__ (( packed )) atapi;
111
+	/** SCSI interface type */
112
+	struct {
113
+		/** SCSI ID */
114
+		uint16_t id;
115
+		/** Logical Unit Number */
116
+		uint64_t lun;
117
+	} __attribute__ (( packed )) scsi;
118
+	/** USB interface type */
119
+	struct {
120
+		/** Serial number */
121
+		uint64_t serial;
122
+	} __attribute__ (( packed )) usb;
123
+	/** IEEE1394 interface type */
124
+	struct {
125
+		/** GUID */
126
+		uint64_t guid;
127
+	} __attribute__ (( packed )) ieee1394;
128
+	/** Fibre Channel interface type */
129
+	struct {
130
+		/** WWN */
131
+		uint64_t wwn;
132
+		/** Logical Unit Number */
133
+		uint64_t lun;
134
+	} __attribute__ (( packed )) fibre;
135
+	/** I2O interface type */
136
+	struct {
137
+		/** Identity tag */
138
+		uint64_t tag;
139
+	} __attribute__ (( packed )) i2o;
140
+	/** RAID interface type */
141
+	struct {
142
+		/** Array number */
143
+		uint32_t array;
144
+	} __attribute__ (( packed )) raid;
145
+	/** SATA interface type */
146
+	struct {
147
+		/** Port number */
148
+		uint8_t port;
149
+		/** Port multiplier number */
150
+		uint8_t multiplier;
151
+	} __attribute__ (( packed )) sata;
152
+	/** SAS interface type */
153
+	struct {
154
+		/** Address */
155
+		uint64_t address;
156
+	} __attribute__ (( packed )) sas;
157
+	/** Padding */
158
+	uint8_t pad[16];
159
+} __attribute__ (( packed ));
160
+
161
+/** EDD device path information */
162
+struct edd_device_path_information {
163
+	/** Key */
164
+	uint16_t key;
165
+	/** Length of this structure */
166
+	uint8_t len;
167
+	/** Reserved */
168
+	uint8_t reserved_a[3];
169
+	/** Host bus type */
170
+	struct edd_host_bus_type host_bus_type;
171
+	/** Interface type */
172
+	struct edd_interface_type interface_type;
173
+	/** Interface path */
174
+	union edd_interface_path interface_path;
175
+	/** Device path */
176
+	union edd_device_path device_path;
177
+	/** Reserved */
178
+	uint8_t reserved_b;
179
+	/** Checksum */
180
+	uint8_t checksum;
181
+} __attribute__ (( packed ));
182
+
183
+/** EDD device path information key */
184
+#define EDD_DEVICE_PATH_INFO_KEY 0xbedd
185
+
186
+extern int edd_describe ( struct interface *intf,
187
+			  struct edd_interface_type *type,
188
+			  union edd_device_path *path );
189
+#define edd_describe_TYPE( object_type )				\
190
+	typeof ( int ( object_type, struct edd_interface_type *type,	\
191
+		       union edd_device_path *path ) )
192
+
193
+#endif /* _IPXE_EDD_H */

+ 1
- 0
src/include/ipxe/errfile.h Wyświetl plik

@@ -58,6 +58,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
58 58
 #define ERRFILE_blockdev	       ( ERRFILE_CORE | 0x00120000 )
59 59
 #define ERRFILE_acpi		       ( ERRFILE_CORE | 0x00130000 )
60 60
 #define ERRFILE_null_sanboot	       ( ERRFILE_CORE | 0x00140000 )
61
+#define ERRFILE_edd		       ( ERRFILE_CORE | 0x00150000 )
61 62
 
62 63
 #define ERRFILE_eisa		     ( ERRFILE_DRIVER | 0x00000000 )
63 64
 #define ERRFILE_isa		     ( ERRFILE_DRIVER | 0x00010000 )

Ładowanie…
Anuluj
Zapisz