+ NULL
+};
+
+/*
+ * Early initialization entry point. This is called by head.S
+ * with MMU translation disabled. We rely on the "feature" of
+ * the CPU that ignores the top 2 bits of the address in real
+ * mode so we can access kernel globals normally provided we
+ * only toy with things in the RMO region. From here, we do
+ * some early parsing of the device-tree to setup out LMB
+ * data structures, and allocate & initialize the hash table
+ * and segment tables so we can start running with translation
+ * enabled.
+ *
+ * It is this function which will call the probe() callback of
+ * the various platform types and copy the matching one to the
+ * global ppc_md structure. Your platform can eventually do
+ * some very early initializations from the probe() routine, but
+ * this is not recommended, be very careful as, for example, the
+ * device-tree is not accessible via normal means at this point.
+ */
+
+void __init early_setup(unsigned long dt_ptr)
+{
+ struct paca_struct *lpaca = get_paca();
+ static struct machdep_calls **mach;
+
+ /*
+ * Enable early debugging if any specified (see top of
+ * this file)
+ */
+ EARLY_DEBUG_INIT();
+
+ DBG(" -> early_setup()\n");
+
+ /*
+ * Fill the default DBG level in naca (do we want to keep
+ * that old mecanism around forever ?)
+ */
+ ppcdbg_initialize();
+
+ /*
+ * Do early initializations using the flattened device
+ * tree, like retreiving the physical memory map or
+ * calculating/retreiving the hash table size
+ */
+ early_init_devtree(__va(dt_ptr));
+
+ /*
+ * Iterate all ppc_md structures until we find the proper
+ * one for the current machine type
+ */
+ DBG("Probing machine type for platform %x...\n",
+ systemcfg->platform);
+
+ for (mach = machines; *mach; mach++) {
+ if ((*mach)->probe(systemcfg->platform))
+ break;
+ }
+ /* What can we do if we didn't find ? */
+ if (*mach == NULL) {
+ DBG("No suitable machine found !\n");
+ for (;;);
+ }
+ ppc_md = **mach;
+
+ /* our udbg callbacks got overriden by the above, let's put them
+ * back in. Ultimately, I want those things to be split from the
+ * main ppc_md
+ */
+ EARLY_DEBUG_INIT();
+
+ DBG("Found, Initializing memory management...\n");
+
+ /*
+ * Initialize stab / SLB management
+ */
+ stab_initialize(lpaca->stab_real);
+
+ /*
+ * Initialize the MMU Hash table and create the linear mapping
+ * of memory
+ */
+ htab_initialize();
+
+ DBG(" <- early_setup()\n");
+}
+
+
+/*
+ * Initialize some remaining members of the naca and systemcfg structures
+ * (at least until we get rid of them completely). This is mostly some
+ * cache informations about the CPU that will be used by cache flush
+ * routines and/or provided to userland
+ */
+static void __init initialize_naca(void)
+{
+ struct device_node *np;
+ unsigned long num_cpus = 0;
+
+ DBG(" -> initialize_naca()\n");
+
+ for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
+ num_cpus += 1;
+
+ /* We're assuming *all* of the CPUs have the same
+ * d-cache and i-cache sizes... -Peter
+ */
+
+ if ( num_cpus == 1 ) {
+ u32 *sizep, *lsizep;
+ u32 size, lsize;
+ const char *dc, *ic;
+
+ /* Then read cache informations */
+ if (systemcfg->platform == PLATFORM_POWERMAC) {
+ dc = "d-cache-block-size";
+ ic = "i-cache-block-size";
+ } else {
+ dc = "d-cache-line-size";
+ ic = "i-cache-line-size";
+ }
+
+ size = 0;
+ lsize = cur_cpu_spec->dcache_bsize;
+ sizep = (u32 *)get_property(np, "d-cache-size", NULL);
+ if (sizep != NULL)
+ size = *sizep;
+ lsizep = (u32 *) get_property(np, dc, NULL);
+ if (lsizep != NULL)
+ lsize = *lsizep;
+
+ if (sizep == 0 || lsizep == 0)
+ DBG("Argh, can't find dcache properties ! "
+ "sizep: %p, lsizep: %p\n", sizep, lsizep);
+
+ systemcfg->dCacheL1Size = size;
+ systemcfg->dCacheL1LineSize = lsize;
+ naca->dCacheL1LogLineSize = __ilog2(lsize);
+ naca->dCacheL1LinesPerPage = PAGE_SIZE/(lsize);
+
+ size = 0;
+ lsize = cur_cpu_spec->icache_bsize;
+ sizep = (u32 *)get_property(np, "i-cache-size", NULL);
+ if (sizep != NULL)
+ size = *sizep;
+ lsizep = (u32 *)get_property(np, ic, NULL);
+ if (lsizep != NULL)
+ lsize = *lsizep;
+ if (sizep == 0 || lsizep == 0)
+ DBG("Argh, can't find icache properties ! "
+ "sizep: %p, lsizep: %p\n", sizep, lsizep);
+
+ systemcfg->iCacheL1Size = size;
+ systemcfg->iCacheL1LineSize = lsize;
+ naca->iCacheL1LogLineSize = __ilog2(lsize);
+ naca->iCacheL1LinesPerPage = PAGE_SIZE/(lsize);
+
+ }
+ }
+
+ /* Add an eye catcher and the systemcfg layout version number */
+ strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
+ systemcfg->version.major = SYSTEMCFG_MAJOR;
+ systemcfg->version.minor = SYSTEMCFG_MINOR;
+ systemcfg->processor = mfspr(SPRN_PVR);
+
+ DBG(" <- initialize_naca()\n");
+}
+
+static void __init check_for_initrd(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ u64 *prop;
+
+ DBG(" -> check_for_initrd()\n");
+
+ prop = (u64 *)get_property(of_chosen, "linux,initrd-start", NULL);
+ if (prop != NULL) {
+ initrd_start = (unsigned long)__va(*prop);
+ prop = (u64 *)get_property(of_chosen, "linux,initrd-end", NULL);
+ if (prop != NULL) {
+ initrd_end = (unsigned long)__va(*prop);
+ initrd_below_start_ok = 1;
+ } else
+ initrd_start = 0;