Skip to contentSkip to conversation

powerpc: Unify udbg

PATCH New Benjamin Herrenschmidt 1 participant 1 message Nov 22, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 powerpc: Unify udbg

This patch unifies udbg for both ppc32 and ppc64 when building the merged achitecture. xmon now has a single "back end". The powermac udbg stuff gets enriched with some ADB capabilities and btext output. In addition, the early_init callback is now called on ppc32 as well, approx. in the same order as ppc64 regarding device-tree manipulations. The init sequences of ppc32 and ppc64 are getting closer, I'll unify them in a later patch.

For now, you can force udbg to the scc using "sccdbg" or to btext using "btextdbg" on powermacs. I'll implement a cleaner way of forcing udbg output to something else than the autodetected OF output device in a later patch.

arch/powerpc/kernel/Makefile +3 -4
Index: linux-serialfix/arch/powerpc/kernel/Makefile
===================================================================
@@ -18,7 +18,7 @@
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 				   signal_64.o ptrace32.o systbl.o \
 				   paca.o ioctl32.o cpu_setup_power4.o \
-				   firmware.o sysfs.o udbg.o idle_64.o
+				   firmware.o sysfs.o idle_64.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_POWER4)		+= idle_power4.o
@@ -45,7 +45,7 @@
 extra-y				+= vmlinux.lds
 
 obj-y				+= process.o init_task.o time.o \
-				   prom.o traps.o setup-common.o
+				   prom.o traps.o setup-common.o udbg.o
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o systbl.o
 obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC_OF)		+= prom_init.o
@@ -55,8 +55,7 @@
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_PPC_MULTIPLATFORM) += legacy_serial.o
-obj64-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o
-obj64-$(CONFIG_PPC_PMAC)	+= udbg_scc.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
 
arch/powerpc/kernel/udbg.c +5 -3
Index: linux-serialfix/arch/powerpc/kernel/udbg.c
===================================================================
@@ -16,8 +16,8 @@
 #include <linux/console.h>
 #include <asm/processor.h>
 
-void (*udbg_putc)(unsigned char c);
-unsigned char (*udbg_getc)(void);
+void (*udbg_putc)(char c);
+char (*udbg_getc)(void);
 int (*udbg_getc_poll)(void);
 
 /* udbg library, used by xmon et al */
