diff options
author | imp <imp@FreeBSD.org> | 2006-04-12 21:22:44 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2006-04-12 21:22:44 +0000 |
commit | 57ab6c1ee2ee07f627dc2448f0c79dcd853d6838 (patch) | |
tree | 657b33145889a4737b378f776cda2d4824396e07 /sys | |
parent | f6f87616ef92c3113d732cd9a7b256998db959a8 (diff) | |
download | FreeBSD-src-57ab6c1ee2ee07f627dc2448f0c79dcd853d6838.zip FreeBSD-src-57ab6c1ee2ee07f627dc2448f0c79dcd853d6838.tar.gz |
Recovery boot loader for the AT91 family of processors. Download it
via xmodem to the DBGU port when the AT91 comes up in recovery mode.
The recovery loader will then load your program via xmodem into SDRAM
at 1MB which can do its things. It needs to be tweaked to the
specific board one is using, but it fits in < 1kB (all of Atmel's ARM
products have at least 8kb of SRAM that I can tell, so this should
work for them all).
Parts of this code were provided by Kwikbyte with copyright
specifically disclaimed. I heavily modified it to act as a recovery
loader (before it was a bootstrap loader) and to optimize for size
(before I started the size was closer to 8k).
Bootstrap loaders for SPI and IIC to follow.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/boot/arm/at91/boot0/Makefile | 21 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/README | 7 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/arm_init.s | 105 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/at91rm9200_lowlevel.c | 184 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/at91rm9200_lowlevel.h | 57 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/lib.c | 76 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/lib.h | 33 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/linker.cfg | 85 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/main.c | 42 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/xmodem.c | 127 | ||||
-rw-r--r-- | sys/boot/arm/at91/boot0/xmodem.h | 32 |
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 */ |