mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 06:48:09 -08:00
Merge fa5f66da59
into 5495b11360
This commit is contained in:
commit
bd772896c2
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"type": "devicetree",
|
||||||
"name": "Example Laptop 16 Gen 7",
|
"name": "Example Laptop 16 Gen 7",
|
||||||
"compatible": "example,laptop-16-g7",
|
"compatible": "example,laptop-16-g7",
|
||||||
"hwids": [
|
"hwids": [
|
||||||
|
@ -23,8 +23,11 @@
|
|||||||
|
|
||||||
/* Validate the descriptor macros a bit that they match our expectations */
|
/* Validate the descriptor macros a bit that they match our expectations */
|
||||||
assert_cc(DEVICE_DESCRIPTOR_DEVICETREE == UINT32_C(0x1000001C));
|
assert_cc(DEVICE_DESCRIPTOR_DEVICETREE == UINT32_C(0x1000001C));
|
||||||
|
assert_cc(DEVICE_DESCRIPTOR_FW == UINT32_C(0x2000001C));
|
||||||
assert_cc(DEVICE_SIZE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == sizeof(Device));
|
assert_cc(DEVICE_SIZE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == sizeof(Device));
|
||||||
assert_cc(DEVICE_TYPE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == DEVICE_TYPE_DEVICETREE);
|
assert_cc(DEVICE_TYPE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == DEVICE_TYPE_DEVICETREE);
|
||||||
|
assert_cc(DEVICE_SIZE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_FW) == sizeof(Device));
|
||||||
|
assert_cc(DEVICE_TYPE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_FW) == DEVICE_TYPE_FW);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smbios_to_hashable_string() - Convert ascii smbios string to stripped char16_t.
|
* smbios_to_hashable_string() - Convert ascii smbios string to stripped char16_t.
|
||||||
@ -112,9 +115,11 @@ EFI_STATUS chid_match(const void *hwid_buffer, size_t hwid_length, const Device
|
|||||||
/* Count devices and check validity */
|
/* Count devices and check validity */
|
||||||
for (; (n_devices + 1) * sizeof(*devices) < hwid_length;) {
|
for (; (n_devices + 1) * sizeof(*devices) < hwid_length;) {
|
||||||
|
|
||||||
|
uint32_t dev_type;
|
||||||
|
dev_type = DEVICE_TYPE_FROM_DESCRIPTOR(devices[n_devices].descriptor);
|
||||||
if (devices[n_devices].descriptor == DEVICE_DESCRIPTOR_EOL)
|
if (devices[n_devices].descriptor == DEVICE_DESCRIPTOR_EOL)
|
||||||
break;
|
break;
|
||||||
if (devices[n_devices].descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
if ((dev_type != DEVICE_TYPE_FW) && (dev_type != DEVICE_TYPE_DEVICETREE))
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
n_devices++;
|
n_devices++;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,13 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEVICE_TYPE_DEVICETREE = 0x1, /* A devicetree blob */
|
DEVICE_TYPE_DEVICETREE = 0x1, /* A devicetree blob */
|
||||||
|
DEVICE_TYPE_FW, /* a firmware blob */
|
||||||
|
|
||||||
/* Maybe later additional types for:
|
/* Maybe later additional types for:
|
||||||
* - CoCo Bring-Your-Own-Firmware
|
* - CoCo Bring-Your-Own-Firmware
|
||||||
* - ACPI DSDT Overrides
|
* - ACPI DSDT Overrides
|
||||||
* - … */
|
* - … */
|
||||||
|
_DEVICE_TYPE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEVICE_SIZE_FROM_DESCRIPTOR(u) ((uint32_t) (u) & UINT32_C(0x0FFFFFFF))
|
#define DEVICE_SIZE_FROM_DESCRIPTOR(u) ((uint32_t) (u) & UINT32_C(0x0FFFFFFF))
|
||||||
@ -23,6 +25,7 @@ enum {
|
|||||||
#define DEVICE_MAKE_DESCRIPTOR(type, size) (((uint32_t) (size) | ((uint32_t) type << 28)))
|
#define DEVICE_MAKE_DESCRIPTOR(type, size) (((uint32_t) (size) | ((uint32_t) type << 28)))
|
||||||
|
|
||||||
#define DEVICE_DESCRIPTOR_DEVICETREE DEVICE_MAKE_DESCRIPTOR(DEVICE_TYPE_DEVICETREE, sizeof(Device))
|
#define DEVICE_DESCRIPTOR_DEVICETREE DEVICE_MAKE_DESCRIPTOR(DEVICE_TYPE_DEVICETREE, sizeof(Device))
|
||||||
|
#define DEVICE_DESCRIPTOR_FW DEVICE_MAKE_DESCRIPTOR(DEVICE_TYPE_FW, sizeof(Device))
|
||||||
#define DEVICE_DESCRIPTOR_EOL UINT32_C(0)
|
#define DEVICE_DESCRIPTOR_EOL UINT32_C(0)
|
||||||
|
|
||||||
typedef struct Device {
|
typedef struct Device {
|
||||||
@ -36,6 +39,13 @@ typedef struct Device {
|
|||||||
uint32_t name_offset; /* nul-terminated string or 0 if not present */
|
uint32_t name_offset; /* nul-terminated string or 0 if not present */
|
||||||
uint32_t compatible_offset; /* nul-terminated string or 0 if not present */
|
uint32_t compatible_offset; /* nul-terminated string or 0 if not present */
|
||||||
} devicetree;
|
} devicetree;
|
||||||
|
struct {
|
||||||
|
/* Offsets are relative to the beginning of the .hwids PE section.
|
||||||
|
They are nul-terminated strings when present or 0 if not present */
|
||||||
|
uint32_t name_offset; /* name or identifier for the firmware blob */
|
||||||
|
uint32_t compatible_offset; /* compatibility identifier to match a specific fw blob */
|
||||||
|
} fw;
|
||||||
|
|
||||||
/* fields for other descriptor types… */
|
/* fields for other descriptor types… */
|
||||||
};
|
};
|
||||||
} _packed_ Device;
|
} _packed_ Device;
|
||||||
@ -45,16 +55,18 @@ assert_cc(offsetof(Device, descriptor) == 0);
|
|||||||
assert_cc(offsetof(Device, chid) == 4);
|
assert_cc(offsetof(Device, chid) == 4);
|
||||||
assert_cc(offsetof(Device, devicetree.name_offset) == 20);
|
assert_cc(offsetof(Device, devicetree.name_offset) == 20);
|
||||||
assert_cc(offsetof(Device, devicetree.compatible_offset) == 24);
|
assert_cc(offsetof(Device, devicetree.compatible_offset) == 24);
|
||||||
|
assert_cc(offsetof(Device, fw.name_offset) == 20);
|
||||||
|
assert_cc(offsetof(Device, fw.compatible_offset) == 24);
|
||||||
assert_cc(sizeof(Device) == 28);
|
assert_cc(sizeof(Device) == 28);
|
||||||
|
|
||||||
static inline const char* device_get_name(const void *base, const Device *device) {
|
static inline const char* device_get_devicetree_name(const void *base, const Device *device) {
|
||||||
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return device->devicetree.name_offset == 0 ? NULL : (const char *) ((const uint8_t *) base + device->devicetree.name_offset);
|
return device->devicetree.name_offset == 0 ? NULL : (const char *) ((const uint8_t *) base + device->devicetree.name_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char* device_get_compatible(const void *base, const Device *device) {
|
static inline const char* device_get_devicetree_compatible(const void *base, const Device *device) {
|
||||||
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ static bool pe_use_this_dtb(
|
|||||||
if (!device || !base)
|
if (!device || !base)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char *compatible = device_get_compatible(base, device);
|
const char *compatible = device_get_devicetree_compatible(base, device);
|
||||||
if (!compatible)
|
if (!compatible)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1014,25 +1014,25 @@ def merge_sbat(input_pe: list[Path], input_text: list[str]) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Keep in sync with Device (DEVICE_TYPE_DEVICETREE) from src/boot/chid.h
|
# Keep in sync with Device from src/boot/chid.h
|
||||||
# uint32_t descriptor, EFI_GUID chid, uint32_t name_offset, uint32_t compatible_offset
|
# uint32_t descriptor, EFI_GUID chid, uint32_t name_offset, uint32_t compatible_offset
|
||||||
DEVICE_STRUCT_SIZE = 4 + 16 + 4 + 4
|
DEVICE_STRUCT_SIZE = 4 + 16 + 4 + 4
|
||||||
NULL_DEVICE = b'\0' * DEVICE_STRUCT_SIZE
|
NULL_DEVICE = b'\0' * DEVICE_STRUCT_SIZE
|
||||||
DEVICE_TYPE_DEVICETREE = 1
|
DEVICE_TYPE_DEVICETREE = 1
|
||||||
|
DEVICE_TYPE_FW = 2
|
||||||
|
|
||||||
|
|
||||||
def device_make_descriptor(device_type: int, size: int) -> int:
|
def device_make_descriptor(device_type: int, size: int) -> int:
|
||||||
return (size) | (device_type << 28)
|
return (size) | (device_type << 28)
|
||||||
|
|
||||||
|
|
||||||
DEVICETREE_DESCRIPTOR = device_make_descriptor(DEVICE_TYPE_DEVICETREE, DEVICE_STRUCT_SIZE)
|
def pack_device(
|
||||||
|
offsets: dict[str, int], devtype: int, name: str, compatible: str, chids: set[uuid.UUID]
|
||||||
|
) -> bytes:
|
||||||
def pack_device(offsets: dict[str, int], name: str, compatible: str, chids: set[uuid.UUID]) -> bytes:
|
|
||||||
data = b''
|
data = b''
|
||||||
|
descriptor = device_make_descriptor(devtype, DEVICE_STRUCT_SIZE)
|
||||||
for chid in sorted(chids):
|
for chid in sorted(chids):
|
||||||
data += struct.pack('<I', DEVICETREE_DESCRIPTOR)
|
data += struct.pack('<I', descriptor)
|
||||||
data += chid.bytes_le
|
data += chid.bytes_le
|
||||||
data += struct.pack('<II', offsets[name], offsets[compatible])
|
data += struct.pack('<II', offsets[name], offsets[compatible])
|
||||||
|
|
||||||
@ -1053,21 +1053,26 @@ def pack_strings(strings: set[str], base: int) -> tuple[bytes, dict[str, int]]:
|
|||||||
|
|
||||||
def parse_hwid_dir(path: Path) -> bytes:
|
def parse_hwid_dir(path: Path) -> bytes:
|
||||||
hwid_files = path.rglob('*.json')
|
hwid_files = path.rglob('*.json')
|
||||||
|
devstr_to_type: dict[str, int] = {
|
||||||
|
'devicetree': DEVICE_TYPE_DEVICETREE,
|
||||||
|
'firmware': DEVICE_TYPE_FW,
|
||||||
|
}
|
||||||
|
|
||||||
strings: set[str] = set()
|
strings: set[str] = set()
|
||||||
devices: collections.defaultdict[tuple[str, str], set[uuid.UUID]] = collections.defaultdict(set)
|
devices: collections.defaultdict[tuple[int, str, str], set[uuid.UUID]] = collections.defaultdict(set)
|
||||||
|
|
||||||
for hwid_file in hwid_files:
|
for hwid_file in hwid_files:
|
||||||
data = json.loads(hwid_file.read_text(encoding='UTF-8'))
|
data = json.loads(hwid_file.read_text(encoding='UTF-8'))
|
||||||
|
|
||||||
for k in ['name', 'compatible', 'hwids']:
|
for k in ['type', 'name', 'compatible', 'hwids']:
|
||||||
if k not in data:
|
if k not in data:
|
||||||
raise ValueError(f'hwid description file "{hwid_file}" does not contain "{k}"')
|
raise ValueError(f'hwid description file "{hwid_file}" does not contain "{k}"')
|
||||||
|
|
||||||
strings |= {data['name'], data['compatible']}
|
strings |= {data['name'], data['compatible']}
|
||||||
|
|
||||||
# (name, compatible) pair uniquely identifies the device
|
# (devtype, name, compatible) pair uniquely identifies the device
|
||||||
devices[(data['name'], data['compatible'])] |= {uuid.UUID(u) for u in data['hwids']}
|
devtype = devstr_to_type[data['type']]
|
||||||
|
devices[(devtype, data['name'], data['compatible'])] |= {uuid.UUID(u) for u in data['hwids']}
|
||||||
|
|
||||||
total_device_structs = 1
|
total_device_structs = 1
|
||||||
for dev, uuids in devices.items():
|
for dev, uuids in devices.items():
|
||||||
@ -1076,8 +1081,8 @@ def parse_hwid_dir(path: Path) -> bytes:
|
|||||||
strings_blob, offsets = pack_strings(strings, total_device_structs * DEVICE_STRUCT_SIZE)
|
strings_blob, offsets = pack_strings(strings, total_device_structs * DEVICE_STRUCT_SIZE)
|
||||||
|
|
||||||
devices_blob = b''
|
devices_blob = b''
|
||||||
for (name, compatible), uuids in devices.items():
|
for (devtype, name, compatible), uuids in devices.items():
|
||||||
devices_blob += pack_device(offsets, name, compatible, uuids)
|
devices_blob += pack_device(offsets, devtype, name, compatible, uuids)
|
||||||
|
|
||||||
devices_blob += NULL_DEVICE
|
devices_blob += NULL_DEVICE
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user