@@ -78,7 +78,7 @@
 #define UDBG_BUFSIZE 256
 void udbg_printf(const char *fmt, ...)
 {
-	unsigned char buf[UDBG_BUFSIZE];
+	char buf[UDBG_BUFSIZE];
 	va_list args;
 
 	va_start(args, fmt);
@@ -116,6 +116,8 @@
 /* called by setup_system */
 void register_early_udbg_console(void)
 {
+	if (early_console_initialized)
+		return;
 	early_console_initialized = 1;
 	register_console(&udbg_console);
 }
arch/powerpc/kernel/udbg_scc.c deleted +0 -135

135 lines not on this page · raw message

arch/powerpc/platforms/powermac/udbg_adb.c new file +218 -0

218 lines not on this page · raw message

arch/powerpc/platforms/powermac/udbg_scc.c new file +165 -0

165 lines not on this page · raw message

arch/powerpc/Kconfig +1 -1
Index: linux-serialfix/arch/powerpc/Kconfig
===================================================================
@@ -50,7 +50,7 @@
 
 config EARLY_PRINTK
 	bool
-	default y if PPC64
+	default y
 
 config COMPAT
 	bool
arch/powerpc/kernel/btext.c +94 -38

237 lines not on this page · raw message

arch/powerpc/kernel/setup_32.c +3 -12
Index: linux-serialfix/arch/powerpc/kernel/setup_32.c
===================================================================
@@ -40,6 +40,7 @@
 #include <asm/xmon.h>
 #include <asm/time.h>
 #include <asm/serial.h>
+#include <asm/udbg.h>
 
 #include "setup.h"
 
@@ -294,21 +295,11 @@
 
 	smp_setup_cpu_maps();
 
-#ifdef CONFIG_BOOTX_TEXT
-	init_boot_display();
-#endif
-
-#ifdef CONFIG_PPC_PMAC
-	/* This could be called "early setup arch", it must be done
-	 * now because xmon need it
-	 */
-	if (_machine == _MACH_Pmac)
-		pmac_feature_init();	/* New cool way */
-#endif
-
 #ifdef CONFIG_XMON_DEFAULT
 	xmon_init(1);
 #endif
+	/* Register early console */
+	register_early_udbg_console();
 
 #if defined(CONFIG_KGDB)
 	if (ppc_md.kgdb_map_scc)
arch/powerpc/kernel/udbg_16550.c +2 -2
Index: linux-serialfix/arch/powerpc/kernel/udbg_16550.c
===================================================================
@@ -47,7 +47,7 @@
 
 static volatile struct NS16550 __iomem *udbg_comport;
 
-static void udbg_550_putc(unsigned char c)
+static void udbg_550_putc(char c)
 {
 	if (udbg_comport) {
 		while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
@@ -69,7 +69,7 @@
 	return -1;
 }
 
-static unsigned char udbg_550_getc(void)
+static char udbg_550_getc(void)
 {
 	if (udbg_comport) {
 		while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0)
arch/powerpc/platforms/powermac/Makefile +1 -0
Index: linux-serialfix/arch/powerpc/platforms/powermac/Makefile
===================================================================
@@ -7,3 +7,4 @@
 # ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
 obj-$(CONFIG_PPC64)		+= nvram.o
 obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_PPC_MERGE)		+= udbg_scc.o udbg_adb.o
arch/powerpc/platforms/powermac/setup.c +23 -29

91 lines not on this page · raw message

arch/powerpc/xmon/Makefile +2 -6
Index: linux-serialfix/arch/powerpc/xmon/Makefile
===================================================================
@@ -3,9 +3,5 @@
 ifdef CONFIG_PPC64
 EXTRA_CFLAGS += -mno-minimal-toc
 endif
-
-obj-$(CONFIG_8xx)	+= start_8xx.o
-obj-$(CONFIG_6xx)	+= start_32.o
-obj-$(CONFIG_4xx)	+= start_32.o
-obj-$(CONFIG_PPC64)	+= start_64.o
-obj-y			+= xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
+obj-y			+= xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \
+			   nonstdio.o
arch/powerpc/xmon/start.c new file +34 -0
Index: linux-serialfix/arch/powerpc/xmon/start.c
===================================================================
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      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.
+ */
+#include <asm/machdep.h>
+#include <asm/udbg.h>
+#include "nonstdio.h"
+
+void xmon_map_scc(void)
+{
+}
+
+int xmon_write(void *ptr, int nb)
+{
+	return udbg_write(ptr, nb);
+}
+
+int xmon_readchar(void)
+{
+	if (udbg_getc)
+		return udbg_getc();
+	return -1;
+}
+
+int xmon_read_poll(void)
+{
+	if (udbg_getc_poll)
+		return udbg_getc_poll();
+	return -1;
+}
arch/powerpc/xmon/start_32.c deleted +0 -441

441 lines not on this page · raw message

arch/powerpc/xmon/start_64.c deleted +0 -34
Index: linux-serialfix/arch/powerpc/xmon/start_64.c
===================================================================
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- *      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.
- */
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-#include "nonstdio.h"
-
-void xmon_map_scc(void)
-{
-}
-
-int xmon_write(void *ptr, int nb)
-{
-	return udbg_write(ptr, nb);
-}
-
-int xmon_readchar(void)
-{
-	if (udbg_getc)
-		return udbg_getc();
-	return -1;
-}
-
-int xmon_read_poll(void)
-{
-	if (udbg_getc_poll)
-		return udbg_getc_poll();
-	return -1;
-}
arch/powerpc/xmon/start_8xx.c deleted +0 -44

44 lines not on this page · raw message

include/asm-powerpc/btext.h +10 -9
Index: linux-serialfix/include/asm-powerpc/btext.h
===================================================================
@@ -7,21 +7,22 @@
 #define __PPC_BTEXT_H
 #ifdef __KERNEL__
 
-extern void btext_clearscreen(void);
-extern void btext_flushscreen(void);
-
-extern int boot_text_mapped;
-
-extern int btext_initialize(struct device_node *np);
-
-extern void map_boot_text(void);
-extern void init_boot_display(void);
+extern int btext_find_display(int allow_nonstdout);
 extern void btext_update_display(unsigned long phys, int width, int height,
 				 int depth, int pitch);
+extern void btext_setup_display(int width, int height, int depth, int pitch,
+				unsigned long address);
+extern void btext_prepare_BAT(void);
+extern void btext_unmap(void);
 
 extern void btext_drawchar(char c);
 extern void btext_drawstring(const char *str);
 extern void btext_drawhex(unsigned long v);
+extern void btext_drawtext(const char *c, unsigned int len);
+
+extern void btext_clearscreen(void);
+extern void btext_flushscreen(void);
+extern void btext_flushline(void);
 
 #endif /* __KERNEL__ */
 #endif /* __PPC_BTEXT_H */
include/asm-powerpc/udbg.h +6 -3
Index: linux-serialfix/include/asm-powerpc/udbg.h
===================================================================
@@ -13,8 +13,8 @@
 #include <linux/compiler.h>
 #include <linux/init.h>
 
-extern void (*udbg_putc)(unsigned char c);
-extern unsigned char (*udbg_getc)(void);
+extern void (*udbg_putc)(char c);
+extern char (*udbg_getc)(void);
 extern int (*udbg_getc_poll)(void);
 
 extern void udbg_puts(const char *s);
@@ -30,5 +30,8 @@
 					  unsigned int clock);
 
 struct device_node;
-extern void udbg_init_scc(struct device_node *np);
+extern void udbg_scc_init(int force_scc);
+extern int udbg_adb_init(int force_btext);
+extern void udbg_adb_init_early(void);
+
 #endif /* _ASM_POWERPC_UDBG_H */
arch/powerpc/kernel/setup_64.c +0 -4
Index: linux-serialfix/arch/powerpc/kernel/setup_64.c
===================================================================
@@ -466,10 +466,6 @@
 	 */
 	finish_device_tree();
 
-#ifdef CONFIG_BOOTX_TEXT
-	init_boot_display();
-#endif
-
 	/*
 	 * Initialize xmon
 	 */
arch/powerpc/platforms/powermac/feature.c +42 -24

100 lines not on this page · raw message

arch/powerpc/platforms/powermac/low_i2c.c +19 -8
Index: linux-serialfix/arch/powerpc/platforms/powermac/low_i2c.c
===================================================================
@@ -36,7 +36,7 @@
 
 #ifdef DEBUG
 #define DBG(x...) do {\
-		printk(KERN_DEBUG "KW:" x);	\
+		printk(KERN_DEBUG "low_i2c:" x);	\
 	} while(0)
 #else
 #define DBG(x...)
