linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/16] add base support for Celleb platform
@ 2006-11-15  9:31 Ishizaki Kou
  2006-11-15 17:23 ` Arnd Bergmann
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Ishizaki Kou @ 2006-11-15  9:31 UTC (permalink / raw)
  To: linuxppc-dev

This patch adds base support for Celleb platform.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

Index: linux-2.6.19/arch/powerpc/Kconfig
diff -u linux-2.6.19/arch/powerpc/Kconfig:1.1.1.2 linux-2.6.19/arch/powerpc/Kconfig:1.3
--- linux-2.6.19/arch/powerpc/Kconfig:1.1.1.2	Tue Oct 24 13:35:52 2006
+++ linux-2.6.19/arch/powerpc/Kconfig	Mon Nov  6 22:04:23 2006
@@ -456,6 +456,14 @@
 	select PPC_UDBG_16550
 	select UDBG_RTAS_CONSOLE
 
+config PPC_CELLEB
+	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
+	depends on PPC_MULTIPLATFORM && PPC64
+	select PPC_CELL
+	select PPC_RTAS
+	select SPU_NEED_SHADOW_INT_MASK
+	select HAS_TXX9_SERIAL
+
 config UDBG_RTAS_CONSOLE
 	bool "RTAS based debug console"
 	depends on PPC_RTAS
Index: linux-2.6.19/arch/powerpc/Kconfig.debug
diff -u linux-2.6.19/arch/powerpc/Kconfig.debug:1.1.1.1 linux-2.6.19/arch/powerpc/Kconfig.debug:1.2
--- linux-2.6.19/arch/powerpc/Kconfig.debug:1.1.1.1	Fri Oct  6 10:40:02 2006
+++ linux-2.6.19/arch/powerpc/Kconfig.debug	Fri Oct  6 12:26:34 2006
@@ -176,6 +176,12 @@
 	  Select this to enable early debugging for legacy iSeries. You need
 	  to hit "Ctrl-x Ctrl-x" to see the messages on the console.
 
+config PPC_EARLY_DEBUG_BEAT
+	bool "Beat HV Console"
+	depends on PPC_CELLEB
+	help
+	  Select this to enable early debugging for Celleb with Beat.
+
 endchoice
 
 endmenu
Index: linux-2.6.19/arch/powerpc/boot/Makefile
diff -u linux-2.6.19/arch/powerpc/boot/Makefile:1.1.1.3 linux-2.6.19/arch/powerpc/boot/Makefile:1.2
--- linux-2.6.19/arch/powerpc/boot/Makefile:1.1.1.3	Wed Nov  1 19:21:09 2006
+++ linux-2.6.19/arch/powerpc/boot/Makefile	Tue Nov  7 20:56:06 2006
@@ -154,6 +154,7 @@
 image-$(CONFIG_PPC_PSERIES)		+= zImage.pseries
 image-$(CONFIG_PPC_MAPLE)		+= zImage.pseries
 image-$(CONFIG_PPC_IBM_CELL_BLADE)	+= zImage.pseries
+image-$(CONFIG_PPC_CELLEB)		+= zImage.pseries
 image-$(CONFIG_PPC_CHRP)		+= zImage.chrp
 image-$(CONFIG_PPC_PMAC)		+= zImage.pmac
 image-$(CONFIG_DEFAULT_UIMAGE)		+= uImage
Index: linux-2.6.19/arch/powerpc/kernel/udbg.c
diff -u linux-2.6.19/arch/powerpc/kernel/udbg.c:1.1.1.1 linux-2.6.19/arch/powerpc/kernel/udbg.c:1.2
--- linux-2.6.19/arch/powerpc/kernel/udbg.c:1.1.1.1	Fri Oct  6 10:40:04 2006
+++ linux-2.6.19/arch/powerpc/kernel/udbg.c	Fri Oct  6 12:26:35 2006
@@ -45,6 +45,8 @@
 #elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES)
 	/* For iSeries - hit Ctrl-x Ctrl-x to see the output */
 	udbg_init_iseries();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_BEAT)
+	udbg_init_debug_beat();
 #endif
 }
 
Index: linux-2.6.19/arch/powerpc/platforms/Makefile
diff -u linux-2.6.19/arch/powerpc/platforms/Makefile:1.1.1.1 linux-2.6.19/arch/powerpc/platforms/Makefile:1.2
--- linux-2.6.19/arch/powerpc/platforms/Makefile:1.1.1.1	Fri Oct  6 10:40:06 2006
+++ linux-2.6.19/arch/powerpc/platforms/Makefile	Fri Oct  6 12:26:35 2006
@@ -16,3 +16,4 @@
 obj-$(CONFIG_PPC_PASEMI)		+= pasemi/
 obj-$(CONFIG_PPC_CELL)		+= cell/
 obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/
+obj-$(CONFIG_PPC_CELLEB)	+= celleb/
Index: linux-2.6.19/include/asm-powerpc/firmware.h
diff -u linux-2.6.19/include/asm-powerpc/firmware.h:1.1.1.2 linux-2.6.19/include/asm-powerpc/firmware.h:1.4
--- linux-2.6.19/include/asm-powerpc/firmware.h:1.1.1.2	Wed Nov  1 19:24:26 2006
+++ linux-2.6.19/include/asm-powerpc/firmware.h	Tue Nov  7 18:50:54 2006
@@ -58,7 +58,12 @@
 	FW_FEATURE_PSERIES_ALWAYS = 0,
 	FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
 	FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
+	FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR,
+	FW_FEATURE_CELLEB_ALWAYS = FW_FEATURE_LPAR,
 	FW_FEATURE_POSSIBLE =
+#ifdef CONFIG_PPC_CELLEB
+		FW_FEATURE_CELLEB_POSSIBLE |
+#endif
 #ifdef CONFIG_PPC_PSERIES
 		FW_FEATURE_PSERIES_POSSIBLE |
 #endif
@@ -67,6 +72,9 @@
 #endif
 		0,
 	FW_FEATURE_ALWAYS =
+#ifdef CONFIG_PPC_CELLEB
+		FW_FEATURE_CELLEB_ALWAYS &
+#endif
 #ifdef CONFIG_PPC_PSERIES
 		FW_FEATURE_PSERIES_ALWAYS &
 #endif
Index: linux-2.6.19/include/asm-powerpc/iommu.h
diff -u linux-2.6.19/include/asm-powerpc/iommu.h:1.1.1.1 linux-2.6.19/include/asm-powerpc/iommu.h:1.2
--- linux-2.6.19/include/asm-powerpc/iommu.h:1.1.1.1	Fri Oct  6 10:43:20 2006
+++ linux-2.6.19/include/asm-powerpc/iommu.h	Fri Oct  6 12:26:36 2006
@@ -89,6 +89,7 @@
 extern void iommu_init_early_pSeries(void);
 extern void iommu_init_early_iSeries(void);
 extern void iommu_init_early_dart(void);
+extern void celleb_init_iommu(void);
 
 #ifdef CONFIG_PCI
 extern void pci_iommu_init(void);
Index: linux-2.6.19/include/asm-powerpc/mmu.h
diff -u linux-2.6.19/include/asm-powerpc/mmu.h:1.1.1.1 linux-2.6.19/include/asm-powerpc/mmu.h:1.2
--- linux-2.6.19/include/asm-powerpc/mmu.h:1.1.1.1	Fri Oct  6 10:43:20 2006
+++ linux-2.6.19/include/asm-powerpc/mmu.h	Fri Oct  6 12:26:36 2006
@@ -247,6 +247,12 @@
 extern void hpte_init_native(void);
 extern void hpte_init_lpar(void);
 extern void hpte_init_iSeries(void);
+extern void hpte_init_beat(void);
+
+extern long beat_lpar_hpte_insert(unsigned long hpte_group,
+				     unsigned long va, unsigned long prpn,
+				     unsigned long rflags,
+				     unsigned long vflags, int psize);
 
 extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 				     unsigned long va, unsigned long prpn,
Index: linux-2.6.19/include/asm-powerpc/ppc-pci.h
diff -u linux-2.6.19/include/asm-powerpc/ppc-pci.h:1.1.1.1 linux-2.6.19/include/asm-powerpc/ppc-pci.h:1.2
--- linux-2.6.19/include/asm-powerpc/ppc-pci.h:1.1.1.1	Fri Oct  6 10:43:21 2006
+++ linux-2.6.19/include/asm-powerpc/ppc-pci.h	Fri Oct  6 12:26:36 2006
@@ -23,6 +23,7 @@
 extern int global_phb_number;
 
 extern unsigned long find_and_init_phbs(void);
+extern unsigned long celleb_find_and_init_phbs(void);
 
 extern struct pci_dev *ppc64_isabridge_dev;	/* may be NULL if no ISA bus */
 
Index: linux-2.6.19/include/asm-powerpc/smp.h
diff -u linux-2.6.19/include/asm-powerpc/smp.h:1.1.1.2 linux-2.6.19/include/asm-powerpc/smp.h:1.3
--- linux-2.6.19/include/asm-powerpc/smp.h:1.1.1.2	Tue Oct 17 08:44:31 2006
+++ linux-2.6.19/include/asm-powerpc/smp.h	Tue Oct 17 13:22:53 2006
@@ -75,6 +75,7 @@
 void smp_init_iSeries(void);
 void smp_init_pSeries(void);
 void smp_init_cell(void);
+void smp_init_celleb(void);
 void smp_setup_cpu_maps(void);
 
 extern int __cpu_disable(void);
Index: linux-2.6.19/include/asm-powerpc/spu_priv1.h
diff -u linux-2.6.19/include/asm-powerpc/spu_priv1.h:1.1.1.1 linux-2.6.19/include/asm-powerpc/spu_priv1.h:1.2
--- linux-2.6.19/include/asm-powerpc/spu_priv1.h:1.1.1.1	Fri Oct  6 10:43:21 2006
+++ linux-2.6.19/include/asm-powerpc/spu_priv1.h	Fri Oct  6 12:26:36 2006
@@ -177,6 +177,7 @@
  */
 
 extern const struct spu_priv1_ops spu_priv1_mmio_ops;
+extern const struct spu_priv1_ops spu_priv1_beat_ops;
 
 #endif /* __KERNEL__ */
 #endif
Index: linux-2.6.19/include/asm-powerpc/udbg.h
diff -u linux-2.6.19/include/asm-powerpc/udbg.h:1.1.1.1 linux-2.6.19/include/asm-powerpc/udbg.h:1.2
--- linux-2.6.19/include/asm-powerpc/udbg.h:1.1.1.1	Fri Oct  6 10:43:21 2006
+++ linux-2.6.19/include/asm-powerpc/udbg.h	Fri Oct  6 12:26:36 2006
@@ -44,6 +44,7 @@
 extern void __init udbg_init_iseries(void);
 extern void __init udbg_init_rtas_panel(void);
 extern void __init udbg_init_rtas_console(void);
+extern void __init udbg_init_debug_beat(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
Index: linux-2.6.19/arch/powerpc/platforms/celleb/Makefile
diff -u /dev/null linux-2.6.19/arch/powerpc/platforms/celleb/Makefile:1.1
--- /dev/null	Thu Nov  9 18:40:50 2006
+++ linux-2.6.19/arch/powerpc/platforms/celleb/Makefile	Fri Oct  6 16:13:36 2006
@@ -0,0 +1,9 @@
+obj-$(CONFIG_PPC_CELLEB)		+= interrupt.o iommu.o setup.o \
+					   lpar.o beat.o ioif.o \
+					   celleb_pci.o celleb_epci.o
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_PPC_CELLEB)		+= smp.o
+endif
+
+spu-priv1-$(CONFIG_PPC_CELLEB)		+= spu_priv1_beat.o
+obj-$(CONFIG_SPU_BASE)			+= $(spu-priv1-y)
Index: linux-2.6.19/arch/powerpc/platforms/celleb/beat.c
diff -u /dev/null linux-2.6.19/arch/powerpc/platforms/celleb/beat.c:1.3
--- /dev/null	Thu Nov  9 18:40:50 2006
+++ linux-2.6.19/arch/powerpc/platforms/celleb/beat.c	Wed Oct 18 17:40:36 2006
@@ -0,0 +1,223 @@
+/*
+ * Simple routines for Celleb/Beat
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <asm/rtas.h>
+#include <asm/hvconsole.h>
+#include <asm/time.h>
+
+#include "beat.h"
+
+int64_t	beat_errno;
+
+static const char *re_det1(const char *det, unsigned char *buf, int size)
+{
+	uint64_t ch;
+
+	for(ch = 0; ch < size; ch++) {
+		buf[ch] = 0;
+	}
+	for(;;) {
+		switch(ch = *det++) {
+		case '\0':
+			return --det;
+		case '.':
+			return det;
+		case '#':
+			det++;		// skip #0
+			break;
+		default:
+			if(size-- <= 0) {
+				return NULL;
+			}
+			*buf++ = ch;
+		}
+	}
+}
+
+int64_t beat_repository_encode(int vendor_id, const char *str, uint64_t name[4])
+{ 
+	union {
+		unsigned char cbuf[8];
+		uint64_t a;
+	} buf[4];
+
+	buf[0].cbuf[0] = vendor_id << 4;
+	buf[0].cbuf[1] = 0;
+	buf[0].cbuf[2] = 0;
+	buf[0].cbuf[3] = 0;
+	if((str = re_det1(str, &buf[0].cbuf[4], 4)) == NULL) {
+		return -1;
+	}
+	if((str = re_det1(str, &buf[1].cbuf[0], 8)) == NULL) {
+		return -2;
+	}
+	if((str = re_det1(str, &buf[2].cbuf[0], 8)) == NULL) {
+		return -3;
+	}
+	if((str = re_det1(str, &buf[3].cbuf[0], 8)) == NULL) {
+		return -4; 
+	}
+	if(*str != 0) {
+		return -5;
+	} 
+	name[0] = buf[0].a;
+	name[1] = buf[1].a;
+	name[2] = buf[2].a;
+	name[3] = buf[3].a;
+	return 0;
+} 
+
+void beat_restart(char *cmd)
+{
+	beat_shutdown_logical_partition(1);
+}
+
+void beat_power_off(void)
+{
+	beat_shutdown_logical_partition(0);
+}
+
+uint64_t beat_halt_code = 0x1000000000000000UL;
+
+void beat_halt(void)
+{
+	beat_shutdown_logical_partition(beat_halt_code);
+}
+
+int beat_set_rtc_time(struct rtc_time *rtc_time)
+{
+	uint64_t tim;
+	tim = mktime(rtc_time->tm_year+1900,
+		     rtc_time->tm_mon+1, rtc_time->tm_mday,
+		     rtc_time->tm_hour, rtc_time->tm_min, rtc_time->tm_sec);
+	if (beat_rtc_write(tim))
+		return -1;
+	return 0;
+}
+
+void beat_get_rtc_time(struct rtc_time *rtc_time)
+{
+	uint64_t tim;
+
+	if (beat_rtc_read(&tim))
+		tim = 0;
+	to_tm(tim, rtc_time);
+	rtc_time->tm_year -= 1900;
+	rtc_time->tm_mon -= 1;
+}
+
+#define	BEAT_NVRAM_SIZE	4096
+#define	BEAT_NVRW_CNT	(sizeof(uint64_t) * 6)
+
+ssize_t beat_nvram_read(char *buf, size_t count, loff_t *index)
+{
+	unsigned int i;
+	unsigned long len;
+	char *p = buf;
+
+	if (*index >= BEAT_NVRAM_SIZE)
+		return -ENODEV;
+	i = *index;
+	if (i + count > BEAT_NVRAM_SIZE)
+		count = BEAT_NVRAM_SIZE - i;
+
+	for (; count != 0; count -= len) {
+		uint64_t nb[6];
+
+		len = count;
+		if (len > BEAT_NVRW_CNT)
+			len = BEAT_NVRW_CNT;
+		if (beat_eeprom_read(i, len,
+			nb+0, nb+1, nb+2, nb+3, nb+4, nb+5)) {
+			return -EIO;
+		}
+
+		memcpy(p, nb, len);
+
+		p += len;
+		i += len;
+	}
+	*index = i;
+	return p - buf;
+}
+
+ssize_t beat_nvram_write(char *buf, size_t count, loff_t *index)
+{
+	unsigned int i;
+	unsigned long len;
+	char *p = buf;
+
+	if (*index >= BEAT_NVRAM_SIZE)
+		return -ENODEV;
+	i = *index;
+	if (i + count > BEAT_NVRAM_SIZE)
+		count = BEAT_NVRAM_SIZE - i;
+
+	for (; count != 0; count -= len) {
+		uint64_t nb[6];
+
+		len = count;
+		if (len > BEAT_NVRW_CNT)
+			len = BEAT_NVRW_CNT;
+		memcpy(nb, p, len);
+		if (beat_eeprom_write(i, len,
+			nb[0], nb[1], nb[2], nb[3], nb[4], nb[5])) {
+			return -EIO;
+		}
+
+		p += len;
+		i += len;
+	}
+	*index = i;
+	return p - buf;
+}
+
+ssize_t beat_nvram_get_size(void)
+{
+	return BEAT_NVRAM_SIZE;
+}
+
+int beat_set_xdabr(unsigned long dabr)
+{
+	if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER))
+		return -1;
+	return 0;
+}
+
+int64_t beat_get_term_char(uint64_t vterm, uint64_t *len, uint64_t *t1, uint64_t *t2)
+{
+	return beat_get_characters_from_console(vterm, len, t1, t2);
+}
+
+int64_t beat_put_term_char(uint64_t vterm, uint64_t len, uint64_t t1, uint64_t t2)
+{
+	return beat_put_characters_to_console(vterm, len, t1, t2);
+}
+
+EXPORT_SYMBOL(beat_get_term_char);
+EXPORT_SYMBOL(beat_put_term_char);
+EXPORT_SYMBOL(beat_repository_encode);
+EXPORT_SYMBOL(beat_errno);
+EXPORT_SYMBOL(beat_halt_code);
Index: linux-2.6.19/arch/powerpc/platforms/celleb/beat.h
diff -u /dev/null linux-2.6.19/arch/powerpc/platforms/celleb/beat.h:1.2
--- /dev/null	Thu Nov  9 18:40:50 2006
+++ linux-2.6.19/arch/powerpc/platforms/celleb/beat.h	Wed Oct 18 17:40:36 2006
@@ -0,0 +1,41 @@
+/*
+ * Guest OS Interfaces.
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _CELLEB_BEAT_H
+#define _CELLEB_BEAT_H
+#include "beat_sys.h"
+
+#define DABRX_KERNEL		(1UL<<1)
+#define DABRX_USER		(1UL<<0)
+
+int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*);
+int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t);
+int64_t beat_repository_encode(int, const char *, uint64_t[4]);
+void beat_restart(char *);
+void beat_power_off(void);
+void beat_halt(void);
+int beat_set_rtc_time(struct rtc_time *);
+void beat_get_rtc_time(struct rtc_time *);
+ssize_t beat_nvram_get_size(void);
+ssize_t beat_nvram_read(char *, size_t, loff_t *);
+ssize_t beat_nvram_write(char *, size_t, loff_t *);
+int beat_set_xdabr(unsigned long);
+
+#endif /* _CELLEB_BEAT_H */
Index: linux-2.6.19/arch/powerpc/platforms/celleb/lpar.c
diff -u /dev/null linux-2.6.19/arch/powerpc/platforms/celleb/lpar.c:1.3
--- /dev/null	Thu Nov  9 18:40:50 2006
+++ linux-2.6.19/arch/powerpc/platforms/celleb/lpar.c	Mon Nov  6 22:04:23 2006
@@ -0,0 +1,429 @@
+/*
+ * "Cell Reference Set" LPAR support.
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This code is based on arch/powerpc/platforms/pseries/lpar.c:
+ * Copyright (C) 2001 Todd Inglett, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG_LOW
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/console.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/abs_addr.h>
+#include <asm/mmu_context.h>
+#include <asm/iommu.h>
+#include <asm/tlbflush.h>
+#include <asm/tlb.h>
+#include <asm/prom.h>
+#include <asm/abs_addr.h>
+#include <asm/cputable.h>
+#include <asm/udbg.h>
+#include <asm/smp.h>
+
+#include "beat.h"
+
+int	celleb_vtermno;
+
+#ifdef DEBUG_LOW
+#define DBG_LOW(fmt...) do { udbg_printf(fmt); } while(0)
+#else
+#define DBG_LOW(fmt...) do { } while(0)
+#endif
+
+static void udbg_putc_beat(char c)
+{
+	unsigned long rc;
+
+	if (c == '\n')
+		udbg_putc_beat('\r');
+
+	rc = beat_put_term_char(celleb_vtermno, 1, (uint64_t)c << 56, 0);
+}
+
+/* Buffered chars getc */
+static long inbuflen;
+static long inbuf[2];	/* must be 2 longs */
+
+static int udbg_getc_poll_beat(void)
+{
+	/* The interface is tricky because it may return up to 16 chars.
+	 * We save them statically for future calls to udbg_getc().
+	 */
+	char ch, *buf = (char *)inbuf;
+	int i;
+	long rc;
+	if (inbuflen == 0) {
+		/* get some more chars. */
+		inbuflen = 0;
+		rc = beat_get_term_char(celleb_vtermno, &inbuflen, inbuf+0, inbuf+1);
+		if (rc != 0)
+			inbuflen = 0;	/* otherwise inbuflen is garbage */
+	}
+	if (inbuflen <= 0 || inbuflen > 16) {
+		/* Catch error case as well as other oddities (corruption) */
+		inbuflen = 0;
+		return -1;
+	}
+	ch = buf[0];
+	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
+		buf[i-1] = buf[i];
+	inbuflen--;
+	return ch;
+}
+
+static int udbg_getc_beat(void)
+{
+	int ch;
+	for (;;) {
+		ch = udbg_getc_poll_beat();
+		if (ch == -1) {
+			/* This shouldn't be needed...but... */
+			volatile unsigned long delay;
+			for (delay=0; delay < 2000000; delay++)
+				;
+		} else {
+			return ch;
+		}
+	}
+}
+
+/* call this from early_init() for a working debug console on
+ * vterm capable LPAR machines
+ */
+void __init udbg_init_debug_beat(void)
+{
+	celleb_vtermno = 0;
+	udbg_putc = udbg_putc_beat;
+	udbg_getc = udbg_getc_beat;
+	udbg_getc_poll = udbg_getc_poll_beat;
+}
+
+#if 0
+/* returns 0 if couldn't find or use /chosen/stdout as console */
+void __init celleb_find_udbg_vterm(void)
+{
+	struct device_node *stdout_node;
+	u32 *termno;
+	char *name;
+	int add_console;
+
+	/* find the boot console from /chosen/stdout */
+	if (!of_chosen)
+		return;
+	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+	if (name == NULL)
+		return;
+	stdout_node = of_find_node_by_path(name);
+	if (!stdout_node)
+		return;
+	name = (char *)get_property(stdout_node, "name", NULL);
+	if (!name) {
+		printk(KERN_WARNING "stdout node missing 'name' property!\n");
+		goto out;
+	}
+	/* The user has requested a console so this is already set up. */
+	add_console = !strstr(cmd_line, "console=");
+
+	/* Check if it's a virtual terminal */
+	if (strncmp(name, "vty", 3) != 0)
+		goto out;
+	termno = (u32 *)get_property(stdout_node, "reg", NULL);
+	if (termno == NULL)
+		goto out;
+	celleb_vtermno = termno[0];
+
+	if (device_is_compatible(stdout_node, "hvterm1")) {
+		udbg_putc = udbg_putc_beat;
+		udbg_getc = udbg_getc_beat;
+		udbg_getc_poll = udbg_getc_poll_beat;
+		if (add_console)
+			add_preferred_console("hvc", termno[0] & 0xff, NULL);
+	}
+out:
+	of_node_put(stdout_node);
+}
+#endif
+
+static inline unsigned int beat_read_mask(unsigned hpte_group)
+{
+	unsigned long hpte_v0, hpte_v1, hpte_v2, hpte_v3, hpte_perms;
+	unsigned long rmask = 0;
+
+	beat_read_htab_entries(0, hpte_group + 0,
+		&hpte_v0, &hpte_v1, &hpte_v2, &hpte_v3, &hpte_perms);
+	if (!(hpte_v0 & HPTE_V_BOLTED))
+		rmask |= 0x8000;
+	if (!(hpte_v1 & HPTE_V_BOLTED))
+		rmask |= 0x4000;
+	if (!(hpte_v2 & HPTE_V_BOLTED))
+		rmask |= 0x2000;
+	if (!(hpte_v3 & HPTE_V_BOLTED))
+		rmask |= 0x1000;
+	beat_read_htab_entries(0, hpte_group + 4,
+		&hpte_v0, &hpte_v1, &hpte_v2, &hpte_v3, &hpte_perms);
+	if (!(hpte_v0 & HPTE_V_BOLTED))
+		rmask |= 0x0800;
+	if (!(hpte_v1 & HPTE_V_BOLTED))
+		rmask |= 0x0400;
+	if (!(hpte_v2 & HPTE_V_BOLTED))
+		rmask |= 0x0200;
+	if (!(hpte_v3 & HPTE_V_BOLTED))
+		rmask |= 0x0100;
+	hpte_group = ~hpte_group & (htab_hash_mask * HPTES_PER_GROUP);
+	beat_read_htab_entries(0, hpte_group + 0,
+		&hpte_v0, &hpte_v1, &hpte_v2, &hpte_v3, &hpte_perms);
+	if (!(hpte_v0 & HPTE_V_BOLTED))
+		rmask |= 0x80;
+	if (!(hpte_v1 & HPTE_V_BOLTED))
+		rmask |= 0x40;
+	if (!(hpte_v2 & HPTE_V_BOLTED))
+		rmask |= 0x20;
+	if (!(hpte_v3 & HPTE_V_BOLTED))
+		rmask |= 0x10;
+	beat_read_htab_entries(0, hpte_group + 4,
+		&hpte_v0, &hpte_v1, &hpte_v2, &hpte_v3, &hpte_perms);
+	if (!(hpte_v0 & HPTE_V_BOLTED))
+		rmask |= 0x08;
+	if (!(hpte_v1 & HPTE_V_BOLTED))
+		rmask |= 0x04;
+	if (!(hpte_v2 & HPTE_V_BOLTED))
+		rmask |= 0x02;
+	if (!(hpte_v3 & HPTE_V_BOLTED))
+		rmask |= 0x01;
+	return rmask;
+}
+
+long beat_lpar_hpte_insert(unsigned long hpte_group,
+			   unsigned long va, unsigned long pa,
+			   unsigned long rflags, unsigned long vflags,
+			   int psize)
+{
+	unsigned long lpar_rc;
+	unsigned long slot;
+	unsigned long hpte_v, hpte_r;
+	unsigned long dummy0, dummy1;
+
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+			"rflags=%lx, vflags=%lx, psize=%d)\n",
+		hpte_group, va, pa, rflags, vflags, psize);
+
+	if (vflags & HPTE_V_SECONDARY) {
+		vflags &= ~HPTE_V_SECONDARY;
+		hpte_group = ~hpte_group & (htab_hash_mask * HPTES_PER_GROUP);
+	}
+
+	hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
+	hpte_r = hpte_encode_r(pa, psize) | rflags;
+
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
+
+	if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+		hpte_r &= ~_PAGE_COHERENT;
+
+	if ((lpar_rc = beat_read_mask(hpte_group)) == 0) {
+		if (!(vflags & HPTE_V_BOLTED))
+			DBG_LOW(" full\n");
+		return -1;
+	}
+
+	lpar_rc = beat_insert_htab_entry(0, hpte_group, lpar_rc << 48,
+		hpte_v, hpte_r, &slot, &dummy0, &dummy1);
+
+	/*
+	 * Since we try and ioremap PHBs we don't own, the pte insert
+	 * will fail. However we must catch the failure in hash_page
+	 * or we will loop forever, so return -2 in this case.
+	 */
+	if (unlikely(lpar_rc != 0)) {
+		if (!(vflags & HPTE_V_BOLTED))
+			DBG_LOW(" lpar err %lx\n", lpar_rc);
+		return -2;
+	}
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW(" -> slot: %lx\n", slot);
+
+	/* Because of iSeries, we have to pass down the secondary
+	 * bucket bit here as well
+	 */
+	return (slot ^ hpte_group) & 15;
+}
+
+static long beat_lpar_hpte_remove(unsigned long hpte_group)
+{
+	DBG_LOW("hpte_remove(group=%lx)\n", hpte_group);
+	return -1;
+}
+
+static unsigned long beat_lpar_hpte_getword0(unsigned long slot)
+{
+	unsigned long dword0, dword[4], dwordX;
+	unsigned long lpar_rc;
+
+	lpar_rc = beat_read_htab_entries(0, slot & ~3UL,
+		dword+0, dword+1, dword+2, dword+3, &dwordX);
+
+	dword0 = dword[slot&3];
+
+	BUG_ON(lpar_rc != 0);
+
+	return dword0;
+}
+
+static void beat_lpar_hptab_clear(void)
+{
+	unsigned long size_bytes = 1UL << ppc64_pft_size;
+	unsigned long hpte_count = size_bytes >> 4;
+	unsigned long dummy1, dummy2;
+	int i;
+
+	/* TODO: Use bulk call */
+	for (i = 0; i < hpte_count; i++)
+		beat_write_htab_entry(0, i, 0, 0, -1UL, -1UL, &dummy1, &dummy2);
+}
+
+/*
+ * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
+ * the low 3 bits of flags happen to line up.  So no transform is needed.
+ * We can probably optimize here and assume the high bits of newpp are
+ * already zero.  For now I am paranoid.
+ */
+static long beat_lpar_hpte_updatepp(unsigned long slot,
+				    unsigned long newpp,
+				    unsigned long va,
+				    int psize, int local)
+{
+	unsigned long lpar_rc;
+	unsigned long dummy0, dummy1, want_v;
+
+	want_v = hpte_encode_v(va, psize);
+
+	DBG_LOW("    update: avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
+		want_v & HPTE_V_AVPN, slot, psize, newpp);
+
+	dummy0 = beat_lpar_hpte_getword0(slot);
+	if ((dummy0 & ~0x7FUL) != (want_v & ~0x7FUL)) {
+		DBG_LOW("not found !\n");
+		return -1;
+	}
+
+	lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7,
+		&dummy0, &dummy1);
+
+	if (lpar_rc != 0 || dummy0 == 0) {
+		DBG_LOW("not found !\n");
+		return -1;
+	}
+
+	DBG_LOW("ok %lx %lx\n", dummy0, dummy1);
+
+	BUG_ON(lpar_rc != 0);
+
+	return 0;
+}
+
+static long beat_lpar_hpte_find(unsigned long va, int psize)
+{
+	unsigned long hash;
+	unsigned long i, j;
+	long slot;
+	unsigned long want_v, hpte_v;
+
+	hash = hpt_hash(va, mmu_psize_defs[psize].shift);
+	want_v = hpte_encode_v(va, psize);
+
+	for (j = 0; j < 2; j++) {
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+		for (i = 0; i < HPTES_PER_GROUP; i++) {
+			hpte_v = beat_lpar_hpte_getword0(slot);
+
+			if (HPTE_V_COMPARE(hpte_v, want_v)
+			    && (hpte_v & HPTE_V_VALID)
+			    && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
+				/* HPTE matches */
+				if (j)
+					slot = -slot;
+				return slot;
+			}
+			++slot;
+		}
+		hash = ~hash;
+	}
+
+	return -1;
+} 
+
+static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
+					  unsigned long ea,
+					  int psize)
+{
+	unsigned long lpar_rc, slot, vsid, va, dummy0, dummy1;
+
+	vsid = get_kernel_vsid(ea);
+	va = (vsid << 28) | (ea & 0x0fffffff);
+
+	slot = beat_lpar_hpte_find(va, psize);
+	BUG_ON(slot == -1);
+
+	lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7,
+		&dummy0, &dummy1);
+
+	BUG_ON(lpar_rc != 0);
+}
+
+static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
+					 int psize, int local)
+{
+	unsigned long want_v;
+	unsigned long lpar_rc;
+	unsigned long dummy1, dummy2;
+
+	DBG_LOW("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
+		slot, va, psize, local);
+	want_v = hpte_encode_v(va, psize);
+
+	dummy1 = beat_lpar_hpte_getword0(slot);
+
+	if ((dummy1 & ~0x7FUL) != (want_v & ~0x7FUL)) {
+		DBG_LOW("not found !\n");
+		return;
+	}
+
+	lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0,
+		&dummy1, &dummy2);
+
+	BUG_ON(lpar_rc != 0);
+}
+
+void hpte_init_beat(void)
+{
+	ppc_md.hpte_invalidate	= beat_lpar_hpte_invalidate;
+	ppc_md.hpte_updatepp	= beat_lpar_hpte_updatepp;
+	ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
+	ppc_md.hpte_insert	= beat_lpar_hpte_insert;
+	ppc_md.hpte_remove	= beat_lpar_hpte_remove;
+	ppc_md.hpte_clear_all	= beat_lpar_hptab_clear;
+}
Index: linux-2.6.19/arch/powerpc/platforms/celleb/setup.c
diff -u /dev/null linux-2.6.19/arch/powerpc/platforms/celleb/setup.c:1.3
--- /dev/null	Thu Nov  9 18:40:50 2006
+++ linux-2.6.19/arch/powerpc/platforms/celleb/setup.c	Wed Oct 18 17:40:36 2006
@@ -0,0 +1,303 @@
+/*
+ * Celleb setup code
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This code is based on arch/powerpc/platforms/cell/setup.c:
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Adapted from 'alpha' version by Gary Thomas
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  Modified by PPC64 Team, IBM Corp
+ *  Modified by Cell Team, IBM Deutschland Entwicklung GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/cpu.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/console.h>
+
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/kexec.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/nvram.h>
+#include <asm/cputable.h>
+#include <asm/ppc-pci.h>
+#include <asm/irq.h>
+#include <asm/spu.h>
+#include <asm/spu_priv1.h>
+#include <asm/firmware.h>
+
+#include "interrupt.h"
+#include "beat.h"
+
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+void celleb_show_cpuinfo(struct seq_file *m)
+{
+	struct device_node *root;
+	const char *model = "";
+
+	root = of_find_node_by_path("/");
+	if (root)
+		model = get_property(root, "model", NULL);
+	seq_printf(m, "machine\t\t: CHRP %s\n", model);
+	of_node_put(root);
+}
+
+static void celleb_progress(char *s, unsigned short hex)
+{
+	printk("*** %04x : %s\n", hex, s ? s : "");
+}
+
+static void __init celleb_setup_arch(void)
+{
+	ppc_md.init_IRQ       = beatic_init_IRQ;
+	ppc_md.get_irq        = beatic_get_irq;
+#ifdef CONFIG_SPU_BASE
+	spu_priv1_ops         = &spu_priv1_beat_ops;
+#endif
+
+
+#ifdef CONFIG_SMP
+	smp_init_celleb();
+#endif
+
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000;
+
+	if (ROOT_DEV == 0) {
+		printk("No ramdisk, default root is /dev/hda2\n");
+		ROOT_DEV = Root_HDA2;
+	}
+
+	/* Find and initialize PCI host bridges */
+	init_pci_config_tokens();
+	celleb_find_and_init_phbs();
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+
+}
+
+/*
+ * Early initialization.  Relocation is on but do not reference unbolted pages
+ */
+static void __init celleb_init_early(void)
+{
+	DBG(" -> celleb_init_early()\n");
+
+	celleb_init_iommu();
+
+	DBG(" <- celleb_init_early()\n");
+}
+
+static void beat_power_save(void)
+{
+	beat_pause(0);
+}
+
+static int __init celleb_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (!of_flat_dt_is_compatible(root, "Beat"))
+		return 0;
+
+	powerpc_firmware_features |= FW_FEATURE_LPAR;
+	hpte_init_beat();
+	return 1;
+}
+
+/*
+ * Cell has no legacy IO; anything calling this function has to
+ * fail or bad things will happen
+ */
+static int celleb_check_legacy_ioport(unsigned int baseport)
+{
+	return -ENODEV;
+}
+
+static int celleb_pci_probe_mode(struct pci_bus *bus){
+
+	struct device_node *node;
+	char *name;
+
+	node = (struct device_node *)bus->sysdata;
+	name = (char *)get_property(node, "name", NULL);
+
+	if(strcmp(name, "pci-pseudo") == 0){
+		return PCI_PROBE_DEVTREE;
+	}
+
+	return PCI_PROBE_NORMAL;
+}
+
+static void celleb_kexec_cpu_down(int crash, int secondary)
+{
+	extern void	beatic_deinit_IRQ(void);
+
+	beatic_deinit_IRQ();
+}
+
+#ifdef CONFIG_SERIAL_TXX9
+/* sio irq0=0xb00010022 irq0=0xb00010023 irq2=0xb00010024
+    mmio=0xfff000-0x1000,0xff2000-0x1000 */
+static int txx9_serial_bitmap = 0;
+
+static struct {
+	uint32_t offset;
+	uint32_t index;
+} txx9_spider_tab[3] = {
+	{ 0x300, 0 },	/* 0xFFF300 */
+	{ 0x400, 0 },	/* 0xFFF400 */
+	{ 0x800, 1 }	/* 0xFF2800 */
+};
+
+static int txx9_serial_init(void)
+{
+	extern int early_serial_txx9_setup(struct uart_port *port);
+	struct device_node *node;
+	uint64_t *irq_prop, *base_prop;
+	int irq_len, base_addr_len;
+	int i, maxi;
+	struct uart_port req;
+
+	node = of_find_node_by_path("/ioif1/sio");
+	if (!node)
+		return 0;
+	
+	irq_prop = (uint64_t *)get_property(node, "interrupts", &irq_len);
+	if (!irq_prop)
+		goto out;
+	irq_len /= sizeof(uint64_t);
+
+	base_prop = (uint64_t *)get_property(node, "toshiba,reg", &base_addr_len);
+	if (!base_prop)
+		goto out;
+	base_addr_len /= sizeof(uint64_t) * 2;
+
+	maxi = sizeof(txx9_spider_tab)/sizeof(txx9_spider_tab[0]);
+	if (maxi > irq_len)
+		maxi = irq_len;
+
+	for(i = 0; i < maxi; i++) {
+		if (!(txx9_serial_bitmap & (1<<i)))
+			continue;
+		if (base_addr_len <= txx9_spider_tab[i].index)
+			continue;
+		
+		memset(&req, 0, sizeof(req));
+		req.line = i;
+		req.iotype = UPIO_MEM;
+		req.mapbase = base_prop[txx9_spider_tab[i].index * 2]
+			+ txx9_spider_tab[i].offset;
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+		req.membase = ioremap(req.mapbase, 0x24);
+#endif
+		req.irq = irq_create_mapping(NULL, irq_prop[i]);
+		req.flags |= UPF_IOREMAP | UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+		req.uartclk = 83300000;
+		early_serial_txx9_setup(&req);
+	}
+
+out:
+	of_node_put(node);
+	return 0;
+}
+
+static int
+txx9_serial_config(char *ptr)
+{
+	int	i;
+
+	for (;;) {
+		switch(get_option(&ptr, &i)) {
+		default:
+			return 0;
+		case 2:
+			txx9_serial_bitmap |= 1 << i;
+			break;
+		case 1:
+			txx9_serial_bitmap |= 1 << i;
+			return 0;
+		}
+	}
+}
+__setup("txx9_serial=", txx9_serial_config);
+
+console_initcall(txx9_serial_init);
+#endif
+
+define_machine(celleb) {
+	.name			= "Cell Reference Set",
+	.probe			= celleb_probe,
+	.setup_arch		= celleb_setup_arch,
+	.init_early		= celleb_init_early,
+	.show_cpuinfo		= celleb_show_cpuinfo,
+	.pci_probe_mode 	= celleb_pci_probe_mode,
+	.restart		= beat_restart,
+	.power_off		= beat_power_off,
+	.halt			= beat_halt,
+	.get_rtc_time		= beat_get_rtc_time,
+	.set_rtc_time		= beat_set_rtc_time,
+	.calibrate_decr		= generic_calibrate_decr,
+	.check_legacy_ioport	= celleb_check_legacy_ioport,
+	.progress		= celleb_progress,
+	.power_save		= beat_power_save,
+	.nvram_size		= beat_nvram_get_size,
+	.nvram_read		= beat_nvram_read,
+	.nvram_write		= beat_nvram_write,
+	.set_dabr		= beat_set_xdabr,
+#ifdef CONFIG_KEXEC
+	.kexec_cpu_down		= celleb_kexec_cpu_down,
+	.machine_kexec		= default_machine_kexec,
+	.machine_kexec_prepare	= default_machine_kexec_prepare,
+	.machine_crash_shutdown	= default_machine_crash_shutdown,
+#endif
+};
Index: linux-2.6.19/arch/powerpc/platforms/celleb/smp.c
diff -u /dev/null linux-2.6.19/arch/powerpc/platforms/celleb/smp.c:1.2
--- /dev/null	Thu Nov  9 18:40:50 2006
+++ linux-2.6.19/arch/powerpc/platforms/celleb/smp.c	Tue Oct 17 13:22:53 2006
@@ -0,0 +1,143 @@
+/*
+ * SMP support for Celleb platform. (Incomplete)
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This code is based on arch/powerpc/platforms/cell/smp.c:
+ * Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
+ * Plus various changes from other IBM teams...
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/paca.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/cputable.h>
+#include <asm/firmware.h>
+#include <asm/system.h>
+#include <asm/rtas.h>
+#include <asm/udbg.h>
+
+#include "interrupt.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * The primary thread of each non-boot processor is recorded here before
+ * smp init.
+ */
+/* static cpumask_t of_spin_map; */
+
+/**
+ * smp_startup_cpu() - start the given cpu
+ *
+ * At boot time, there is nothing to do for primary threads which were
+ * started from Open Firmware.  For anything else, call RTAS with the
+ * appropriate start location.
+ *
+ * Returns:
+ *	0	- failure
+ *	1	- success
+ */
+static inline int __devinit smp_startup_cpu(unsigned int lcpu)
+{
+	return 0;
+}
+
+static void smp_beatic_message_pass(int target, int msg)
+{
+	unsigned int i;
+
+	if (target < NR_CPUS) {
+		beatic_cause_IPI(target, msg);
+	} else {
+		for_each_online_cpu(i) {
+			if (target == MSG_ALL_BUT_SELF
+			    && i == smp_processor_id())
+				continue;
+			beatic_cause_IPI(i, msg);
+		}
+	}
+}
+
+static int __init smp_beatic_probe(void)
+{
+	return cpus_weight(cpu_possible_map);
+}
+
+static void __devinit smp_beatic_setup_cpu(int cpu)
+{
+	beatic_setup_cpu(cpu);
+}
+
+static void __devinit smp_celleb_kick_cpu(int nr)
+{
+	BUG_ON(nr < 0 || nr >= NR_CPUS);
+
+	if (!smp_startup_cpu(nr))
+		return;
+	/*  */
+}
+
+static int smp_celleb_cpu_bootable(unsigned int nr)
+{
+	return 1;
+}
+static struct smp_ops_t bpa_beatic_smp_ops = {
+	.message_pass	= smp_beatic_message_pass,
+	.probe		= smp_beatic_probe,
+	.kick_cpu	= smp_celleb_kick_cpu,
+	.setup_cpu	= smp_beatic_setup_cpu,
+	.cpu_bootable	= smp_celleb_cpu_bootable,
+};
+
+/* This is called very early */
+void __init smp_init_celleb(void)
+{
+	DBG(" -> smp_init_celleb()\n");
+
+	smp_ops = &bpa_beatic_smp_ops;
+
+	DBG(" <- smp_init_celleb()\n");
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: [PATCH 3/16] add base support for Celleb platform
@ 2006-11-17 10:27 Ishizaki Kou
  0 siblings, 0 replies; 8+ messages in thread
From: Ishizaki Kou @ 2006-11-17 10:27 UTC (permalink / raw)
  To: linuxppc-dev

Hello Christoph-san,

> > +         if(size-- <= 0) {
> > +             return NULL;
> > +         }

> No need for the {} braces for single line conditionals.  also
> please put a space in front of opening braces.  If you're unsure
> please take a look at Documentation/CodingStyle in the kernel tree.

> > + if((str = re_det1(str, &buf[0].cbuf[4], 4)) == NULL) {
> > +     return -1;
> > + }

> Similarly this should be written as:

>     str = re_det1(str, &buf[0].cbuf[4], 4);
>     if (!str)
>         return -1;

Thank you for your comment; these will be fixed at next time.

> And btw, all these function have very non-descriptive names
> and no comments.  That could use some work.  Also I'm not
> sure -N returns are very useful - you should at least have
> descriptive enums for the error cases.

We don't think these functions are useful for all kernel users,
since they work only on Beat. And, for debugging purpose, return values
indicate the locations of errors in above case, so we don't have enums
for these error cases. But it isn't easy to understand them without
comments as you mentioned, so we will add adequate comments at next time.

Thank you,
Kou Ishizaki
Toshiba

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-11-20 21:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-15  9:31 [PATCH 3/16] add base support for Celleb platform Ishizaki Kou
2006-11-15 17:23 ` Arnd Bergmann
2006-11-15 18:36 ` Christoph Hellwig
2006-11-15 23:31   ` Benjamin Herrenschmidt
2006-11-17  6:52     ` Christoph Hellwig
2006-11-16  0:51   ` Geoff Levand
2006-11-20 21:03 ` Geoff Levand
  -- strict thread matches above, loose matches on Subject: below --
2006-11-17 10:27 Ishizaki Kou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).