Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Dec 2008 02:56:09 +0000 (UTC)
From:      Sam Leffler <sam@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r186013 - projects/cambria/sys/boot/arm/ixp425/boot2
Message-ID:  <200812130256.mBD2u9r8015704@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sam
Date: Sat Dec 13 02:56:08 2008
New Revision: 186013
URL: http://svn.freebsd.org/changeset/base/186013

Log:
  merge WIP multi-board support; tested on Avila and Cambria, still
  needs Proghorn testing

Modified:
  projects/cambria/sys/boot/arm/ixp425/boot2/arm_init.S
  projects/cambria/sys/boot/arm/ixp425/boot2/boot2.c
  projects/cambria/sys/boot/arm/ixp425/boot2/ixp425_board.c
  projects/cambria/sys/boot/arm/ixp425/boot2/lib.h

Modified: projects/cambria/sys/boot/arm/ixp425/boot2/arm_init.S
==============================================================================
--- projects/cambria/sys/boot/arm/ixp425/boot2/arm_init.S	Sat Dec 13 02:53:12 2008	(r186012)
+++ projects/cambria/sys/boot/arm/ixp425/boot2/arm_init.S	Sat Dec 13 02:56:08 2008	(r186013)
@@ -24,8 +24,9 @@
  * $FreeBSD$
  */
 
-start:
+#include <machine/asm.h>
 
+ASENTRY_NP(start)
 /* Initialise bss and sp */
 	nop
 	adr	r1, .Lstart
@@ -47,4 +48,9 @@ infiniteLoop:
 	.word	_edata
 	.word	_end
 	.word	BOOT_STACK
+
+ENTRY(cpu_id)
+	mrc	p15, 0, r0, c0, c0, 0
+	RET
+
 /* End */

Modified: projects/cambria/sys/boot/arm/ixp425/boot2/boot2.c
==============================================================================
--- projects/cambria/sys/boot/arm/ixp425/boot2/boot2.c	Sat Dec 13 02:53:12 2008	(r186012)
+++ projects/cambria/sys/boot/arm/ixp425/boot2/boot2.c	Sat Dec 13 02:56:08 2008	(r186013)
@@ -163,7 +163,7 @@ main(void)
 	p_memset((char *)dmadat, 0, 32 * 1024);
 	bt = board_init();
 
-	printf("FreeBSD ARM (%s) boot2 v%d.%d\n", bt, 0, 3);
+	printf("FreeBSD ARM (%s) boot2 v%d.%d\n", bt, 0, 4);
 
 	autoboot = 1;
 

Modified: projects/cambria/sys/boot/arm/ixp425/boot2/ixp425_board.c
==============================================================================
--- projects/cambria/sys/boot/arm/ixp425/boot2/ixp425_board.c	Sat Dec 13 02:53:12 2008	(r186012)
+++ projects/cambria/sys/boot/arm/ixp425/boot2/ixp425_board.c	Sat Dec 13 02:56:08 2008	(r186013)
@@ -27,20 +27,35 @@
 __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/ata.h>
+#include <sys/linker_set.h>
 
 #include <stdarg.h>
 
 #include "lib.h"
 #include "cf_ata.h"
 
+#include <machine/armreg.h>
 #include <arm/xscale/ixp425/ixp425reg.h>
 #include <dev/ic/ns16550.h>
 