@@ -342,7 +342,7 @@
 static void keywest_low_i2c_add(struct device_node *np)
 {
 	struct low_i2c_host	*host = find_low_i2c_host(NULL);
-	u32			*psteps, *prate, steps, aoffset = 0;
+	u32			*psteps, *prate, *addrp, steps;
 	struct device_node	*parent;
 
 	if (host == NULL) {
@@ -352,6 +352,16 @@
 	}
 	memset(host, 0, sizeof(*host));
 
+	/* Apple is kind enough to provide a valid AAPL,address property
+	 * on all i2c keywest nodes so far ... we would have to fallback
+	 * to macio parsing if that wasn't the case
+	 */
+	addrp = (u32 *)get_property(np, "AAPL,address", NULL);
+	if (addrp == NULL) {
+		printk(KERN_ERR "low_i2c: Can't find address for %s\n",
+		       np->full_name);
+		return;
+	}
 	init_MUTEX(&host->mutex);
 	host->np = of_node_get(np);	
 	psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
@@ -360,12 +370,10 @@
 		steps >>= 1;
 	parent = of_get_parent(np);
 	host->num_channels = 1;
-	if (parent && parent->name[0] == 'u') {
+	if (parent && parent->name[0] == 'u')
 		host->num_channels = 2;
-		aoffset = 3;
-	}
 	/* Select interface rate */
-	host->speed = KW_I2C_MODE_100KHZ;
+	host->speed = KW_I2C_MODE_25KHZ;
 	prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
 	if (prate) switch(*prate) {
 	case 100:
@@ -379,9 +387,12 @@
 		break;
 	}	
 
+	printk(KERN_INFO "low_i2c: Bus %s found at 0x%08x, %d channels,"
+	       " speed = %d KHz\n",
+	       np->full_name, *addrp, host->num_channels, prate ? *prate : 25);
+
 	host->mode = pmac_low_i2c_mode_std;
-	host->base = ioremap(np->addrs[0].address + aoffset,
-						np->addrs[0].size);
+	host->base = ioremap((*addrp), 0x1000);
 	host->func = keywest_low_i2c_func;
 }
 
