[PATCH 10/10] ppc64: Define /cpus in iSeries device tree

Michael Ellerman michael at ellerman.id.au
Wed Aug 10 14:18:48 EST 2005


Add the /cpus node and nodes for each cpu, as well as cache size properties,
reg propery, "linux,boot-cpu", and timebase/clock frequency.

With those properties in place we can remove:

- setup_iSeries_cache_sizes()
- code in iSeries_setup_arch() to calculate timebase etc.
- iSeries_calibrate_decr()
- smp_iSeries_numProcs() and simplify smp_iSeries_probe()

Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---

 arch/ppc64/kernel/iSeries_setup.c |  178 +++++++++++---------------------------
 arch/ppc64/kernel/iSeries_smp.c   |   30 ------
 arch/ppc64/kernel/time.c          |    2 
 3 files changed, 57 insertions(+), 153 deletions(-)

Index: work/arch/ppc64/kernel/iSeries_setup.c
===================================================================
--- work.orig/arch/ppc64/kernel/iSeries_setup.c
+++ work/arch/ppc64/kernel/iSeries_setup.c
@@ -74,7 +74,6 @@ extern void hvlog(char *fmt, ...);
 extern void ppcdbg_initialize(void);
 
 static void build_iSeries_Memory_Map(void);
-static void setup_iSeries_cache_sizes(void);
 static int iseries_shared_idle(void);
 static int iseries_dedicated_idle(void);
 #ifdef CONFIG_PCI
@@ -84,14 +83,6 @@ static void iSeries_pci_final_fixup(void
 #endif
 
 /* Global Variables */
-static unsigned long procFreqHz;
-static unsigned long procFreqMhz;
-static unsigned long procFreqMhzHundreths;
-
-static unsigned long tbFreqHz;
-static unsigned long tbFreqMhz;
-static unsigned long tbFreqMhzHundreths;
-
 int piranha_simulator;
 
 extern int rd_size;		/* Defined in drivers/block/rd.c */
@@ -344,12 +335,6 @@ static void __init iSeries_init_early(vo
 	iSeries_recal_titan = HvCallXm_loadTod();
 
 	/*
-	 * Cache sizes must be initialized before hpte_init_iSeries is called
-	 * as the later need them for flush_icache_range()
-	 */
-	setup_iSeries_cache_sizes();
-
-	/*
 	 * Initialize the hash table management pointers
 	 */
 	hpte_init_iSeries();
@@ -581,47 +566,6 @@ static void __init build_iSeries_Memory_
 }
 
 /*
- * Set up the variables that describe the cache line sizes
- * for this machine.
- */
-static void __init setup_iSeries_cache_sizes(void)
-{
-	unsigned int i, n;
-	unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
-
-	systemcfg->icache_size =
-	ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
-	systemcfg->icache_line_size =
-	ppc64_caches.iline_size =
-		xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
-	systemcfg->dcache_size =
-	ppc64_caches.dsize =
-		xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
-	systemcfg->dcache_line_size =
-	ppc64_caches.dline_size =
-		xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
-	ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
-	ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
-
-	i = ppc64_caches.iline_size;
-	n = 0;
-	while ((i = (i / 2)))
-		++n;
-	ppc64_caches.log_iline_size = n;
-
-	i = ppc64_caches.dline_size;
-	n = 0;
-	while ((i = (i / 2)))
-		++n;
-	ppc64_caches.log_dline_size = n;
-
-	printk("D-cache line size = %d\n",
-			(unsigned int)ppc64_caches.dline_size);
-	printk("I-cache line size = %d\n",
-			(unsigned int)ppc64_caches.iline_size);
-}
-
-/*
  * Document me.
  */
 static void __init iSeries_setup_arch(void)
@@ -636,36 +580,14 @@ static void __init iSeries_setup_arch(vo
 		printk(KERN_INFO "Using dedicated idle loop\n");
 	}
 
-	/* 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;
-
 	/* Setup the Lp Event Queue */
 	setup_hvlpevent_queue();
 
-	/* Compute processor frequency */
-	procFreqHz = ((1UL << 34) * 1000000) /
-			xIoHriProcessorVpd[procIx].xProcFreq;
-	procFreqMhz = procFreqHz / 1000000;
-	procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100);
-	ppc_proc_freq = procFreqHz;
-
-	/* Compute time base frequency */
-	tbFreqHz = ((1UL << 32) * 1000000) /
-		xIoHriProcessorVpd[procIx].xTimeBaseFreq;
-	tbFreqMhz = tbFreqHz / 1000000;
-	tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100);
-	ppc_tb_freq = tbFreqHz;
-
 	printk("Max  logical processors = %d\n",
 			itVpdAreas.xSlicMaxLogicalProcs);
 	printk("Max physical processors = %d\n",
 			itVpdAreas.xSlicMaxPhysicalProcs);
-	printk("Processor frequency = %lu.%02lu\n", procFreqMhz,
-			procFreqMhzHundreths);
-	printk("Time base frequency = %lu.%02lu\n", tbFreqMhz,
-			tbFreqMhzHundreths);
+
 	systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
 	printk("Processor version = %x\n", systemcfg->processor);
 }
@@ -709,49 +631,6 @@ static void iSeries_halt(void)
 	mf_power_off();
 }
 
