static int hammerhead_add_extra_regs(void *dtb_buf) { FILE *f; uint32_t reg; int res; int off; off = fdt_path_offset(dtb_buf, "/memory"); if (off < 0) { fprintf(stderr, "DTB: Could not find memory node.\n"); return -1; } f = fopen("/proc/device-tree/memory/reg", "r"); if(!f) { fprintf(stderr, "DTB: Failed to open /proc/device-tree/memory/reg!\n"); return -1; } fdt_delprop(dtb_buf, off, "reg"); while(fread(®, sizeof(reg), 1, f) == 1) fdt_appendprop(dtb_buf, off, "reg", ®, sizeof(reg)); fclose(f); return 0; }
static int shamu_copy_prop(void *dtb_buf, const char *node, const char *name) { char buf[256]; FILE *f; int res = -1; int off; size_t len; snprintf(buf, sizeof(buf), "/proc/device-tree/%s/%s", node, name); f = fopen(buf, "re"); if(!f) { fprintf(stderr, "Failed to open %s!\n", buf); return -1; } off = fdt_path_offset(dtb_buf, node); if(off < 0) { fprintf(stderr, "DTB: Could not find node %s.\n", node); goto exit; } fdt_delprop(dtb_buf, off, name); while((len = fread(buf, 1, sizeof(buf)-1, f))) { buf[len] = 0; printf("DTB: adding %s/%s: %s\n", node, name, buf); fdt_appendprop(dtb_buf, off, name, buf, len); } res = 0; exit: fclose(f); return res; }
int main(int argc, char *argv[]) { void *fdt, *buf; int err; uint8_t bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04}; test_init(argc, argv); fdt = load_blob_arg(argc, argv); buf = xmalloc(SPACE); CHECK(fdt_open_into(fdt, buf, SPACE)); fdt = buf; CHECK(fdt_appendprop(fdt, 0, "prop-bytes", bytes, sizeof(bytes))); CHECK(fdt_appendprop_cell(fdt, 0, "prop-int", TEST_VALUE_2)); CHECK(fdt_appendprop_u64(fdt, 0, "prop-int64", TEST_VALUE64_1)); CHECK(fdt_appendprop_string(fdt, 0, "prop-str", TEST_STRING_2)); CHECK(fdt_pack(fdt)); save_blob("appendprop2.test.dtb", fdt); PASS(); }
STATIC EFI_STATUS PrepareFdt ( IN OUT VOID *Fdt, IN UINTN FdtSize ) { EFI_STATUS Status; INT32 Node; INT32 CpuNode; UINTN Index; ARM_CORE_INFO *ArmCoreInfoTable; UINTN ArmCoreCount; INT32 MapNode; INT32 ClusterNode; INT32 PmuNode; PMU_INTERRUPT PmuInt; INT32 Phandle[NUM_CORES]; UINT32 ClusterIndex; UINT32 CoreIndex; UINT32 ClusterCount; UINT32 CoresInCluster; UINT32 ClusterId; UINTN MpId; CHAR8 Name[10]; AMD_MP_CORE_INFO_PROTOCOL *AmdMpCoreInfoProtocol; // // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms. // // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file // in the kernel documentation: // Documentation/devicetree/bindings/arm/cpus.txt // Status = gBS->LocateProtocol ( &gAmdMpCoreInfoProtocolGuid, NULL, (VOID **)&AmdMpCoreInfoProtocol ); ASSERT_EFI_ERROR (Status); // Get pointer to ARM core info table ArmCoreInfoTable = AmdMpCoreInfoProtocol->GetArmCoreInfoTable (&ArmCoreCount); ASSERT (ArmCoreInfoTable != NULL); ASSERT (ArmCoreCount <= NUM_CORES); // Get Id from primary CPU MpId = (UINTN)ArmReadMpidr (); // Create /pmu node PmuNode = fdt_add_subnode(Fdt, 0, "pmu"); if (PmuNode >= 0) { fdt_setprop_string (Fdt, PmuNode, "compatible", "arm,armv8-pmuv3"); // append PMU interrupts for (Index = 0; Index < ArmCoreCount; Index++) { MpId = (UINTN)GET_MPID (ArmCoreInfoTable[Index].ClusterId, ArmCoreInfoTable[Index].CoreId); Status = AmdMpCoreInfoProtocol->GetPmuSpiFromMpId (MpId, &PmuInt.IntId); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "FDT: Error getting PMU interrupt for MpId '0x%x'\n", MpId)); return Status; } PmuInt.Flag = cpu_to_fdt32 (PMU_INT_FLAG_SPI); PmuInt.IntId = cpu_to_fdt32 (PmuInt.IntId); PmuInt.Type = cpu_to_fdt32 (PMU_INT_TYPE_HIGH_LEVEL); fdt_appendprop (Fdt, PmuNode, "interrupts", &PmuInt, sizeof(PmuInt)); } } else { DEBUG ((DEBUG_ERROR, "FDT: Error creating 'pmu' node\n")); return EFI_INVALID_PARAMETER; } // Create /cpus noide Node = fdt_add_subnode (Fdt, 0, "cpus"); if (Node >= 0) { // Configure the 'cpus' node fdt_setprop_string (Fdt, Node, "name", "cpus"); fdt_setprop_cell (Fdt, Node, "#address-cells", sizeof (UINTN) / 4); fdt_setprop_cell (Fdt, Node, "#size-cells", 0); } else { DEBUG ((DEBUG_ERROR, "FDT: Error creating 'cpus' node\n")); return EFI_INVALID_PARAMETER; } // // Walk the processor table in reverse order for proper listing in FDT // Index = ArmCoreCount; while (Index--) { // Create 'cpu' node AsciiSPrint (Name, sizeof (Name), "CPU%d", Index); CpuNode = fdt_add_subnode (Fdt, Node, Name); if (CpuNode < 0) { DEBUG ((DEBUG_ERROR, "FDT: Error on creating '%a' node\n", Name)); return EFI_INVALID_PARAMETER; } Phandle[Index] = fdt_alloc_phandle (Fdt); fdt_setprop_cell (Fdt, CpuNode, "phandle", Phandle[Index]); fdt_setprop_cell (Fdt, CpuNode, "linux,phandle", Phandle[Index]); fdt_setprop_string (Fdt, CpuNode, "enable-method", "psci"); MpId = (UINTN)GET_MPID (ArmCoreInfoTable[Index].ClusterId, ArmCoreInfoTable[Index].CoreId); MpId = cpu_to_fdt64 (MpId); fdt_setprop (Fdt, CpuNode, "reg", &MpId, sizeof (MpId)); fdt_setprop_string (Fdt, CpuNode, "compatible", "arm,armv8"); fdt_setprop_string (Fdt, CpuNode, "device_type", "cpu"); } // Create /cpu-map node MapNode = fdt_add_subnode (Fdt, Node, "cpu-map"); if (MapNode >= 0) { ClusterIndex = ArmCoreCount - 1; ClusterCount = NumberOfClustersInTable (ArmCoreInfoTable, ArmCoreCount); while (ClusterCount--) { // Create 'cluster' node AsciiSPrint (Name, sizeof (Name), "cluster%d", ClusterCount); ClusterNode = fdt_add_subnode (Fdt, MapNode, Name); if (ClusterNode < 0) { DEBUG ((DEBUG_ERROR, "FDT: Error creating '%a' node\n", Name)); return EFI_INVALID_PARAMETER; } ClusterId = ArmCoreInfoTable[ClusterIndex].ClusterId; CoreIndex = ClusterIndex; CoresInCluster = NumberOfCoresInCluster (ArmCoreInfoTable, ArmCoreCount, ClusterId); while (CoresInCluster--) { // Create 'core' node AsciiSPrint (Name, sizeof (Name), "core%d", CoresInCluster); CpuNode = fdt_add_subnode (Fdt, ClusterNode, Name); if (CpuNode < 0) { DEBUG ((DEBUG_ERROR, "FDT: Error creating '%a' node\n", Name)); return EFI_INVALID_PARAMETER; } fdt_setprop_cell (Fdt, CpuNode, "cpu", Phandle[CoreIndex]); // iterate to next core in cluster if (CoresInCluster) { do { --CoreIndex; } while (ClusterId != ArmCoreInfoTable[CoreIndex].ClusterId); } } // iterate to next cluster if (ClusterCount) { do { --ClusterIndex; } while (ClusterInRange (ArmCoreInfoTable, ArmCoreInfoTable[ClusterIndex].ClusterId, ClusterIndex + 1, ArmCoreCount - 1)); } } } else { DEBUG ((DEBUG_ERROR,"FDT: Error creating 'cpu-map' node\n")); return EFI_INVALID_PARAMETER; } SetSocIdStatus (Fdt); SetXgbeStatus (Fdt); // Update the real size of the Device Tree fdt_pack (Fdt); return EFI_SUCCESS; }
static int append_psci_compatible(void *fdt, int offs, const char *str) { return fdt_appendprop(fdt, offs, "compatible", str, strlen(str) + 1); }