-static u_int8_t *ubase;
+struct board_config {
+	const char *desc;
+	int	(*probe)(int boardtype_hint);
+	void	(*init)(void);
+};
+/* set of registered boards */
+SET_DECLARE(boards, struct board_config);
+#define	BOARD_CONFIG(name, _desc)			\
+static struct board_config name##config = {		\
+	.desc	= _desc,				\
+	.probe	= name##_probe,				\
+	.init	= name##_init,				\
+};							\
+DATA_SET(boards, name##config)
 
-#define BOARD_AVILA		0
-#define BOARD_PRONGHORN		1
-static int board;
+static u_int cputype;
+#define	cpu_is_ixp43x()	(cputype == CPU_ID_IXP435)
+static u_int8_t *ubase;
 
 static u_int8_t uart_getreg(u_int8_t *, int);
 static void uart_setreg(u_int8_t *, int, u_int8_t);
@@ -57,32 +72,18 @@ static void cf_clr(void);
 const char *
 board_init(void)
 {
-	volatile u_int32_t *cs;
-	const char *bt = NULL;
+	struct board_config **pbp;
 
-	/*
-	 * Redboot only configure the chip selects that are needed, so
-	 * use that to figure out if it is an Avila or ADI board. The
-	 * Avila boards use CS2 and ADI does not.
-	 */
-	cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
-	if (*cs != 0) {
-		board = BOARD_AVILA;
-		bt = "Avila";
-	} else {
-		board = BOARD_PRONGHORN;
-		bt = "Pronghorn Metro";
-	}
+	cputype = cpu_id() & CPU_ID_CPU_MASK;
 
-	/* Config the serial port. RedBoot should do the rest. */
-	if (board == BOARD_AVILA)
-		ubase = (u_int8_t *)(IXP425_UART0_HWBASE);
-	else
-		ubase = (u_int8_t *)(IXP425_UART1_HWBASE);
-
-	cf_init();
-
-	return bt;
+	SET_FOREACH(pbp, boards)
+		/* XXX pass down redboot board type */
+		if ((*pbp)->probe(0)) {
+			(*pbp)->init();
+			return (*pbp)->desc;
+		}
+	/* XXX panic, unknown board type */
+	return "???";
 }
 
 /*
@@ -228,6 +229,9 @@ struct {
 	u_int8_t sectors;
 	u_int32_t cylinders;
 
+	u_int32_t *cs1to;
+	u_int32_t *cs2to;
+
 	u_int8_t *cs1;
 	u_int8_t *cs2;
 
@@ -265,38 +269,21 @@ cf_init(void)
 #ifdef DEBUG
 	int rval;
 #endif
-	volatile u_int32_t *cs;
-
-	/* Setup the CF select timeing. Maybe already done by RedBoot? */
-	if (board == BOARD_AVILA) {
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS1_OFFSET);
-		*cs |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
-		DPRINTF("t1 %x, ", *cs);
-
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
-		*cs |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
-		DPRINTF("t2 %x\n", *cs);
-
-		dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS1_HWBASE;
-		dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS2_HWBASE;
-	} else {
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
-		*cs |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
-		DPRINTF("t1 %x, ", *cs);
-
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET);
-		*cs |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
-		DPRINTF("t2 %x\n", *cs);
-
-		dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS3_HWBASE;
-		dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS4_HWBASE;
-	}
-	DPRINTF("cs1 %x, cs2 %x\n", dskinf.cs1, dskinf.cs2);
 
+	/* NB: board init routines setup other parts of dskinf */
 	dskinf.use_stream8 = 0;
 	dskinf.use_lba = 0;
 	dskinf.debug = 1;
 
+	DPRINTF("cs1 %x, cs2 %x\n", dskinf.cs1, dskinf.cs2);
+
+	/* Setup the CF window */
+	*dskinf.cs1to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+	DPRINTF("t1 %x, ", *dskinf.cs1to);
+
+	*dskinf.cs2to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+	DPRINTF("t2 %x\n", *dskinf.cs2to);
+
 	/* Detect if there is a disk. */
 	cfwrite8(CF_DRV_HEAD, CF_D_IBM);
 	DELAY(1000);
@@ -340,29 +327,24 @@ static void
 cfenable16(void)
 {
 	u_int32_t val;
-	volatile u_int32_t *cs;
 
-	if (board == BOARD_AVILA)
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS1_OFFSET);
-	else
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
-	val = *cs;
-	*cs = val & (~1);
-	DPRINTF("cfenable16: cs1 timing reg %x\n", *cs);
+	val = *dskinf.cs1to;
+	*dskinf.cs1to = val &~ EXP_BYTE_EN;
+#if 0
+	DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__);
+#endif
 }
 
 static void
 cfdisable16(void)
 {
 	u_int32_t val;
-	volatile u_int32_t *cs;
 
-	if (board == BOARD_AVILA)
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS1_OFFSET);
-	else
-		cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
-	val = *cs;
-	*cs = val | 1;
+	val = *dskinf.cs1to;
+	*dskinf.cs1to = val | EXP_BYTE_EN;
+#if 0
+	DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__);
+#endif
 }
 
 static u_int8_t
