[haiku-commits] r42486 - in haiku/trunk: headers/private/kernel/platform/openfirmware src/system/boot/platform/openfirmware src/system/boot/platform/openfirmware/arch/ppc

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 26 Jul 2011 00:26:36 +0200 (CEST)

Author: kallisti5
Date: 2011-07-26 00:26:35 +0200 (Tue, 26 Jul 2011)
New Revision: 42486
Changeset: https://dev.haiku-os.org/changeset/42486

Added:
   haiku/trunk/src/system/boot/platform/openfirmware/of_support.cpp
   haiku/trunk/src/system/boot/platform/openfirmware/of_support.h
Removed:
   haiku/trunk/src/system/boot/platform/openfirmware/support.cpp
Modified:
   haiku/trunk/headers/private/kernel/platform/openfirmware/openfirmware.h
   haiku/trunk/src/system/boot/platform/openfirmware/Jamfile
   haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp
Log:
* Move platform support.cpp into less generic of_support.cpp
* Add header file to support of_support.cpp
* Add support functions to obtain address and size cell lengths
* Small style cleanups
* Add support for G5 PowerPC cpus...
* Refactor memory region code to be aware of 64-bit OF addresses.
  As-is the boot loader wouldn't start on G5 systems because
  OpenFirmware memory base addresses are stored as two 32-bit
  unsigned int 'cells' vs one 32-bit unsigned int 'cell' on G3/G4.
  I removed the static struct and replaced it with a template
  and pass uint32 or uint64 depending on the address cell size.
  Thanks for the idea DeadYak!


Modified: 
haiku/trunk/headers/private/kernel/platform/openfirmware/openfirmware.h
===================================================================
--- haiku/trunk/headers/private/kernel/platform/openfirmware/openfirmware.h     
2011-07-25 17:39:20 UTC (rev 42485)
+++ haiku/trunk/headers/private/kernel/platform/openfirmware/openfirmware.h     
2011-07-25 22:26:35 UTC (rev 42486)
@@ -15,6 +15,13 @@
 extern int gChosen;
 
 
+template<typename addressSize>
+struct of_region
+{
+       addressSize base;
+       uint32 size;
+};
+
 struct of_arguments {
        const char      *name;
        int                     num_args;
@@ -27,12 +34,7 @@
 #endif
 };
 
-struct of_region {
-       void    *base;
-       uint32  size;
-};
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif

Modified: haiku/trunk/src/system/boot/platform/openfirmware/Jamfile
===================================================================
--- haiku/trunk/src/system/boot/platform/openfirmware/Jamfile   2011-07-25 
17:39:20 UTC (rev 42485)
+++ haiku/trunk/src/system/boot/platform/openfirmware/Jamfile   2011-07-25 
22:26:35 UTC (rev 42486)
@@ -17,7 +17,7 @@
        network.cpp
        real_time_clock.cpp
        start.cpp
-       support.cpp
+       of_support.cpp
        video.cpp
 
        openfirmware.cpp

Modified: haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp
===================================================================
--- haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp  
2011-07-25 17:39:20 UTC (rev 42485)
+++ haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp  
2011-07-25 22:26:35 UTC (rev 42486)
@@ -17,6 +17,7 @@
 #include <arch_mmu.h>
 #include <kernel.h>
 
+#include "of_support.h"
 
 // set protection to WIMGNPP: -----PP
 // PP: 00 - no access
