#include #include #include #include #include #include void DTBParse(Pointer dtb) { FDTHeader* header = (FDTHeader*)dtb; if (BytesSwap32(header->magic) != kFDTHeaderMagic) { OSPanic("Invalid DTB magic"); } UInt32 offStruct = BytesSwap32(header->offDtStruct); UInt32 offStrings = BytesSwap32(header->offDtStrings); BytePointer structs = (BytePointer)dtb + offStruct; ASCII* strings = (ASCII*)dtb + offStrings; ASCII* currentNode = ""; while (true) { UInt32 token = BytesSwap32(*(UInt32*)structs); structs += 4; switch (token) { case FDTTokenBeginNode: { currentNode = (ASCII*)structs; UInt32 nameLength = StringGetLength(currentNode); structs += (nameLength + 1); structs = (BytePointer)AlignUp64((Address)structs, 4); break; } case FDTTokenProperty: { UInt32 propertyLength = BytesSwap32(*(UInt32*)structs); UInt32 nameOffset = BytesSwap32(*(UInt32*)(structs + 4)); structs += 8; ASCII* propertyName = strings + nameOffset; if (StringCompare(propertyName, "reg") == 0 && StringStartsWith(currentNode, "memory")) { UInt32* cells = (UInt32*)structs; UInt64 base = Merge32To64(BytesSwap32(cells[0]), BytesSwap32(cells[1])); UInt64 size = Merge32To64(BytesSwap32(cells[2]), BytesSwap32(cells[3])); OSLog("Memory: base=0x%x, size=0x%x\n", base, size); } structs += propertyLength; structs = (BytePointer)AlignUp64((Address)structs, 4); break; } case FDTTokenEndNode: break; case FDTTokenNOP: continue; case FDTTokenEnd: return; default: OSPanic("Invalid DTB token"); } } }