arch/powerpc/platforms/powermac/pic.c +1 -1
Index: linux-serialfix/arch/powerpc/platforms/powermac/pic.c
===================================================================
@@ -459,7 +459,7 @@
 			mpic_setup_cascade(irqctrler2->intrs[0].line,
 					   pmac_u3_cascade, mpic2);
 		}
-#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
+#ifdef CONFIG_XMON
 		{
 			struct device_node* pswitch;
 			int nmi_irq;
arch/powerpc/platforms/pseries/lpar.c +4 -4
Index: linux-serialfix/arch/powerpc/platforms/pseries/lpar.c
===================================================================
@@ -61,7 +61,7 @@
 int vtermno;	/* virtual terminal# for udbg  */
 
 #define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
-static void udbg_hvsi_putc(unsigned char c)
+static void udbg_hvsi_putc(char c)
 {
 	/* packet's seqno isn't used anyways */
 	uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c };
@@ -112,7 +112,7 @@
 	return ch;
 }
 
-static unsigned char udbg_hvsi_getc(void)
+static char udbg_hvsi_getc(void)
 {
 	int ch;
 	for (;;) {
@@ -128,7 +128,7 @@
 	}
 }
 
-static void udbg_putcLP(unsigned char c)
+static void udbg_putcLP(char c)
 {
 	char buf[16];
 	unsigned long rc;
@@ -173,7 +173,7 @@
 	return ch;
 }
 