-/*
- * void __init iSeries_calibrate_decr()
- *
- * Description:
- *   This routine retrieves the internal processor frequency from the VPD,
- *   and sets up the kernel timer decrementer based on that value.
- *
- */
-static void __init iSeries_calibrate_decr(void)
-{
-	unsigned long	cyclesPerUsec;
-	struct div_result divres;
-
-	/* Compute decrementer (and TB) frequency in cycles/sec */
-	cyclesPerUsec = ppc_tb_freq / 1000000;
-
-	/*
-	 * Set the amount to refresh the decrementer by.  This
-	 * is the number of decrementer ticks it takes for
-	 * 1/HZ seconds.
-	 */
-	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
-
-#if 0
-	/* TEST CODE FOR ADJTIME */
-	tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
-	/* END OF TEST CODE */
-#endif
-
-	/*
-	 * tb_ticks_per_sec = freq; would give better accuracy
-	 * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
-	 * that jiffies (and xtime) will match the time returned
-	 * by do_gettimeofday.
-	 */
-	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
-	tb_ticks_per_usec = cyclesPerUsec;
-	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
-	div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres);
-	tb_to_xs = divres.result_low;
-	setup_default_decr();
-}
-
 static void __init iSeries_progress(char * st, unsigned short code)
 {
 	printk("Progress: [%04x] - %s\n", (unsigned)code, st);
@@ -901,7 +780,7 @@ struct machdep_calls __initdata iseries_
 	.get_boot_time	= iSeries_get_boot_time,
 	.set_rtc_time	= iSeries_set_rtc_time,
 	.get_rtc_time	= iSeries_get_rtc_time,
-	.calibrate_decr	= iSeries_calibrate_decr,
+	.calibrate_decr	= generic_calibrate_decr,
 	.progress	= iSeries_progress,
 	.probe		= iseries_probe,
 	/* XXX Implement enable_pmcs for iSeries */
@@ -1032,6 +911,57 @@ void dt_prop_empty(struct iseries_flat_d
 	dt_prop(dt, name, NULL, 0);
 }
 
+void dt_cpus(struct iseries_flat_dt *dt)
+{
+	unsigned char buf[32];
+	unsigned char *p;
+	unsigned int i, index;
+	struct IoHriProcessorVpd *d;
+
+	/* yuck */
+	snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
+	p = strchr(buf, ' ');
+	if (!p) p = buf + strlen(buf);
+
+	dt_start_node(dt, "cpus");
+	dt_prop_u32(dt, "#address-cells", 1);
+	dt_prop_u32(dt, "#size-cells", 0);
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (paca[i].lppaca.dyn_proc_status >= 2)
+			continue;
+
+		snprintf(p, 32 - (p - buf), "@%d", i);
+		dt_start_node(dt, buf);
+
+		dt_prop_str(dt, "device_type", "cpu");
+
+		index = paca[i].lppaca.dyn_hv_phys_proc_index;
+		d = &xIoHriProcessorVpd[index];
+
+		dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
+		dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
+
+		dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
+		dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
+
+		/* magic conversions to Hz copied from old code */
+		dt_prop_u32(dt, "clock-frequency",
+			((1UL << 34) * 1000000) / d->xProcFreq);
+		dt_prop_u32(dt, "timebase-frequency",
+			((1UL << 32) * 1000000) / d->xTimeBaseFreq);
+
+		dt_prop_u32(dt, "reg", i);
+
+		if (dt->header.boot_cpuid_phys == i)
+			dt_prop_empty(dt, "linux,boot-cpu");
+
+		dt_end_node(dt);
+	}
+
+	dt_end_node(dt);
+}
+
 void build_flat_dt(struct iseries_flat_dt *dt)
 {
 	u64 tmp[2];
@@ -1057,6 +987,8 @@ void build_flat_dt(struct iseries_flat_d
 	dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
 	dt_end_node(dt);
 
+	dt_cpus(dt);
+
 	dt_end_node(dt);
 
 	dt_push_u32(dt, OF_DT_END);
Index: work/arch/ppc64/kernel/iSeries_smp.c
===================================================================
--- work.orig/arch/ppc64/kernel/iSeries_smp.c
+++ work/arch/ppc64/kernel/iSeries_smp.c
@@ -82,35 +82,9 @@ static void smp_iSeries_message_pass(int
 	}
 }
 
-static int smp_iSeries_numProcs(void)
-{
-	unsigned np, i;
-
-	np = 0;
-        for (i=0; i < NR_CPUS; ++i) {
-                if (paca[i].lppaca.dyn_proc_status < 2) {
-			cpu_set(i, cpu_possible_map);
-			cpu_set(i, cpu_present_map);
-			cpu_set(i, cpu_sibling_map[i]);
-                        ++np;
-                }
-        }
-	return np;
-}
-
 static int smp_iSeries_probe(void)
 {
-	unsigned i;
-	unsigned np = 0;
-
-	for (i=0; i < NR_CPUS; ++i) {
-		if (paca[i].lppaca.dyn_proc_status < 2) {
-			/*paca[i].active = 1;*/
-			++np;
-		}
-	}
-
-	return np;
+	return cpus_weight(cpu_possible_map);
 }
 
 static void smp_iSeries_kick_cpu(int nr)
@@ -144,6 +118,4 @@ static struct smp_ops_t iSeries_smp_ops 
 void __init smp_init_iSeries(void)
 {
 	smp_ops = &iSeries_smp_ops;
-	systemcfg->processorCount	= smp_iSeries_numProcs();
 }
-
Index: work/arch/ppc64/kernel/time.c
===================================================================
--- work.orig/arch/ppc64/kernel/time.c
+++ work/arch/ppc64/kernel/time.c
@@ -471,7 +471,7 @@ int do_settimeofday(struct timespec *tv)
 
 EXPORT_SYMBOL(do_settimeofday);
 
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) || defined(CONFIG_PPC_ISERIES)
 void __init generic_calibrate_decr(void)
 {
 	struct device_node *cpu;



More information about the Linuxppc64-dev mailing list