diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index 029fd3da54..7641bea93c 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -52,6 +52,7 @@ KernelMergeObject boot_platform_u-boot_common.o : uimage.cpp video.cpp fdt_support.cpp + openfirmware.cpp $(genericPlatformSources) $(libFDTSources) @@ -247,6 +248,9 @@ Depends haiku-mmc-image : haiku-$(HAIKU_BOOT_BOARD).mmc ; SEARCH on [ FGristFiles $(genericPlatformSources) ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; +SEARCH on [ FGristFiles openfirmware.cpp ] + = [ FDirName $(HAIKU_TOP) src system kernel platform u-boot ] ; + SEARCH on [ FGristFiles $(libFDTSources) ] = [ FDirName $(HAIKU_TOP) src libs libfdt ] ; diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 81b03bf03c..1f51487af5 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -198,6 +199,9 @@ start_raw(int argc, const char **argv) args.platform.boot_tgz_data, args.platform.boot_tgz_size); } } + + // also initialize the OpenFirmware wrapper + of_init(NULL); } // if we get passed a uimage, try to find the second blob diff --git a/src/system/kernel/platform/u-boot/Jamfile b/src/system/kernel/platform/u-boot/Jamfile index d1845da417..b9604505c7 100644 --- a/src/system/kernel/platform/u-boot/Jamfile +++ b/src/system/kernel/platform/u-boot/Jamfile @@ -3,6 +3,8 @@ SubDir HAIKU_TOP src system kernel platform u-boot ; SubDirCcFlags $(TARGET_KERNEL_PIC_CCFLAGS) ; SubDirC++Flags $(TARGET_KERNEL_PIC_CCFLAGS) ; +UseLibraryHeaders [ FDirName libfdt ] ; + KernelMergeObject kernel_platform_u-boot.o : platform.cpp openfirmware.cpp diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index 5ee024cd1b..557f4e5bc2 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -7,13 +7,45 @@ #include #include +#include + +extern "C" { +#include +#include +#include +}; // FIXME: HACK: until we support multiple platforms at once in the kernel. +extern void *gFDT; int gChosen; +static int fdt2of(int err) +{ + if (err >= 0) + return err; + switch (err) { + case -FDT_ERR_NOTFOUND: + case -FDT_ERR_EXISTS: + case -FDT_ERR_NOSPACE: + case -FDT_ERR_BADOFFSET: + case -FDT_ERR_BADPATH: + case -FDT_ERR_BADPHANDLE: + case -FDT_ERR_BADSTATE: + case -FDT_ERR_TRUNCATED: + case -FDT_ERR_BADMAGIC: + case -FDT_ERR_BADVERSION: + case -FDT_ERR_BADSTRUCTURE: + case -FDT_ERR_BADLAYOUT: + case -FDT_ERR_INTERNAL: + default: + return OF_FAILED; + } +} + + status_t of_init(int (*openFirmwareEntry)(void *)) { @@ -49,7 +81,18 @@ of_call_method(int handle, const char *method, int numArgs, int numReturns, ...) int of_finddevice(const char *device) { - return OF_FAILED; + const char *name = device; + int node; + + if (device == NULL) + return OF_FAILED; + + if (device[0] != '/' && fdt_get_alias(gFDT, device)) + name = fdt_get_alias(gFDT, device); + + node = fdt_path_offset(gFDT, name); +dprintf("of_finddevice('%s') name='%s' node=%d ret=%d\n", device, name, node, fdt2of(node)); + return fdt2of(node); } @@ -108,7 +151,13 @@ of_instance_to_package(int instance) int of_getprop(int package, const char *property, void *buffer, int bufferSize) { - return OF_FAILED; +int oldSize = bufferSize; + const void *p = fdt_getprop(gFDT, package, property, &bufferSize); +dprintf("of_getprop(%d, '%s', , %d) =%p sz=%d ret=%d\n", package, property, oldSize, p, bufferSize, fdt2of(bufferSize)); + if (p == NULL) + return fdt2of(bufferSize); + memcpy(buffer, p, bufferSize); + return bufferSize; } @@ -140,6 +189,32 @@ of_package_to_path(int package, char *pathBuffer, int bufferSize) } +/** given the package provided, get the number of cells ++ in the reg property ++ */ + +int32 +of_address_cells(int package) { + uint32 address_cells; + if (of_getprop(package, "#address-cells", + &address_cells, sizeof(address_cells)) == OF_FAILED) + return OF_FAILED; + + return address_cells; +} + + +int32 +of_size_cells(int package) { + uint32 size_cells; + if (of_getprop(package, "#size-cells", + &size_cells, sizeof(size_cells)) == OF_FAILED) + return OF_FAILED; + + return size_cells; +} + + // I/O functions