ArmVirtPkg/FdtClientDxe: add methods to iterate over memory nodes

Add high level methods to iterate over all 'reg' properties of all DT
nodes whose device_type properties have the value "memory". Since we are
modifying the FdtClient protocol, update the protocol and the only existing
implementation at the same time.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
Ard Biesheuvel 2016-09-15 13:33:23 +01:00
parent cfc8d51c0c
commit 969d2eb387
2 changed files with 101 additions and 0 deletions

View File

@ -192,6 +192,79 @@ FindCompatibleNodeReg (
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
FindNextMemoryNodeReg (
IN FDT_CLIENT_PROTOCOL *This,
IN INT32 PrevNode,
OUT INT32 *Node,
OUT CONST VOID **Reg,
OUT UINTN *AddressCells,
OUT UINTN *SizeCells,
OUT UINT32 *RegSize
)
{
INT32 Prev, Next;
CONST CHAR8 *DeviceType;
INT32 Len;
EFI_STATUS Status;
ASSERT (mDeviceTreeBase != NULL);
ASSERT (Node != NULL);
for (Prev = PrevNode;; Prev = Next) {
Next = fdt_next_node (mDeviceTreeBase, Prev, NULL);
if (Next < 0) {
break;
}
DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len);
if (DeviceType != NULL && AsciiStrCmp (DeviceType, "memory") == 0) {
//
// Get the 'reg' property of this memory node. For now, we will assume
// 8 byte quantities for base and size, respectively.
// TODO use #cells root properties instead
//
Status = GetNodeProperty (This, Next, "reg", Reg, RegSize);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_WARN,
"%a: ignoring memory node with no 'reg' property\n",
__FUNCTION__));
continue;
}
if ((*RegSize % 16) != 0) {
DEBUG ((EFI_D_WARN,
"%a: ignoring memory node with invalid 'reg' property (size == 0x%x)\n",
__FUNCTION__, *RegSize));
continue;
}
*Node = Next;
*AddressCells = 2;
*SizeCells = 2;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
STATIC
EFI_STATUS
EFIAPI
FindMemoryNodeReg (
IN FDT_CLIENT_PROTOCOL *This,
OUT INT32 *Node,
OUT CONST VOID **Reg,
OUT UINTN *AddressCells,
OUT UINTN *SizeCells,
OUT UINT32 *RegSize
)
{
return FindNextMemoryNodeReg (This, 0, Node, Reg, AddressCells, SizeCells,
RegSize);
}
STATIC
EFI_STATUS
GetOrInsertChosenNode (
@ -225,6 +298,8 @@ STATIC FDT_CLIENT_PROTOCOL mFdtClientProtocol = {
FindNextCompatibleNode,
FindCompatibleNodeProperty,
FindCompatibleNodeReg,
FindMemoryNodeReg,
FindNextMemoryNodeReg,
GetOrInsertChosenNode,
};

View File

@ -85,6 +85,29 @@ EFI_STATUS
OUT UINT32 *RegSize
);
typedef
EFI_STATUS
(EFIAPI *FDT_CLIENT_FIND_NEXT_MEMORY_NODE_REG) (
IN FDT_CLIENT_PROTOCOL *This,
IN INT32 PrevNode,
OUT INT32 *Node,
OUT CONST VOID **Reg,
OUT UINTN *AddressCells,
OUT UINTN *SizeCells,
OUT UINT32 *RegSize
);
typedef
EFI_STATUS
(EFIAPI *FDT_CLIENT_FIND_MEMORY_NODE_REG) (
IN FDT_CLIENT_PROTOCOL *This,
OUT INT32 *Node,
OUT CONST VOID **Reg,
OUT UINTN *AddressCells,
OUT UINTN *SizeCells,
OUT UINT32 *RegSize
);
typedef
EFI_STATUS
(EFIAPI *FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE) (
@ -101,6 +124,9 @@ struct _FDT_CLIENT_PROTOCOL {
FDT_CLIENT_FIND_COMPATIBLE_NODE_PROPERTY FindCompatibleNodeProperty;
FDT_CLIENT_FIND_COMPATIBLE_NODE_REG FindCompatibleNodeReg;
FDT_CLIENT_FIND_MEMORY_NODE_REG FindMemoryNodeReg;
FDT_CLIENT_FIND_NEXT_MEMORY_NODE_REG FindNextMemoryNodeReg;
FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE GetOrInsertChosenNode;
};