summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/boot/arm/at91/boot0/Makefile21
-rw-r--r--sys/boot/arm/at91/boot0/README7
-rw-r--r--sys/boot/arm/at91/boot0/arm_init.s105
-rw-r--r--sys/boot/arm/at91/boot0/at91rm9200_lowlevel.c184
-rw-r--r--sys/boot/arm/at91/boot0/at91rm9200_lowlevel.h57
-rw-r--r--sys/boot/arm/at91/boot0/lib.c76
-rw-r--r--sys/boot/arm/at91/boot0/lib.h33
-rw-r--r--sys/boot/arm/at91/boot0/linker.cfg85
-rw-r--r--sys/boot/arm/at91/boot0/main.c42
-rw-r--r--sys/boot/arm/at91/boot0/xmodem.c127
-rw-r--r--sys/boot/arm/at91/boot0/xmodem.h32
11 files changed, 769 insertions, 0 deletions
diff --git a/sys/boot/arm/at91/boot0/Makefile b/sys/boot/arm/at91/boot0/Makefile
new file mode 100644
index 0000000..d0c9f2f
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+PROG=boot0
+SRCS=arm_init.s at91rm9200_lowlevel.c lib.c main.c xmodem.c
+NO_MAN=
+LDFLAGS=-e 0 -T linker.cfg
+CFLAGS=-O2 -mcpu=arm9 -ffreestanding -I${.CURDIR}/../inc
+CFLAGS+=-DBOOT0_KB9202
+OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+CLEANFILES=${OBJS} ${PROG} ${PROG}.out
+
+all: ${PROG}
+
+${PROG}: ${PROG}.out ${OBJS}
+ objcopy -S -O binary ${PROG}.out ${PROG}
+
+${PROG}.out: ${OBJS}
+ ld ${LDFLAGS} -o ${PROG}.out ${OBJS}
+
+clean:
+ rm -f ${CLEANFILES}
diff --git a/sys/boot/arm/at91/boot0/README b/sys/boot/arm/at91/boot0/README
new file mode 100644
index 0000000..1d617d6
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/README
@@ -0,0 +1,7 @@
+This is a bootstrap bootloader. It is intended to be used when the
+AT91RM9200 is running xmodem over DBGU. It will download the next stage
+of the booting process (or the recovery program) and jump to it. It loads
+the program at a 1MB offset into SDRAM. Programs are expected to be
+smaller than this and copy themselves to the right location.
+
+$FreeBSD$
diff --git a/sys/boot/arm/at91/boot0/arm_init.s b/sys/boot/arm/at91/boot0/arm_init.s
new file mode 100644
index 0000000..58c9099
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/arm_init.s
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software is derived from code provided by Kwikbyte with the
+ * following information:
+ *
+ * Initialization for C-environment and basic operation. Adapted from
+ * ATMEL cstartup.s.
+ *
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ *
+ * $FreeBSD$
+ */
+
+ .equ ARM_MODE_USER, 0x10
+ .equ ARM_MODE_FIQ, 0x11
+ .equ ARM_MODE_IRQ, 0x12
+ .equ ARM_MODE_SVC, 0x13
+ .equ ARM_MODE_ABORT, 0x17
+ .equ ARM_MODE_UNDEF, 0x1B
+ .equ ARM_MODE_SYS, 0x1F
+
+ .equ I_BIT, 0x80
+ .equ F_BIT, 0x40
+ .equ T_BIT, 0x20
+
+/*
+ * Stack definitions
+ *
+ * Start near top of internal RAM.
+ */
+
+ .equ END_INT_SRAM, 0x4000
+ .equ SVC_STACK_START, (END_INT_SRAM - 0x4)
+ .equ SVC_STACK_USE, 0x21800000
+
+start:
+
+/* vectors - must reside at address 0 */
+/* the format of this table is defined in the datasheet */
+ B InitReset @; reset
+undefvec:
+ B undefvec @; Undefined Instruction
+swivec:
+ B swivec @; Software Interrupt
+pabtvec:
+ B pabtvec @; Prefetch Abort
+dabtvec:
+ B dabtvec @; Data Abort
+rsvdvec:
+ B rsvdvec
+irqvec:
+ ldr pc, [pc,#-0xF20] @; IRQ : read the AIC
+fiqvec:
+ B fiqvec @; FIQ
+
+
+InitReset:
+
+/* Set stack and init for SVC */
+ ldr r1, = SVC_STACK_START
+ mov sp, r1 @; Init stack SYS
+
+ msr cpsr_c, #(ARM_MODE_SVC | I_BIT | F_BIT)
+ mov sp, r1 @ ; Init stack SYS
+
+/* Perform system initialization */
+
+ .extern _init
+ bl _init
+
+/* Start execution at main */
+
+ .extern main
+ bl main
+
+/* main should not return. If it does, spin forever */
+
+infiniteLoop:
+ b infiniteLoop
diff --git a/sys/boot/arm/at91/boot0/at91rm9200_lowlevel.c b/sys/boot/arm/at91/boot0/at91rm9200_lowlevel.c
new file mode 100644
index 0000000..ab3ae24
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/at91rm9200_lowlevel.c
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code.
+ *
+ * $FreeBSD$
+ */
+
+#include "AT91RM9200.h"
+#include "at91rm9200_lowlevel.h"
+
+#define BAUD 115200
+#define AT91C_US_ASYNC_MODE (AT91C_US_USMODE_NORMAL | AT91C_US_NBSTOP_1_BIT | \
+ AT91C_US_PAR_NONE | AT91C_US_CHRL_8_BITS | AT91C_US_CLKS_CLOCK)
+
+/*
+ * void DefaultSystemInit(void)
+ * Load the system with sane values based on how the system is configured.
+ * at91rm9200_lowlevel.h is expected to define the necessary parameters.
+ */
+void
+_init(void)
+{
+ AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
+ AT91PS_PDC pPDC = (AT91PS_PDC)&(pUSART->US_RPR);
+ AT91PS_PIO pPio = AT91C_BASE_PIOA;
+
+ register unsigned value;
+ int i;
+ volatile sdram_size_t *p = (sdram_size_t *)SDRAM_BASE;
+
+#ifdef BOOT0_TSC
+ // For the TSC board, we turn ON the one LED we have while
+ // early in boot.
+ AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC10;
+ AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC10;
+ AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC10;
+#endif
+
+ // configure clocks
+ // assume:
+ // main osc = 10Mhz
+ // PLLB configured for 96MHz (48MHz after div)
+ // CSS = PLLB
+ // set PLLA = 180MHz
+ // assume main osc = 10Mhz
+ // div = 5 , out = 2 (150MHz = 240MHz)
+ value = AT91C_BASE_CKGR->CKGR_PLLAR;
+ value &= ~(AT91C_CKGR_DIVA | AT91C_CKGR_OUTA | AT91C_CKGR_MULA);
+ value |= OSC_MAIN_FREQ_DIV | AT91C_CKGR_OUTA_2 | AT91C_CKGR_SRCA |
+ ((OSC_MAIN_MULT - 1) << 16);
+ AT91C_BASE_CKGR->CKGR_PLLAR = value;
+
+ // wait for lock
+ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA))
+ continue;
+
+ // change divider = 3, pres = 1
+ value = AT91C_BASE_PMC->PMC_MCKR;
+ value &= ~(AT91C_PMC_MDIV | AT91C_PMC_PRES);
+ value |= AT91C_PMC_MDIV_3 | AT91C_PMC_PRES_CLK;
+ AT91C_BASE_PMC->PMC_MCKR = value;
+
+ // wait for update
+ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
+ continue;
+
+ // change CSS = PLLA
+ value &= ~AT91C_PMC_CSS;
+ value |= AT91C_PMC_CSS_PLLA_CLK;
+ AT91C_BASE_PMC->PMC_MCKR = value;
+
+ // wait for update
+ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
+ continue;
+
+ // setup SDRAM access
+ // EBI chip-select register (CS1 = SDRAM controller)
+ // 9 col, 13row, 4 bank, CAS2
+ // write recovery = 2 (Twr)
+ // row cycle = 5 (Trc)
+ // precharge delay = 2 (Trp)
+ // row to col delay 2 (Trcd)
+ // active to precharge = 4 (Tras)
+ // exit self refresh to active = 6 (Txsr)
+ value = ((AT91PS_EBI)AT91C_BASE_EBI)->EBI_CSA;
+ value &= ~AT91C_EBI_CS1A;
+ value |= AT91C_EBI_CS1A_SDRAMC;
+ AT91C_BASE_EBI->EBI_CSA = value;
+
+ AT91C_BASE_SDRC->SDRC_CR =
+ AT91C_SDRC_NC_9 |
+ AT91C_SDRC_NR_13 |
+ AT91C_SDRC_NB_4_BANKS |
+ AT91C_SDRC_CAS_2 |
+ ((2 << 7) & AT91C_SDRC_TWR) |
+ ((5 << 11) & AT91C_SDRC_TRC) |
+ ((2 << 15) & AT91C_SDRC_TRP) |
+ ((2 << 19) & AT91C_SDRC_TRCD) |
+ ((4 << 23) & AT91C_SDRC_TRAS) |
+ ((6 << 27) & AT91C_SDRC_TXSR);
+
+ // Step 1: We assume 200us of idle time.
+ // Step 2: Issue an all banks precharge command
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_PRCGALL_CMD;
+ *p = 0;
+
+ // Step 3: Issue 8 Auto-refresh (CBR) cycles
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_RFSH_CMD;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+ *p = 0;
+
+ // Step 4: Issue an Mode Set Register (MRS) cycle to program in
+ // the parameters that we setup in the SDRC_CR register above.
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_LMR_CMD;
+ *p = 0;
+
+ // Step 5: set the refresh timer and access memory to start it
+ // running. We have to wait 3 clocks after the LMR_CMD above,
+ // and this fits the bill nicely.
+ AT91C_BASE_SDRC->SDRC_TR = 7 * AT91C_MASTER_CLOCK / 1000000;
+ *p = 0;
+
+ // Step 6: Set normal mode.
+ AT91C_BASE_SDRC->SDRC_MR = SDRAM_WIDTH | AT91C_SDRC_MODE_NORMAL_CMD;
+ *p = 0;
+
+ // Configure DBGU -use local routine optimized for space
+ pPio->PIO_ASR = AT91C_PA31_DTXD | AT91C_PA30_DRXD;
+ pPio->PIO_BSR = 0;
+ pPio->PIO_PDR = AT91C_PA31_DTXD | AT91C_PA30_DRXD;
+ pUSART->US_IDR = (unsigned int) -1;
+ pUSART->US_CR =
+ AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
+ pUSART->US_BRGR = ((((AT91C_MASTER_CLOCK*10)/(BAUD*16))+5)/10);
+ pUSART->US_TTGR = 0;
+ pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
+ pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
+ pPDC->PDC_TNPR = 0;
+ pPDC->PDC_TNCR = 0;
+
+ pPDC->PDC_RNPR = 0;
+ pPDC->PDC_RNCR = 0;
+
+ pPDC->PDC_TPR = 0;
+ pPDC->PDC_TCR = 0;
+
+ pPDC->PDC_RPR = 0;
+ pPDC->PDC_RCR = 0;
+
+ pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
+ pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
+
+ pUSART->US_MR = AT91C_US_ASYNC_MODE;
+ pUSART->US_CR = AT91C_US_TXEN;
+ pUSART->US_CR = AT91C_US_RXEN;
+}
diff --git a/sys/boot/arm/at91/boot0/at91rm9200_lowlevel.h b/sys/boot/arm/at91/boot0/at91rm9200_lowlevel.h
new file mode 100644
index 0000000..8445e16
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/at91rm9200_lowlevel.h
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AT91RM9200_LOWLEVEL_H_
+#define _AT91RM9200_LOWLEVEL_H_
+
+/* default system config parameters */
+
+#define SDRAM_BASE 0x20000000
+
+#ifdef BOOT0_KB9202
+/* The following divisor sets PLLA frequency: e.g. 10/5 * 90 = 180MHz */
+#define OSC_MAIN_FREQ_DIV 5 /* for 10MHz osc */
+#define SDRAM_WIDTH AT91C_SDRC_DBW_16_BITS
+typedef unsigned short sdram_size_t;
+#define OSC_MAIN_MULT 90
+#endif
+
+#ifdef BOOT0_TSC
+/* The following divisor sets PLLA frequency: e.g. 16/4 * 45 = 180MHz */
+#define OSC_MAIN_FREQ_DIV 4 /* for 16MHz osc */
+#define SDRAM_WIDTH AT91C_SDRC_DBW_16_BITS
+typedef unsigned int sdram_size_t;
+#define OSC_MAIN_MULT 45
+#endif
+
+/* Master clock frequency at power-up */
+#define AT91C_MASTER_CLOCK 60000000
+
+#define GetSeconds() (AT91C_BASE_RTC->RTC_TIMR & AT91C_RTC_SEC)
+
+extern void DefaultSystemInit(void);
+
+#endif /* _AT91RM9200_LOWLEVEL_H_ */
diff --git a/sys/boot/arm/at91/boot0/lib.c b/sys/boot/arm/at91/boot0/lib.c
new file mode 100644
index 0000000..1f3e6e6
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/lib.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software is derived from software provided by kwikbyte without
+ * copyright as follows:
+ *
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ *
+ * $FreeBSD$
+ */
+
+#include "AT91RM9200.h"
+#include "at91rm9200_lowlevel.h"
+
+/*
+ * void putc(int ch)
+ * Writes a character to the DBGU port. It assumes that DBGU has
+ * already been initialized.
+ */
+void
+putc(int ch)
+{
+ AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
+
+ while (!(pUSART->US_CSR & AT91C_US_TXRDY))
+ continue;
+ pUSART->US_THR = (ch & 0xFF);
+}
+
+/*
+ * int getc(int seconds)
+ *
+ * Reads a character from the DBGU port, if one is available within about
+ * seconds seconds. It assumes that DBGU has already been initialized.
+ */
+int
+getc(int seconds)
+{
+ AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
+ unsigned thisSecond;
+
+ thisSecond = GetSeconds();
+ seconds = thisSecond + seconds;
+
+ while (thisSecond <= seconds) {
+ if ((pUSART->US_CSR & AT91C_US_RXRDY))
+ return (pUSART->US_RHR & 0xFF);
+ thisSecond = GetSeconds();
+ }
+ return (-1);
+}
diff --git a/sys/boot/arm/at91/boot0/lib.h b/sys/boot/arm/at91/boot0/lib.h
new file mode 100644
index 0000000..535b719
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/lib.h
@@ -0,0 +1,33 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ARM_BOOT_LIB_H
+#define ARM_BOOT_LIB_H
+
+int getc(int);
+void putc(int);
+
+#endif
diff --git a/sys/boot/arm/at91/boot0/linker.cfg b/sys/boot/arm/at91/boot0/linker.cfg
new file mode 100644
index 0000000..8e2c96b
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/linker.cfg
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ *
+ * Filename: linker.cfg
+ *
+ * linker config file used for internal RAM or eeprom images at address 0.
+ *
+ * Revision information:
+ *
+ * 20AUG2004 kb_admin initial creation
+ * 12JAN2005 kb_admin move data to SDRAM
+ *
+ * BEGIN_KBDD_BLOCK
+ * No warranty, expressed or implied, is included with this software. It is
+ * provided "AS IS" and no warranty of any kind including statutory or aspects
+ * relating to merchantability or fitness for any purpose is provided. All
+ * intellectual property rights of others is maintained with the respective
+ * owners. This software is not copyrighted and is intended for reference
+ * only.
+ * END_BLOCK
+ *
+ * $FreeBSD$
+ ******************************************************************************/
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(start)
+ SEARCH_DIR(/usr/local/arm/2.95.3/arm-linux/lib);
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0;
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7t) *(.glue_7)
+ }
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .data :
+ {
+ __data_start = . ;
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss)
+ *(.sbss.*)
+ *(.gnu.linkonce.sb.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ PROVIDE (___sbss_end = .);
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+}
diff --git a/sys/boot/arm/at91/boot0/main.c b/sys/boot/arm/at91/boot0/main.c
new file mode 100644
index 0000000..5f4cc72
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/main.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "AT91RM9200.h"
+#include "lib.h"
+
+typedef void fn_t(void);
+
+int
+main(void)
+{
+ char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
+ fn_t *fn = (fn_t *)addr;
+
+ while (xmodem_rx(addr) == -1)
+ continue;
+ fn();
+ return (1);
+}
diff --git a/sys/boot/arm/at91/boot0/xmodem.c b/sys/boot/arm/at91/boot0/xmodem.c
new file mode 100644
index 0000000..8781187
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/xmodem.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software is derived from software provide by Kwikbyte who specifically
+ * disclaimed copyright on the code. This version of xmodem has been nearly
+ * completely rewritten, but the CRC is from the original.
+ *
+ * $FreeBSD$
+ */
+
+#include "lib.h"
+
+#define PACKET_SIZE 128
+
+/* Line control codes */
+#define SOH 0x01 /* start of header */
+#define ACK 0x06 /* Acknowledge */
+#define NAK 0x15 /* Negative acknowledge */
+#define CAN 0x18 /* Cancel */
+#define EOT 0x04 /* end of text */
+
+/*
+ * int GetRecord(char , char *)
+ * This private function receives a x-modem record to the pointer and
+ * returns non-zero on success.
+ */
+static int
+GetRecord(char blocknum, char *dest)
+{
+ int size;
+ int ch;
+ unsigned chk, j;
+
+ chk = 0;
+
+ if ((ch = getc(1)) == -1)
+ goto err;
+ if (ch != blocknum)
+ goto err;
+ if ((ch = getc(1)) == -1)
+ goto err;
+ if (ch != (~blocknum & 0xff))
+ goto err;
+
+ for (size = 0; size < PACKET_SIZE; ++size) {
+ if ((ch = getc(1)) == -1)
+ goto err;
+ chk = chk ^ ch << 8;
+ for (j = 0; j < 8; ++j) {
+ if (chk & 0x8000)
+ chk = chk << 1 ^ 0x1021;
+ else
+ chk = chk << 1;
+ }
+ *dest++ = ch;
+ }
+
+ chk &= 0xFFFF;
+
+ if (((ch = getc(1)) == -1) || ((ch & 0xff) != ((chk >> 8) & 0xFF)))
+ goto err;
+ if (((ch = getc(1)) == -1) || ((ch & 0xff) != (chk & 0xFF)))
+ goto err;
+ putc(ACK);
+
+ return (1);
+err:;
+ putc(CAN);
+ // We should allow for resend, but we don't.
+ return (0);
+}
+
+/*
+ * int xmodem_rx(char *)
+ * This global function receives a x-modem transmission consisting of
+ * (potentially) several blocks. Returns the number of bytes received or
+ * -1 on error.
+ */
+int
+xmodem_rx(char *dest)
+{
+ int starting, ch;
+ char packetNumber, *startAddress = dest;
+
+ packetNumber = 1;
+ starting = 1;
+
+ while (1) {
+ if (starting)
+ putc('C');
+ if (((ch = getc(1)) == -1) || (ch != SOH && ch != EOT))
+ continue;
+ if (ch == EOT) {
+ putc(ACK);
+ return (dest - startAddress);
+ }
+ starting = 0;
+ // Xmodem packets: SOH PKT# ~PKT# 128-bytes CRC16
+ if (!GetRecord(packetNumber, dest))
+ return (-1);
+ dest += PACKET_SIZE;
+ packetNumber++;
+ }
+
+ // the loop above should return in all cases
+ return (-1);
+}
diff --git a/sys/boot/arm/at91/boot0/xmodem.h b/sys/boot/arm/at91/boot0/xmodem.h
new file mode 100644
index 0000000..bcc156c
--- /dev/null
+++ b/sys/boot/arm/at91/boot0/xmodem.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2006 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef BOOT_ARM_XMODEM_H
+#define BOOT_ARM_XMODEM_H
+
+int xmodem_rx(char *dst);
+
+#endif /* BOOT_ARM_XMODEM_H */
OpenPOWER on IntegriCloud