OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
Apm.c
Go to the documentation of this file.
1
9#include "Partition.h"
10
28EFI_STATUS
30 IN EFI_DRIVER_BINDING_PROTOCOL *This,
31 IN EFI_HANDLE Handle,
32 IN EFI_DISK_IO_PROTOCOL *DiskIo,
33 IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
34 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
35 IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
36 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
37 )
38{
39 EFI_STATUS Status;
40 UINT32 BlockSize;
42 APM_ENTRY *ApmEntry;
44 UINT64 Offset;
45 UINT64 PartitionSize;
46 UINT64 PartitionStart;
47 EFI_LBA StartingLBA;
48 EFI_LBA EndingLBA;
49 UINT64 LBASize;
50 UINT32 Remainder;
51 UINTN Index;
52 EFI_STATUS ApmStatus;
53 HARDDRIVE_DEVICE_PATH HdDev;
54 EFI_PARTITION_INFO_PROTOCOL PartitionInfo;
55 APPLE_PARTITION_INFO_PROTOCOL ApplePartitionInfo;
56
57 //
58 // Check whether a medium is present
59 //
60 if (BlockIo->Media == NULL) {
61 return EFI_NO_MEDIA;
62 }
63
64 //
65 // Cerify the partition is physical
66 //
67 if (BlockIo->Media->LogicalPartition) {
68 return EFI_INVALID_PARAMETER;
69 }
70
71 //
72 // Allocate a buffer for the APM Driver Descriptor Map
73 //
74 Apm = AllocatePool (BlockIo->Media->BlockSize);
75 if (Apm == NULL) {
76 return EFI_OUT_OF_RESOURCES;
77 }
78
79 ApmStatus = EFI_NOT_FOUND;
80
81 //
82 // Read the APM Driver Descriptor Map from LBA #0
83 //
84 Status = BlockIo->ReadBlocks (
85 BlockIo,
86 BlockIo->Media->MediaId,
87 0,
88 BlockIo->Media->BlockSize,
89 Apm
90 );
91 if (EFI_ERROR (Status)) {
92 gBS->FreePool (Apm);
93 return Status;
94 }
95
96 //
97 // Verify that the APM Driver Descriptor Map is valid
98 //
99 if (Apm->Signature != APM_DRIVER_DESCRIPTOR_MAP_SIGNATURE) {
100 gBS->FreePool (Apm);
101 return EFI_NOT_FOUND;
102 }
103
104 BlockSize = SwapBytes16 (Apm->BlockSize);
105
106 //
107 // Allocate a buffer for an APM Entry
108 //
109 ApmEntry = AllocatePool (BlockSize);
110
111 if (ApmEntry == NULL) {
112 FreePool (Apm);
113 return EFI_OUT_OF_RESOURCES;
114 }
115
116 //
117 // Read the APM from LBA #1
118 //
119 Status = DiskIo->ReadDisk (
120 DiskIo,
121 BlockIo->Media->MediaId,
122 BlockSize,
123 BlockSize,
124 ApmEntry
125 );
126 if (EFI_ERROR (Status)) {
127 ApmStatus = Status;
128 goto Done;
129 }
130
131 //
132 // Verify that the APM is valid
133 //
134 if ( (ApmEntry->Signature != APM_ENTRY_SIGNATURE)
135 || (CompareMem (ApmEntry->PartitionType, APM_ENTRY_TYPE_APM, sizeof (APM_ENTRY_TYPE_APM)) != 0))
136 {
137 goto Done;
138 }
139
140 NumberOfPartitionEntries = SwapBytes32 (ApmEntry->NumberOfPartitionEntries);
141
142 //
143 // Check if there are Apple Partition Entries
144 //
145 if (NumberOfPartitionEntries < 2) {
146 goto Done;
147 }
148
149 Offset = 2 * BlockSize;
150
151 //
152 // Read the Apple Partition Entries
153 //
154 for (Index = 1; Index < NumberOfPartitionEntries; ++Index, Offset += BlockSize) {
155 Status = DiskIo->ReadDisk (
156 DiskIo,
157 BlockIo->Media->MediaId,
158 Offset,
159 BlockSize,
160 ApmEntry
161 );
162
163 if ( EFI_ERROR (Status)
164 || (ApmEntry->Signature != APM_ENTRY_SIGNATURE))
165 {
166 goto Done;
167 }
168
169 //
170 // Verify that the Apple Partition Entry is valid
171 //
172 if ( (CompareMem (ApmEntry->PartitionType, APM_ENTRY_TYPE_FREE, sizeof (APM_ENTRY_TYPE_FREE)) == 0)
173 || (SwapBytes32 (ApmEntry->PartitionSize) == 0))
174 {
175 continue;
176 }
177
178 PartitionStart = SwapBytes32 (ApmEntry->PartitionStart);
179
180 StartingLBA = DivU64x32Remainder (
182 BlockIo->Media->BlockSize,
183 &Remainder
184 );
185
186 if (Remainder != 0) {
187 continue;
188 }
189
190 // BUG: Already calculated above -> cache!
191 PartitionSize = SwapBytes32 (ApmEntry->PartitionSize);
192
195 BlockIo->Media->BlockSize,
196 &Remainder
197 );
198
199 if (Remainder != 0) {
200 continue;
201 }
202
203 EndingLBA = StartingLBA + LBASize - 1;
204
205 if (EndingLBA > BlockIo->Media->LastBlock) {
206 continue;
207 }
208
209 ZeroMem (&HdDev, sizeof (HdDev));
210 HdDev.Header.Type = MEDIA_DEVICE_PATH;
211 HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
212 SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
213
214 HdDev.PartitionNumber = (UINT32)Index + 1;
216 HdDev.PartitionStart = StartingLBA;
217 HdDev.PartitionSize = LBASize;
218
219 DEBUG ((EFI_D_INFO, " Index : %d\n", Index));
220 DEBUG ((EFI_D_INFO, " Start LBA : %x\n", HdDev.PartitionStart));
221 DEBUG ((EFI_D_INFO, " End LBA: %x\n", EndingLBA));
222 DEBUG ((EFI_D_INFO, " Partition size: %x\n", HdDev.PartitionSize));
223 DEBUG ((EFI_D_INFO, " Start : %x", MultU64x32 (PartitionStart, BlockSize)));
224 DEBUG ((EFI_D_INFO, " End : %x", MultU64x32 ((PartitionStart + PartitionSize - 1), BlockSize)));
225
226 ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));
227 PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
228 PartitionInfo.Type = PARTITION_TYPE_OTHER;
229
230 ZeroMem (&ApplePartitionInfo, sizeof (APPLE_PARTITION_INFO_PROTOCOL));
231 ApplePartitionInfo.Revision = APPLE_PARTITION_INFO_REVISION;
232 ApplePartitionInfo.PartitionNumber = HdDev.PartitionNumber;
233 ApplePartitionInfo.MBRType = HdDev.MBRType;
234 ApplePartitionInfo.PartitionStart = HdDev.PartitionStart;
235 ApplePartitionInfo.PartitionSize = HdDev.PartitionSize;
236
237 CopyMem (&ApplePartitionInfo.PartitionType, ApmEntry->PartitionType, sizeof (EFI_GUID));
238
240 This,
241 Handle,
242 DiskIo,
243 DiskIo2,
244 BlockIo,
245 BlockIo2,
246 DevicePath,
247 (EFI_DEVICE_PATH_PROTOCOL *)&HdDev,
248 &PartitionInfo,
249 &ApplePartitionInfo,
250 StartingLBA,
251 EndingLBA,
252 BlockIo->Media->BlockSize,
253 (EFI_GUID *)&ApplePartitionInfo.PartitionType
254 );
255
256 if (!EFI_ERROR (Status)) {
257 ApmStatus = EFI_SUCCESS;
258 }
259 }
260
261Done:
262 FreePool (ApmEntry);
263 FreePool (Apm);
264
265 return ApmStatus;
266}
EFI_STATUS PartitionInstallAppleChildHandles(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_DISK_IO2_PROTOCOL *DiskIo2, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition Apm.c:29
UINT32 LBASize
Definition Apm.h:70
#define MBR_TYPE_APPLE_PARTITION_TABLE_HEADER
Definition Apm.h:14
#define APM_ENTRY_TYPE_FREE
Definition Apm.h:17
UINT16 BlockSize
Definition Apm.h:32
PACKED struct @12 APM_DRIVER_DESCRIPTOR_MAP
UINT32 PartitionSize
Definition Apm.h:66
PACKED struct @13 APM_ENTRY
#define APM_ENTRY_TYPE_APM
Definition Apm.h:16
#define APM_ENTRY_SIGNATURE
Definition Apm.h:42
UINT32 PartitionStart
Definition Apm.h:65
#define APM_DRIVER_DESCRIPTOR_MAP_SIGNATURE
Definition Apm.h:25
UINT32 NumberOfPartitionEntries
Definition Apm.h:64
#define APPLE_PARTITION_INFO_REVISION
EFI_BOOT_SERVICES * gBS
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
EFI_STATUS PartitionInstallChildHandle(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ParentHandle, IN EFI_DISK_IO_PROTOCOL *ParentDiskIo, IN EFI_DISK_IO2_PROTOCOL *ParentDiskIo2, IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo, IN EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, IN EFI_PARTITION_INFO_PROTOCOL *PartitionInfo, IN APPLE_PARTITION_INFO_PROTOCOL *ApplePartitionInfo, IN EFI_LBA Start, IN EFI_LBA End, IN UINT32 BlockSize, IN EFI_GUID *TypeGuid)
Definition Partition.c:1140
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition UserMath.c:96
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
Definition UserMath.c:25