@@ -69,30 +70,81 @@
 static status_t
 find_physical_memory_ranges(size_t &total)
 {
-       int memory, package;
+       int memory;
        dprintf("checking for memory...\n");
        if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
                return B_ERROR;
-       package = of_instance_to_package(memory);
+       int package = of_instance_to_package(memory);
 
        total = 0;
 
-       struct of_region regions[64];
-       int count;
-       count = of_getprop(package, "reg", regions, sizeof(regions));
+       /* Memory base addresses are provided in 32 or 64 bit flavors
+          #address-cells and #size-cells matches the number of 32-bit 'cells'
+          representing the length of the base address and size fields
+       */
+       int root = of_finddevice("/");
+       int regAddressCount = of_address_cells(root);
+       int regSizeCount = of_size_cells(root);
+       if (regAddressCount == OF_FAILED || regSizeCount == OF_FAILED) {
+               dprintf("finding base/size length counts failed, assume 
32-bit.\n");
+               regAddressCount = 1;
+               regSizeCount = 1;
+       }
+       dprintf("memory range address cells: %d; size cells: %d;\n",
+               regAddressCount, regSizeCount);
+
+       if (regAddressCount > 2 || regSizeCount > 1) {
+               dprintf("Unsupported cell size detected. (machine is > 
64bit?).\n");
+               return B_ERROR;
+       }
+
+       // On 64-bit PowerPC systems (G5), our mem base range address is larger
+       if (regAddressCount == 2) {
+               struct of_region<uint64> regions[64];
+               int count = of_getprop(package, "reg", regions, 
sizeof(regions));
+               if (count == OF_FAILED)
+                       count = of_getprop(memory, "reg", regions, 
sizeof(regions));
+               if (count == OF_FAILED)
+                       return B_ERROR;
+               count /= sizeof(regions[0]);
+
+               for (int32 i = 0; i < count; i++) {
+                       if (regions[i].size <= 0) {
+                               dprintf("%ld: empty region\n", i);
+                               continue;
+                       }
+                       dprintf("%" B_PRIu32 ": base = %" B_PRIu64 ","
+                               "size = %" B_PRIu32 "\n", i, regions[i].base, 
regions[i].size);
+
+                       total += regions[i].size;
+
+                       if 
(insert_physical_memory_range((addr_t)regions[i].base,
+                                       regions[i].size) != B_OK) {
+                               dprintf("cannot map physical memory range "
+                                       "(num ranges = %" B_PRIu32 ")!\n",
+                                       gKernelArgs.num_physical_memory_ranges);
+                               return B_ERROR;
+                       }
+               }
+               return B_OK;
+       }
+
+       // Otherwise, normal 32-bit PowerPC G3 or G4 have a smaller 32-bit one
+       struct of_region<uint32> regions[64];
+       int count = of_getprop(package, "reg", regions, sizeof(regions));
        if (count == OF_FAILED)
                count = of_getprop(memory, "reg", regions, sizeof(regions));
        if (count == OF_FAILED)
                return B_ERROR;
-       count /= sizeof(of_region);
+       count /= sizeof(regions[0]);
 
        for (int32 i = 0; i < count; i++) {
                if (regions[i].size <= 0) {
                        dprintf("%ld: empty region\n", i);
                        continue;
                }
-               dprintf("%" B_PRIu32 ": base = %p, size = %" B_PRIu32 "\n", i,
-                       regions[i].base, regions[i].size);
+               dprintf("%" B_PRIu32 ": base = %" B_PRIu32 ","
+                       "size = %" B_PRIu32 "\n", i, regions[i].base, 
regions[i].size);
 
                total += regions[i].size;
 

Copied: haiku/trunk/src/system/boot/platform/openfirmware/of_support.cpp (from 
rev 42485, haiku/trunk/src/system/boot/platform/openfirmware/support.cpp)
===================================================================
--- haiku/trunk/src/system/boot/platform/openfirmware/of_support.cpp            
                (rev 0)
+++ haiku/trunk/src/system/boot/platform/openfirmware/of_support.cpp    
2011-07-25 22:26:35 UTC (rev 42486)
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2005, Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>.
+ * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold, bonefish@xxxxxxxxxxxxxxx
+ *             Alexander von Gluck, kallisti5@xxxxxxxxxxx
+ */
+
+
+#include "of_support.h"
+#include <platform/openfirmware/openfirmware.h>
+
+
+bigtime_t
+system_time(void)
+{
+       int result = of_milliseconds();
+       return (result == OF_FAILED ? 0 : bigtime_t(result) * 1000);
+}
+
+
+/** given the package provided, get the number of cells
++   in the reg property
++ */
+
+uint32
+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;
+}
+
+
+uint32
+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;
+}
+
+

Added: haiku/trunk/src/system/boot/platform/openfirmware/of_support.h
===================================================================
--- haiku/trunk/src/system/boot/platform/openfirmware/of_support.h              
                (rev 0)
+++ haiku/trunk/src/system/boot/platform/openfirmware/of_support.h      
2011-07-25 22:26:35 UTC (rev 42486)
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *      Alexander von Gluck, kallisti5@xxxxxxxxxxx
+ */
+#ifndef OF_SUPPORT_H
+#define OF_SUPPORT_H
+
+
+#include <OS.h>
+
+
+bigtime_t system_time(void);
+uint32 of_address_cells(int package);
+uint32 of_size_cells(int package);
+
+#endif


Other related posts: