Author: arty
Date: Sun Nov 11 14:14:52 2007
New Revision: 30354
URL:
http://svn.reactos.org/svn/reactos?rev=30354&view=rev
Log:
Debug devtree.
Add generation of simple device tree in freeldr.
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c
trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h
trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c
trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c
trunk/reactos/lib/lib.rbuild
trunk/reactos/lib/ppcdevtree/devtree.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c Sun Nov 11 14:14:52 2007
@@ -474,10 +474,71 @@
//printf("RTCGeturrentDateTime\n");
}
+/* Recursively copy the device tree into our representation
+ * It'll be passed to HAL.
+ *
+ * When NT was first done on PPC, it was on PReP hardware, which is very
+ * like PC hardware (really, just a PPC on a PC motherboard). HAL can guess
+ * the addresses of needed resources in this scheme as it can on x86.
+ *
+ * Most PPC hardware doesn't assign fixed addresses to hardware, which is
+ * the problem that open firmware partially solves. It allows hardware makers
+ * much more leeway in building PPC systems. Unfortunately, because
+ * openfirmware as originally specified neither captures nor standardizes
+ * all possible information, and also because of bugs, most OSs use a hybrid
+ * configuration scheme that relies both on verification of devices and
+ * recording information from openfirmware to be treated as hints.
+ */
+VOID OfwCopyDeviceTree(PPPC_DEVICE_TREE tree, int innode)
+{
+ int proplen = 0, node = innode;
+ char *prev_name, cur_name[64], data[256], *slash;
+
+ /* Add properties */
+ for (prev_name = ""; ofw_nextprop(node, prev_name, cur_name) == 1; )
+ {
+ proplen = ofw_getproplen(node, cur_name);
+ if (proplen > 256 || proplen < 0)
+ {
+ printf("Warning: not getting prop %s (too long: %d)\n",
+ cur_name, proplen);
+ continue;
+ }
+ ofw_getprop(node, cur_name, data, sizeof(data));
+ PpcDevTreeAddProperty(tree, 0, cur_name, data, proplen);
+ strcpy(data, cur_name);
+ prev_name = data;
+ }
+
+ /* Subdevices */
+ for (node = ofw_child(node); node; node = ofw_peer(node))
+ {
+ ofw_package_to_path(node, data, sizeof(data));
+ slash = strrchr(data, '/');
+ if (slash) slash++; else continue;
+ PpcDevTreeAddDevice(tree, 0, slash);
+ OfwCopyDeviceTree(tree, node);
+ PpcDevTreeCloseDevice(tree);
+ }
+}
+
VOID PpcHwDetect() {
- printf("PpcHwDetect\n");
- /* Almost all PowerPC boxen use PCI */
- BootInfo.machineType = PCIBus;
+ PPC_DEVICE_TREE tree;
+ int node = ofw_finddevice("/");
+
+ /* Start the tree */
+ if(!PpcDevTreeInitialize
+ (&tree,
+ PAGE_SIZE, sizeof(long long),
+ (PPC_DEVICE_ALLOC)MmAllocateMemory,
+ (PPC_DEVICE_FREE)MmFreeMemory))
+ return;
+
+ OfwCopyDeviceTree(&tree,node);
+
+ PpcDevTreeCloseDevice(&tree);
+
+ BootInfo.machine = tree.head;
}
BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) {
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c Sun Nov 11 14:14:52 2007
@@ -207,7 +207,9 @@
reactos_memory_map[i].length_low = tmp;
}
+ printf("PpcInitializeMmu\n");
PpcInitializeMmu(0);
+ printf("PpcInitializeMmu done\n");
/* We'll use vsid 1 for freeldr (expendable) */
MmuAllocVsid(1, 0xff);
@@ -222,6 +224,14 @@
i += (1<<PFN_SHIFT) ) {
FrLdrAddPageMapping(&memmap, 0, i, KernelBase + i - (ULONG)KernelMemory);
+ }
+
+ /* Map device data */
+ for (i = (ULONG)BootInfo.machine;
+ i < (ULONG)PpcDevTreeSiblingNode(BootInfo.machine);
+ i += (1<<PFN_SHIFT) )
+ {
+ FrLdrAddPageMapping(&memmap, 0, i, 0);
}
/* Map module name strings */
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.c Sun Nov 11 14:14:52 2007
@@ -65,9 +65,6 @@
void PpcPrepVideoPrepareForReactOS(BOOLEAN setup)
{
- /* Prep boxen are PCI */
- BootInfo.machineType = PCIBus;
- pci_setup(&pci1_desc);
}
VOID PpcInitializeMmu(int max);
@@ -109,6 +106,83 @@
return 1;
}
+/* Most PReP hardware is in standard locations, based on the corresponding
+ * hardware on PCs. */
+VOID PpcPrepHwDetect() {
+ PPC_DEVICE_TREE tree;
+ PPC_DEVICE_RANGE range;
+ int interrupt;
+
+ /* Start the tree */
+ if(!PpcDevTreeInitialize
+ (&tree,
+ PAGE_SIZE, sizeof(long long),
+ (PPC_DEVICE_ALLOC)MmAllocateMemory,
+ (PPC_DEVICE_FREE)MmFreeMemory))
+ return;
+
+ /* PCI Bus */
+ PpcDevTreeAddDevice(&tree, PPC_DEVICE_PCI_EAGLE, "pci");
+
+ /* Check out the devices on the bus */
+ pci_setup(&tree, &pci1_desc);
+
+ /* End PCI Bus */
+ PpcDevTreeCloseDevice(&tree);
+
+ /* ISA Bus */
+ PpcDevTreeAddDevice(&tree, PPC_DEVICE_ISA_BUS, "isa");
+
+ /* Serial port */
+ PpcDevTreeAddDevice(&tree, PPC_DEVICE_SERIAL_8250, "com1");
+ range.start = (PVOID)0x800003f8;
+ range.len = 8;
+ range.type = PPC_DEVICE_IO_RANGE;
+ interrupt = 4;
+ PpcDevTreeAddProperty
+ (&tree, PPC_DEVICE_SPACE_RANGE, "reg", (char *)&range,
sizeof(range));
+ PpcDevTreeAddProperty
+ (&tree, PPC_DEVICE_INTERRUPT, "interrupt",
+ (char *)&interrupt, sizeof(interrupt));
+ PpcDevTreeCloseDevice(&tree);
+
+ /* We probably have an ISA IDE controller */
+ PpcDevTreeAddDevice(&tree, PPC_DEVICE_IDE_DISK, "ide0");
+ range.start = (PVOID)0x800001f8;
+ range.len = 8;
+ range.type = PPC_DEVICE_IO_RANGE;
+ interrupt = 14;
+ PpcDevTreeAddProperty
+ (&tree, PPC_DEVICE_SPACE_RANGE, "reg", (char *)&range,
sizeof(range));
+ PpcDevTreeAddProperty
+ (&tree, PPC_DEVICE_INTERRUPT, "interrupt",
+ (char *)&interrupt, sizeof(interrupt));
+ PpcDevTreeCloseDevice(&tree);
+
+ /* Describe VGA */
+ PpcDevTreeAddDevice(&tree, PPC_DEVICE_VGA, "vga");
+ range.start = (PVOID)0x800003c0;
+ range.len = 0x20;
+ range.type = PPC_DEVICE_IO_RANGE;
+ PpcDevTreeAddProperty
+ (&tree, PPC_DEVICE_SPACE_RANGE, "reg", (char *)&range,
sizeof(range));
+ range.start = BootInfo.dispDeviceBase;
+ range.len = BootInfo.dispDeviceRowBytes * BootInfo.dispDeviceRect[3];
+ range.type = PPC_DEVICE_MEM_RANGE;
+ PpcDevTreeAddProperty
+ (&tree, PPC_DEVICE_SPACE_RANGE, "mem", (char *)&range,
sizeof(range));
+ PpcDevTreeCloseDevice(&tree);
+
+ /* End ISA Bus */
+ PpcDevTreeCloseDevice(&tree);
+
+ /* And finish by closing the root node */
+ PpcDevTreeCloseDevice(&tree);
+
+ /* Now fish out the root node. The dev tree is a slab of memory */
+ BootInfo.machine = PpcDevTreeGetRootNode(&tree);
+}
+
void PpcPrepInit()
{
MachVtbl.ConsPutChar = PpcPrepPutChar;
@@ -129,6 +203,7 @@
MachVtbl.VideoPrepareForReactOS = PpcPrepVideoPrepareForReactOS;
MachVtbl.GetMemoryMap = PpcPrepGetMemoryMap;
+ MachVtbl.HwDetect = PpcPrepHwDetect;
printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep.h Sun Nov 11 14:14:52 2007
@@ -1,5 +1,7 @@
#ifndef FREELDR_ARCH_POWERPC_PREP_H
#define FREELDR_ARCH_POWERPC_PREP_H
+
+#include "ppcboot.h"
extern struct _pci_desc pci1_desc;
extern struct _idectl_desc ide1_desc;
@@ -15,10 +17,11 @@
void ide_setup( void *extension );
void print_bar( struct _pci_bar *bar );
-void pci_setup( struct _pci_desc *pci_desc );
+void pci_setup( PPC_DEVICE_TREE *tree, struct _pci_desc *pci_desc );
void pci_read_bar( struct _pci_desc *pci_desc, int bus, int dev, int fn, int bar, struct
_pci_bar *bar_data );
-void vga_setup( struct _pci_desc *pci_desc, struct _vga_desc *vga_desc,
+void vga_setup( PPC_DEVICE_TREE *tree,
+ struct _pci_desc *pci_desc, struct _vga_desc *vga_desc,
int bus, int dev, int fn );
#endif//FREELDR_ARCH_POWERPC_PREP_H
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_pci.c Sun Nov 11 14:14:52 2007
@@ -93,7 +93,7 @@
#define PCI_HEADER_TYPE 0xe
#define PCI_BASECLASS 0xb
-void pci_setup( pci_desc *desc ) {
+void pci_setup( PPC_DEVICE_TREE *tree, pci_desc *desc ) {
unsigned char type;
unsigned short vendor, device, devclass;
int funcs, bus, dev, fn;
@@ -117,7 +117,7 @@
if( devclass == 3 ) {
printf("Setting up vga...\n");
- vga_setup(desc,&vga1_desc,bus,dev,fn);
+ vga_setup(tree,desc,&vga1_desc,bus,dev,fn);
printf("Done with vga\n");
}
}
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/prep_vga.c Sun Nov 11 14:14:52 2007
@@ -13,7 +13,8 @@
#define VGA_HEIGHT 768
struct _vga_desc vga1_desc = { (char *)0x800003c0 };
-void vga_setup( struct _pci_desc *desc, struct _vga_desc *vga_desc,
+void vga_setup( PPC_DEVICE_TREE *tree,
+ struct _pci_desc *desc, struct _vga_desc *vga_desc,
int bus, int dev, int fn ) {
struct _pci_bar bar_data;
int i;
Modified: trunk/reactos/lib/lib.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/lib.rbuild?rev=30354&a…
==============================================================================
--- trunk/reactos/lib/lib.rbuild (original)
+++ trunk/reactos/lib/lib.rbuild Sun Nov 11 14:14:52 2007
@@ -28,6 +28,9 @@
<directory name="ppcmmu">
<xi:include href="ppcmmu/ppcmmu.rbuild" />
</directory>
+ <directory name="ppcdevtree">
+ <xi:include href="ppcdevtree/ppcdevtree.rbuild" />
+ </directory>
<directory name="pseh">
<xi:include href="pseh/pseh.rbuild" />
</directory>
Modified: trunk/reactos/lib/ppcdevtree/devtree.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/ppcdevtree/devtree.c?r…
==============================================================================
--- trunk/reactos/lib/ppcdevtree/devtree.c (original)
+++ trunk/reactos/lib/ppcdevtree/devtree.c Sun Nov 11 14:14:52 2007
@@ -46,11 +46,13 @@
if (tree->alloc_size >= newSize) return tree->head;
newArea = tree->allocFn(newSize);
if (!newArea) return NULL;
- memcpy(newArea, tree->head, tree->alloc_size);
+ memcpy(newArea, tree->head, tree->used_bytes);
tree->alloc_size = newSize;
if (tree->active)
tree->active =
- (((char *)tree->active) - ((char *)tree->head)) + newArea;
+ (PPPC_DEVICE_NODE)
+ (((char *)tree->active) - ((char *)tree->head) +
+ ((char *)newArea));
if (tree->head) tree->freeFn(tree->head);
tree->head = newArea;
return tree->head;
@@ -125,6 +127,9 @@
newHead = (PPPC_DEVICE_NODE)
(((char *)tree->active) + tree->active->total_size);
memset(newHead, 0, size);
+ tree->used_bytes =
+ (((char *)newHead) + DT_ROUND_UP(newHead->this_size, tree->align)) -
+ ((char *)tree->head);
return newHead;
}
@@ -145,6 +150,9 @@
tree->active->total_size =
(((char *)newprop) + DT_ROUND_UP(newprop->this_size, tree->align)) -
((char *)tree->active);
+ tree->used_bytes =
+ (((char *)newprop) + DT_ROUND_UP(newprop->this_size, tree->align)) -
+ ((char *)tree->head);
return PPC_DT_TRUE;
}