From owner-p4-projects@FreeBSD.ORG Mon Dec 1 23:35:53 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6CFDE106567C; Mon, 1 Dec 2008 23:35:53 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 036011065675 for ; Mon, 1 Dec 2008 23:35:53 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id EBBFE8FC16 for ; Mon, 1 Dec 2008 23:35:52 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id mB1NZqMD036956 for ; Mon, 1 Dec 2008 23:35:52 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id mB1NZq3t036954 for perforce@freebsd.org; Mon, 1 Dec 2008 23:35:52 GMT (envelope-from sam@freebsd.org) Date: Mon, 1 Dec 2008 23:35:52 GMT Message-Id: <200812012335.mB1NZq3t036954@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 153922 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Dec 2008 23:35:53 -0000 http://perforce.freebsd.org/chv.cgi?CH=153922 Change 153922 by sam@sam_ebb on 2008/12/01 23:35:44 Switch to a scheme more driven by a central board definition: each board has a probe+init method and a record that's collected in a linker set for doing board id+setup. When we have a passed through board type hint from the 1st level bootstrap we can add code to use it (e.g. RedBoot). Add new board def for the Gateworks Cambria. Tested on Avila and Cambria boards; needs Pronghorn testing before it can go in svn. Affected files ... .. //depot/projects/vap/sys/boot/arm/ixp425/boot2/arm_init.S#2 edit .. //depot/projects/vap/sys/boot/arm/ixp425/boot2/boot2.c#2 edit .. //depot/projects/vap/sys/boot/arm/ixp425/boot2/ixp425_board.c#2 edit .. //depot/projects/vap/sys/boot/arm/ixp425/boot2/lib.h#2 edit Differences ... ==== //depot/projects/vap/sys/boot/arm/ixp425/boot2/arm_init.S#2 (text+ko) ==== @@ -24,8 +24,9 @@ * $FreeBSD: src/sys/boot/arm/ixp425/boot2/arm_init.S,v 1.1 2008/10/06 19:38:10 jhay Exp $ */ -start: +#include +ASENTRY_NP(start) /* Initialise bss and sp */ nop adr r1, .Lstart @@ -47,4 +48,9 @@ .word _edata .word _end .word BOOT_STACK + +ENTRY(cpu_id) + mrc p15, 0, r0, c0, c0, 0 + RET + /* End */ ==== //depot/projects/vap/sys/boot/arm/ixp425/boot2/boot2.c#2 (text+ko) ==== @@ -163,7 +163,7 @@ 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; ==== //depot/projects/vap/sys/boot/arm/ixp425/boot2/ixp425_board.c#2 (text+ko) ==== @@ -27,21 +27,36 @@ __FBSDID("$FreeBSD: src/sys/boot/arm/ixp425/boot2/ixp425_board.c,v 1.1 2008/10/06 19:38:10 jhay Exp $"); #include #include +#include #include #include "lib.h" #include "cf_ata.h" +#include #include #include +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) + +static u_int cputype; +#define cpu_is_ixp43x() (cputype == CPU_ID_IXP435) static u_int8_t *ubase; -#define BOARD_AVILA 0 -#define BOARD_PRONGHORN 1 -static int board; - 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 @@ 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 @@ 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 @@ #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); + /* NB: board init routines setup other parts of dskinf */ + dskinf.use_stream8 = 0; + dskinf.use_lba = 0; + dskinf.debug = 1; - 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); + DPRINTF("cs1 %x, cs2 %x\n", dskinf.cs1, dskinf.cs2); - 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); + /* Setup the CF window */ + *dskinf.cs1to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN); + DPRINTF("t1 %x, ", *dskinf.cs1to); - 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); + *dskinf.cs2to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN); + DPRINTF("t2 %x\n", *dskinf.cs2to); - dskinf.use_stream8 = 0; - dskinf.use_lba = 0; - dskinf.debug = 1; - /* Detect if there is a disk. */ cfwrite8(CF_DRV_HEAD, CF_D_IBM); DELAY(1000); @@ -340,29 +327,24 @@ 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 @@ 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 @@ 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 @@ 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"); ==== //depot/projects/vap/sys/boot/arm/ixp425/boot2/lib.h#2 (text+ko) ==== @@ -60,5 +60,6 @@ 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 */