diff options
-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 */ |