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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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&am... ============================================================================== --- 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?re... ============================================================================== --- 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; }