-static unsigned char udbg_getcLP(void)
+static char udbg_getcLP(void)
 {
 	int ch;
 	for (;;) {
arch/powerpc/kernel/head_32.S +29 -0
Index: linux-serialfix/arch/powerpc/kernel/head_32.S
===================================================================
@@ -153,6 +153,9 @@
 	bl	flush_tlbs
 
 	bl	initial_bats
+#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+	bl	setup_disp_bat
+#endif
 
 /*
  * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -1306,6 +1309,32 @@
 	blr
 
 
+#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+setup_disp_bat:
+	/*
+	 * setup the display bat prepared for us in prom.c
+	 */
+	mflr	r8
+	bl	reloc_offset
+	mtlr	r8
+	addis	r8,r3,disp_BAT@ha
+	addi	r8,r8,disp_BAT@l
+	cmpwi	cr0,r8,0
+	beqlr
+	lwz	r11,0(r8)
+	lwz	r8,4(r8)
+	mfspr	r9,SPRN_PVR
+	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
+	cmpwi	0,r9,1
+	beq	1f
+	mtspr	SPRN_DBAT3L,r8
+	mtspr	SPRN_DBAT3U,r11
+	blr
+1:	mtspr	SPRN_IBAT3L,r8
+	mtspr	SPRN_IBAT3U,r11
+	blr
+#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
+
 #ifdef CONFIG_8260
 /* Jump into the system reset for the rom.
  * We first disable the MMU, and then jump to the ROM reset address.
arch/powerpc/mm/init_32.c +5 -0
Index: linux-serialfix/arch/powerpc/mm/init_32.c
===================================================================
@@ -188,6 +188,11 @@
 
 	if (ppc_md.progress)
 		ppc_md.progress("MMU:exit", 0x211);
+
+	/* From now on, btext is no longer BAT mapped if it was at all */
+#ifdef CONFIG_BOOTX_TEXT
+	btext_unmap();
+#endif
 }
 
 /* This is only called until mem_init is done. */
drivers/i2c/busses/i2c-keywest.c +14 -11
Index: linux-serialfix/drivers/i2c/busses/i2c-keywest.c
===================================================================
@@ -505,16 +505,23 @@
 create_iface(struct device_node *np, struct device *dev)
 {
 	unsigned long steps;
-	unsigned bsteps, tsize, i, nchan, addroffset;
+	unsigned bsteps, tsize, i, nchan;
 	struct keywest_iface* iface;
-	u32 *psteps, *prate;
+	u32 *psteps, *prate, *addrp;
 	int rc;
 
-	if (np->n_intrs < 1 || np->n_addrs < 1) {
-		printk(KERN_ERR "%s: Missing interrupt or address !\n",
+	if (np->n_intrs < 1) {
+		printk(KERN_ERR "%s: Missing interrupt !\n",
 		       np->full_name);
 		return -ENODEV;
 	}
+	addrp = (u32 *)get_property(np, "AAPL,address", NULL);
+	if (addrp == NULL) {
+		printk(KERN_ERR "%s: Can't find address !\n",
+		       np->full_name);
+		return -ENODEV;
+	}
+
 	if (pmac_low_i2c_lock(np))
 		return -ENODEV;
 
@@ -525,13 +532,10 @@
 	for (bsteps = 0; (steps & 0x01) == 0; bsteps++)
 		steps >>= 1;
 
-	if (np->parent->name[0] == 'u') {
+	if (np->parent->name[0] == 'u')
 		nchan = 2;
-		addroffset = 3;
-	} else {
-		addroffset = 0;
+	else
 		nchan = 1;
-	}
 
 	tsize = sizeof(struct keywest_iface) +
 		(sizeof(struct keywest_chan) + 4) * nchan;
@@ -550,8 +554,7 @@
 	iface->irq = np->intrs[0].line;
 	iface->channels = (struct keywest_chan *)
 		(((unsigned long)(iface + 1) + 3UL) & ~3UL);
-	iface->base = ioremap(np->addrs[0].address + addroffset,
-						np->addrs[0].size);
+	iface->base = ioremap(*addrp, 0x1000);
 	if (!iface->base) {
 		printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
 		kfree(iface);
drivers/macintosh/via-cuda.c +24 -24

69 lines not on this page · raw message

drivers/macintosh/via-pmu.c +55 -32

157 lines not on this page · raw message

arch/ppc/kernel/setup.c +3 -0
Index: linux-serialfix/arch/ppc/kernel/setup.c
===================================================================
@@ -744,6 +744,9 @@
 	/* so udelay does something sensible, assume <= 1000 bogomips */
 	loops_per_jiffy = 500000000 / HZ;
 
+	if (ppc_md.init_early)
+		ppc_md.init_early();
+
 #ifdef CONFIG_PPC_MULTIPLATFORM
 	/* This could be called "early setup arch", it must be done
 	 * now because xmon need it
include/asm-ppc/btext.h +1 -1
Index: linux-serialfix/include/asm-ppc/btext.h
===================================================================
@@ -17,7 +17,7 @@
 extern boot_infos_t disp_bi;
 extern int boot_text_mapped;
 
-extern void init_boot_display(void);
+extern void btext_init(boot_infos_t *bi);
 extern void btext_welcome(void);
 extern void btext_prepare_BAT(void);
 extern void btext_setup_display(int width, int height, int depth, int pitch,
include/asm-ppc/machdep.h +3 -1
Index: linux-serialfix/include/asm-ppc/machdep.h
===================================================================
@@ -35,8 +35,10 @@
 	int		(*get_irq)(struct pt_regs *);
 	
 	/* A general init function, called by ppc_init in init/main.c.
-	   May be NULL. */
+	   May be NULL. DEPRECATED ! */
 	void		(*init)(void);
+	/* For compatibility with merged platforms */
+	void		(*init_early)(void);
 
 	void		(*restart)(char *cmd);
 	void		(*power_off)(void);