@@ -478,7 +460,8 @@ cfwait(u_int8_t mask)
 	while (tout <= 5000000) {
 		status = cfread8(CF_STATUS);
 		if (status == 0xff) {
-			printf("cfwait: master: no status, reselecting\n");
+			printf("%s: master: no status, reselecting\n",
+			    __func__);
 			cfwrite8(CF_DRV_HEAD, CF_D_IBM);
 			DELAY(1);
 			status = cfread8(CF_STATUS);
@@ -487,10 +470,14 @@ cfwait(u_int8_t mask)
 			return -1;
 		dskinf.status = status;
 		if (!(status & CF_S_BUSY)) {
-			if (status & CF_S_ERROR)
+			if (status & CF_S_ERROR) {
 				dskinf.error = cfread8(CF_ERROR);
+				printf("%s: error, status 0x%x error 0x%x\n",
+				    __func__, status, dskinf.error);
+			}
 			if ((status & mask) == mask) {
-				DPRINTF("cfwait: tout %u\n", tout);
+				DPRINTF("%s: status 0x%x mask 0x%x tout %u\n",
+				    __func__, status, mask, tout);
 				return (status & CF_S_ERROR);
 			}
 		}
@@ -695,3 +682,88 @@ avila_read(char *dest, unsigned source, 
 	return 0;
 }
 
+/*
+ * Gateworks Avila Support.
+ */
+static int
+avila_probe(int boardtype_hint)
+{
+	volatile u_int32_t *cs;
+	/*
+	 * Redboot only configure the chip selects that are needed, so
+	 * use that to figure out if it is an Avila or ADI board. The
+	 * Avila boards use CS2 and ADI does not.
+	 */
+	cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
+	return (*cs != 0);
+}
+
+static void
+avila_init(void)
+{
+	/* Config the serial port. RedBoot should do the rest. */
+	ubase = (u_int8_t *)(IXP425_UART0_HWBASE);
+
+	dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS1_OFFSET);
+	dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
+	dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS1_HWBASE;
+	dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS2_HWBASE;
+
+	cf_init();
+}
+BOARD_CONFIG(avila, "Gateworks Avila");
+
+/*
+ * Gateworks Cambria Support.
+ */
+static int
+cambria_probe(int boardtype_hint)
+{
+	return cpu_is_ixp43x();
+}
+
+static void
+cambria_init(void)
+{
+	/* Config the serial port. RedBoot should do the rest. */
+	ubase = (u_int8_t *)(IXP425_UART0_HWBASE);
+
+	dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
+	dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET);
+	dskinf.cs1 = (u_int8_t *)CAMBRIA_CFSEL0_HWBASE;
+	dskinf.cs2 = (u_int8_t *)CAMBRIA_CFSEL1_HWBASE;
+
+	cf_init();
+}
+BOARD_CONFIG(cambria, "Gateworks Cambria");
+
+/*
+ * Pronghorn Metro Support.
+ */
+static int
+pronghorn_probe(int boardtype_hint)
+{
+	volatile u_int32_t *cs;
+	/*
+	 * Redboot only configure the chip selects that are needed, so
+	 * use that to figure out if it is an Avila or ADI board. The
+	 * Avila boards use CS2 and ADI does not.
+	 */
+	cs = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS2_OFFSET);
+	return (*cs == 0);
+}
+
+static void
+pronghorn_init(void)
+{
+	/* Config the serial port. RedBoot should do the rest. */
+	ubase = (u_int8_t *)(IXP425_UART1_HWBASE);
+
+	dskinf.cs1to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS3_OFFSET);
+	dskinf.cs2to = (u_int32_t *)(IXP425_EXP_HWBASE + EXP_TIMING_CS4_OFFSET);
+	dskinf.cs1 = (u_int8_t *)IXP425_EXP_BUS_CS3_HWBASE;
+	dskinf.cs2 = (u_int8_t *)IXP425_EXP_BUS_CS4_HWBASE;
+
+	cf_init();
+}
+BOARD_CONFIG(pronghorn, "Pronghorn Metro");

Modified: projects/cambria/sys/boot/arm/ixp425/boot2/lib.h
==============================================================================
--- projects/cambria/sys/boot/arm/ixp425/boot2/lib.h	Sat Dec 13 02:53:12 2008	(r186012)
+++ projects/cambria/sys/boot/arm/ixp425/boot2/lib.h	Sat Dec 13 02:56:08 2008	(r186013)
@@ -60,5 +60,6 @@ u_int32_t swap32(u_int32_t);
 const char *board_init(void);
 void clr_board(void);
 int avila_read(char*, unsigned, unsigned);
+u_int cpu_id(void);
 
 #endif /* !ARM_BOOT_LIB_H */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812130256.mBD2u9r8015704>