Remove sys/boot/arm/at91 and ixp425
Remove at91 bootloader. It only worked on AT91RM9200, and only specific boards that were all EOLd 10 years ago. Remove ixp425. It doesn't build anymore and is for boards that were EOLd 8 years ago. Sponsored by: Netflix
This commit is contained in:
parent
b533f63ed0
commit
e1b6a0cd96
@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= libat91 boot0 boot0iic boot0spi boot2 bootiic bootspi
|
||||
|
||||
.include <bsd.subdir.mk>
|
@ -1,57 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if !target(__at91_boot_Makefile.inc__)
|
||||
.PATH: ${.CURDIR}/../../../../libkern ${.CURDIR}/../../../../libkern/arm
|
||||
|
||||
__at91_boot_Makefile.inc__:
|
||||
|
||||
# tsc, bwct, kb920x, centipad are the supported flavors
|
||||
BOOT_FLAVOR?=kb920x
|
||||
|
||||
CFLAGS=-Os -mcpu=arm9 -ffreestanding \
|
||||
-I${.CURDIR}/../libat91 \
|
||||
-I${.CURDIR}/../../../.. \
|
||||
-I${.CURDIR}/../../../../arm \
|
||||
-D_KERNEL \
|
||||
-Wall -Waggregate-return \
|
||||
-Wnested-externs \
|
||||
-Wpointer-arith -Wshadow -Wwrite-strings \
|
||||
-Werror \
|
||||
-Wmissing-prototypes \
|
||||
-Wmissing-declarations
|
||||
# -Wstrict-prototypes
|
||||
|
||||
CFLAGS+=-DBOOT_${BOOT_FLAVOR:tu}
|
||||
|
||||
LIBAT91=${.OBJDIR}/../libat91/libat91.a
|
||||
|
||||
LD ?= ld
|
||||
OBJCOPY ?= objcopy
|
||||
|
||||
.if defined(P)
|
||||
${P}: ${P}.out
|
||||
${OBJCOPY} -S -O binary ${P}.out ${.TARGET}
|
||||
@set -- `ls -l ${.TARGET}`; x=$$((12288-$$5)); \
|
||||
echo "$$x bytes available"; test $$x -ge 0
|
||||
|
||||
${P}.out: ${OBJS}
|
||||
${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LIBAT91}
|
||||
|
||||
CLEANFILES+= ${P} ${P}.out
|
||||
.endif
|
||||
|
||||
.if defined(WITH_TAG_LIST)
|
||||
MK_TAG_LIST:=yes
|
||||
.else
|
||||
MK_TAG_LIST:=no
|
||||
.endif
|
||||
|
||||
.if defined(WITH_FPGA)
|
||||
MK_FPGA:=yes
|
||||
.else
|
||||
MK_FPGA:=no
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
||||
.include "../Makefile.inc"
|
@ -1,14 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libat91
|
||||
|
||||
P=boot0
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S main.c
|
||||
MAN=
|
||||
LDFLAGS=-e 0 -T ${.CURDIR}/linker.cfg
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
CFLAGS+=-DBOOT_BOOT0
|
@ -1,7 +0,0 @@
|
||||
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$
|
@ -1,84 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 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)
|
||||
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 = .);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
|
||||
typedef void fn_t(void);
|
||||
|
||||
int main(void);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
|
||||
fn_t *fn = (fn_t *)(SDRAM_BASE + (1 << 20)); /* Load to base + 1MB */
|
||||
|
||||
while (xmodem_rx(addr) == -1)
|
||||
continue;
|
||||
fn();
|
||||
return (0);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libat91
|
||||
|
||||
P=boot0iic
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S main.c
|
||||
MAN=
|
||||
LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
CFLAGS+=-DBOOT_BOOT0
|
@ -1,52 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
|
||||
int main(void);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
|
||||
int len, sec;
|
||||
|
||||
printf("\nSend data to be written into EEPROM\n");
|
||||
while ((len = xmodem_rx(addr)) == -1)
|
||||
continue;
|
||||
sec = GetSeconds() + 1;
|
||||
while (sec >= GetSeconds())
|
||||
continue;
|
||||
printf("\nWriting EEPROM from 0x%x to addr 0, 0x%x bytes\n", addr,
|
||||
len);
|
||||
InitEEPROM();
|
||||
printf("init done\n");
|
||||
WriteEEPROM(0, addr, len);
|
||||
printf("\nWrote %d bytes. Press reset\n", len);
|
||||
return (1);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libat91
|
||||
|
||||
P=boot0spi
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S main.c
|
||||
MAN=
|
||||
LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
CFLAGS+=-DBOOT_BOOT0
|
@ -1,65 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#define OFFSET 0
|
||||
|
||||
int main(void);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int len, i, j, off, sec;
|
||||
char *addr = (char *)SDRAM_BASE + (1 << 20); /* download at + 1MB */
|
||||
char *addr2 = (char *)SDRAM_BASE + (2 << 20); /* readback to + 2MB */
|
||||
|
||||
SPI_InitFlash();
|
||||
printf("Waiting for data\n");
|
||||
while ((len = xmodem_rx(addr)) == -1)
|
||||
continue;
|
||||
printf("Writing %u bytes at %u\n", len, OFFSET);
|
||||
for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
|
||||
off = i + OFFSET;
|
||||
for (j = 0; j < 10; j++) {
|
||||
SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE);
|
||||
SPI_ReadFlash(off, addr2 + i, FLASH_PAGE_SIZE);
|
||||
if (p_memcmp(addr + i, addr2 + i, FLASH_PAGE_SIZE) == 0)
|
||||
break;
|
||||
}
|
||||
if (j >= 10)
|
||||
printf("Bad Readback at %u\n", i);
|
||||
}
|
||||
sec = GetSeconds() + 2;
|
||||
while (sec <= GetSeconds())
|
||||
continue;
|
||||
printf("Done\n");
|
||||
reset();
|
||||
return (1);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libat91 ${.CURDIR}/../bootspi
|
||||
|
||||
P=boot2
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S boot2.c ${BOOT_FLAVOR:tl}_board.c
|
||||
MAN=
|
||||
LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
.if ${BOOT_FLAVOR} == "kb920x"
|
||||
CFLAGS+=-DBOOT_IIC
|
||||
.endif
|
||||
CFLAGS+= \
|
||||
-I${.CURDIR}/../bootspi \
|
||||
-I${.CURDIR}/../../../common \
|
||||
-I${.CURDIR}/../../../.. \
|
||||
-D_KERNEL \
|
||||
-DUFS1_ONLY
|
@ -1,29 +0,0 @@
|
||||
/*-
|
||||
* 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$
|
||||
*/
|
||||
|
||||
void Update(void);
|
||||
void board_init(void);
|
||||
int drvread(void *, unsigned, unsigned);
|
@ -1,368 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay
|
||||
* Copyright (c) 2006 M Warner Losh <imp@freebsd.org>
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are freely
|
||||
* permitted provided that the above copyright notice and this
|
||||
* paragraph and the following disclaimer are duplicated in all
|
||||
* such forms.
|
||||
*
|
||||
* This software is provided "AS IS" and without any express or
|
||||
* implied warranties, including, without limitation, the implied
|
||||
* warranties of merchantability and fitness for a particular
|
||||
* purpose.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <machine/elf.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lib.h"
|
||||
#include "board.h"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
#undef PATH_KERNEL
|
||||
#define PATH_KERNEL "/boot/kernel/kernel.gz.tramp"
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
#define NOPT 6
|
||||
|
||||
static const char optstr[NOPT] = "agnrsv";
|
||||
static const unsigned char bootflags[NOPT] = {
|
||||
RBX_ASKNAME,
|
||||
RBX_GDB,
|
||||
RBX_NOINTR,
|
||||
RBX_DFLTROOT,
|
||||
RBX_SINGLE,
|
||||
RBX_VERBOSE
|
||||
};
|
||||
|
||||
unsigned board_id; /* board type to pass to kernel, if set by board_* code */
|
||||
unsigned dsk_start;
|
||||
static char cmd[512];
|
||||
static char kname[1024];
|
||||
uint32_t opts;
|
||||
static uint8_t dsk_meta;
|
||||
|
||||
int main(void);
|
||||
static void load(void);
|
||||
static int parse(void);
|
||||
static int dskread(void *, unsigned, unsigned);
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
static void fixup_boot_drv(caddr_t, int, int, int);
|
||||
#endif
|
||||
|
||||
#define UFS_SMALL_CGBASE
|
||||
#include "ufsread.c"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
|
||||
{
|
||||
if ((size_t)fsread(inode, buf, nbyte) != nbyte)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
getstr(int c)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = cmd;
|
||||
if (c == 0)
|
||||
c = getc(10000);
|
||||
for (;;) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case '\177':
|
||||
case '\b':
|
||||
if (s > cmd) {
|
||||
s--;
|
||||
printf("\b \b");
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
*s = 0;
|
||||
return;
|
||||
default:
|
||||
if (s - cmd < sizeof(cmd) - 1)
|
||||
*s++ = c;
|
||||
xputchar(c);
|
||||
}
|
||||
c = getc(10000);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int autoboot, c = 0;
|
||||
ufs_ino_t ino;
|
||||
|
||||
dmadat = (void *)(0x20000000 + (16 << 20));
|
||||
board_init();
|
||||
|
||||
autoboot = 1;
|
||||
|
||||
/* Process configuration file */
|
||||
if ((ino = lookup(PATH_CONFIG)) ||
|
||||
(ino = lookup(PATH_DOTCONFIG)))
|
||||
fsread(ino, cmd, sizeof(cmd));
|
||||
|
||||
if (*cmd) {
|
||||
if (parse())
|
||||
autoboot = 0;
|
||||
printf("%s: %s\n", PATH_CONFIG, cmd);
|
||||
/* Do not process this command twice */
|
||||
*cmd = 0;
|
||||
}
|
||||
|
||||
if (*kname == '\0')
|
||||
strcpy(kname, PATH_KERNEL);
|
||||
|
||||
/* Present the user with the boot2 prompt. */
|
||||
for (;;) {
|
||||
printf("\nDefault: %s\nboot: ", kname);
|
||||
if (!autoboot ||
|
||||
(OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
|
||||
getstr(c);
|
||||
xputchar('\n');
|
||||
autoboot = 0;
|
||||
c = 0;
|
||||
if (parse())
|
||||
xputchar('\a');
|
||||
else
|
||||
load();
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
load(void)
|
||||
{
|
||||
Elf32_Ehdr eh;
|
||||
static Elf32_Phdr ep[2];
|
||||
caddr_t p;
|
||||
ufs_ino_t ino;
|
||||
uint32_t addr;
|
||||
int i, j;
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
caddr_t staddr;
|
||||
int klen;
|
||||
|
||||
staddr = (caddr_t)0xffffffff;
|
||||
klen = 0;
|
||||
#endif
|
||||
if (!(ino = lookup(kname))) {
|
||||
if (!ls)
|
||||
printf("No %s\n", kname);
|
||||
return;
|
||||
}
|
||||
if (xfsread(ino, &eh, sizeof(eh)))
|
||||
return;
|
||||
if (!IS_ELF(eh)) {
|
||||
printf("Invalid %s\n", "format");
|
||||
return;
|
||||
}
|
||||
fs_off = eh.e_phoff;
|
||||
for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
|
||||
if (xfsread(ino, ep + j, sizeof(ep[0])))
|
||||
return;
|
||||
if (ep[j].p_type == PT_LOAD)
|
||||
j++;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
p = (caddr_t)ep[i].p_paddr;
|
||||
fs_off = ep[i].p_offset;
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
if (staddr == (caddr_t)0xffffffff)
|
||||
staddr = p;
|
||||
klen += ep[i].p_filesz;
|
||||
#endif
|
||||
if (xfsread(ino, p, ep[i].p_filesz))
|
||||
return;
|
||||
}
|
||||
addr = eh.e_entry;
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
fixup_boot_drv(staddr, klen, bootslice, bootpart);
|
||||
#endif
|
||||
((void(*)(int, int, int, int))addr)(opts & RBX_MASK, board_id, 0, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
parse()
|
||||
{
|
||||
char *arg = cmd;
|
||||
char *ep, *p;
|
||||
int c, i;
|
||||
|
||||
while ((c = *arg++)) {
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
continue;
|
||||
for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
|
||||
ep = p;
|
||||
if (*p)
|
||||
*p++ = 0;
|
||||
if (c == '-') {
|
||||
while ((c = *arg++)) {
|
||||
for (i = 0; c != optstr[i]; i++)
|
||||
if (i == NOPT - 1)
|
||||
return -1;
|
||||
opts ^= OPT_SET(bootflags[i]);
|
||||
}
|
||||
} else {
|
||||
arg--;
|
||||
if ((i = ep - arg)) {
|
||||
if ((size_t)i >= sizeof(kname))
|
||||
return -1;
|
||||
memcpy(kname, arg, i + 1);
|
||||
}
|
||||
}
|
||||
arg = p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dskread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
struct dos_partition *dp;
|
||||
struct disklabel *d;
|
||||
char *sec;
|
||||
int i;
|
||||
|
||||
if (!dsk_meta) {
|
||||
sec = dmadat->secbuf;
|
||||
dsk_start = 0;
|
||||
if (drvread(sec, DOSBBSECTOR, 1))
|
||||
return -1;
|
||||
dp = (void *)(sec + DOSPARTOFF);
|
||||
for (i = 0; i < NDOSPART; i++) {
|
||||
if (dp[i].dp_typ == DOSPTYP_386BSD)
|
||||
break;
|
||||
}
|
||||
if (i == NDOSPART)
|
||||
return -1;
|
||||
/*
|
||||
* Although dp_start is aligned within the disk
|
||||
* partition structure, DOSPARTOFF is 446, which is
|
||||
* only word (2) aligned, not longword (4) aligned.
|
||||
* Cope by using memcpy to fetch the start of this
|
||||
* partition.
|
||||
*/
|
||||
memcpy(&dsk_start, &dp[1].dp_start, 4);
|
||||
if (drvread(sec, dsk_start + LABELSECTOR, 1))
|
||||
return -1;
|
||||
d = (void *)(sec + LABELOFFSET);
|
||||
if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
|
||||
printf("Invalid %s\n", "label");
|
||||
return -1;
|
||||
}
|
||||
if (!d->d_partitions[0].p_size) {
|
||||
printf("Invalid %s\n", "partition");
|
||||
return -1;
|
||||
}
|
||||
dsk_start += d->d_partitions[0].p_offset;
|
||||
dsk_start -= d->d_partitions[RAW_PART].p_offset;
|
||||
dsk_meta++;
|
||||
}
|
||||
return drvread(buf, dsk_start + lba, nblk);
|
||||
}
|
||||
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
/*
|
||||
* fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel
|
||||
* and change it to what was specified on the comandline or /boot.conf
|
||||
* file or to what was encountered on the disk. It will try to handle 3
|
||||
* different disk layouts, raw (dangerously dedicated), slice only and
|
||||
* slice + partition. It will look for the following strings in the
|
||||
* kernel, but if it is one of the first three, the string in the kernel
|
||||
* must use the correct form to match the actual disk layout:
|
||||
* - ufs:ad0a
|
||||
* - ufs:ad0s1
|
||||
* - ufs:ad0s1a
|
||||
* - ufs:ROOTDEVNAME
|
||||
* In the case of the first three strings, only the "a" at the end and
|
||||
* the "1" after the "s" will be modified, if they exist. The string
|
||||
* length will not be changed. In the case of the last string, the
|
||||
* whole string will be built up and nul, '\0' terminated.
|
||||
*/
|
||||
static void
|
||||
fixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
|
||||
{
|
||||
const u_int8_t op[] = "ufs:ROOTDEVNAME";
|
||||
const u_int8_t op2[] = "ufs:ad0";
|
||||
u_int8_t *p, *ps;
|
||||
|
||||
DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
|
||||
(int)addr, klen, bs, bp);
|
||||
if (bs > 4)
|
||||
return;
|
||||
if (bp > 7)
|
||||
return;
|
||||
ps = memmem(addr, klen, op, sizeof(op));
|
||||
if (ps != NULL) {
|
||||
p = ps + 4; /* past ufs: */
|
||||
DPRINTF("Found it at 0x%x\n", (int)ps);
|
||||
p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */
|
||||
p += 3;
|
||||
if (bs > 0) {
|
||||
/* append slice */
|
||||
*p++ = 's';
|
||||
*p++ = bs + '0';
|
||||
}
|
||||
if (disk_layout != DL_SLICE) {
|
||||
/* append partition */
|
||||
*p++ = bp + 'a';
|
||||
}
|
||||
*p = '\0';
|
||||
} else {
|
||||
ps = memmem(addr, klen, op2, sizeof(op2) - 1);
|
||||
if (ps != NULL) {
|
||||
p = ps + sizeof(op2) - 1;
|
||||
DPRINTF("Found it at 0x%x\n", (int)ps);
|
||||
if (*p == 's') {
|
||||
/* fix slice */
|
||||
p++;
|
||||
*p++ = bs + '0';
|
||||
}
|
||||
if (*p == 'a')
|
||||
*p = bp + 'a';
|
||||
}
|
||||
}
|
||||
if (ps == NULL) {
|
||||
printf("Could not locate \"%s\" to fix kernel boot device, "
|
||||
"check ROOTDEVNAME is set\n", op);
|
||||
return;
|
||||
}
|
||||
DPRINTF("Changed boot device to %s\n", ps);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Arm EABIs */
|
||||
void __aeabi_unwind_cpp_pr0(void);
|
||||
void
|
||||
__aeabi_unwind_cpp_pr0(void)
|
||||
{
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "at91rm9200.h"
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
#include "ee.h"
|
||||
#include "board.h"
|
||||
#include "sd-card.h"
|
||||
|
||||
unsigned char mac[6] = { 0x00, 0x0e, 0x42, 0x02, 0x00, 0x28 };
|
||||
|
||||
static void USART0_Init();
|
||||
static void USART1_Init();
|
||||
static void USART2_Init();
|
||||
static void USART3_Init();
|
||||
static void DS1672_Init();
|
||||
|
||||
static void
|
||||
DS1672_Init() {
|
||||
char buf[] = {0x00, 0xa9};
|
||||
|
||||
EEWrite(0xd0, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static void
|
||||
USART0_Init() {
|
||||
|
||||
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
|
||||
|
||||
// setup GPIO
|
||||
pPio->PIO_ASR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0;
|
||||
pPio->PIO_PDR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0;
|
||||
|
||||
// enable power
|
||||
pPMC->PMC_PCER = 1u << AT91C_ID_US0;
|
||||
}
|
||||
|
||||
static void
|
||||
USART1_Init() {
|
||||
|
||||
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
|
||||
|
||||
// setup GPIO
|
||||
pPio->PIO_ASR = AT91C_PB20_TXD1 | AT91C_PB21_RXD1;
|
||||
pPio->PIO_PDR = AT91C_PB20_TXD1 | AT91C_PB21_RXD1;
|
||||
|
||||
// enable power
|
||||
pPMC->PMC_PCER = 1u << AT91C_ID_US1;
|
||||
}
|
||||
|
||||
static void
|
||||
USART2_Init() {
|
||||
|
||||
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
|
||||
|
||||
// setup GPIO
|
||||
pPio->PIO_ASR = AT91C_PA23_TXD2 | AT91C_PA22_RXD2;
|
||||
pPio->PIO_PDR = AT91C_PA23_TXD2 | AT91C_PA22_RXD2;
|
||||
|
||||
// enable power
|
||||
pPMC->PMC_PCER = 1u << AT91C_ID_US2;
|
||||
}
|
||||
|
||||
static void
|
||||
USART3_Init() {
|
||||
|
||||
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
|
||||
|
||||
// setup GPIO
|
||||
pPio->PIO_BSR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3;
|
||||
pPio->PIO_PDR = AT91C_PA5_TXD3 | AT91C_PA6_RXD3;
|
||||
|
||||
// enable power
|
||||
pPMC->PMC_PCER = 1u << AT91C_ID_US3;
|
||||
}
|
||||
|
||||
void
|
||||
board_init(void)
|
||||
{
|
||||
|
||||
printf("\n\n");
|
||||
printf("BWCT FSB-A920-1\n");
|
||||
printf("http://www.bwct.de\n");
|
||||
printf("\n");
|
||||
#if defined(SDRAM_128M)
|
||||
printf("AT92RM9200 180MHz 128MB\n");
|
||||
#else
|
||||
printf("AT92RM9200 180MHz 64MB\n");
|
||||
#endif
|
||||
printf("Initialising USART0\n");
|
||||
USART0_Init();
|
||||
printf("Initialising USART1\n");
|
||||
USART1_Init();
|
||||
printf("Initialising USART2\n");
|
||||
USART2_Init();
|
||||
printf("Initialising USART3\n");
|
||||
USART3_Init();
|
||||
printf("Initialising TWI\n");
|
||||
EEInit();
|
||||
printf("Initialising DS1672\n");
|
||||
DS1672_Init();
|
||||
printf("Initialising Ethernet\n");
|
||||
printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0],
|
||||
mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
EMAC_Init();
|
||||
EMAC_SetMACAddress(mac);
|
||||
printf("Initialising SD-card\n");
|
||||
sdcard_init();
|
||||
}
|
||||
|
||||
#include "../bootspi/ee.c"
|
||||
|
||||
int
|
||||
drvread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
return (MCI_read((char *)buf, lba << 9, nblk << 9));
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
#include "board.h"
|
||||
#include "sd-card.h"
|
||||
|
||||
unsigned char mac[6] = { 0x42, 0x53, 0x44, 0, 1, 1 };
|
||||
|
||||
static void
|
||||
MacFromEE()
|
||||
{
|
||||
#if 0
|
||||
uint32_t sig;
|
||||
sig = 0;
|
||||
ReadEEPROM(12 * 1024, (uint8_t *)&sig, sizeof(sig));
|
||||
if (sig != 0x92021054)
|
||||
return;
|
||||
ReadEEPROM(12 * 1024 + 4, mac, 6);
|
||||
#endif
|
||||
printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0],
|
||||
mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
void
|
||||
board_init(void)
|
||||
{
|
||||
InitEEPROM();
|
||||
MacFromEE();
|
||||
EMAC_Init();
|
||||
EMAC_SetMACAddress(mac);
|
||||
while (sdcard_init() == 0)
|
||||
printf("Looking for SD card\n");
|
||||
}
|
||||
|
||||
int
|
||||
drvread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
return (MCI_read((char *)buf, lba << 9, nblk << 9));
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
#include "board.h"
|
||||
#include "sd-card.h"
|
||||
|
||||
unsigned char mac[6] = { 0x42, 0x53, 0x44, 0, 0, 1 };
|
||||
|
||||
static void
|
||||
MacFromEE()
|
||||
{
|
||||
uint32_t sig;
|
||||
sig = 0;
|
||||
ReadEEPROM(12 * 1024, (uint8_t *)&sig, sizeof(sig));
|
||||
if (sig != 0x92021054)
|
||||
return;
|
||||
ReadEEPROM(12 * 1024 + 4, mac, 6);
|
||||
printf("MAC %x:%x:%x:%x:%x:%x\n", mac[0],
|
||||
mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
void
|
||||
board_init(void)
|
||||
{
|
||||
InitEEPROM();
|
||||
MacFromEE();
|
||||
EMAC_Init();
|
||||
EMAC_SetMACAddress(mac);
|
||||
while (sdcard_init() == 0)
|
||||
printf("Looking for SD card\n");
|
||||
}
|
||||
|
||||
int
|
||||
drvread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
return (MCI_read((char *)buf, lba << 9, nblk << 9));
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libat91
|
||||
|
||||
P=bootiic
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S main.c loader_prompt.c env_vars.c
|
||||
MAN=
|
||||
LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
CFLAGS += -DBOOT_IIC -DBOOT_COMMANDS
|
@ -1,35 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
This image is intended to be programmed into boot EEPROM. The image is nearly
|
||||
0x4000 so it will not fit in KB9200's 0x2000. It is intended for KB9201 or
|
||||
later. Alternatively, the KB9200 can be upgraded with larger EEPROM.
|
||||
It performs basic functions prior to executing an image at a
|
||||
specified address. The pre-boot functions can be modified and saved back into
|
||||
EEPROM.
|
||||
The MAC address is set with 0.0.0.0.0.0 by default. This is an invalid address
|
||||
and must be changed to a valid value in order to use the ethernet interface.
|
||||
|
||||
Memory usage:
|
||||
|
||||
EEPROM = 0x4000
|
||||
SDRAM =
|
||||
run stack = 0x21800000
|
||||
variables = 0x21200000
|
||||
ethernet = 0x21000000 (buffers and descriptors)
|
||||
|
||||
|
||||
Functions supported:
|
||||
|
||||
c - copy
|
||||
d - display auto command table (in RAM)
|
||||
e - execute image
|
||||
? - help
|
||||
ip - set local ip
|
||||
m - set mac
|
||||
server_ip - set server ip
|
||||
s - set auto command entry
|
||||
t - create linux boot tag list
|
||||
tftp - download image via tftp
|
||||
w - update auto command table
|
||||
x - download image via xmodem
|
||||
|
@ -1,207 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: env_vars.c
|
||||
*
|
||||
* Instantiation of environment variables, structures, and other globals.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "env_vars.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "lib.h"
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE];
|
||||
|
||||
char env_table[MAX_ENV_SIZE_BYTES];
|
||||
|
||||
extern char BootCommandSection;
|
||||
|
||||
/************************** PRIVATE FUNCTIONS ********************************/
|
||||
|
||||
|
||||
static int currentIndex;
|
||||
static int currentOffset;
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int ReadCharFromEnvironment(char *)
|
||||
* This private function reads characters from the environment variables
|
||||
* to service the command prompt during auto-boot or just to setup the
|
||||
* default environment. Returns positive value if valid character was
|
||||
* set in the pointer. Returns negative value to signal input stream
|
||||
* terminated. Returns 0 to indicate _wait_ condition.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
ReadCharFromEnvironment(int timeout)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (currentIndex < MAX_BOOT_COMMANDS) {
|
||||
ch = boot_commands[currentIndex][currentOffset++];
|
||||
if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) {
|
||||
currentOffset = 0;
|
||||
++currentIndex;
|
||||
ch = '\r';
|
||||
}
|
||||
return (ch);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void WriteCommandTable(void)
|
||||
* This global function write the current command table to the non-volatile
|
||||
* memory.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
WriteCommandTable(void)
|
||||
{
|
||||
int i, size = MAX_ENV_SIZE_BYTES, copySize;
|
||||
char *cPtr = env_table;
|
||||
|
||||
p_memset(env_table, 0, sizeof(env_table));
|
||||
|
||||
for (i = 0; i < MAX_BOOT_COMMANDS; ++i) {
|
||||
|
||||
copySize = p_strlen(boot_commands[i]);
|
||||
size -= copySize + 1;
|
||||
|
||||
if (size < 0) {
|
||||
continue;
|
||||
}
|
||||
memcpy(cPtr, boot_commands[i], copySize);
|
||||
cPtr += copySize;
|
||||
*cPtr++ = 0;
|
||||
}
|
||||
|
||||
/* We're executing in low RAM so addr in ram == offset in eeprom */
|
||||
WriteEEPROM((unsigned)&BootCommandSection, env_table,
|
||||
sizeof(env_table));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SetBootCommand(int index, char *command)
|
||||
* This global function replaces the specified index with the string residing
|
||||
* at command. Execute this function with a NULL string to clear the
|
||||
* associated command index.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SetBootCommand(int index, char *command)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((unsigned)index < MAX_BOOT_COMMANDS) {
|
||||
|
||||
p_memset(boot_commands[index], 0, MAX_INPUT_SIZE);
|
||||
|
||||
if (!command)
|
||||
return ;
|
||||
|
||||
for (i = 0; i < MAX_INPUT_SIZE; ++i) {
|
||||
boot_commands[index][i] = command[i];
|
||||
if (!(boot_commands[index][i]))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void DumpBootCommands(void)
|
||||
* This global function displays the current boot commands.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
DumpBootCommands(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < MAX_BOOT_COMMANDS; ++i) {
|
||||
printf("0x%x : ", i);
|
||||
for (j = 0; j < MAX_INPUT_SIZE; ++j) {
|
||||
putchar(boot_commands[i][j]);
|
||||
if (!(boot_commands[i][j]))
|
||||
break;
|
||||
}
|
||||
printf("[E]\n\r");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void LoadBootCommands(void)
|
||||
* This global function loads the existing boot commands from raw format and
|
||||
* coverts it to the standard, command-index format. Notice, the processed
|
||||
* boot command table has much more space allocated than the actual table
|
||||
* stored in non-volatile memory. This is because the processed table
|
||||
* exists in RAM which is larger than the non-volatile space.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
LoadBootCommands(void)
|
||||
{
|
||||
int index, j, size;
|
||||
char *cPtr;
|
||||
|
||||
p_memset((char*)boot_commands, 0, sizeof(boot_commands));
|
||||
|
||||
cPtr = &BootCommandSection;
|
||||
|
||||
size = MAX_ENV_SIZE_BYTES;
|
||||
|
||||
for (index = 0; (index < MAX_BOOT_COMMANDS) && size; ++index) {
|
||||
for (j = 0; (j < MAX_INPUT_SIZE) && size; ++j) {
|
||||
size--;
|
||||
boot_commands[index][j] = *cPtr++;
|
||||
if (!(boot_commands[index][j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ExecuteEnvironmentFunctions(void)
|
||||
* This global function executes applicable entries in the environment.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
ExecuteEnvironmentFunctions(void)
|
||||
{
|
||||
currentIndex = 0;
|
||||
currentOffset = 0;
|
||||
|
||||
DumpBootCommands();
|
||||
Bootloader(ReadCharFromEnvironment);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: env_vars.h
|
||||
*
|
||||
* Definition of environment variables, structures, and other globals.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _ENV_VARS_H_
|
||||
#define _ENV_VARS_H_
|
||||
|
||||
/* each environment variable is a string following the standard command */
|
||||
/* definition used by the interactive loader in the following format: */
|
||||
/* <command> <parm1> <parm2> ... */
|
||||
/* all environment variables (or commands) are stored in a string */
|
||||
/* format: NULL-terminated. */
|
||||
/* this implies that commands can never utilize 0-values: actual 0, not */
|
||||
/* the string '0'. this is not an issue as the string '0' is handled */
|
||||
/* by the command parse routine. */
|
||||
|
||||
/* the following defines the maximum size of the environment for */
|
||||
/* including variables. */
|
||||
/* this value must match that declared in the low-level file that */
|
||||
/* actually reserves the space for the non-volatile environment. */
|
||||
#define MAX_ENV_SIZE_BYTES 0x100
|
||||
|
||||
#define MAX_BOOT_COMMANDS 10
|
||||
|
||||
/* C-style reference section */
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void WriteCommandTable(void);
|
||||
extern void SetBootCommand(int index, char *command);
|
||||
extern void DumpBootCommands(void);
|
||||
extern void LoadBootCommands(void);
|
||||
extern void ExecuteEnvironmentFunctions(void);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ENV_VARS_H_ */
|
@ -1,387 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: loader_prompt.c
|
||||
*
|
||||
* Instantiation of the interactive loader functions.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin massive changes for tftp, strings, and more
|
||||
* 05JUL2005 kb_admin save tag address, and set registers on boot
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
#include "tag_list.h"
|
||||
#endif
|
||||
#include "emac.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "env_vars.h"
|
||||
#include "lib.h"
|
||||
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
|
||||
|
||||
/*********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
static char inputBuffer[MAX_INPUT_SIZE];
|
||||
static int buffCount;
|
||||
|
||||
// argv pointer are either NULL or point to locations in inputBuffer
|
||||
static char *argv[MAX_COMMAND_PARAMS];
|
||||
|
||||
static const char *backspaceString = "\010 \010";
|
||||
|
||||
static const command_entry_t CommandTable[] = {
|
||||
{COMMAND_COPY, "c"},
|
||||
{COMMAND_DUMP, "d"},
|
||||
{COMMAND_EXEC, "e"},
|
||||
{COMMAND_HELP, "?"},
|
||||
{COMMAND_LOCAL_IP, "ip"},
|
||||
{COMMAND_MAC, "m"},
|
||||
{COMMAND_SERVER_IP, "server_ip"},
|
||||
{COMMAND_SET, "s"},
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
{COMMAND_TAG, "t"},
|
||||
#endif
|
||||
{COMMAND_TFTP, "tftp"},
|
||||
{COMMAND_WRITE, "w"},
|
||||
{COMMAND_XMODEM, "x"},
|
||||
{COMMAND_FINAL_FLAG, 0}
|
||||
};
|
||||
|
||||
static unsigned tagAddress;
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned BuildIP(void)
|
||||
* This private function packs the test IP info to an unsigned value.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static unsigned
|
||||
BuildIP(void)
|
||||
{
|
||||
return ((p_ASCIIToDec(argv[1]) << 24) |
|
||||
(p_ASCIIToDec(argv[2]) << 16) |
|
||||
(p_ASCIIToDec(argv[3]) << 8) |
|
||||
p_ASCIIToDec(argv[4]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int StringToCommand(char *cPtr)
|
||||
* This private function converts a command string to a command code.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
StringToCommand(char *cPtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
|
||||
if (!strcmp(CommandTable[i].c_string, cPtr))
|
||||
return (CommandTable[i].command);
|
||||
|
||||
return (COMMAND_INVALID);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void RestoreSpace(int)
|
||||
* This private function restores NULL characters to spaces in order to
|
||||
* process the remaining args as a string. The number passed is the argc
|
||||
* of the first entry to begin restoring space in the inputBuffer.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
RestoreSpace(int startArgc)
|
||||
{
|
||||
char *cPtr;
|
||||
|
||||
for (startArgc++; startArgc < MAX_COMMAND_PARAMS; startArgc++) {
|
||||
if ((cPtr = argv[startArgc]))
|
||||
*(cPtr - 1) = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int BreakCommand(char *)
|
||||
* This private function splits the buffer into separate strings as pointed
|
||||
* by argv and returns the number of parameters (< 0 on failure).
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
BreakCommand(char *buffer)
|
||||
{
|
||||
int pCount, cCount, state;
|
||||
|
||||
state = pCount = 0;
|
||||
p_memset((char*)argv, 0, sizeof(argv));
|
||||
|
||||
for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
|
||||
|
||||
if (!state) {
|
||||
/* look for next command */
|
||||
if (!p_IsWhiteSpace(buffer[cCount])) {
|
||||
argv[pCount++] = &buffer[cCount];
|
||||
state = 1;
|
||||
} else {
|
||||
buffer[cCount] = 0;
|
||||
}
|
||||
} else {
|
||||
/* in command, find next white space */
|
||||
if (p_IsWhiteSpace(buffer[cCount])) {
|
||||
buffer[cCount] = 0;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCount >= MAX_COMMAND_PARAMS) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (pCount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ParseCommand(char *)
|
||||
* This private function executes matching functions.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
ParseCommand(char *buffer)
|
||||
{
|
||||
int argc, i;
|
||||
|
||||
if ((argc = BreakCommand(buffer)) < 1)
|
||||
return;
|
||||
|
||||
switch (StringToCommand(argv[0])) {
|
||||
case COMMAND_COPY:
|
||||
{
|
||||
// "c <to> <from> <size in bytes>"
|
||||
// copy memory
|
||||
char *to, *from;
|
||||
unsigned size;
|
||||
|
||||
if (argc > 3) {
|
||||
to = (char *)p_ASCIIToHex(argv[1]);
|
||||
from = (char *)p_ASCIIToHex(argv[2]);
|
||||
size = p_ASCIIToHex(argv[3]);
|
||||
memcpy(to, from, size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_DUMP:
|
||||
// display boot commands
|
||||
DumpBootCommands();
|
||||
break;
|
||||
|
||||
case COMMAND_EXEC:
|
||||
{
|
||||
// "e <address>"
|
||||
// execute at address
|
||||
void (*execAddr)(unsigned, unsigned, unsigned);
|
||||
|
||||
if (argc > 1) {
|
||||
/* in future, include machtypes (MACH_KB9200 = 612) */
|
||||
execAddr = (void (*)(unsigned, unsigned, unsigned))
|
||||
p_ASCIIToHex(argv[1]);
|
||||
(*execAddr)(0, 612, tagAddress);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_TFTP:
|
||||
{
|
||||
// "tftp <local_dest_addr filename>"
|
||||
// tftp download
|
||||
unsigned address = 0;
|
||||
|
||||
if (argc > 2)
|
||||
address = p_ASCIIToHex(argv[1]);
|
||||
TFTP_Download(address, argv[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_SERVER_IP:
|
||||
// "server_ip <server IP 192 200 1 20>"
|
||||
// set download server address
|
||||
if (argc > 4)
|
||||
SetServerIPAddress(BuildIP());
|
||||
break;
|
||||
|
||||
case COMMAND_HELP:
|
||||
// dump command info
|
||||
printf("Commands:\n"
|
||||
"\tc\n"
|
||||
"\td\n"
|
||||
"\te\n"
|
||||
"\tip\n"
|
||||
"\tserver_ip\n"
|
||||
"\tm\n"
|
||||
"\ttftp\n"
|
||||
"\ts\n"
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
"\tt\n"
|
||||
#endif
|
||||
"\tw\n"
|
||||
"\tx\n");
|
||||
break;
|
||||
|
||||
case COMMAND_LOCAL_IP:
|
||||
// "local_ip <local IP 192 200 1 21>
|
||||
// set ip of this module
|
||||
if (argc > 4)
|
||||
SetLocalIPAddress(BuildIP());
|
||||
break;
|
||||
|
||||
case COMMAND_MAC:
|
||||
{
|
||||
// "m <mac address 12 34 56 78 9a bc>
|
||||
// set mac address using 6 byte values
|
||||
unsigned char mac[6];
|
||||
|
||||
if (argc > 6) {
|
||||
for (i = 0; i < 6; i++)
|
||||
mac[i] = p_ASCIIToHex(argv[i + 1]);
|
||||
EMAC_SetMACAddress(mac);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_SET:
|
||||
{
|
||||
// s <index> <new boot command>
|
||||
// set the boot command at index (0-based)
|
||||
unsigned index;
|
||||
|
||||
if (argc > 1) {
|
||||
RestoreSpace(2);
|
||||
index = p_ASCIIToHex(argv[1]);
|
||||
SetBootCommand(index, argv[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
case COMMAND_TAG:
|
||||
// t <address> <boot command line>
|
||||
// create tag-list for linux boot
|
||||
if (argc > 2) {
|
||||
RestoreSpace(2);
|
||||
tagAddress = p_ASCIIToHex(argv[1]);
|
||||
InitTagList(argv[2], (void*)tagAddress);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case COMMAND_WRITE:
|
||||
// write the command table to non-volatile
|
||||
WriteCommandTable();
|
||||
break;
|
||||
|
||||
case COMMAND_XMODEM:
|
||||
{
|
||||
// "x <address>"
|
||||
// download X-modem record at address
|
||||
if (argc > 1)
|
||||
xmodem_rx((char *)p_ASCIIToHex(argv[1]));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ServicePrompt(char)
|
||||
* This private function process each character checking for valid commands.
|
||||
* This function is only executed if the character is considered valid.
|
||||
* Each command is terminated with NULL (0) or ''.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
ServicePrompt(char p_char)
|
||||
{
|
||||
if (p_char == '\r')
|
||||
p_char = 0;
|
||||
|
||||
if (p_char == '\010') {
|
||||
if (buffCount) {
|
||||
/* handle backspace BS */
|
||||
inputBuffer[--buffCount] = 0;
|
||||
printf(backspaceString);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (buffCount < MAX_INPUT_SIZE - 1) {
|
||||
inputBuffer[buffCount++] = p_char;
|
||||
putchar(p_char);
|
||||
}
|
||||
if (!p_char) {
|
||||
printf("\n");
|
||||
ParseCommand(inputBuffer);
|
||||
p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
|
||||
buffCount = 0;
|
||||
printf("\n>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void Bootloader(void *inputFunction)
|
||||
* This global function is the entry point for the bootloader. If the
|
||||
* inputFunction pointer is NULL, the loader input will be serviced from
|
||||
* the uart. Otherwise, inputFunction is called to get characters which
|
||||
* the loader will parse.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
Bootloader(int(*inputFunction)(int))
|
||||
{
|
||||
int ch = 0;
|
||||
|
||||
p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
|
||||
|
||||
buffCount = 0;
|
||||
if (!inputFunction) {
|
||||
inputFunction = getc;
|
||||
}
|
||||
|
||||
printf("\n>");
|
||||
|
||||
while (1)
|
||||
if ((ch = ((*inputFunction)(0))) > 0)
|
||||
ServicePrompt(ch);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: loader_prompt.h
|
||||
*
|
||||
* Definition of the interactive loader functions.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _LOADER_PROMPT_H_
|
||||
#define _LOADER_PROMPT_H_
|
||||
|
||||
#define MAX_INPUT_SIZE 256
|
||||
#define MAX_COMMAND_PARAMS 10
|
||||
|
||||
enum {
|
||||
COMMAND_INVALID = 0,
|
||||
COMMAND_COPY,
|
||||
COMMAND_DUMP,
|
||||
COMMAND_EXEC,
|
||||
COMMAND_HELP,
|
||||
COMMAND_LOCAL_IP,
|
||||
COMMAND_MAC,
|
||||
COMMAND_SERVER_IP,
|
||||
COMMAND_SET,
|
||||
COMMAND_TAG,
|
||||
COMMAND_TFTP,
|
||||
COMMAND_WRITE,
|
||||
COMMAND_XMODEM,
|
||||
COMMAND_FINAL_FLAG
|
||||
} e_cmd_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int command;
|
||||
const char *c_string;
|
||||
} command_entry_t;
|
||||
|
||||
void EnterInteractiveBootloader(int(*inputFunction)(int));
|
||||
void Bootloader(int(*inputFunction)(int));
|
||||
|
||||
#endif /* _LOADER_PROMPT_H_ */
|
@ -1,55 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Filename: main.c
|
||||
*
|
||||
* Basic entry points for top-level functions
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin cosmetic changes
|
||||
* 29APR2005 kb_admin modified boot delay
|
||||
*
|
||||
* 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$
|
||||
******************************************************************************/
|
||||
|
||||
#include "env_vars.h"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
|
||||
int main(void);
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int main(void)
|
||||
* This global function waits at least one second, but not more than two
|
||||
* seconds, for input from the serial port. If no response is recognized,
|
||||
* it acts according to the parameters specified by the environment. For
|
||||
* example, the function might boot an operating system. Do not return
|
||||
* from this function.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
InitEEPROM();
|
||||
EMAC_Init();
|
||||
LoadBootCommands();
|
||||
printf("\n\rKB9202(www.kwikbyte.com)\n\rAuto boot..\n\r");
|
||||
if (getc(1) == -1)
|
||||
ExecuteEnvironmentFunctions();
|
||||
Bootloader(0);
|
||||
|
||||
return (1);
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
.PATH: ${.CURDIR}/../libat91
|
||||
|
||||
P=bootspi
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S main.c loader_prompt.c env_vars.c ee.c
|
||||
MAN=
|
||||
LDFLAGS=-e 0 -T ${.CURDIR}/../linker.cfg
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
.if ${MK_FPGA} == "yes"
|
||||
CFLAGS += -DTSC_FPGA
|
||||
.endif
|
||||
CFLAGS += -DBOOT_COMMANDS
|
@ -1,34 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
This image is intended to be programmed into boot EEPROM. The image is nearly
|
||||
0x4000 so it will not fit in KB9200's 0x2000. It is intended for KB9201 or
|
||||
later. Alternatively, the KB9200 can be upgraded with larger EEPROM.
|
||||
It performs basic functions prior to executing an image at a
|
||||
specified address. The pre-boot functions can be modified and saved back into
|
||||
EEPROM.
|
||||
The MAC address is set with 0.0.0.0.0.0 by default. This is an invalid address
|
||||
and must be changed to a valid value in order to use the ethernet interface.
|
||||
|
||||
Memory usage:
|
||||
|
||||
EEPROM = 0x4000
|
||||
SDRAM =
|
||||
run stack = 0x21800000
|
||||
variables = 0x21200000
|
||||
ethernet = 0x21000000 (buffers and descriptors)
|
||||
|
||||
|
||||
Functions supported:
|
||||
|
||||
c - copy
|
||||
d - display auto command table (in RAM)
|
||||
e - execute image
|
||||
? - help
|
||||
ip - set local ip
|
||||
m - set mac
|
||||
server_ip - set server ip
|
||||
s - set auto command entry
|
||||
t - create linux boot tag list
|
||||
tftp - download image via tftp
|
||||
w - update auto command table
|
||||
x - download image via xmodem
|
@ -1,160 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: eeprom.c
|
||||
*
|
||||
* Instantiation of eeprom routines
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 28AUG2004 kb_admin initial creation - adapted from Atmel sources
|
||||
* 12JAN2005 kb_admin fixed clock generation, write polling, init
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "at91rm9200.h"
|
||||
#include "lib.h"
|
||||
#include "ee.h"
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
|
||||
|
||||
/*********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
|
||||
/* Use a macro to calculate the TWI clock generator value to save code space. */
|
||||
#define AT91C_TWSI_CLOCK 100000
|
||||
#define TWSI_EEPROM_ADDRESS 0x40
|
||||
|
||||
#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2)
|
||||
#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
|
||||
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void InitEEPROM(void)
|
||||
* This global function initializes the EEPROM interface (TWI). Intended
|
||||
* to be called a single time.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
EEInit(void)
|
||||
{
|
||||
|
||||
AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI;
|
||||
|
||||
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
|
||||
|
||||
pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
|
||||
pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
|
||||
|
||||
pPio->PIO_MDDR = ~AT91C_PIO_PA25;
|
||||
pPio->PIO_MDER = AT91C_PIO_PA25;
|
||||
|
||||
pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
|
||||
|
||||
twiPtr->TWI_IDR = 0xffffffffu;
|
||||
twiPtr->TWI_CR = AT91C_TWI_SWRST;
|
||||
twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
|
||||
|
||||
twiPtr->TWI_CWGR = SET_TWI_CLOCK;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
iicaddr(unsigned ee_off)
|
||||
{
|
||||
return (TWSI_EEPROM_ADDRESS | ((ee_off >> 8) & 0x7));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
|
||||
* This global function reads data from the eeprom at ee_addr storing data
|
||||
* to data_addr for size bytes. Assume the TWI has been initialized.
|
||||
* This function does not utilize the page read mode to simplify the code.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
EERead(unsigned ee_off, char *data_addr, unsigned size)
|
||||
{
|
||||
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
|
||||
unsigned int status;
|
||||
|
||||
if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) {
|
||||
printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size);
|
||||
return;
|
||||
}
|
||||
|
||||
status = twiPtr->TWI_SR;
|
||||
status = twiPtr->TWI_RHR;
|
||||
twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) | AT91C_TWI_IADRSZ_1_BYTE |
|
||||
AT91C_TWI_MREAD;
|
||||
twiPtr->TWI_IADR = ee_off & 0xff;
|
||||
twiPtr->TWI_CR = AT91C_TWI_START;
|
||||
while (size-- > 1) {
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
|
||||
continue;
|
||||
*(data_addr++) = twiPtr->TWI_RHR;
|
||||
}
|
||||
twiPtr->TWI_CR = AT91C_TWI_STOP;
|
||||
status = twiPtr->TWI_SR;
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
|
||||
continue;
|
||||
*data_addr = twiPtr->TWI_RHR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
|
||||
* This global function writes data to the eeprom at ee_off using data
|
||||
* from data_addr for size bytes. Assume the TWI has been initialized.
|
||||
* This function does not utilize the page write mode as the write time is
|
||||
* much greater than the time required to access the device for byte-write
|
||||
* functionality. This allows the function to be much simpler.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
EEWrite(unsigned ee_off, const char *data_addr, unsigned size)
|
||||
{
|
||||
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
|
||||
unsigned status;
|
||||
char test_data;
|
||||
|
||||
while (size--) {
|
||||
// Set the TWI Master Mode Register
|
||||
twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) |
|
||||
AT91C_TWI_IADRSZ_1_BYTE;
|
||||
twiPtr->TWI_IADR = ee_off++;
|
||||
status = twiPtr->TWI_SR;
|
||||
|
||||
// Load one data byte
|
||||
twiPtr->TWI_THR = *(data_addr++);
|
||||
twiPtr->TWI_CR = AT91C_TWI_START;
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY))
|
||||
continue;
|
||||
twiPtr->TWI_CR = AT91C_TWI_STOP;
|
||||
status = twiPtr->TWI_SR;
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
|
||||
continue;
|
||||
|
||||
// wait for write operation to complete, it is done once
|
||||
// we can read it back...
|
||||
EERead(ee_off, &test_data, 1);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
void EEInit(void);
|
||||
void EERead(unsigned ee_off, char *data_addr, unsigned size);
|
||||
void EEWrite(unsigned ee_off, const char *data_addr, unsigned size);
|
||||
|
@ -1,130 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: env_vars.c
|
||||
*
|
||||
* Instantiation of environment variables, structures, and other globals.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "env_vars.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "lib.h"
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE];
|
||||
|
||||
char env_table[MAX_ENV_SIZE_BYTES];
|
||||
|
||||
extern char BootCommandSection;
|
||||
|
||||
/************************** PRIVATE FUNCTIONS ********************************/
|
||||
|
||||
|
||||
static int currentIndex;
|
||||
static int currentOffset;
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int ReadCharFromEnvironment(char *)
|
||||
* This private function reads characters from the environment variables
|
||||
* to service the command prompt during auto-boot or just to setup the
|
||||
* default environment. Returns positive value if valid character was
|
||||
* set in the pointer. Returns negative value to signal input stream
|
||||
* terminated. Returns 0 to indicate _wait_ condition.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
ReadCharFromEnvironment(int timeout)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (currentIndex < MAX_BOOT_COMMANDS) {
|
||||
ch = boot_commands[currentIndex][currentOffset++];
|
||||
if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) {
|
||||
currentOffset = 0;
|
||||
++currentIndex;
|
||||
ch = '\r';
|
||||
}
|
||||
return (ch);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void DumpBootCommands(void)
|
||||
* This global function displays the current boot commands.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
DumpBootCommands(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; boot_commands[i][0]; i++)
|
||||
printf("0x%x : %s[E]\n", i, boot_commands[i]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void LoadBootCommands(void)
|
||||
* This global function loads the existing boot commands from raw format and
|
||||
* coverts it to the standard, command-index format. Notice, the processed
|
||||
* boot command table has much more space allocated than the actual table
|
||||
* stored in non-volatile memory. This is because the processed table
|
||||
* exists in RAM which is larger than the non-volatile space.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
LoadBootCommands(void)
|
||||
{
|
||||
int index, j;
|
||||
char *cptr;
|
||||
|
||||
p_memset((char*)boot_commands, 0, sizeof(boot_commands));
|
||||
cptr = &BootCommandSection;
|
||||
for (index = 0; *cptr; index++) {
|
||||
for (j = 0; *cptr; j++)
|
||||
boot_commands[index][j] = *cptr++;
|
||||
cptr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ExecuteEnvironmentFunctions(void)
|
||||
* This global function executes applicable entries in the environment.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
ExecuteEnvironmentFunctions(void)
|
||||
{
|
||||
currentIndex = 0;
|
||||
currentOffset = 0;
|
||||
|
||||
DumpBootCommands();
|
||||
printf("Autoboot...\n");
|
||||
Bootloader(ReadCharFromEnvironment);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: env_vars.h
|
||||
*
|
||||
* Definition of environment variables, structures, and other globals.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _ENV_VARS_H_
|
||||
#define _ENV_VARS_H_
|
||||
|
||||
/* each environment variable is a string following the standard command */
|
||||
/* definition used by the interactive loader in the following format: */
|
||||
/* <command> <parm1> <parm2> ... */
|
||||
/* all environment variables (or commands) are stored in a string */
|
||||
/* format: NULL-terminated. */
|
||||
/* this implies that commands can never utilize 0-values: actual 0, not */
|
||||
/* the string '0'. this is not an issue as the string '0' is handled */
|
||||
/* by the command parse routine. */
|
||||
|
||||
/* the following defines the maximum size of the environment for */
|
||||
/* including variables. */
|
||||
/* this value must match that declared in the low-level file that */
|
||||
/* actually reserves the space for the non-volatile environment. */
|
||||
#define MAX_ENV_SIZE_BYTES 0x100
|
||||
|
||||
#define MAX_BOOT_COMMANDS 10
|
||||
|
||||
/* C-style reference section */
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void WriteCommandTable(void);
|
||||
extern void SetBootCommand(int index, char *command);
|
||||
extern void DumpBootCommands(void);
|
||||
extern void LoadBootCommands(void);
|
||||
extern void ExecuteEnvironmentFunctions(void);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ENV_VARS_H_ */
|
@ -1,363 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: loader_prompt.c
|
||||
*
|
||||
* Instantiation of the interactive loader functions.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin massive changes for tftp, strings, and more
|
||||
* 05JUL2005 kb_admin save tag address, and set registers on boot
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "at91rm9200.h"
|
||||
#include "emac.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "env_vars.h"
|
||||
#include "lib.h"
|
||||
#include "spi_flash.h"
|
||||
#include "ee.h"
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
|
||||
|
||||
/*********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
static char inputBuffer[MAX_INPUT_SIZE];
|
||||
static int buffCount;
|
||||
|
||||
// argv pointer are either NULL or point to locations in inputBuffer
|
||||
static char *argv[MAX_COMMAND_PARAMS];
|
||||
|
||||
#define FLASH_OFFSET (0 * FLASH_PAGE_SIZE)
|
||||
#define KERNEL_OFFSET (220 * FLASH_PAGE_SIZE)
|
||||
#define KERNEL_LEN (6 * 1024 * FLASH_PAGE_SIZE)
|
||||
static const char *backspaceString = "\010 \010";
|
||||
|
||||
static const command_entry_t CommandTable[] = {
|
||||
{COMMAND_DUMP, "d"},
|
||||
{COMMAND_EXEC, "e"},
|
||||
{COMMAND_LOCAL_IP, "ip"},
|
||||
{COMMAND_MAC, "m"},
|
||||
{COMMAND_SERVER_IP, "server_ip"},
|
||||
{COMMAND_TFTP, "tftp"},
|
||||
{COMMAND_XMODEM, "x"},
|
||||
{COMMAND_RESET, "R"},
|
||||
{COMMAND_LOAD_SPI_KERNEL, "k"},
|
||||
{COMMAND_REPLACE_KERNEL_VIA_XMODEM, "K"},
|
||||
{COMMAND_REPLACE_FLASH_VIA_XMODEM, "I"},
|
||||
{COMMAND_REPLACE_ID_EEPROM, "E"},
|
||||
{COMMAND_FINAL_FLAG, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned BuildIP(void)
|
||||
* This private function packs the test IP info to an unsigned value.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static unsigned
|
||||
BuildIP(void)
|
||||
{
|
||||
return ((p_ASCIIToDec(argv[1]) << 24) |
|
||||
(p_ASCIIToDec(argv[2]) << 16) |
|
||||
(p_ASCIIToDec(argv[3]) << 8) |
|
||||
p_ASCIIToDec(argv[4]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int StringToCommand(char *cPtr)
|
||||
* This private function converts a command string to a command code.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
StringToCommand(char *cPtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
|
||||
if (!strcmp(CommandTable[i].c_string, cPtr))
|
||||
return (CommandTable[i].command);
|
||||
|
||||
return (COMMAND_INVALID);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int BreakCommand(char *)
|
||||
* This private function splits the buffer into separate strings as pointed
|
||||
* by argv and returns the number of parameters (< 0 on failure).
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
BreakCommand(char *buffer)
|
||||
{
|
||||
int pCount, cCount, state;
|
||||
|
||||
state = pCount = 0;
|
||||
p_memset((char*)argv, 0, sizeof(argv));
|
||||
|
||||
for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
|
||||
|
||||
if (!state) {
|
||||
/* look for next command */
|
||||
if (!p_IsWhiteSpace(buffer[cCount])) {
|
||||
argv[pCount++] = &buffer[cCount];
|
||||
state = 1;
|
||||
} else {
|
||||
buffer[cCount] = 0;
|
||||
}
|
||||
} else {
|
||||
/* in command, find next white space */
|
||||
if (p_IsWhiteSpace(buffer[cCount])) {
|
||||
buffer[cCount] = 0;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCount >= MAX_COMMAND_PARAMS) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (pCount);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
UpdateEEProm(int eeaddr)
|
||||
{
|
||||
char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
|
||||
int len;
|
||||
|
||||
while ((len = xmodem_rx(addr)) == -1)
|
||||
continue;
|
||||
printf("\nDownloaded %u bytes.\n", len);
|
||||
WriteEEPROM(eeaddr, 0, addr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
UpdateFlash(int offset)
|
||||
{
|
||||
char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
|
||||
int len, i, off;
|
||||
|
||||
while ((len = xmodem_rx(addr)) == -1)
|
||||
continue;
|
||||
printf("\nDownloaded %u bytes.\n", len);
|
||||
for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
|
||||
off = i + offset;
|
||||
SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LoadKernelFromSpi(char *addr)
|
||||
{
|
||||
int i, off;
|
||||
|
||||
for (i = 0; i < KERNEL_LEN; i+= FLASH_PAGE_SIZE) {
|
||||
off = i + KERNEL_OFFSET;
|
||||
SPI_ReadFlash(off, addr + i, FLASH_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ParseCommand(char *)
|
||||
* This private function executes matching functions.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
ParseCommand(char *buffer)
|
||||
{
|
||||
int argc, i;
|
||||
|
||||
if ((argc = BreakCommand(buffer)) < 1)
|
||||
return;
|
||||
|
||||
switch (StringToCommand(argv[0])) {
|
||||
case COMMAND_DUMP:
|
||||
// display boot commands
|
||||
DumpBootCommands();
|
||||
break;
|
||||
|
||||
case COMMAND_EXEC:
|
||||
{
|
||||
// "e <address>"
|
||||
// execute at address
|
||||
void (*execAddr)(unsigned, unsigned);
|
||||
|
||||
if (argc > 1) {
|
||||
/* in future, include machtypes (MACH_KB9200 = 612) */
|
||||
execAddr = (void (*)(unsigned, unsigned))
|
||||
p_ASCIIToHex(argv[1]);
|
||||
(*execAddr)(0, 612);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_TFTP:
|
||||
{
|
||||
// "tftp <local_dest_addr filename>"
|
||||
// tftp download
|
||||
unsigned address = 0;
|
||||
|
||||
if (argc > 2)
|
||||
address = p_ASCIIToHex(argv[1]);
|
||||
TFTP_Download(address, argv[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_SERVER_IP:
|
||||
// "server_ip <server IP 192 200 1 20>"
|
||||
// set download server address
|
||||
if (argc > 4)
|
||||
SetServerIPAddress(BuildIP());
|
||||
break;
|
||||
|
||||
case COMMAND_LOCAL_IP:
|
||||
// "local_ip <local IP 192 200 1 21>
|
||||
// set ip of this module
|
||||
if (argc > 4)
|
||||
SetLocalIPAddress(BuildIP());
|
||||
break;
|
||||
|
||||
case COMMAND_MAC:
|
||||
{
|
||||
// "m <mac address 12 34 56 78 9a bc>
|
||||
// set mac address using 6 byte values
|
||||
unsigned char mac[6];
|
||||
|
||||
if (argc > 6) {
|
||||
for (i = 0; i < 6; i++)
|
||||
mac[i] = p_ASCIIToHex(argv[i + 1]);
|
||||
EMAC_SetMACAddress(mac);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_LOAD_SPI_KERNEL:
|
||||
// "k <address>"
|
||||
if (argc > 1)
|
||||
LoadKernelFromSpi((char *)p_ASCIIToHex(argv[1]));
|
||||
break;
|
||||
|
||||
case COMMAND_XMODEM:
|
||||
// "x <address>"
|
||||
// download X-modem record at address
|
||||
if (argc > 1)
|
||||
xmodem_rx((char *)p_ASCIIToHex(argv[1]));
|
||||
break;
|
||||
|
||||
case COMMAND_RESET:
|
||||
printf("Reset\n");
|
||||
reset();
|
||||
while (1) continue;
|
||||
break;
|
||||
|
||||
case COMMAND_REPLACE_KERNEL_VIA_XMODEM:
|
||||
printf("Updating KERNEL image\n");
|
||||
UpdateFlash(KERNEL_OFFSET);
|
||||
break;
|
||||
case COMMAND_REPLACE_FLASH_VIA_XMODEM:
|
||||
printf("Updating FLASH image\n");
|
||||
UpdateFlash(FLASH_OFFSET);
|
||||
break;
|
||||
|
||||
case COMMAND_REPLACE_ID_EEPROM:
|
||||
{
|
||||
char buf[25];
|
||||
printf("Testing Config EEPROM\n");
|
||||
EEWrite(0, "This is a test", 15);
|
||||
EERead(0, buf, 15);
|
||||
printf("Found '%s'\n", buf);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ServicePrompt(char)
|
||||
* This private function process each character checking for valid commands.
|
||||
* This function is only executed if the character is considered valid.
|
||||
* Each command is terminated with NULL (0) or ''.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
ServicePrompt(char p_char)
|
||||
{
|
||||
if (p_char == '\r')
|
||||
p_char = 0;
|
||||
|
||||
if (p_char == '\010') {
|
||||
if (buffCount) {
|
||||
/* handle backspace BS */
|
||||
inputBuffer[--buffCount] = 0;
|
||||
printf(backspaceString);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (buffCount < MAX_INPUT_SIZE - 1) {
|
||||
inputBuffer[buffCount++] = p_char;
|
||||
putchar(p_char);
|
||||
}
|
||||
if (!p_char) {
|
||||
printf("\n");
|
||||
ParseCommand(inputBuffer);
|
||||
p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
|
||||
buffCount = 0;
|
||||
printf("\n>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void Bootloader(void *inputFunction)
|
||||
* This global function is the entry point for the bootloader. If the
|
||||
* inputFunction pointer is NULL, the loader input will be serviced from
|
||||
* the uart. Otherwise, inputFunction is called to get characters which
|
||||
* the loader will parse.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
Bootloader(int(*inputFunction)(int))
|
||||
{
|
||||
int ch = 0;
|
||||
|
||||
p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
|
||||
buffCount = 0;
|
||||
|
||||
printf("\n>");
|
||||
|
||||
while (1)
|
||||
if ((ch = ((*inputFunction)(0))) > 0)
|
||||
ServicePrompt(ch);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: loader_prompt.h
|
||||
*
|
||||
* Definition of the interactive loader functions.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _LOADER_PROMPT_H_
|
||||
#define _LOADER_PROMPT_H_
|
||||
|
||||
#define MAX_INPUT_SIZE 256
|
||||
#define MAX_COMMAND_PARAMS 10
|
||||
|
||||
enum {
|
||||
COMMAND_INVALID = 0,
|
||||
COMMAND_COPY,
|
||||
COMMAND_DUMP,
|
||||
COMMAND_EXEC,
|
||||
COMMAND_HELP,
|
||||
COMMAND_LOCAL_IP,
|
||||
COMMAND_MAC,
|
||||
COMMAND_SERVER_IP,
|
||||
COMMAND_SET,
|
||||
COMMAND_TAG,
|
||||
COMMAND_TFTP,
|
||||
COMMAND_WRITE,
|
||||
COMMAND_XMODEM,
|
||||
COMMAND_RESET,
|
||||
COMMAND_LOAD_SPI_KERNEL,
|
||||
COMMAND_REPLACE_KERNEL_VIA_XMODEM,
|
||||
COMMAND_REPLACE_FLASH_VIA_XMODEM,
|
||||
COMMAND_REPLACE_FPGA_VIA_XMODEM,
|
||||
COMMAND_REPLACE_ID_EEPROM,
|
||||
COMMAND_FINAL_FLAG
|
||||
} e_cmd_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int command;
|
||||
const char *c_string;
|
||||
} command_entry_t;
|
||||
|
||||
void EnterInteractiveBootloader(int(*inputFunction)(int));
|
||||
void Bootloader(int(*inputFunction)(int));
|
||||
void fpga_load(void);
|
||||
|
||||
#endif /* _LOADER_PROMPT_H_ */
|
@ -1,65 +0,0 @@
|
||||
/*-
|
||||
* 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 "env_vars.h"
|
||||
#include "at91rm9200.h"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
#include "spi_flash.h"
|
||||
#include "ee.h"
|
||||
|
||||
int main(void);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
printf("\nBoot\n");
|
||||
EEInit();
|
||||
SPI_InitFlash();
|
||||
#ifdef TSC_FPGA
|
||||
fpga_load();
|
||||
#endif
|
||||
EMAC_Init();
|
||||
LoadBootCommands();
|
||||
if (getc(1) == -1) {
|
||||
start_wdog(30);
|
||||
ExecuteEnvironmentFunctions();
|
||||
}
|
||||
Bootloader(getc);
|
||||
return (1);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
.include "${.CURDIR}/../Makefile.inc"
|
||||
|
||||
SOC?=at91rm9200
|
||||
|
||||
LIB= at91
|
||||
INTERNALLIB=
|
||||
SRCS=${SOC}_lowlevel.c delay.c eeprom.c emac.c emac_init.c getc.c \
|
||||
putchar.c printf.c reset.c spi_flash.c xmodem.c \
|
||||
sd-card.c strcvt.c strlen.c strcmp.c memcpy.c strcpy.c \
|
||||
memset.c memcmp.c
|
||||
SRCS+=ashldi3.c divsi3.S
|
||||
MAN=
|
||||
|
||||
.if ${MK_TAG_LIST} != "no"
|
||||
CFLAGS += -I${.CURDIR}/.. -DSUPPORT_TAG_LIST
|
||||
SRCS+=tag_list.c
|
||||
.endif
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -1,129 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Filename: arm_init.s
|
||||
*
|
||||
* Initialization for C-environment and basic operation. Adapted from
|
||||
* ATMEL cstartup.s.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin updated for 16KB eeprom
|
||||
* Atmel stack prevents loading full size at once
|
||||
*
|
||||
* 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$
|
||||
******************************************************************************/
|
||||
|
||||
.equ TWI_EEPROM_SIZE, 0x3000
|
||||
.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:
|
||||
#ifdef BOOT_IIC
|
||||
.long (TWI_EEPROM_SIZE >> 9)
|
||||
#else
|
||||
#ifdef BOOT_BWCT
|
||||
.long ((528 << 17) | (13 << 13) | (12 * 2))
|
||||
#else
|
||||
.long ((1056 << 17) | (13 << 13) | (12 * 2))
|
||||
#endif
|
||||
#endif
|
||||
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
|
||||
#ifndef BOOT_BOOT0
|
||||
ldr r1, = SVC_STACK_USE
|
||||
mov sp, r1 @ ; Move the stack to SDRAM
|
||||
#endif
|
||||
|
||||
/* Start execution at main */
|
||||
.extern main
|
||||
_main:
|
||||
__main:
|
||||
bl main
|
||||
/* main should not return. If it does, spin forever */
|
||||
infiniteLoop:
|
||||
b infiniteLoop
|
||||
|
||||
#ifdef BOOT_COMMANDS
|
||||
/* the following section is used to store boot commands in */
|
||||
/* non-volatile memory. */
|
||||
|
||||
.global BootCommandSection
|
||||
BootCommandSection:
|
||||
#ifdef SUPPORT_LINUX
|
||||
.string "Bootloader for KB9202 Evaluation Board."
|
||||
.string "c 0x20210000 0x10100000 0x80000 "
|
||||
.string "m 0 0 0 0 0 0 "
|
||||
.string "t 0x20000100 console=ttyS0,115200 root=/dev/ram rw initrd=0x20210000,654933"
|
||||
.string "e 0x10000000 "
|
||||
.string " "
|
||||
#else
|
||||
#if 1
|
||||
.string "m 42 53 44 0 0 1"
|
||||
.string "ip 206 168 13 194"
|
||||
.string "server_ip 206 168 13 207"
|
||||
.string "tftp 0x20000000 kernel.bin"
|
||||
.string "e 0x20000000"
|
||||
#else
|
||||
.string "m 42 53 44 0 0 1"
|
||||
.string "k 0x20000000"
|
||||
.string "e 0x20000000"
|
||||
#endif
|
||||
.word 0
|
||||
#endif
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,223 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
|
||||
extern int __bss_start__[];
|
||||
extern int __bss_end__[];
|
||||
|
||||
#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)
|
||||
{
|
||||
int *i;
|
||||
|
||||
AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
|
||||
AT91PS_PDC pPDC = (AT91PS_PDC)&(pUSART->US_RPR);
|
||||
|
||||
register unsigned value;
|
||||
volatile sdram_size_t *p = (sdram_size_t *)SDRAM_BASE;
|
||||
|
||||
AT91C_BASE_ST->ST_RTMR = 1;
|
||||
#ifdef BOOT_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
|
||||
|
||||
#if defined(BOOT_KB920X)
|
||||
AT91C_BASE_PIOC->PIO_PER = AT91C_PIO_PC18 | AT91C_PIO_PC19 |
|
||||
AT91C_PIO_PC20;
|
||||
AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC18 | AT91C_PIO_PC19 |
|
||||
AT91C_PIO_PC20;
|
||||
AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC18 | AT91C_PIO_PC19 |
|
||||
AT91C_PIO_PC20;
|
||||
AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC18;
|
||||
#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;
|
||||
|
||||
#ifdef BOOT_KB920X
|
||||
// setup flash access (allow ample margin)
|
||||
// 9 wait states, 1 setup, 1 hold, 1 float for 8-bit device
|
||||
((AT91PS_SMC2)AT91C_BASE_SMC2)->SMC2_CSR[0] =
|
||||
AT91C_SMC2_WSEN |
|
||||
(9 & AT91C_SMC2_NWS) |
|
||||
((1 << 8) & AT91C_SMC2_TDF) |
|
||||
AT91C_SMC2_DBW_8 |
|
||||
((1 << 24) & AT91C_SMC2_RWSETUP) |
|
||||
((1 << 29) & AT91C_SMC2_RWHOLD);
|
||||
#endif
|
||||
|
||||
// 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 =
|
||||
#if defined(KB9202_B) || defined(SDRAM_128M)
|
||||
AT91C_SDRC_NC_10 |
|
||||
#else
|
||||
AT91C_SDRC_NC_9 |
|
||||
#endif
|
||||
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;
|
||||
|
||||
#if SDRAM_WIDTH == AT91C_SDRC_DBW_32_BITS
|
||||
// Turn on the upper 16 bits on the SDRAM bus.
|
||||
AT91C_BASE_PIOC->PIO_ASR = 0xffff0000;
|
||||
AT91C_BASE_PIOC->PIO_PDR = 0xffff0000;
|
||||
#endif
|
||||
// Configure DBGU -use local routine optimized for space
|
||||
AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA31 | AT91C_PIO_PA30;
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA31 | AT91C_PIO_PA30;
|
||||
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;
|
||||
|
||||
/* Zero BSS now that we have memory setup */
|
||||
i = (int *)__bss_start__;
|
||||
while (i < (int *)__bss_end__)
|
||||
*i++ = 0;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*-
|
||||
* 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 BOOT_KB920X
|
||||
/* 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 BOOT_CENTIPAD
|
||||
/* 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 BOOT_BWCT
|
||||
/* 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_32_BITS
|
||||
typedef unsigned int sdram_size_t;
|
||||
#define OSC_MAIN_MULT 45
|
||||
#endif
|
||||
|
||||
#ifdef BOOT_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_32_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) */
|
||||
#define GetSeconds() (AT91C_BASE_ST->ST_CRTR >> 15)
|
||||
|
||||
extern void _init(void);
|
||||
|
||||
#endif /* _AT91RM9200_LOWLEVEL_H_ */
|
@ -1,43 +0,0 @@
|
||||
/*-
|
||||
* 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 "spi_flash.h"
|
||||
#include "lib.h"
|
||||
|
||||
void
|
||||
Delay(int us)
|
||||
{
|
||||
unsigned later, now;
|
||||
|
||||
now = AT91C_BASE_ST->ST_CRTR;
|
||||
later = (now + us / 25 + 1) & AT91C_ST_CRTV;
|
||||
while (later != AT91C_BASE_ST->ST_CRTR)
|
||||
continue;
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: eeprom.c
|
||||
*
|
||||
* Instantiation of eeprom routines
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 28AUG2004 kb_admin initial creation - adapted from Atmel sources
|
||||
* 12JAN2005 kb_admin fixed clock generation, write polling, init
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "at91rm9200.h"
|
||||
#include "lib.h"
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
|
||||
|
||||
/*********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
|
||||
/* Use a macro to calculate the TWI clock generator value to save code space. */
|
||||
#define AT91C_TWSI_CLOCK 100000
|
||||
#define TWSI_EEPROM_ADDRESS 0x50
|
||||
|
||||
#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2)
|
||||
#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
|
||||
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void InitEEPROM(void)
|
||||
* This global function initializes the EEPROM interface (TWI). Intended
|
||||
* to be called a single time.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
InitEEPROM(void)
|
||||
{
|
||||
|
||||
AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI;
|
||||
|
||||
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
|
||||
|
||||
pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
|
||||
pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
|
||||
|
||||
pPio->PIO_MDDR = ~AT91C_PIO_PA25;
|
||||
pPio->PIO_MDER = AT91C_PIO_PA25;
|
||||
|
||||
pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
|
||||
|
||||
twiPtr->TWI_IDR = 0xffffffffu;
|
||||
twiPtr->TWI_CR = AT91C_TWI_SWRST;
|
||||
twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
|
||||
|
||||
twiPtr->TWI_CWGR = SET_TWI_CLOCK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
|
||||
* This global function reads data from the eeprom at ee_addr storing data
|
||||
* to data_addr for size bytes. Assume the TWI has been initialized.
|
||||
* This function does not utilize the page read mode to simplify the code.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
int
|
||||
ReadEEPROM(unsigned ee_off, unsigned char *data_addr, unsigned size)
|
||||
{
|
||||
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
|
||||
unsigned int status;
|
||||
unsigned int count;
|
||||
|
||||
status = twiPtr->TWI_SR;
|
||||
status = twiPtr->TWI_RHR;
|
||||
|
||||
// Set the TWI Master Mode Register
|
||||
twiPtr->TWI_MMR = (TWSI_EEPROM_ADDRESS << 16) |
|
||||
AT91C_TWI_IADRSZ_2_BYTE | AT91C_TWI_MREAD;
|
||||
|
||||
// Set TWI Internal Address Register
|
||||
twiPtr->TWI_IADR = ee_off;
|
||||
|
||||
// Start transfer
|
||||
twiPtr->TWI_CR = AT91C_TWI_START;
|
||||
|
||||
status = twiPtr->TWI_SR;
|
||||
|
||||
while (size-- > 1){
|
||||
// Wait RHR Holding register is full
|
||||
count = 1000000;
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0)
|
||||
continue;
|
||||
if (count <= 0)
|
||||
return -1;
|
||||
|
||||
// Read byte
|
||||
*(data_addr++) = twiPtr->TWI_RHR;
|
||||
}
|
||||
|
||||
twiPtr->TWI_CR = AT91C_TWI_STOP;
|
||||
|
||||
status = twiPtr->TWI_SR;
|
||||
|
||||
// Wait transfer is finished
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
|
||||
continue;
|
||||
|
||||
// Read last byte
|
||||
*data_addr = twiPtr->TWI_RHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
|
||||
* This global function writes data to the eeprom at ee_off using data
|
||||
* from data_addr for size bytes. Assume the TWI has been initialized.
|
||||
* This function does not utilize the page write mode as the write time is
|
||||
* much greater than the time required to access the device for byte-write
|
||||
* functionality. This allows the function to be much simpler.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
|
||||
{
|
||||
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
|
||||
unsigned status;
|
||||
unsigned char test_data;
|
||||
|
||||
while (size--) {
|
||||
if (!(ee_off & 0x3f))
|
||||
putchar('.');
|
||||
|
||||
// Set the TWI Master Mode Register
|
||||
twiPtr->TWI_MMR = ((TWSI_EEPROM_ADDRESS << 16) |
|
||||
AT91C_TWI_IADRSZ_2_BYTE) & ~AT91C_TWI_MREAD;
|
||||
|
||||
// Set TWI Internal Address Register
|
||||
twiPtr->TWI_IADR = ee_off++;
|
||||
|
||||
status = twiPtr->TWI_SR;
|
||||
|
||||
twiPtr->TWI_THR = *(data_addr++);
|
||||
|
||||
twiPtr->TWI_CR = AT91C_TWI_START;
|
||||
|
||||
// Wait transfer is finished
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY))
|
||||
continue;
|
||||
|
||||
twiPtr->TWI_CR = AT91C_TWI_STOP;
|
||||
|
||||
status = twiPtr->TWI_SR;
|
||||
|
||||
// Wait transfer is finished
|
||||
while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
|
||||
continue;
|
||||
|
||||
// wait for write operation to complete
|
||||
ReadEEPROM(ee_off, &test_data, 1);
|
||||
}
|
||||
|
||||
putchar('\r');
|
||||
putchar('\n');
|
||||
}
|
@ -1,575 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Filename: emac.c
|
||||
*
|
||||
* Instantiation of routines for MAC/ethernet functions supporting tftp.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 28AUG2004 kb_admin initial creation
|
||||
* 08JAN2005 kb_admin added tftp download
|
||||
* also adapted from external sources
|
||||
*
|
||||
* 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$
|
||||
******************************************************************************/
|
||||
|
||||
#include "at91rm9200.h"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
|
||||
/* ****************************** GLOBALS *************************************/
|
||||
|
||||
/* ********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
static receive_descriptor_t *p_rxBD;
|
||||
static unsigned short localPort;
|
||||
static unsigned short serverPort;
|
||||
static unsigned serverMACSet;
|
||||
static unsigned localIPSet, serverIPSet;
|
||||
static unsigned lastSize;
|
||||
static unsigned char serverMACAddr[6];
|
||||
static unsigned char localIPAddr[4], serverIPAddr[4];
|
||||
static int ackBlock;
|
||||
static char *dlAddress;
|
||||
|
||||
static unsigned transmitBuffer[1024 / sizeof(unsigned)];
|
||||
static unsigned tftpSendPacket[256 / sizeof(unsigned)];
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned short IP_checksum(unsigned short *p, int len)
|
||||
* This private function calculates the IP checksum for various headers.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static unsigned short
|
||||
IP_checksum(unsigned short *p, int len)
|
||||
{
|
||||
unsigned i, t;
|
||||
|
||||
len &= ~1;
|
||||
|
||||
for (i=0,t=0; i<len; i+=2, ++p)
|
||||
t += SWAP16(*p);
|
||||
|
||||
t = (t & 0xffff) + (t >> 16);
|
||||
return (~t);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void GetServerAddress(void)
|
||||
* This private function sends an ARP request to determine the server MAC.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
GetServerAddress(void)
|
||||
{
|
||||
arp_header_t *p_ARP;
|
||||
|
||||
p_ARP = (arp_header_t*)transmitBuffer;
|
||||
|
||||
p_memset((char*)p_ARP->dest_mac, 0xFF, 6);
|
||||
|
||||
memcpy(p_ARP->src_mac, localMACAddr, 6);
|
||||
|
||||
p_ARP->frame_type = SWAP16(PROTOCOL_ARP);
|
||||
p_ARP->hard_type = SWAP16(1);
|
||||
p_ARP->prot_type = SWAP16(PROTOCOL_IP);
|
||||
p_ARP->hard_size = 6;
|
||||
p_ARP->prot_size = 4;
|
||||
p_ARP->operation = SWAP16(ARP_REQUEST);
|
||||
|
||||
memcpy(p_ARP->sender_mac, localMACAddr, 6);
|
||||
memcpy(p_ARP->sender_ip, localIPAddr, 4);
|
||||
p_memset((char*)p_ARP->target_mac, 0, 6);
|
||||
memcpy(p_ARP->target_ip, serverIPAddr, 4);
|
||||
|
||||
// wait until transmit is available
|
||||
while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ))
|
||||
continue;
|
||||
|
||||
*AT91C_EMAC_TSR |= AT91C_EMAC_COMP;
|
||||
*AT91C_EMAC_TAR = (unsigned)transmitBuffer;
|
||||
*AT91C_EMAC_TCR = 0x40;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void Send_TFTP_Packet(char *tftpData, unsigned tftpLength)
|
||||
* This private function initializes and send a TFTP packet.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
Send_TFTP_Packet(char *tftpData, unsigned tftpLength)
|
||||
{
|
||||
transmit_header_t *macHdr = (transmit_header_t*)tftpSendPacket;
|
||||
ip_header_t *ipHdr;
|
||||
udp_header_t *udpHdr;
|
||||
unsigned t_checksum;
|
||||
|
||||
memcpy(macHdr->dest_mac, serverMACAddr, 6);
|
||||
memcpy(macHdr->src_mac, localMACAddr, 6);
|
||||
macHdr->proto_mac = SWAP16(PROTOCOL_IP);
|
||||
|
||||
ipHdr = (ip_header_t*)&macHdr->packet_length;
|
||||
|
||||
ipHdr->ip_v_hl = 0x45;
|
||||
ipHdr->ip_tos = 0;
|
||||
ipHdr->ip_len = SWAP16(28 + tftpLength);
|
||||
ipHdr->ip_id = 0;
|
||||
ipHdr->ip_off = SWAP16(0x4000);
|
||||
ipHdr->ip_ttl = 64;
|
||||
ipHdr->ip_p = PROTOCOL_UDP;
|
||||
ipHdr->ip_sum = 0;
|
||||
|
||||
memcpy(ipHdr->ip_src, localIPAddr, 4);
|
||||
memcpy(ipHdr->ip_dst, serverIPAddr, 4);
|
||||
|
||||
ipHdr->ip_sum = SWAP16(IP_checksum((unsigned short*)ipHdr, 20));
|
||||
|
||||
udpHdr = (udp_header_t*)(ipHdr + 1);
|
||||
|
||||
udpHdr->src_port = localPort;
|
||||
udpHdr->dst_port = serverPort;
|
||||
udpHdr->udp_len = SWAP16(8 + tftpLength);
|
||||
udpHdr->udp_cksum = 0;
|
||||
|
||||
memcpy((char *)udpHdr+8, tftpData, tftpLength);
|
||||
|
||||
t_checksum = IP_checksum((unsigned short*)ipHdr + 6, (16 + tftpLength));
|
||||
|
||||
t_checksum = (~t_checksum) & 0xFFFF;
|
||||
t_checksum += 25 + tftpLength;
|
||||
|
||||
t_checksum = (t_checksum & 0xffff) + (t_checksum >> 16);
|
||||
t_checksum = (~t_checksum) & 0xFFFF;
|
||||
|
||||
udpHdr->udp_cksum = SWAP16(t_checksum);
|
||||
|
||||
while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ))
|
||||
continue;
|
||||
|
||||
*AT91C_EMAC_TSR |= AT91C_EMAC_COMP;
|
||||
*AT91C_EMAC_TAR = (unsigned)tftpSendPacket;
|
||||
*AT91C_EMAC_TCR = 42 + tftpLength;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void TFTP_RequestFile(char *filename)
|
||||
* This private function sends a RRQ packet to the server.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
TFTP_RequestFile(char *filename)
|
||||
{
|
||||
tftp_header_t tftpHeader;
|
||||
char *cPtr, *ePtr, *mPtr;
|
||||
unsigned length;
|
||||
|
||||
tftpHeader.opcode = TFTP_RRQ_OPCODE;
|
||||
|
||||
cPtr = (char*)&(tftpHeader.block_num);
|
||||
|
||||
ePtr = strcpy(cPtr, filename);
|
||||
mPtr = strcpy(ePtr, "octet");
|
||||
|
||||
length = mPtr - cPtr;
|
||||
length += 2;
|
||||
|
||||
Send_TFTP_Packet((char*)&tftpHeader, length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void TFTP_ACK_Data(char *data, unsigned short block_num, unsigned short len)
|
||||
* This private function sends an ACK packet to the server.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
TFTP_ACK_Data(unsigned char *data, unsigned short block_num, unsigned short len)
|
||||
{
|
||||
tftp_header_t tftpHeader;
|
||||
|
||||
if (block_num == (ackBlock + 1)) {
|
||||
++ackBlock;
|
||||
memcpy(dlAddress, data, len);
|
||||
dlAddress += len;
|
||||
lastSize += len;
|
||||
if (ackBlock % 128 == 0)
|
||||
printf("tftp: %u kB\r", lastSize / 1024);
|
||||
}
|
||||
tftpHeader.opcode = TFTP_ACK_OPCODE;
|
||||
tftpHeader.block_num = SWAP16(ackBlock);
|
||||
Send_TFTP_Packet((char*)&tftpHeader, 4);
|
||||
if (len < 512) {
|
||||
ackBlock = -2;
|
||||
printf("tftp: %u byte\n", lastSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void CheckForNewPacket(ip_header_t *pHeader)
|
||||
* This private function polls for received ethernet packets and handles
|
||||
* any here.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
CheckForNewPacket(ip_header_t *pHeader)
|
||||
{
|
||||
unsigned short *pFrameType;
|
||||
unsigned i;
|
||||
char *pData;
|
||||
ip_header_t *pIpHeader;
|
||||
arp_header_t *p_ARP;
|
||||
int process = 0;
|
||||
|
||||
process = 0;
|
||||
for (i = 0; i < MAX_RX_PACKETS; ++i) {
|
||||
if(p_rxBD[i].address & 0x1) {
|
||||
process = 1;
|
||||
(*AT91C_EMAC_RSR) |= (*AT91C_EMAC_RSR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!process)
|
||||
return (0);
|
||||
process = i;
|
||||
|
||||
pFrameType = (unsigned short *)((p_rxBD[i].address & 0xFFFFFFFC) + 12);
|
||||
pData = (char *)(p_rxBD[i].address & 0xFFFFFFFC);
|
||||
|
||||
switch (*pFrameType) {
|
||||
|
||||
case SWAP16(PROTOCOL_ARP):
|
||||
p_ARP = (arp_header_t*)pData;
|
||||
if (p_ARP->operation == SWAP16(ARP_REPLY)) {
|
||||
// check if new server info is available
|
||||
if ((!serverMACSet) &&
|
||||
(!(p_memcmp((char*)p_ARP->sender_ip,
|
||||
(char*)serverIPAddr, 4)))) {
|
||||
|
||||
serverMACSet = 1;
|
||||
memcpy(serverMACAddr, p_ARP->sender_mac, 6);
|
||||
}
|
||||
} else if (p_ARP->operation == SWAP16(ARP_REQUEST)) {
|
||||
// ARP REPLY operation
|
||||
p_ARP->operation = SWAP16(ARP_REPLY);
|
||||
|
||||
// Fill the dest address and src address
|
||||
for (i = 0; i <6; i++) {
|
||||
// swap ethernet dest address and ethernet src address
|
||||
pData[i] = pData[i+6];
|
||||
pData[i+6] = localMACAddr[i];
|
||||
// swap sender ethernet address and target ethernet address
|
||||
pData[i+22] = localMACAddr[i];
|
||||
pData[i+32] = pData[i+6];
|
||||
}
|
||||
|
||||
// swap sender IP address and target IP address
|
||||
for (i = 0; i<4; i++) {
|
||||
pData[i+38] = pData[i+28];
|
||||
pData[i+28] = localIPAddr[i];
|
||||
}
|
||||
|
||||
if (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) break;
|
||||
|
||||
*AT91C_EMAC_TSR |= AT91C_EMAC_COMP;
|
||||
*AT91C_EMAC_TAR = (unsigned)pData;
|
||||
*AT91C_EMAC_TCR = 0x40;
|
||||
}
|
||||
break;
|
||||
case SWAP16(PROTOCOL_IP):
|
||||
pIpHeader = (ip_header_t*)(pData + 14);
|
||||
memcpy(pHeader, pIpHeader, sizeof(ip_header_t));
|
||||
|
||||
if (pIpHeader->ip_p == PROTOCOL_UDP) {
|
||||
udp_header_t *udpHdr;
|
||||
tftp_header_t *tftpHdr;
|
||||
|
||||
udpHdr = (udp_header_t*)((char*)pIpHeader+20);
|
||||
tftpHdr = (tftp_header_t*)((char*)udpHdr + 8);
|
||||
|
||||
if (udpHdr->dst_port != localPort)
|
||||
break;
|
||||
|
||||
if (tftpHdr->opcode != TFTP_DATA_OPCODE)
|
||||
break;
|
||||
|
||||
if (ackBlock == -1) {
|
||||
if (tftpHdr->block_num != SWAP16(1))
|
||||
break;
|
||||
serverPort = udpHdr->src_port;
|
||||
ackBlock = 0;
|
||||
}
|
||||
|
||||
if (serverPort != udpHdr->src_port)
|
||||
break;
|
||||
|
||||
TFTP_ACK_Data(tftpHdr->data,
|
||||
SWAP16(tftpHdr->block_num),
|
||||
SWAP16(udpHdr->udp_len) - 12);
|
||||
}
|
||||
}
|
||||
p_rxBD[process].address &= ~0x01;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned short AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr)
|
||||
* This private function reads the PHY device.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
#ifndef BOOT_BWCT
|
||||
static unsigned short
|
||||
AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr)
|
||||
{
|
||||
unsigned value = 0x60020000 | (addr << 18);
|
||||
|
||||
pEmac->EMAC_CTL |= AT91C_EMAC_MPE;
|
||||
pEmac->EMAC_MAN = value;
|
||||
while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE));
|
||||
pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE;
|
||||
return (pEmac->EMAC_MAN & 0x0000ffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned short AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s)
|
||||
* This private function writes the PHY device.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
#ifdef BOOT_TSC
|
||||
static unsigned short
|
||||
AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s)
|
||||
{
|
||||
unsigned value = 0x50020000 | (addr << 18) | s;
|
||||
|
||||
pEmac->EMAC_CTL |= AT91C_EMAC_MPE;
|
||||
pEmac->EMAC_MAN = value;
|
||||
while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE));
|
||||
pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE;
|
||||
return (pEmac->EMAC_MAN & 0x0000ffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void MII_GetLinkSpeed(AT91PS_EMAC pEmac)
|
||||
* This private function determines the link speed set by the PHY.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
MII_GetLinkSpeed(AT91PS_EMAC pEmac)
|
||||
{
|
||||
#if defined(BOOT_TSC) || defined(BOOT_KB920X) || defined(BOOT_CENTIPAD)
|
||||
unsigned short stat2;
|
||||
#endif
|
||||
unsigned update;
|
||||
#ifdef BOOT_TSC
|
||||
unsigned sec;
|
||||
int i;
|
||||
#endif
|
||||
#ifdef BOOT_BWCT
|
||||
/* hardcoded link speed since we connect a switch via MII */
|
||||
update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
|
||||
update |= AT91C_EMAC_SPD;
|
||||
update |= AT91C_EMAC_FD;
|
||||
#endif
|
||||
#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD)
|
||||
stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS2_REG);
|
||||
if (!(stat2 & MII_STS2_LINK))
|
||||
return ;
|
||||
update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
|
||||
if (stat2 & MII_STS2_100TX)
|
||||
update |= AT91C_EMAC_SPD;
|
||||
if (stat2 & MII_STS2_FDX)
|
||||
update |= AT91C_EMAC_FD;
|
||||
#endif
|
||||
#ifdef BOOT_TSC
|
||||
while (1) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS_REG);
|
||||
if (stat2 & MII_STS_LINK_STAT)
|
||||
break;
|
||||
printf(".");
|
||||
sec = GetSeconds();
|
||||
while (GetSeconds() == sec)
|
||||
continue;
|
||||
}
|
||||
if (stat2 & MII_STS_LINK_STAT)
|
||||
break;
|
||||
printf("Resetting MII...");
|
||||
AT91F_MII_WritePhy(pEmac, 0x0, 0x8000);
|
||||
while (AT91F_MII_ReadPhy(pEmac, 0x0) & 0x8000) continue;
|
||||
}
|
||||
printf("emac: link");
|
||||
stat2 = AT91F_MII_ReadPhy(pEmac, MII_SPEC_STS_REG);
|
||||
update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
|
||||
if (stat2 & (MII_SSTS_100FDX | MII_SSTS_100HDX)) {
|
||||
printf(" 100TX");
|
||||
update |= AT91C_EMAC_SPD;
|
||||
}
|
||||
if (stat2 & (MII_SSTS_100FDX | MII_SSTS_10FDX)) {
|
||||
printf(" FDX");
|
||||
update |= AT91C_EMAC_FD;
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
pEmac->EMAC_CFG = update;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void AT91F_EmacEntry(void)
|
||||
* This private function initializes the EMAC on the chip.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
AT91F_EmacEntry(void)
|
||||
{
|
||||
unsigned i;
|
||||
char *pRxPacket = (char*)RX_DATA_START;
|
||||
AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
|
||||
|
||||
p_rxBD = (receive_descriptor_t*)RX_BUFFER_START;
|
||||
localPort = SWAP16(0x8002);
|
||||
|
||||
for (i = 0; i < MAX_RX_PACKETS; ++i) {
|
||||
|
||||
p_rxBD[i].address = (unsigned)pRxPacket;
|
||||
p_rxBD[i].size = 0;
|
||||
pRxPacket += RX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
// Set the WRAP bit at the end of the list descriptor
|
||||
p_rxBD[MAX_RX_PACKETS-1].address |= 0x02;
|
||||
|
||||
if (!(pEmac->EMAC_SR & AT91C_EMAC_LINK))
|
||||
MII_GetLinkSpeed(pEmac);
|
||||
|
||||
pEmac->EMAC_RBQP = (unsigned) p_rxBD;
|
||||
pEmac->EMAC_RSR |= (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
|
||||
pEmac->EMAC_CTL = AT91C_EMAC_TE | AT91C_EMAC_RE;
|
||||
|
||||
pEmac->EMAC_TAR = (unsigned)transmitBuffer;
|
||||
}
|
||||
|
||||
|
||||
/* ************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SetServerIPAddress(unsigned address)
|
||||
* This global function sets the IP of the TFTP download server.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SetServerIPAddress(unsigned address)
|
||||
{
|
||||
// force update in case the IP has changed
|
||||
serverMACSet = 0;
|
||||
|
||||
serverIPAddr[0] = (address >> 24) & 0xFF;
|
||||
serverIPAddr[1] = (address >> 16) & 0xFF;
|
||||
serverIPAddr[2] = (address >> 8) & 0xFF;
|
||||
serverIPAddr[3] = (address >> 0) & 0xFF;
|
||||
|
||||
serverIPSet = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SetLocalIPAddress(unsigned address)
|
||||
* This global function sets the IP of this module.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SetLocalIPAddress(unsigned address)
|
||||
{
|
||||
// force update in case the IP has changed
|
||||
serverMACSet = 0;
|
||||
|
||||
localIPAddr[0] = (address >> 24) & 0xFF;
|
||||
localIPAddr[1] = (address >> 16) & 0xFF;
|
||||
localIPAddr[2] = (address >> 8) & 0xFF;
|
||||
localIPAddr[3] = (address >> 0) & 0xFF;
|
||||
|
||||
localIPSet = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void TFTP_Download(unsigned address, char *filename)
|
||||
* This global function initiates and processes a tftp download request.
|
||||
* The server IP, local IP, local MAC must be set before this function is
|
||||
* executed.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
TFTP_Download(unsigned address, char *filename)
|
||||
{
|
||||
ip_header_t IpHeader;
|
||||
unsigned thisSeconds;
|
||||
int timeout;
|
||||
|
||||
if ((!localMACSet) || (!localIPSet) || (!serverIPSet))
|
||||
return ;
|
||||
|
||||
AT91F_EmacEntry();
|
||||
GetServerAddress();
|
||||
dlAddress = (char*)address;
|
||||
lastSize = 0;
|
||||
timeout = 10;
|
||||
thisSeconds = (GetSeconds() + 2) % 32;
|
||||
serverPort = SWAP16(69);
|
||||
++localPort;
|
||||
ackBlock = -1;
|
||||
|
||||
while (timeout) {
|
||||
if (CheckForNewPacket(&IpHeader)) {
|
||||
if (ackBlock == -2)
|
||||
break;
|
||||
timeout = 10;
|
||||
thisSeconds = (GetSeconds() + 2) % 32;
|
||||
} else if (GetSeconds() == thisSeconds) {
|
||||
--timeout;
|
||||
thisSeconds = (GetSeconds() + 2) % 32;
|
||||
if (!serverMACSet)
|
||||
GetServerAddress();
|
||||
else if (ackBlock == -1)
|
||||
TFTP_RequestFile(filename);
|
||||
else {
|
||||
// Be sure to send a NAK, which is done by
|
||||
// ACKing the last block we got.
|
||||
TFTP_ACK_Data(0, ackBlock, 512);
|
||||
printf("\nNAK %u\n", ackBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (timeout == 0)
|
||||
printf("TFTP TIMEOUT!\n");
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: emac.h
|
||||
*
|
||||
* Definition of routine to set the MAC address.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 28AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef _EMAC_H_
|
||||
#define _EMAC_H_
|
||||
|
||||
extern void EMAC_SetMACAddress(unsigned char addr[6]);
|
||||
extern void SetServerIPAddress(unsigned address);
|
||||
extern void SetLocalIPAddress(unsigned address);
|
||||
extern void EMAC_Init(void);
|
||||
extern void TFTP_Download(unsigned address, char *filename);
|
||||
|
||||
#define MAX_RX_PACKETS 8
|
||||
#define RX_PACKET_SIZE 1536
|
||||
#define RX_BUFFER_START 0x21000000
|
||||
#define RX_DATA_START (RX_BUFFER_START + (8 * MAX_RX_PACKETS))
|
||||
|
||||
#define ARP_REQUEST 0x0001
|
||||
#define ARP_REPLY 0x0002
|
||||
#define PROTOCOL_ARP 0x0806
|
||||
#define PROTOCOL_IP 0x0800
|
||||
#define PROTOCOL_UDP 0x11
|
||||
|
||||
#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8))
|
||||
|
||||
typedef struct {
|
||||
unsigned address;
|
||||
unsigned size;
|
||||
} receive_descriptor_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
unsigned char dest_mac[6];
|
||||
|
||||
unsigned char src_mac[6];
|
||||
|
||||
unsigned short frame_type;
|
||||
unsigned short hard_type;
|
||||
unsigned short prot_type;
|
||||
unsigned char hard_size;
|
||||
unsigned char prot_size;
|
||||
|
||||
unsigned short operation;
|
||||
|
||||
unsigned char sender_mac[6];
|
||||
unsigned char sender_ip[4];
|
||||
|
||||
unsigned char target_mac[6];
|
||||
unsigned char target_ip[4];
|
||||
|
||||
} __attribute__((__packed__)) arp_header_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char ip_v_hl;
|
||||
unsigned char ip_tos;
|
||||
unsigned short ip_len;
|
||||
unsigned short ip_id;
|
||||
unsigned short ip_off;
|
||||
unsigned char ip_ttl;
|
||||
unsigned char ip_p;
|
||||
unsigned short ip_sum;
|
||||
unsigned char ip_src[4];
|
||||
unsigned char ip_dst[4];
|
||||
} __attribute__((__packed__)) ip_header_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char dest_mac[6];
|
||||
unsigned char src_mac[6];
|
||||
unsigned short proto_mac;
|
||||
unsigned short packet_length;
|
||||
ip_header_t iphdr;
|
||||
} __attribute__((__packed__)) transmit_header_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short src_port;
|
||||
unsigned short dst_port;
|
||||
unsigned short udp_len;
|
||||
unsigned short udp_cksum;
|
||||
} __attribute__((__packed__)) udp_header_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short opcode;
|
||||
unsigned short block_num;
|
||||
unsigned char data[512];
|
||||
} __attribute__((__packed__)) tftp_header_t;
|
||||
|
||||
// Preswap bytes
|
||||
#define TFTP_RRQ_OPCODE 0x0100
|
||||
#define TFTP_WRQ_OPCODE 0x0200
|
||||
#define TFTP_DATA_OPCODE 0x0300
|
||||
#define TFTP_ACK_OPCODE 0x0400
|
||||
#define TFTP_ERROR_OPCODE 0x0500
|
||||
|
||||
/* MII registers definition */
|
||||
#define MII_STS_REG 0x01
|
||||
#define MII_STS_LINK_STAT 0x04
|
||||
#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD)
|
||||
#define MII_STS2_REG 0x11
|
||||
#define MII_STS2_LINK 0x400
|
||||
#define MII_STS2_100TX 0x4000
|
||||
#define MII_STS2_FDX 0x200
|
||||
#else
|
||||
#define MII_SPEC_STS_REG 0x11
|
||||
#define MII_SSTS_100FDX 0x8000
|
||||
#define MII_SSTS_100HDX 0x4000
|
||||
#define MII_SSTS_10FDX 0x2000
|
||||
#define MII_SSTS_10HDX 0x1000
|
||||
#endif
|
||||
|
||||
extern unsigned char localMACAddr[6];
|
||||
extern unsigned localMAClow, localMAChigh;
|
||||
extern unsigned localMACSet;
|
||||
#define EMAC_Init()
|
||||
|
||||
#endif /* _EMAC_H_ */
|
@ -1,117 +0,0 @@
|
||||
/*-
|
||||
* 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$
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: emac.c
|
||||
*
|
||||
* Instantiation of routines for MAC/ethernet functions supporting tftp.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 28AUG2004 kb_admin initial creation
|
||||
* 08JAN2005 kb_admin added tftp download
|
||||
* also adapted from external sources
|
||||
*
|
||||
* 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
|
||||
******************************************************************************/
|
||||
|
||||
#include "at91rm9200.h"
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "emac.h"
|
||||
#include "lib.h"
|
||||
|
||||
/* ****************************** GLOBALS *************************************/
|
||||
|
||||
unsigned localMACSet;
|
||||
unsigned char localMACAddr[6];
|
||||
unsigned localMAClow, localMAChigh;
|
||||
|
||||
/* ********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void EMAC_SetMACAddress(unsigned low_address, unsigned high_address)
|
||||
* This global function sets the MAC address. low_address is the first
|
||||
* four bytes while high_address is the last 2 bytes of the 48-bit value.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
EMAC_SetMACAddress(unsigned char mac[6])
|
||||
{
|
||||
AT91PS_PMC pPMC = AT91C_BASE_PMC;
|
||||
AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
|
||||
|
||||
/* enable the peripheral clock before using EMAC */
|
||||
pPMC->PMC_PCER = ((unsigned) 1 << AT91C_ID_EMAC);
|
||||
|
||||
memcpy(localMACAddr, mac, 6);
|
||||
localMAClow = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
|
||||
localMAChigh = (mac[5] << 8) | mac[4];
|
||||
localMACSet = 1;
|
||||
|
||||
AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_EMAC;
|
||||
AT91C_BASE_PIOA->PIO_ASR =
|
||||
AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 |
|
||||
AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 |
|
||||
AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 |
|
||||
AT91C_PIO_PA7;
|
||||
AT91C_BASE_PIOA->PIO_PDR =
|
||||
AT91C_PIO_PA14 | AT91C_PIO_PA12 | AT91C_PIO_PA13 |
|
||||
AT91C_PIO_PA8 | AT91C_PIO_PA16 | AT91C_PIO_PA9 |
|
||||
AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA15 |
|
||||
AT91C_PIO_PA7;
|
||||
#if defined(BOOT_KB920X) | defined(BOOT_BWCT) /* Really !RMII */
|
||||
AT91C_BASE_PIOB->PIO_BSR =
|
||||
AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
|
||||
AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
|
||||
AT91C_PIO_PB18 | AT91C_PIO_PB19;
|
||||
AT91C_BASE_PIOB->PIO_PDR =
|
||||
AT91C_PIO_PB12 | AT91C_PIO_PB13 | AT91C_PIO_PB14 |
|
||||
AT91C_PIO_PB15 | AT91C_PIO_PB16 | AT91C_PIO_PB17 |
|
||||
AT91C_PIO_PB18 | AT91C_PIO_PB19;
|
||||
#endif
|
||||
pEmac->EMAC_CTL = 0;
|
||||
|
||||
pEmac->EMAC_CFG = (pEmac->EMAC_CFG & ~(AT91C_EMAC_CLK)) |
|
||||
#ifdef BOOT_TSC
|
||||
AT91C_EMAC_RMII |
|
||||
#endif
|
||||
AT91C_EMAC_CLK_HCLK_32 | AT91C_EMAC_CAF;
|
||||
// the sequence write EMAC_SA1L and write EMAC_SA1H must be respected
|
||||
pEmac->EMAC_SA1L = localMAClow;
|
||||
pEmac->EMAC_SA1H = localMAChigh;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
#include "lib.h"
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
// Clamp to 20s
|
||||
if (seconds > 20)
|
||||
seconds = 20;
|
||||
thisSecond = GetSeconds();
|
||||
seconds = thisSecond + seconds;
|
||||
do {
|
||||
if ((pUSART->US_CSR & AT91C_US_RXRDY))
|
||||
return (pUSART->US_RHR & 0xFF);
|
||||
thisSecond = GetSeconds();
|
||||
} while (thisSecond != seconds);
|
||||
return (-1);
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*-
|
||||
* 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 putchar(int);
|
||||
void xputchar(int);
|
||||
void printf(const char *fmt,...);
|
||||
|
||||
/* The following function write eeprom at ee_addr using data */
|
||||
/* from data_add for size bytes. */
|
||||
int ReadEEPROM(unsigned eeoff, unsigned char *data_addr, unsigned size);
|
||||
void WriteEEPROM(unsigned eeoff, char *data_addr, unsigned size);
|
||||
void InitEEPROM(void);
|
||||
|
||||
/* XMODEM protocol */
|
||||
int xmodem_rx(char *dst);
|
||||
|
||||
/* */
|
||||
void start_wdog(int n);
|
||||
void reset(void);
|
||||
|
||||
/* Delay us */
|
||||
void Delay(int us);
|
||||
|
||||
#define ToASCII(x) ((x > 9) ? (x + 'A' - 0xa) : (x + '0'))
|
||||
|
||||
int p_IsWhiteSpace(char cValue);
|
||||
unsigned p_HexCharValue(char cValue);
|
||||
unsigned p_ASCIIToHex(const char *buf);
|
||||
unsigned p_ASCIIToDec(const char *buf);
|
||||
|
||||
void p_memset(char *buffer, char value, int size);
|
||||
int p_strlen(const char *buffer);
|
||||
char *strcpy(char *to, const char *from);
|
||||
void memcpy(void *to, const void *from, unsigned size);
|
||||
int p_memcmp(const char *to, const char *from, unsigned size);
|
||||
int strcmp(const char *to, const char *from);
|
||||
|
||||
#endif
|
@ -1,277 +0,0 @@
|
||||
/*-
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef __LIBAT91RM9200_H
|
||||
#define __LIBAT91RM9200_H
|
||||
|
||||
#include "at91rm9200.h"
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PMC_EnablePeriphClock
|
||||
//* \brief Enable peripheral clock
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PMC_EnablePeriphClock (
|
||||
AT91PS_PMC pPMC, // \arg pointer to PMC controller
|
||||
unsigned int periphIds) // \arg IDs of peripherals to enable
|
||||
{
|
||||
pPMC->PMC_PCER = periphIds;
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
SOFTWARE API FOR PIO
|
||||
***************************************************************************** */
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PIO_CfgPeriph
|
||||
//* \brief Enable pins to be drived by peripheral
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline
|
||||
void AT91F_PIO_CfgPeriph(
|
||||
AT91PS_PIO pPio, // \arg pointer to a PIO controller
|
||||
unsigned int periphAEnable, // \arg PERIPH A to enable
|
||||
unsigned int periphBEnable) // \arg PERIPH B to enable
|
||||
|
||||
{
|
||||
if (periphAEnable)
|
||||
pPio->PIO_ASR = periphAEnable;
|
||||
if (periphBEnable)
|
||||
pPio->PIO_BSR = periphBEnable;
|
||||
pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
SOFTWARE API FOR MCI
|
||||
***************************************************************************** */
|
||||
//* Classic MCI Data Timeout Register Configuration with 1048576 MCK cycles between 2 data transfer
|
||||
#define AT91C_MCI_DTOR_1MEGA_CYCLES (AT91C_MCI_DTOCYC | AT91C_MCI_DTOMUL)
|
||||
|
||||
//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot A
|
||||
#define AT91C_MCI_MMC_SLOTA (AT91C_MCI_SCDSEL & 0x0)
|
||||
|
||||
//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot B
|
||||
#define AT91C_MCI_MMC_SLOTB (AT91C_MCI_SCDSEL)
|
||||
|
||||
//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot A
|
||||
#define AT91C_MCI_SDCARD_4BITS_SLOTA ( (AT91C_MCI_SCDSEL & 0x0) | AT91C_MCI_SCDBUS )
|
||||
|
||||
//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot B
|
||||
#define AT91C_MCI_SDCARD_4BITS_SLOTB (AT91C_MCI_SCDSEL | AT91C_MCI_SCDBUS)
|
||||
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_MCI_Configure
|
||||
//* \brief Configure the MCI
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline
|
||||
void AT91F_MCI_Configure(
|
||||
AT91PS_MCI pMCI, // \arg pointer to a MCI controller
|
||||
unsigned int DTOR_register, // \arg Data Timeout Register to be programmed
|
||||
unsigned int MR_register, // \arg Mode Register to be programmed
|
||||
unsigned int SDCR_register) // \arg SDCard Register to be programmed
|
||||
{
|
||||
//* Reset the MCI
|
||||
pMCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN;
|
||||
|
||||
//* Disable all the interrupts
|
||||
pMCI->MCI_IDR = 0xFFFFFFFF;
|
||||
|
||||
//* Set the Data Timeout Register
|
||||
pMCI->MCI_DTOR = DTOR_register;
|
||||
|
||||
//* Set the Mode Register
|
||||
pMCI->MCI_MR = MR_register;
|
||||
|
||||
//* Set the SDCard Register
|
||||
pMCI->MCI_SDCR = SDCR_register;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_MCI_CfgPMC
|
||||
//* \brief Enable Peripheral clock in PMC for MCI
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_MCI_CfgPMC(void)
|
||||
{
|
||||
AT91F_PMC_EnablePeriphClock(
|
||||
AT91C_BASE_PMC, // PIO controller base address
|
||||
((unsigned int) 1 << AT91C_ID_MCI));
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_MCI_CfgPIO
|
||||
//* \brief Configure PIO controllers to drive MCI signals
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_MCI_CfgPIO(void)
|
||||
{
|
||||
// Configure PIO controllers to periph mode
|
||||
AT91F_PIO_CfgPeriph(
|
||||
AT91C_BASE_PIOA, // PIO controller base address
|
||||
((unsigned int) AT91C_PIO_PA28 ) |
|
||||
((unsigned int) AT91C_PIO_PA29 ) |
|
||||
((unsigned int) AT91C_PIO_PA27 ), // Peripheral A
|
||||
0); // Peripheral B
|
||||
// Configure PIO controllers to periph mode
|
||||
AT91F_PIO_CfgPeriph(
|
||||
AT91C_BASE_PIOB, // PIO controller base address
|
||||
0, // Peripheral A
|
||||
((unsigned int) AT91C_PIO_PB5 ) |
|
||||
((unsigned int) AT91C_PIO_PB3 ) |
|
||||
((unsigned int) AT91C_PIO_PB4 )); // Peripheral B
|
||||
}
|
||||
|
||||
|
||||
/* *****************************************************************************
|
||||
SOFTWARE API FOR PDC
|
||||
***************************************************************************** */
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_SetNextRx
|
||||
//* \brief Set the next receive transfer descriptor
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_SetNextRx (
|
||||
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
|
||||
char *address, // \arg address to the next bloc to be received
|
||||
unsigned int bytes) // \arg number of bytes to be received
|
||||
{
|
||||
pPDC->PDC_RNPR = (unsigned int) address;
|
||||
pPDC->PDC_RNCR = bytes;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_SetNextTx
|
||||
//* \brief Set the next transmit transfer descriptor
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_SetNextTx(
|
||||
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
|
||||
char *address, // \arg address to the next bloc to be transmitted
|
||||
unsigned int bytes) // \arg number of bytes to be transmitted
|
||||
{
|
||||
pPDC->PDC_TNPR = (unsigned int) address;
|
||||
pPDC->PDC_TNCR = bytes;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_SetRx
|
||||
//* \brief Set the receive transfer descriptor
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_SetRx(
|
||||
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
|
||||
char *address, // \arg address to the next bloc to be received
|
||||
unsigned int bytes) // \arg number of bytes to be received
|
||||
{
|
||||
pPDC->PDC_RPR = (unsigned int) address;
|
||||
pPDC->PDC_RCR = bytes;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_SetTx
|
||||
//* \brief Set the transmit transfer descriptor
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_SetTx(
|
||||
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
|
||||
char *address, // \arg address to the next bloc to be transmitted
|
||||
unsigned int bytes) // \arg number of bytes to be transmitted
|
||||
{
|
||||
pPDC->PDC_TPR = (unsigned int) address;
|
||||
pPDC->PDC_TCR = bytes;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_EnableTx
|
||||
//* \brief Enable transmit
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_EnableTx(
|
||||
AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
|
||||
{
|
||||
pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_EnableRx
|
||||
//* \brief Enable receive
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_EnableRx(
|
||||
AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
|
||||
{
|
||||
pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_DisableTx
|
||||
//* \brief Disable transmit
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_DisableTx(
|
||||
AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
|
||||
{
|
||||
pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_DisableRx
|
||||
//* \brief Disable receive
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_DisableRx(
|
||||
AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
|
||||
{
|
||||
pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_PDC_Open
|
||||
//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
|
||||
//*----------------------------------------------------------------------------
|
||||
static inline void
|
||||
AT91F_PDC_Open(
|
||||
AT91PS_PDC pPDC) // \arg pointer to a PDC controller
|
||||
{
|
||||
//* Disable the RX and TX PDC transfer requests
|
||||
AT91F_PDC_DisableRx(pPDC);
|
||||
AT91F_PDC_DisableTx(pPDC);
|
||||
|
||||
//* Reset all Counter register Next buffer first
|
||||
AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
|
||||
AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
|
||||
AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
|
||||
AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
|
||||
|
||||
//* Enable the RX and TX PDC transfer requests
|
||||
AT91F_PDC_EnableRx(pPDC);
|
||||
AT91F_PDC_EnableTx(pPDC);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,434 +0,0 @@
|
||||
/*-
|
||||
* 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$
|
||||
*/
|
||||
|
||||
//*---------------------------------------------------------------------------
|
||||
//* ATMEL Microcontroller Software Support - ROUSSET -
|
||||
//*---------------------------------------------------------------------------
|
||||
//* The software is delivered "AS IS" without warranty or condition of any
|
||||
//* kind, either express, implied or statutory. This includes without
|
||||
//* limitation any warranty or condition with respect to merchantability or
|
||||
//* fitness for any particular purpose, or against the infringements of
|
||||
//* intellectual property rights of others.
|
||||
//*---------------------------------------------------------------------------
|
||||
//* File Name : AT91C_MCI_Device.h
|
||||
//* Object : Data Flash Atmel Description File
|
||||
//* Translator :
|
||||
//*
|
||||
//* 1.0 26/11/02 FB : Creation
|
||||
//*---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __MCI_Device_h
|
||||
#define __MCI_Device_h
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef unsigned int AT91S_MCIDeviceStatus;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AT91C_CARD_REMOVED 0
|
||||
#define AT91C_MMC_CARD_INSERTED 1
|
||||
#define AT91C_SD_CARD_INSERTED 2
|
||||
|
||||
#define AT91C_NO_ARGUMENT 0x0
|
||||
|
||||
#define AT91C_FIRST_RCA 0xCAFE
|
||||
#define AT91C_MAX_MCI_CARDS 10
|
||||
|
||||
#define AT91C_BUS_WIDTH_1BIT 0x00
|
||||
#define AT91C_BUS_WIDTH_4BITS 0x02
|
||||
|
||||
/* Driver State */
|
||||
#define AT91C_MCI_IDLE 0x0
|
||||
#define AT91C_MCI_TIMEOUT_ERROR 0x1
|
||||
#define AT91C_MCI_RX_SINGLE_BLOCK 0x2
|
||||
#define AT91C_MCI_RX_MULTIPLE_BLOCK 0x3
|
||||
#define AT91C_MCI_RX_STREAM 0x4
|
||||
#define AT91C_MCI_TX_SINGLE_BLOCK 0x5
|
||||
#define AT91C_MCI_TX_MULTIPLE_BLOCK 0x6
|
||||
#define AT91C_MCI_TX_STREAM 0x7
|
||||
|
||||
/* TimeOut */
|
||||
#define AT91C_TIMEOUT_CMDRDY 30
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MMC & SDCard Structures
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*---------------------------------------------*/
|
||||
/* MCI Device Structure Definition */
|
||||
/*---------------------------------------------*/
|
||||
typedef struct _AT91S_MciDevice
|
||||
{
|
||||
volatile unsigned char state;
|
||||
unsigned char SDCard_bus_width;
|
||||
unsigned char IsSDv2;
|
||||
unsigned char IsSDHC;
|
||||
unsigned int RCA; // RCA
|
||||
unsigned int READ_BL_LEN;
|
||||
#ifdef REPORT_SIZE
|
||||
unsigned int Memory_Capacity;
|
||||
#endif
|
||||
} AT91S_MciDevice;
|
||||
|
||||
#include <dev/mmc/mmcreg.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Functions returnals
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_CMD_SEND_OK 0 // Command ok
|
||||
#define AT91C_CMD_SEND_ERROR -1 // Command failed
|
||||
#define AT91C_INIT_OK 2 // Init Successful
|
||||
#define AT91C_INIT_ERROR 3 // Init Failed
|
||||
#define AT91C_READ_OK 4 // Read Successful
|
||||
#define AT91C_READ_ERROR 5 // Read Failed
|
||||
#define AT91C_WRITE_OK 6 // Write Successful
|
||||
#define AT91C_WRITE_ERROR 7 // Write Failed
|
||||
#define AT91C_ERASE_OK 8 // Erase Successful
|
||||
#define AT91C_ERASE_ERROR 9 // Erase Failed
|
||||
#define AT91C_CARD_SELECTED_OK 10 // Card Selection Successful
|
||||
#define AT91C_CARD_SELECTED_ERROR 11 // Card Selection Failed
|
||||
|
||||
#define AT91C_MCI_SR_ERROR (AT91C_MCI_UNRE | AT91C_MCI_OVRE | AT91C_MCI_DTOE | \
|
||||
AT91C_MCI_DCRCE | AT91C_MCI_RTOE | AT91C_MCI_RENDE | AT91C_MCI_RCRCE | \
|
||||
AT91C_MCI_RDIRE | AT91C_MCI_RINDE)
|
||||
|
||||
#define MMC_CMDNB (0x1Fu << 0) // Command Number
|
||||
#define MMC_RSPTYP (0x3u << 6) // Response Type
|
||||
#define MMC_RSPTYP_NO (0x0u << 6) // No response
|
||||
#define MMC_RSPTYP_48 (0x1u << 6) // 48-bit response
|
||||
#define MMC_RSPTYP_136 (0x2u << 6) // 136-bit response
|
||||
#define MMC_SPCMD (0x7u << 8) // Special CMD
|
||||
#define MMC_SPCMD_NONE (0x0u << 8) // Not a special CMD
|
||||
#define MMC_SPCMD_INIT (0x1u << 8) // Initialization CMD
|
||||
#define MMC_SPCMD_SYNC (0x2u << 8) // Synchronized CMD
|
||||
#define MMC_SPCMD_IT_CMD (0x4u << 8) // Interrupt command
|
||||
#define MMC_SPCMD_IT_REP (0x5u << 8) // Interrupt response
|
||||
#define MMC_OPDCMD (0x1u << 11) // Open Drain Command
|
||||
#define MMC_MAXLAT (0x1u << 12) // Maximum Latency for Command to respond
|
||||
#define MMC_TRCMD (0x3u << 16) // Transfer CMD
|
||||
#define MMC_TRCMD_NO (0x0u << 16) // No transfer
|
||||
#define MMC_TRCMD_START (0x1u << 16) // Start transfer
|
||||
#define MMC_TRCMD_STOP (0x2u << 16) // Stop transfer
|
||||
#define MMC_TRDIR (0x1u << 18) // Transfer Direction
|
||||
#define MMC_TRTYP (0x3u << 19) // Transfer Type
|
||||
#define MMC_TRTYP_BLOCK (0x0u << 19) // Block Transfer type
|
||||
#define MMC_TRTYP_MULTIPLE (0x1u << 19) // Multiple Block transfer type
|
||||
#define MMC_TRTYP_STREAM (0x2u << 19) // Stream transfer type
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MCI_CMD Register Value
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define POWER_ON_INIT \
|
||||
(0 | MMC_TRCMD_NO | MMC_SPCMD_INIT | MMC_OPDCMD)
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Class 0 & 1 commands: Basic commands and Read Stream commands
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#define GO_IDLE_STATE_CMD \
|
||||
(0 | MMC_TRCMD_NO | MMC_SPCMD_NONE )
|
||||
#define MMC_GO_IDLE_STATE_CMD \
|
||||
(0 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_OPDCMD)
|
||||
#define MMC_SEND_OP_COND_CMD \
|
||||
(1 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_OPDCMD)
|
||||
|
||||
#define ALL_SEND_CID_CMD \
|
||||
(2 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136)
|
||||
#define MMC_ALL_SEND_CID_CMD \
|
||||
(2 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \
|
||||
MMC_OPDCMD)
|
||||
|
||||
#define SET_RELATIVE_ADDR_CMD \
|
||||
(3 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT)
|
||||
#define MMC_SET_RELATIVE_ADDR_CMD \
|
||||
(3 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT | MMC_OPDCMD)
|
||||
|
||||
#define SET_DSR_CMD \
|
||||
(4 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_NO | \
|
||||
MMC_MAXLAT) // no tested
|
||||
|
||||
#define SEL_DESEL_CARD_CMD \
|
||||
(7 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT)
|
||||
#define SEND_CSD_CMD \
|
||||
(9 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \
|
||||
MMC_MAXLAT)
|
||||
#define SEND_CID_CMD \
|
||||
(10 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_136 | \
|
||||
MMC_MAXLAT)
|
||||
#define MMC_READ_DAT_UNTIL_STOP_CMD \
|
||||
(11 | MMC_TRTYP_STREAM | MMC_SPCMD_NONE | \
|
||||
MMC_RSPTYP_48 | MMC_TRDIR | MMC_TRCMD_START | \
|
||||
MMC_MAXLAT)
|
||||
|
||||
#define STOP_TRANSMISSION_CMD \
|
||||
(12 | MMC_TRCMD_STOP | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT)
|
||||
#define STOP_TRANSMISSION_SYNC_CMD \
|
||||
(12 | MMC_TRCMD_STOP | MMC_SPCMD_SYNC | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT)
|
||||
#define SEND_STATUS_CMD \
|
||||
(13 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT)
|
||||
#define GO_INACTIVE_STATE_CMD \
|
||||
(15 | MMC_RSPTYP_NO)
|
||||
#define SD_SEND_IF_COND_CMD \
|
||||
(8 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | \
|
||||
MMC_MAXLAT)
|
||||
//*------------------------------------------------
|
||||
//* Class 2 commands: Block oriented Read commands
|
||||
//*------------------------------------------------
|
||||
|
||||
#define SET_BLOCKLEN_CMD (16 | MMC_TRCMD_NO | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_MAXLAT )
|
||||
#define READ_SINGLE_BLOCK_CMD (17 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | MMC_TRTYP_BLOCK | MMC_TRDIR | MMC_MAXLAT)
|
||||
#define READ_MULTIPLE_BLOCK_CMD (18 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | MMC_TRTYP_MULTIPLE | MMC_TRDIR | MMC_MAXLAT)
|
||||
|
||||
//*--------------------------------------------
|
||||
//* Class 3 commands: Sequential write commands
|
||||
//*--------------------------------------------
|
||||
|
||||
#define MMC_WRITE_DAT_UNTIL_STOP_CMD (20 | MMC_TRTYP_STREAM| MMC_SPCMD_NONE | MMC_RSPTYP_48 & ~(MMC_TRDIR) | MMC_TRCMD_START | MMC_MAXLAT ) // MMC
|
||||
|
||||
//*------------------------------------------------
|
||||
//* Class 4 commands: Block oriented write commands
|
||||
//*------------------------------------------------
|
||||
|
||||
#define WRITE_BLOCK_CMD (24 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | (MMC_TRTYP_BLOCK & ~(MMC_TRDIR)) | MMC_MAXLAT)
|
||||
#define WRITE_MULTIPLE_BLOCK_CMD (25 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_START | (MMC_TRTYP_MULTIPLE & ~(MMC_TRDIR)) | MMC_MAXLAT)
|
||||
#define PROGRAM_CSD_CMD (27 | MMC_RSPTYP_48 )
|
||||
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 6 commands: Group Write protect
|
||||
//*----------------------------------------
|
||||
|
||||
#define SET_WRITE_PROT_CMD (28 | MMC_RSPTYP_48 )
|
||||
#define CLR_WRITE_PROT_CMD (29 | MMC_RSPTYP_48 )
|
||||
#define SEND_WRITE_PROT_CMD (30 | MMC_RSPTYP_48 )
|
||||
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 5 commands: Erase commands
|
||||
//*----------------------------------------
|
||||
|
||||
#define TAG_SECTOR_START_CMD (32 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define TAG_SECTOR_END_CMD (33 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define MMC_UNTAG_SECTOR_CMD (34 | MMC_RSPTYP_48 )
|
||||
#define MMC_TAG_ERASE_GROUP_START_CMD (35 | MMC_RSPTYP_48 )
|
||||
#define MMC_TAG_ERASE_GROUP_END_CMD (36 | MMC_RSPTYP_48 )
|
||||
#define MMC_UNTAG_ERASE_GROUP_CMD (37 | MMC_RSPTYP_48 )
|
||||
#define ERASE_CMD (38 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT )
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 7 commands: Lock commands
|
||||
//*----------------------------------------
|
||||
|
||||
#define LOCK_UNLOCK (42 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) // no tested
|
||||
|
||||
//*-----------------------------------------------
|
||||
// Class 8 commands: Application specific commands
|
||||
//*-----------------------------------------------
|
||||
|
||||
#define APP_CMD (55 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define GEN_CMD (56 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT) // no tested
|
||||
|
||||
#define SDCARD_SET_BUS_WIDTH_CMD (6 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define SDCARD_STATUS_CMD (13 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define SDCARD_SEND_NUM_WR_BLOCKS_CMD (22 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define SDCARD_SET_WR_BLK_ERASE_COUNT_CMD (23 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define SDCARD_APP_OP_COND_CMD (41 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define SDCARD_SET_CLR_CARD_DETECT_CMD (42 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
#define SDCARD_SEND_SCR_CMD (51 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
|
||||
#define SDCARD_APP_ALL_CMD (SDCARD_SET_BUS_WIDTH_CMD +\
|
||||
SDCARD_STATUS_CMD +\
|
||||
SDCARD_SEND_NUM_WR_BLOCKS_CMD +\
|
||||
SDCARD_SET_WR_BLK_ERASE_COUNT_CMD +\
|
||||
SDCARD_APP_OP_COND_CMD +\
|
||||
SDCARD_SET_CLR_CARD_DETECT_CMD +\
|
||||
SDCARD_SEND_SCR_CMD)
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 9 commands: IO Mode commands
|
||||
//*----------------------------------------
|
||||
|
||||
#define MMC_FAST_IO_CMD (39 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_MAXLAT)
|
||||
#define MMC_GO_IRQ_STATE_CMD (40 | MMC_SPCMD_NONE | MMC_RSPTYP_48 | MMC_TRCMD_NO | MMC_MAXLAT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OCR Register
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_VDD_16_17 (1 << 4)
|
||||
#define AT91C_VDD_17_18 (1 << 5)
|
||||
#define AT91C_VDD_18_19 (1 << 6)
|
||||
#define AT91C_VDD_19_20 (1 << 7)
|
||||
#define AT91C_VDD_20_21 (1 << 8)
|
||||
#define AT91C_VDD_21_22 (1 << 9)
|
||||
#define AT91C_VDD_22_23 (1 << 10)
|
||||
#define AT91C_VDD_23_24 (1 << 11)
|
||||
#define AT91C_VDD_24_25 (1 << 12)
|
||||
#define AT91C_VDD_25_26 (1 << 13)
|
||||
#define AT91C_VDD_26_27 (1 << 14)
|
||||
#define AT91C_VDD_27_28 (1 << 15)
|
||||
#define AT91C_VDD_28_29 (1 << 16)
|
||||
#define AT91C_VDD_29_30 (1 << 17)
|
||||
#define AT91C_VDD_30_31 (1 << 18)
|
||||
#define AT91C_VDD_31_32 (1 << 19)
|
||||
#define AT91C_VDD_32_33 (1 << 20)
|
||||
#define AT91C_VDD_33_34 (1 << 21)
|
||||
#define AT91C_VDD_34_35 (1 << 22)
|
||||
#define AT91C_VDD_35_36 (1 << 23)
|
||||
#define AT91C_CCS (1 << 30)
|
||||
#define AT91C_CARD_POWER_UP_DONE (1U << 31)
|
||||
|
||||
#define AT91C_MMC_HOST_VOLTAGE_RANGE (AT91C_VDD_27_28 | AT91C_VDD_28_29 | \
|
||||
AT91C_VDD_29_30 | AT91C_VDD_30_31 | AT91C_VDD_31_32 | AT91C_VDD_32_33)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CURRENT_STATE & READY_FOR_DATA in SDCard Status Register definition (response type R1)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_SR_READY_FOR_DATA (1 << 8) // corresponds to buffer empty signalling on the bus
|
||||
#define AT91C_SR_IDLE (0 << 9)
|
||||
#define AT91C_SR_READY (1 << 9)
|
||||
#define AT91C_SR_IDENT (2 << 9)
|
||||
#define AT91C_SR_STBY (3 << 9)
|
||||
#define AT91C_SR_TRAN (4 << 9)
|
||||
#define AT91C_SR_DATA (5 << 9)
|
||||
#define AT91C_SR_RCV (6 << 9)
|
||||
#define AT91C_SR_PRG (7 << 9)
|
||||
#define AT91C_SR_DIS (8 << 9)
|
||||
|
||||
#define AT91C_SR_CARD_SELECTED (AT91C_SR_READY_FOR_DATA + AT91C_SR_TRAN)
|
||||
|
||||
#define MMC_FIRST_RCA 0xCAFE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MMC CSD register header File
|
||||
// CSD_x_xxx_S for shift value for word x
|
||||
// CSD_x_xxx_M for mask value for word x
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// First Response INT <=> CSD[3] : bits 0 to 31
|
||||
#define CSD_3_BIT0_S 0 // [0:0]
|
||||
#define CSD_3_BIT0_M 0x01
|
||||
#define CSD_3_CRC_S 1 // [7:1]
|
||||
#define CSD_3_CRC_M 0x7F
|
||||
#define CSD_3_MMC_ECC_S 8 // [9:8] reserved for MMC compatibility
|
||||
#define CSD_3_MMC_ECC_M 0x03
|
||||
#define CSD_3_FILE_FMT_S 10 // [11:10]
|
||||
#define CSD_3_FILE_FMT_M 0x03
|
||||
#define CSD_3_TMP_WP_S 12 // [12:12]
|
||||
#define CSD_3_TMP_WP_M 0x01
|
||||
#define CSD_3_PERM_WP_S 13 // [13:13]
|
||||
#define CSD_3_PERM_WP_M 0x01
|
||||
#define CSD_3_COPY_S 14 // [14:14]
|
||||
#define CSD_3_COPY_M 0x01
|
||||
#define CSD_3_FILE_FMT_GRP_S 15 // [15:15]
|
||||
#define CSD_3_FILE_FMT_GRP_M 0x01
|
||||
// reserved 16 // [20:16]
|
||||
// reserved 0x1F
|
||||
#define CSD_3_WBLOCK_P_S 21 // [21:21]
|
||||
#define CSD_3_WBLOCK_P_M 0x01
|
||||
#define CSD_3_WBLEN_S 22 // [25:22]
|
||||
#define CSD_3_WBLEN_M 0x0F
|
||||
#define CSD_3_R2W_F_S 26 // [28:26]
|
||||
#define CSD_3_R2W_F_M 0x07
|
||||
#define CSD_3_MMC_DEF_ECC_S 29 // [30:29] reserved for MMC compatibility
|
||||
#define CSD_3_MMC_DEF_ECC_M 0x03
|
||||
#define CSD_3_WP_GRP_EN_S 31 // [31:31]
|
||||
#define CSD_3_WP_GRP_EN_M 0x01
|
||||
|
||||
// Seconde Response INT <=> CSD[2] : bits 32 to 63
|
||||
#define CSD_2_v21_WP_GRP_SIZE_S 0 // [38:32]
|
||||
#define CSD_2_v21_WP_GRP_SIZE_M 0x7F
|
||||
#define CSD_2_v21_SECT_SIZE_S 7 // [45:39]
|
||||
#define CSD_2_v21_SECT_SIZE_M 0x7F
|
||||
#define CSD_2_v21_ER_BLEN_EN_S 14 // [46:46]
|
||||
#define CSD_2_v21_ER_BLEN_EN_M 0x01
|
||||
|
||||
#define CSD_2_v22_WP_GRP_SIZE_S 0 // [36:32]
|
||||
#define CSD_2_v22_WP_GRP_SIZE_M 0x1F
|
||||
#define CSD_2_v22_ER_GRP_SIZE_S 5 // [41:37]
|
||||
#define CSD_2_v22_ER_GRP_SIZE_M 0x1F
|
||||
#define CSD_2_v22_SECT_SIZE_S 10 // [46:42]
|
||||
#define CSD_2_v22_SECT_SIZE_M 0x1F
|
||||
|
||||
#define CSD_2_C_SIZE_M_S 15 // [49:47]
|
||||
#define CSD_2_C_SIZE_M_M 0x07
|
||||
#define CSD_2_VDD_WMAX_S 18 // [52:50]
|
||||
#define CSD_2_VDD_WMAX_M 0x07
|
||||
#define CSD_2_VDD_WMIN_S 21 // [55:53]
|
||||
#define CSD_2_VDD_WMIN_M 0x07
|
||||
#define CSD_2_RCUR_MAX_S 24 // [58:56]
|
||||
#define CSD_2_RCUR_MAX_M 0x07
|
||||
#define CSD_2_RCUR_MIN_S 27 // [61:59]
|
||||
#define CSD_2_RCUR_MIN_M 0x07
|
||||
#define CSD_2_CSIZE_L_S 30 // [63:62] <=> 2 LSB of CSIZE
|
||||
#define CSD_2_CSIZE_L_M 0x03
|
||||
|
||||
// Third Response INT <=> CSD[1] : bits 64 to 95
|
||||
#define CSD_1_CSIZE_H_S 0 // [73:64] <=> 10 MSB of CSIZE
|
||||
#define CSD_1_CSIZE_H_M 0x03FF
|
||||
// reserved 10 // [75:74]
|
||||
// reserved 0x03
|
||||
#define CSD_1_DSR_I_S 12 // [76:76]
|
||||
#define CSD_1_DSR_I_M 0x01
|
||||
#define CSD_1_RD_B_MIS_S 13 // [77:77]
|
||||
#define CSD_1_RD_B_MIS_M 0x01
|
||||
#define CSD_1_WR_B_MIS_S 14 // [78:78]
|
||||
#define CSD_1_WR_B_MIS_M 0x01
|
||||
#define CSD_1_RD_B_PAR_S 15 // [79:79]
|
||||
#define CSD_1_RD_B_PAR_M 0x01
|
||||
#define CSD_1_RD_B_LEN_S 16 // [83:80]
|
||||
#define CSD_1_RD_B_LEN_M 0x0F
|
||||
#define CSD_1_CCC_S 20 // [95:84]
|
||||
#define CSD_1_CCC_M 0x0FFF
|
||||
|
||||
// Fourth Response INT <=> CSD[0] : bits 96 to 127
|
||||
#define CSD_0_TRANS_SPEED_S 0 // [103:96]
|
||||
#define CSD_0_TRANS_SPEED_M 0xFF
|
||||
#define CSD_0_NSAC_S 8 // [111:104]
|
||||
#define CSD_0_NSAC_M 0xFF
|
||||
#define CSD_0_TAAC_S 16 // [119:112]
|
||||
#define CSD_0_TAAC_M 0xFF
|
||||
// reserved 24 // [121:120]
|
||||
// reserved 0x03
|
||||
#define CSD_0_MMC_SPEC_VERS_S 26 // [125:122] reserved for MMC compatibility
|
||||
#define CSD_0_MMC_SPEC_VERS_M 0x0F
|
||||
#define CSD_0_STRUCT_S 30 // [127:126]
|
||||
#define CSD_0_STRUCT_M 0x03
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#endif
|
@ -1,38 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
int
|
||||
p_memcmp(const char *to, const char *from, unsigned size)
|
||||
{
|
||||
while ((--size) && (*to++ == *from++))
|
||||
continue;
|
||||
|
||||
return (size || (*to != *from));
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
void
|
||||
memcpy(void *dst, const void *src, unsigned len)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (len--)
|
||||
*d++ = *s++;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
void
|
||||
p_memset(char *buffer, char value, int size)
|
||||
{
|
||||
while (size--)
|
||||
*buffer++ = value;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: p_string.c
|
||||
*
|
||||
* Instantiation of basic string operations to prevent inclusion of full
|
||||
* string library. These are simple implementations not necessarily optimized
|
||||
* for speed, but rather to show intent.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin minor updates
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void p_memset(char *buffer, char value, int size)
|
||||
* This global function sets memory at the pointer for the specified
|
||||
* number of bytes to value.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
p_memset(char *buffer, char value, int size)
|
||||
{
|
||||
while (size--)
|
||||
*buffer++ = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int p_memcmp(char *to, char *from, unsigned size)
|
||||
* This global function compares data at to against data at from for
|
||||
* size bytes. Returns 0 if the locations are equal. size must be
|
||||
* greater than 0.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
int
|
||||
p_memcmp(const char *to, const char *from, unsigned size)
|
||||
{
|
||||
while ((--size) && (*to++ == *from++))
|
||||
continue;
|
||||
|
||||
return (*to != *from);
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006 M. Warner Losh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are freely
|
||||
* permitted provided that the above copyright notice and this
|
||||
* paragraph and the following disclaimer are duplicated in all
|
||||
* such forms.
|
||||
*
|
||||
* This software is provided "AS IS" and without any express or
|
||||
* implied warranties, including, without limitation, the implied
|
||||
* warranties of merchantability and fitness for a particular
|
||||
* purpose.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "lib.h"
|
||||
|
||||
void
|
||||
printf(const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *hex = "0123456789abcdef";
|
||||
char buf[10];
|
||||
char *s;
|
||||
unsigned u;
|
||||
int c;
|
||||
|
||||
va_start(ap, fmt);
|
||||
while ((c = *fmt++)) {
|
||||
if (c == '%') {
|
||||
c = *fmt++;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
xputchar(va_arg(ap, int));
|
||||
continue;
|
||||
case 's':
|
||||
for (s = va_arg(ap, char *); *s; s++)
|
||||
xputchar(*s);
|
||||
continue;
|
||||
case 'd': /* A lie, always prints unsigned */
|
||||
case 'u':
|
||||
u = va_arg(ap, unsigned);
|
||||
s = buf;
|
||||
do
|
||||
*s++ = '0' + u % 10U;
|
||||
while (u /= 10U);
|
||||
dumpbuf:;
|
||||
while (--s >= buf)
|
||||
xputchar(*s);
|
||||
continue;
|
||||
case 'x':
|
||||
u = va_arg(ap, unsigned);
|
||||
s = buf;
|
||||
do
|
||||
*s++ = hex[u & 0xfu];
|
||||
while (u >>= 4);
|
||||
goto dumpbuf;
|
||||
}
|
||||
}
|
||||
xputchar(c);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
return;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
#include "lib.h"
|
||||
|
||||
/*
|
||||
* void putchar(int ch)
|
||||
* Writes a character to the DBGU port. It assumes that DBGU has
|
||||
* already been initialized.
|
||||
*/
|
||||
void
|
||||
putchar(int ch)
|
||||
{
|
||||
AT91PS_USART pUSART = (AT91PS_USART)AT91C_BASE_DBGU;
|
||||
|
||||
while (!(pUSART->US_CSR & AT91C_US_TXRDY))
|
||||
continue;
|
||||
pUSART->US_THR = (ch & 0xFF);
|
||||
}
|
||||
|
||||
void
|
||||
xputchar(int ch)
|
||||
{
|
||||
if (ch == '\n')
|
||||
putchar('\r');
|
||||
putchar(ch);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*-
|
||||
* 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"
|
||||
|
||||
/*
|
||||
* void reset()
|
||||
*
|
||||
* Forces a reset of the system. Uses watchdog timer of '1', which
|
||||
* corresponds to 128 / SLCK seconds (SLCK is 32,768 Hz, so 128/32768 is
|
||||
* 1 / 256 ~= 5.4ms
|
||||
*/
|
||||
void
|
||||
reset(void)
|
||||
{
|
||||
// The following should effect a reset.
|
||||
AT91C_BASE_ST->ST_WDMR = 1 | AT91C_ST_RSTEN;
|
||||
AT91C_BASE_ST->ST_CR = AT91C_ST_WDRST;
|
||||
}
|
||||
|
||||
/*
|
||||
* void start_wdog()
|
||||
*
|
||||
* Starts a watchdog timer. We force the boot process to get to the point
|
||||
* it can kick the watch dog part of the ST part for the OS's driver.
|
||||
*/
|
||||
void
|
||||
start_wdog(int n)
|
||||
{
|
||||
// The following should effect a reset after N seconds.
|
||||
AT91C_BASE_ST->ST_WDMR = (n * (32768 / 128)) | AT91C_ST_RSTEN;
|
||||
AT91C_BASE_ST->ST_CR = AT91C_ST_WDRST;
|
||||
}
|
@ -1,517 +0,0 @@
|
||||
/*-
|
||||
* 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$
|
||||
*/
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* ATMEL Microcontroller Software Support - ROUSSET -
|
||||
//*----------------------------------------------------------------------------
|
||||
//* The software is delivered "AS IS" without warranty or condition of any
|
||||
//* kind, either express, implied or statutory. This includes without
|
||||
//* limitation any warranty or condition with respect to merchantability or
|
||||
//* fitness for any particular purpose, or against the infringements of
|
||||
//* intellectual property rights of others.
|
||||
//*----------------------------------------------------------------------------
|
||||
//* File Name : main.c
|
||||
//* Object : main application written in C
|
||||
//* Creation : FB 21/11/2002
|
||||
//*
|
||||
//*----------------------------------------------------------------------------
|
||||
#include "at91rm9200.h"
|
||||
#include "lib_AT91RM9200.h"
|
||||
#include "mci_device.h"
|
||||
#include "lib.h"
|
||||
#include "sd-card.h"
|
||||
|
||||
#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */
|
||||
#define SD_BLOCK_SIZE 512
|
||||
|
||||
//* Global Variables
|
||||
static AT91S_MciDevice MCI_Device;
|
||||
|
||||
/******************************************************************************
|
||||
**Error return codes
|
||||
******************************************************************************/
|
||||
#define MCI_UNSUPP_SIZE_ERROR 5
|
||||
#define MCI_UNSUPP_OFFSET_ERROR 6
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCIDeviceWaitReady
|
||||
//* \brief Wait for MCI Device ready
|
||||
//*----------------------------------------------------------------------------
|
||||
static unsigned int
|
||||
MCIDeviceWaitReady(unsigned int timeout)
|
||||
{
|
||||
volatile unsigned int status;
|
||||
int waitfor;
|
||||
|
||||
if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK)
|
||||
waitfor = AT91C_MCI_RXBUFF;
|
||||
else
|
||||
waitfor = AT91C_MCI_NOTBUSY;
|
||||
do
|
||||
{
|
||||
status = AT91C_BASE_MCI->MCI_SR;
|
||||
timeout--;
|
||||
}
|
||||
while( !(status & waitfor) && (timeout>0) );
|
||||
|
||||
status = AT91C_BASE_MCI->MCI_SR;
|
||||
|
||||
// If End of Tx Buffer Empty interrupt occurred
|
||||
if (MCI_Device.state == AT91C_MCI_TX_SINGLE_BLOCK && status & AT91C_MCI_TXBUFE) {
|
||||
AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE;
|
||||
AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS;
|
||||
MCI_Device.state = AT91C_MCI_IDLE;
|
||||
} // End of if AT91C_MCI_TXBUFF
|
||||
|
||||
// If End of Rx Buffer Full interrupt occurred
|
||||
if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK && status & AT91C_MCI_RXBUFF) {
|
||||
AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF;
|
||||
AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
MCI_Device.state = AT91C_MCI_IDLE;
|
||||
} // End of if AT91C_MCI_RXBUFF
|
||||
|
||||
//printf("WaitReady returning status %x\n", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
swap(unsigned int v)
|
||||
{
|
||||
unsigned int t1;
|
||||
|
||||
__asm __volatile("eor %1, %0, %0, ror #16\n"
|
||||
"bic %1, %1, #0x00ff0000\n"
|
||||
"mov %0, %0, ror #8\n"
|
||||
"eor %0, %0, %1, lsr #8\n"
|
||||
: "+r" (v), "=r" (t1));
|
||||
|
||||
return (v);
|
||||
}
|
||||
|
||||
inline static unsigned int
|
||||
wait_ready()
|
||||
{
|
||||
int status;
|
||||
int timeout = AT91C_MCI_TIMEOUT;
|
||||
|
||||
// wait for CMDRDY Status flag to read the response
|
||||
do
|
||||
{
|
||||
status = AT91C_BASE_MCI->MCI_SR;
|
||||
} while( !(status & AT91C_MCI_CMDRDY) && (--timeout > 0) );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_SendCommand
|
||||
//* \brief Generic function to send a command to the MMC or SDCard
|
||||
//*----------------------------------------------------------------------------
|
||||
static int
|
||||
MCI_SendCommand(
|
||||
unsigned int Cmd,
|
||||
unsigned int Arg)
|
||||
{
|
||||
unsigned int error;
|
||||
unsigned int errorMask = AT91C_MCI_SR_ERROR;
|
||||
unsigned int opcode = Cmd & 0x3F;
|
||||
|
||||
//printf("SendCmd %d (%x) arg %x\n", opcode, Cmd, Arg);
|
||||
|
||||
// Don't check response CRC on ACMD41 (R3 response type).
|
||||
|
||||
if (opcode == 41)
|
||||
errorMask &= ~AT91C_MCI_RCRCE;
|
||||
|
||||
AT91C_BASE_MCI->MCI_ARGR = Arg;
|
||||
AT91C_BASE_MCI->MCI_CMDR = Cmd;
|
||||
|
||||
error = wait_ready();
|
||||
|
||||
if ((error & errorMask) != 0) {
|
||||
return (1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_GetStatus
|
||||
//* \brief Addressed card sends its status register
|
||||
//*----------------------------------------------------------------------------
|
||||
static unsigned int
|
||||
MCI_GetStatus()
|
||||
{
|
||||
if (MCI_SendCommand(SEND_STATUS_CMD, MCI_Device.RCA << 16))
|
||||
return 0;
|
||||
return (AT91C_BASE_MCI->MCI_RSPR[0]);
|
||||
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_ReadBlock
|
||||
//* \brief Start the read for a single 512-byte block
|
||||
//*----------------------------------------------------------------------------
|
||||
static int
|
||||
MCI_StartReadBlock(unsigned blknum, void *dataBuffer)
|
||||
{
|
||||
// Init Mode Register
|
||||
AT91C_BASE_MCI->MCI_MR |= ((SD_BLOCK_SIZE << 16) | AT91C_MCI_PDCMODE);
|
||||
|
||||
// (PDC) Receiver Transfer Enable
|
||||
AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS);
|
||||
AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer;
|
||||
AT91C_BASE_PDC_MCI->PDC_RCR = SD_BLOCK_SIZE / 4;
|
||||
AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
|
||||
// SDHC wants block offset, non-HC wants byte offset.
|
||||
if (!MCI_Device.IsSDHC)
|
||||
blknum *= SD_BLOCK_SIZE;
|
||||
|
||||
// Send the Read single block command
|
||||
if (MCI_SendCommand(READ_SINGLE_BLOCK_CMD, blknum)) {
|
||||
return AT91C_READ_ERROR;
|
||||
}
|
||||
MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_readblocks
|
||||
//* \brief Read one or more blocks
|
||||
//*----------------------------------------------------------------------------
|
||||
int
|
||||
MCI_readblocks(char* dest, unsigned blknum, unsigned blkcount)
|
||||
{
|
||||
unsigned int status;
|
||||
unsigned int *walker;
|
||||
|
||||
if (MCI_Device.state != AT91C_MCI_IDLE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// As long as there is data to read
|
||||
while (blkcount)
|
||||
{
|
||||
//Do the reading
|
||||
if (MCI_StartReadBlock(blknum, dest))
|
||||
return -1;
|
||||
|
||||
// Wait MCI Device Ready
|
||||
status = MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
|
||||
if (status & AT91C_MCI_SR_ERROR)
|
||||
return 1;
|
||||
|
||||
// Fix erratum in MCI part - endian-swap all data.
|
||||
for (walker = (unsigned int *)dest;
|
||||
walker < (unsigned int *)(dest + SD_BLOCK_SIZE); walker++)
|
||||
*walker = swap(*walker);
|
||||
|
||||
// Update counters & pointers
|
||||
++blknum;
|
||||
--blkcount;
|
||||
dest += SD_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_read
|
||||
//* \brief Legacy read function, takes byte offset and length but was always
|
||||
//* used to read full blocks; interface preserved for existing boot code.
|
||||
//*----------------------------------------------------------------------------
|
||||
int
|
||||
MCI_read(char* dest, unsigned byteoffset, unsigned length)
|
||||
{
|
||||
return MCI_readblocks(dest,
|
||||
byteoffset/SD_BLOCK_SIZE, length/SD_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_SDCard_SendAppCommand
|
||||
//* \brief Specific function to send a specific command to the SDCard
|
||||
//*----------------------------------------------------------------------------
|
||||
static int
|
||||
MCI_SDCard_SendAppCommand(
|
||||
unsigned int Cmd_App,
|
||||
unsigned int Arg)
|
||||
{
|
||||
int status;
|
||||
|
||||
if ((status = MCI_SendCommand(APP_CMD, (MCI_Device.RCA << 16))) == 0)
|
||||
status = MCI_SendCommand(Cmd_App,Arg);
|
||||
return status;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_GetCSD
|
||||
//* \brief Asks to the specified card to send its CSD
|
||||
//*----------------------------------------------------------------------------
|
||||
static int
|
||||
MCI_GetCSD(unsigned int rca, unsigned int *response)
|
||||
{
|
||||
if (MCI_SendCommand(SEND_CSD_CMD, (rca << 16)))
|
||||
return 1;
|
||||
|
||||
response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
|
||||
response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
|
||||
response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
|
||||
response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_SDCard_GetOCR
|
||||
//* \brief Wait for card to power up and determine whether it's SDHC or not.
|
||||
//*----------------------------------------------------------------------------
|
||||
static int
|
||||
MCI_SDCard_GetOCR()
|
||||
{
|
||||
unsigned int response;
|
||||
unsigned int arg = AT91C_MMC_HOST_VOLTAGE_RANGE;
|
||||
int timeout = AT91C_MCI_TIMEOUT;
|
||||
|
||||
// Force card to idle state.
|
||||
|
||||
MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
|
||||
|
||||
// Begin probe for SDHC by sending CMD8; only v2.0 cards respond to it.
|
||||
//
|
||||
// Arg is vvpp where vv is voltage range and pp is an arbitrary bit
|
||||
// pattern that gets echoed back in the response. The only voltage
|
||||
// ranges defined are:
|
||||
// 0x01 = 2.7 - 3.6
|
||||
// 0x02 = "reserved for low voltage" whatever that means.
|
||||
//
|
||||
// If the card fails to respond then it's not v2.0. If it responds by
|
||||
// echoing back exactly the arg we sent, then it's a v2.0 card and can
|
||||
// run at our voltage. That means that when we send the ACMD41 (in
|
||||
// MCI_SDCard_GetOCR) we can include the HCS bit to inquire about SDHC.
|
||||
|
||||
if (MCI_SendCommand(SD_SEND_IF_COND_CMD, 0x01AA) == 0) {
|
||||
MCI_Device.IsSDv2 = (AT91C_BASE_MCI->MCI_RSPR[0] == 0x01AA);
|
||||
}
|
||||
|
||||
// If we've determined the card supports v2.0 functionality, set the
|
||||
// HCS/CCS bit to indicate that we support SDHC. This will cause a
|
||||
// v2.0 card to report whether it is SDHC in the ACMD41 response.
|
||||
|
||||
if (MCI_Device.IsSDv2) {
|
||||
arg |= AT91C_CCS;
|
||||
}
|
||||
|
||||
// The RCA to be used for CMD55 in Idle state shall be the card's
|
||||
// default RCA=0x0000.
|
||||
|
||||
MCI_Device.RCA = 0x0;
|
||||
|
||||
// Repeat ACMD41 until the card comes out of power-up-busy state.
|
||||
|
||||
do {
|
||||
if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD, arg)) {
|
||||
return 1;
|
||||
}
|
||||
response = AT91C_BASE_MCI->MCI_RSPR[0];
|
||||
} while (!(response & AT91C_CARD_POWER_UP_DONE) && (--timeout > 0));
|
||||
|
||||
// A v2.0 card sets CCS (card capacity status) in the response if it's SDHC.
|
||||
|
||||
if (MCI_Device.IsSDv2) {
|
||||
MCI_Device.IsSDHC = ((response & AT91C_CCS) == AT91C_CCS);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn MCI_SDCard_GetCID
|
||||
//* \brief Asks to the SDCard on the chosen slot to send its CID
|
||||
//*----------------------------------------------------------------------------
|
||||
static int
|
||||
MCI_SDCard_GetCID(unsigned int *response)
|
||||
{
|
||||
if (MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT))
|
||||
return 1;
|
||||
|
||||
response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
|
||||
response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
|
||||
response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
|
||||
response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn sdcard_4wire
|
||||
//* \brief Set bus width to 1-bit or 4-bit according to the parm.
|
||||
//*
|
||||
//* Unlike most functions in this file, the return value from this one is
|
||||
//* bool-ish; returns 0 on failure, 1 on success.
|
||||
//*----------------------------------------------------------------------------
|
||||
int
|
||||
sdcard_use4wire(int use4wire)
|
||||
{
|
||||
volatile int ret_value;
|
||||
|
||||
do {
|
||||
ret_value=MCI_GetStatus();
|
||||
}
|
||||
while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0));
|
||||
|
||||
// If going to 4-wire mode, ask the card to turn off the DAT3 card detect
|
||||
// pullup resistor, if going to 1-wire ask it to turn it back on.
|
||||
|
||||
ret_value = MCI_SDCard_SendAppCommand(SDCARD_SET_CLR_CARD_DETECT_CMD,
|
||||
use4wire ? 0 : 1);
|
||||
if (ret_value != AT91C_CMD_SEND_OK)
|
||||
return 0;
|
||||
|
||||
// Ask the card to go into the requested mode.
|
||||
|
||||
ret_value = MCI_SDCard_SendAppCommand(SDCARD_SET_BUS_WIDTH_CMD,
|
||||
use4wire ? AT91C_BUS_WIDTH_4BITS :
|
||||
AT91C_BUS_WIDTH_1BIT);
|
||||
if (ret_value != AT91C_CMD_SEND_OK)
|
||||
return 0;
|
||||
|
||||
// Set the MCI device to match the mode we set in the card.
|
||||
|
||||
if (use4wire) {
|
||||
MCI_Device.SDCard_bus_width = AT91C_BUS_WIDTH_4BITS;
|
||||
AT91C_BASE_MCI->MCI_SDCR |= AT91C_MCI_SCDBUS;
|
||||
} else {
|
||||
MCI_Device.SDCard_bus_width = AT91C_BUS_WIDTH_1BIT;
|
||||
AT91C_BASE_MCI->MCI_SDCR &= ~AT91C_MCI_SCDBUS;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn sdcard_init
|
||||
//* \brief get the mci device ready to read from an SD or SDHC card.
|
||||
//*
|
||||
//* Unlike most functions in this file, the return value from this one is
|
||||
//* bool-ish; returns 0 on failure, 1 on success.
|
||||
//*----------------------------------------------------------------------------
|
||||
int
|
||||
sdcard_init(void)
|
||||
{
|
||||
unsigned int tab_response[4];
|
||||
int i;
|
||||
|
||||
// Init MCI for MMC and SDCard interface
|
||||
AT91F_MCI_CfgPIO();
|
||||
AT91F_MCI_CfgPMC();
|
||||
AT91F_PDC_Open(AT91C_BASE_PDC_MCI);
|
||||
|
||||
// Init Device Structure
|
||||
MCI_Device.state = AT91C_MCI_IDLE;
|
||||
MCI_Device.SDCard_bus_width = 0;
|
||||
MCI_Device.IsSDv2 = 0;
|
||||
MCI_Device.IsSDHC = 0;
|
||||
|
||||
// Reset the MCI and set the bus speed.
|
||||
// Using MCK/230 gives a legal (under 400khz) bus speed for the card id
|
||||
// sequence for all reasonable master clock speeds.
|
||||
|
||||
AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIDIS | 0x80;
|
||||
AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF;
|
||||
AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES;
|
||||
AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 114; /* clkdiv 114 = MCK/230 */
|
||||
AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_MMC_SLOTA;
|
||||
AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN|AT91C_MCI_PWSEN;
|
||||
|
||||
// Wait for the card to come out of power-up-busy state by repeatedly
|
||||
// sending ACMD41. This also probes for SDHC versus standard cards.
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (MCI_SDCard_GetOCR() == 0)
|
||||
break;
|
||||
if ((i & 0x01) == 0) {
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
if (i >= 100)
|
||||
return 0;
|
||||
|
||||
if (MCI_SDCard_GetCID(tab_response))
|
||||
return 0;
|
||||
|
||||
// Tell the card to set its address, and remember the result.
|
||||
|
||||
if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0))
|
||||
return 0;
|
||||
MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16);
|
||||
|
||||
// After sending CMD3 (set addr) we can increase the clock to full speed.
|
||||
// Using MCK/4 gives a legal (under 25mhz) bus speed for all reasonable
|
||||
// master clock speeds.
|
||||
|
||||
AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 1; /* clkdiv 1 = MCK/4 */
|
||||
|
||||
if (MCI_GetCSD(MCI_Device.RCA,tab_response))
|
||||
return 0;
|
||||
MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) &
|
||||
CSD_1_RD_B_LEN_M;
|
||||
|
||||
#ifdef REPORT_SIZE
|
||||
{
|
||||
unsigned int mult,blocknr;
|
||||
// compute MULT
|
||||
mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) &
|
||||
CSD_2_C_SIZE_M_M) + 2 );
|
||||
// compute MSB of C_SIZE
|
||||
blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) &
|
||||
CSD_1_CSIZE_H_M) << 2;
|
||||
// compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR
|
||||
blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) &
|
||||
CSD_2_CSIZE_L_M)) + 1);
|
||||
MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr;
|
||||
printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Select card and set block length for following transfers.
|
||||
|
||||
if (MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16))
|
||||
return 0;
|
||||
if (MCI_SendCommand(SET_BLOCKLEN_CMD, SD_BLOCK_SIZE))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*-
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef __SD_CARD_H
|
||||
#define __SD_CARD_H
|
||||
|
||||
/* MCI_read() is the original read function, taking a byte offset and byte
|
||||
* count. It is preserved to support existing customized boot code that still
|
||||
* refers to it; it will work fine even on SDHC cards as long as the kernel and
|
||||
* the metadata for locating it all exist within the first 4GB of the card.
|
||||
*
|
||||
* MCI_readblocks() is the new read function, taking offset and length in terms
|
||||
* of block counts (where the SD spec defines a block as 512 bytes), allowing
|
||||
* the kernel and filesystem metadata to be located anywhere on an SDHC card.
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*/
|
||||
|
||||
int MCI_read (char* dest, unsigned bytenum, unsigned length);
|
||||
int MCI_readblocks (char* dest, unsigned blknum, unsigned blkcount);
|
||||
|
||||
/* sdcard_init() - get things set up to read from an SD or SDHC card.
|
||||
*
|
||||
* Returns 0 on failure, non-zero on success.
|
||||
*/
|
||||
|
||||
int sdcard_init(void);
|
||||
|
||||
/* By default sdcard_init() sets things up for a 1-wire interface to the
|
||||
* SD card. Calling sdcard_4wire(true) after sdcard_init() allows customized
|
||||
* boot code to change to 4-bit transfers when the hardware supports it.
|
||||
*
|
||||
* Returns 0 on failure, non-zero on success.
|
||||
*/
|
||||
int sdcard_use4wire(int use4wire);
|
||||
|
||||
#endif
|
||||
|
@ -1,267 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: spi_flash.c
|
||||
*
|
||||
* Instantiation of SPI flash control routines supporting AT45DB161B
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 17JAN2005 kb_admin initial creation
|
||||
* adapted from external sources
|
||||
* tested for basic operation only!!!
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "at91rm9200.h"
|
||||
#include "spi_flash.h"
|
||||
#include "lib.h"
|
||||
|
||||
/*********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
|
||||
static spiCommand_t spi_command;
|
||||
static char tx_commandBuffer[8], rx_commandBuffer[8];
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SendCommand(spiCommand_t *pCommand)
|
||||
* Private function sends 8-bit value to the device and returns the 8-bit
|
||||
* value in response.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
SendCommand(spiCommand_t *pCommand)
|
||||
{
|
||||
AT91PS_SPI pSPI = AT91C_BASE_SPI;
|
||||
|
||||
pSPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;
|
||||
|
||||
pSPI->SPI_RPR = (unsigned)pCommand->rx_cmd;
|
||||
pSPI->SPI_RCR = pCommand->rx_cmd_size;
|
||||
pSPI->SPI_TPR = (unsigned)pCommand->tx_cmd;
|
||||
pSPI->SPI_TCR = pCommand->tx_cmd_size;
|
||||
|
||||
pSPI->SPI_TNPR = (unsigned)pCommand->tx_data;
|
||||
pSPI->SPI_TNCR = pCommand->tx_data_size;
|
||||
pSPI->SPI_RNPR = (unsigned)pCommand->rx_data;
|
||||
pSPI->SPI_RNCR = pCommand->rx_data_size;
|
||||
|
||||
pSPI->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;
|
||||
|
||||
// wait for completion
|
||||
while (!(pSPI->SPI_SR & AT91C_SPI_SPENDRX))
|
||||
Delay(700);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* char GetFlashStatus(void)
|
||||
* Private function to return device status.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static char
|
||||
GetFlashStatus(void)
|
||||
{
|
||||
p_memset((char *)&spi_command, 0, sizeof(spi_command));
|
||||
p_memset(tx_commandBuffer, 0, 8);
|
||||
tx_commandBuffer[0] = STATUS_REGISTER_READ;
|
||||
p_memset(rx_commandBuffer, 0, 8);
|
||||
spi_command.tx_cmd = tx_commandBuffer;
|
||||
spi_command.rx_cmd = rx_commandBuffer;
|
||||
spi_command.rx_cmd_size = 2;
|
||||
spi_command.tx_cmd_size = 2;
|
||||
SendCommand(&spi_command);
|
||||
return (rx_commandBuffer[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void WaitForDeviceReady(void)
|
||||
* Private function to poll until the device is ready for next operation.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
WaitForDeviceReady(void)
|
||||
{
|
||||
while (!(GetFlashStatus() & 0x80)) ;
|
||||
}
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SPI_ReadFlash(unsigned flash_addr, unsigned dest_addr, unsigned size)
|
||||
* Global function to read the SPI flash device using the continuous read
|
||||
* array command.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SPI_ReadFlash(unsigned flash_addr, char *dest_addr, unsigned size)
|
||||
{
|
||||
unsigned pageAddress, byteAddress;
|
||||
|
||||
// determine page address
|
||||
pageAddress = flash_addr / FLASH_PAGE_SIZE;
|
||||
|
||||
// determine byte address
|
||||
byteAddress = flash_addr % FLASH_PAGE_SIZE;
|
||||
|
||||
p_memset(tx_commandBuffer, 0, 8);
|
||||
#ifdef BOOT_BWCT
|
||||
tx_commandBuffer[0] = 0xd2;
|
||||
tx_commandBuffer[1] = ((pageAddress >> 6) & 0xFF);
|
||||
tx_commandBuffer[2] = ((pageAddress << 2) & 0xFC) |
|
||||
((byteAddress >> 8) & 0x3);
|
||||
tx_commandBuffer[3] = byteAddress & 0xFF;
|
||||
spi_command.tx_cmd = tx_commandBuffer;
|
||||
spi_command.tx_cmd_size = 8;
|
||||
spi_command.tx_data_size = size;
|
||||
spi_command.tx_data = dest_addr;
|
||||
|
||||
p_memset(rx_commandBuffer, 0, 8);
|
||||
spi_command.rx_cmd = rx_commandBuffer;
|
||||
spi_command.rx_cmd_size = 8;
|
||||
spi_command.rx_data_size = size;
|
||||
spi_command.rx_data = dest_addr;
|
||||
#else
|
||||
tx_commandBuffer[0] = CONTINUOUS_ARRAY_READ_HF;
|
||||
tx_commandBuffer[1] = ((pageAddress >> 5) & 0xFF);
|
||||
tx_commandBuffer[2] = ((pageAddress << 3) & 0xF8) |
|
||||
((byteAddress >> 8) & 0x7);
|
||||
tx_commandBuffer[3] = byteAddress & 0xFF;
|
||||
spi_command.tx_cmd = tx_commandBuffer;
|
||||
spi_command.tx_cmd_size = 5;
|
||||
spi_command.tx_data_size = size;
|
||||
spi_command.tx_data = dest_addr;
|
||||
|
||||
p_memset(rx_commandBuffer, 0, 8);
|
||||
spi_command.rx_cmd = rx_commandBuffer;
|
||||
spi_command.rx_cmd_size = 5;
|
||||
spi_command.rx_data_size = size;
|
||||
spi_command.rx_data = dest_addr;
|
||||
#endif
|
||||
|
||||
SendCommand(&spi_command);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SPI_WriteFlash(unsigned flash_addr, unsigned src_addr, unsigned size)
|
||||
* Global function to program the SPI flash device. Notice the warning
|
||||
* provided in lower-level functions regarding corruption of data in non-
|
||||
* page aligned write operations.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SPI_WriteFlash(unsigned flash_addr, char *src_addr, unsigned size)
|
||||
{
|
||||
unsigned pageAddress, byteAddress;
|
||||
|
||||
// determine page address
|
||||
pageAddress = flash_addr / FLASH_PAGE_SIZE;
|
||||
|
||||
// determine byte address
|
||||
byteAddress = flash_addr % FLASH_PAGE_SIZE;
|
||||
|
||||
p_memset(tx_commandBuffer, 0, 8);
|
||||
#ifdef BOOT_BWCT
|
||||
tx_commandBuffer[0] = 0x82;
|
||||
tx_commandBuffer[1] = ((pageAddress >> 6) & 0xFF);
|
||||
tx_commandBuffer[2] = ((pageAddress << 2) & 0xFC) |
|
||||
((byteAddress >> 8) & 0x3);
|
||||
tx_commandBuffer[3] = (byteAddress & 0xFF);
|
||||
#else
|
||||
tx_commandBuffer[0] = PROGRAM_THROUGH_BUFFER;
|
||||
tx_commandBuffer[1] = ((pageAddress >> 5) & 0xFF);
|
||||
tx_commandBuffer[2] = ((pageAddress << 3) & 0xF8) |
|
||||
((byteAddress >> 8) & 0x7);
|
||||
tx_commandBuffer[3] = (byteAddress & 0xFF);
|
||||
#endif
|
||||
|
||||
p_memset(rx_commandBuffer, 0, 8);
|
||||
|
||||
spi_command.tx_cmd = tx_commandBuffer;
|
||||
spi_command.rx_cmd = rx_commandBuffer;
|
||||
spi_command.rx_cmd_size = 4;
|
||||
spi_command.tx_cmd_size = 4;
|
||||
|
||||
spi_command.tx_data_size = size;
|
||||
spi_command.tx_data = src_addr;
|
||||
spi_command.rx_data_size = size;
|
||||
spi_command.rx_data = src_addr;
|
||||
|
||||
SendCommand(&spi_command);
|
||||
|
||||
WaitForDeviceReady();
|
||||
}
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SPI_InitFlash(void)
|
||||
* Global function to initialize the SPI flash device/accessor functions.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SPI_InitFlash(void)
|
||||
{
|
||||
AT91PS_PIO pPio;
|
||||
AT91PS_SPI pSPI = AT91C_BASE_SPI;
|
||||
unsigned value;
|
||||
|
||||
// enable CS0, CLK, MOSI, MISO
|
||||
pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
|
||||
pPio->PIO_ASR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 |
|
||||
AT91C_PIO_PA2;
|
||||
pPio->PIO_PDR = AT91C_PIO_PA3 | AT91C_PIO_PA1 | AT91C_PIO_PA0 |
|
||||
AT91C_PIO_PA2;
|
||||
|
||||
// enable clocks to SPI
|
||||
AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_SPI;
|
||||
|
||||
// reset the SPI
|
||||
pSPI->SPI_CR = AT91C_SPI_SWRST;
|
||||
|
||||
pSPI->SPI_MR = (0xf << 24) | AT91C_SPI_MSTR | AT91C_SPI_MODFDIS |
|
||||
(0xE << 16);
|
||||
|
||||
pSPI->SPI_CSR[0] = AT91C_SPI_CPOL | (4 << 16) | (2 << 8);
|
||||
pSPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||
|
||||
pSPI->SPI_PTCR = AT91C_PDC_TXTDIS;
|
||||
pSPI->SPI_PTCR = AT91C_PDC_RXTDIS;
|
||||
pSPI->SPI_RNPR = 0;
|
||||
pSPI->SPI_RNCR = 0;
|
||||
pSPI->SPI_TNPR = 0;
|
||||
pSPI->SPI_TNCR = 0;
|
||||
pSPI->SPI_RPR = 0;
|
||||
pSPI->SPI_RCR = 0;
|
||||
pSPI->SPI_TPR = 0;
|
||||
pSPI->SPI_TCR = 0;
|
||||
pSPI->SPI_PTCR = AT91C_PDC_RXTEN;
|
||||
pSPI->SPI_PTCR = AT91C_PDC_TXTEN;
|
||||
|
||||
value = pSPI->SPI_RDR;
|
||||
value = pSPI->SPI_SR;
|
||||
|
||||
value = GetFlashStatus() & 0xFC;
|
||||
#ifdef BOOT_BWCT
|
||||
if (value != 0xB4 && value != 0xAC)
|
||||
printf(" Bad SPI status: 0x%x\n", value);
|
||||
#else
|
||||
if (value != 0xBC)
|
||||
printf(" Bad SPI status: 0x%x\n", value);
|
||||
#endif
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Filename: spi_flash.h
|
||||
*
|
||||
* Definition of flash control routines supporting AT45DB161B
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 17JAN2005 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _SPI_FLASH_H_
|
||||
#define _SPI_FLASH_H_
|
||||
|
||||
typedef struct {
|
||||
char *tx_cmd;
|
||||
unsigned tx_cmd_size;
|
||||
char *rx_cmd;
|
||||
unsigned rx_cmd_size;
|
||||
char *tx_data;
|
||||
unsigned tx_data_size;
|
||||
char *rx_data;
|
||||
unsigned rx_data_size;
|
||||
} spiCommand_t;
|
||||
|
||||
void SPI_ReadFlash(unsigned flash_addr, char *dest_addr, unsigned size);
|
||||
void SPI_WriteFlash(unsigned flash_addr, char *dest_addr, unsigned size);
|
||||
void SPI_InitFlash(void);
|
||||
|
||||
void SPI_GetId(unsigned *id);
|
||||
|
||||
#ifdef BOOT_BWCT
|
||||
#define FLASH_PAGE_SIZE 528
|
||||
#else
|
||||
#define FLASH_PAGE_SIZE 1056
|
||||
#endif
|
||||
|
||||
// Flash commands
|
||||
|
||||
#define CONTINUOUS_ARRAY_READ 0xE8
|
||||
#define CONTINUOUS_ARRAY_READ_HF 0x0B
|
||||
#define CONTINUOUS_ARRAY_READ_LF 0x03
|
||||
#define STATUS_REGISTER_READ 0xD7
|
||||
#define PROGRAM_THROUGH_BUFFER 0x82
|
||||
#define MANUFACTURER_ID 0x9F
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
int
|
||||
strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
for (; *s1 == *s2 && *s1; s1++, s2++);
|
||||
return (unsigned char)*s1 - (unsigned char)*s2;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
char *
|
||||
strcpy(char *to, const char *from)
|
||||
{
|
||||
while (*from)
|
||||
*to++ = *from++;
|
||||
*to++ = '\0';
|
||||
return (to);
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: p_string.c
|
||||
*
|
||||
* Instantiation of basic string operations to prevent inclusion of full
|
||||
* string library. These are simple implementations not necessarily optimized
|
||||
* for speed, but rather to show intent.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin minor updates
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int p_IsWhiteSpace(char)
|
||||
* This global function returns true if the character is not considered
|
||||
* a non-space character.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
int
|
||||
p_IsWhiteSpace(char cValue)
|
||||
{
|
||||
return ((cValue == ' ') ||
|
||||
(cValue == '\t') ||
|
||||
(cValue == 0) ||
|
||||
(cValue == '\r') ||
|
||||
(cValue == '\n'));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned p_HexCharValue(char)
|
||||
* This global function returns the decimal value of the validated hex char.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
unsigned
|
||||
p_HexCharValue(char cValue)
|
||||
{
|
||||
if (cValue < ('9' + 1))
|
||||
return (cValue - '0');
|
||||
if (cValue < ('F' + 1))
|
||||
return (cValue - 'A' + 10);
|
||||
return (cValue - 'a' + 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned p_ASCIIToHex(char *)
|
||||
* This global function set the unsigned value equal to the converted
|
||||
* hex number passed as a string. No error checking is performed; the
|
||||
* string must be valid hex value, point at the start of string, and be
|
||||
* NULL-terminated.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
unsigned
|
||||
p_ASCIIToHex(const char *buf)
|
||||
{
|
||||
unsigned lValue = 0;
|
||||
|
||||
if ((*buf == '0') && ((buf[1] == 'x') || (buf[1] == 'X')))
|
||||
buf += 2;
|
||||
|
||||
while (*buf) {
|
||||
lValue <<= 4;
|
||||
lValue += p_HexCharValue(*buf++);
|
||||
}
|
||||
return (lValue);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned p_ASCIIToDec(char *)
|
||||
* This global function set the unsigned value equal to the converted
|
||||
* decimal number passed as a string. No error checking is performed; the
|
||||
* string must be valid decimal value, point at the start of string, and be
|
||||
* NULL-terminated.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
unsigned
|
||||
p_ASCIIToDec(const char *buf)
|
||||
{
|
||||
unsigned v = 0;
|
||||
|
||||
while (*buf) {
|
||||
v *= 10;
|
||||
v += (*buf++) - '0';
|
||||
}
|
||||
return (v);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: p_string.c
|
||||
*
|
||||
* Instantiation of basic string operations to prevent inclusion of full
|
||||
* string library. These are simple implementations not necessarily optimized
|
||||
* for speed, but rather to show intent.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin minor updates
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int p_strlen(char *)
|
||||
* This global function returns the number of bytes starting at the pointer
|
||||
* before (not including) the string termination character ('/0').
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
int
|
||||
p_strlen(const char *buffer)
|
||||
{
|
||||
const char *ptr = buffer;
|
||||
while (*ptr++)
|
||||
continue;
|
||||
return (ptr - buffer - 1);
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: tag_list.c
|
||||
*
|
||||
* Instantiation of basic routines that create linux-boot tag list.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 22AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
|
||||
/********************** PRIVATE FUNCTIONS/DATA/DEFINES ***********************/
|
||||
|
||||
#define u32 unsigned
|
||||
#define u16 unsigned short
|
||||
#define u8 unsigned char
|
||||
|
||||
// #include "/usr/src/arm/linux/include/asm/setup.h"
|
||||
#include <linux/asm/setup.h>
|
||||
#include "tag_list.h"
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
#define MEM_SIZE 0x2000000
|
||||
#define PHYS_OFFSET 0x20000000
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void InitTagList(char*, void *)
|
||||
* This global function populates a linux-boot style tag list from the
|
||||
* string passed in the pointer at the location specified.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void InitTagList(char *parms, void *output) {
|
||||
|
||||
char *src, *dst;
|
||||
struct tag *tagList = (struct tag*)output;
|
||||
|
||||
tagList->hdr.size = tag_size(tag_core);
|
||||
tagList->hdr.tag = ATAG_CORE;
|
||||
tagList->u.core.flags = 1;
|
||||
tagList->u.core.pagesize = PAGE_SIZE;
|
||||
tagList->u.core.rootdev = 0xff;
|
||||
tagList = tag_next(tagList);
|
||||
|
||||
tagList->hdr.size = tag_size(tag_mem32);
|
||||
tagList->hdr.tag = ATAG_MEM;
|
||||
tagList->u.mem.size = MEM_SIZE;
|
||||
tagList->u.mem.start = PHYS_OFFSET;
|
||||
tagList = tag_next(tagList);
|
||||
|
||||
tagList->hdr.size = tag_size(tag_cmdline);
|
||||
tagList->hdr.tag = ATAG_CMDLINE;
|
||||
|
||||
src = parms;
|
||||
dst = tagList->u.cmdline.cmdline;
|
||||
while (*src) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst = 0;
|
||||
|
||||
tagList->hdr.size += ((unsigned)(src - parms) + 1) / sizeof(unsigned);
|
||||
tagList = tag_next(tagList);
|
||||
|
||||
tagList->hdr.size = 0;
|
||||
tagList->hdr.tag = ATAG_NONE;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Filename: tag_list.h
|
||||
*
|
||||
* Definition of basic routines that create linux-boot tag list.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 22AUG2004 kb_admin initial creation
|
||||
*
|
||||
* 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$
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _TAG_LIST_H_
|
||||
#define _TAG_LIST_H_
|
||||
|
||||
extern void InitTagList(char *parms, void*);
|
||||
|
||||
#endif /* _TAG_LIST_H_ */
|
@ -1,128 +0,0 @@
|
||||
/*-
|
||||
* 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 */
|
||||
|
||||
#define TO 10
|
||||
/*
|
||||
* 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(TO)) == -1)
|
||||
goto err;
|
||||
if (ch != blocknum)
|
||||
goto err;
|
||||
if ((ch = getc(TO)) == -1)
|
||||
goto err;
|
||||
if (ch != (~blocknum & 0xff))
|
||||
goto err;
|
||||
|
||||
for (size = 0; size < PACKET_SIZE; ++size) {
|
||||
if ((ch = getc(TO)) == -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(TO)) == -1) || ((ch & 0xff) != ((chk >> 8) & 0xFF)))
|
||||
goto err;
|
||||
if (((ch = getc(TO)) == -1) || ((ch & 0xff) != (chk & 0xFF)))
|
||||
goto err;
|
||||
putchar(ACK);
|
||||
|
||||
return (1);
|
||||
err:;
|
||||
putchar(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)
|
||||
putchar('C');
|
||||
if (((ch = getc(1)) == -1) || (ch != SOH && ch != EOT))
|
||||
continue;
|
||||
if (ch == EOT) {
|
||||
putchar(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);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 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)
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = 0;
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.data :
|
||||
{
|
||||
__data_start = . ;
|
||||
*(.data)
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
. = ALIGN(32 / 8);
|
||||
}
|
||||
. = ALIGN(32 / 8);
|
||||
_end = .;
|
||||
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if !target(__ixp425_boot_Makefile.inc__)
|
||||
.PATH: ${.CURDIR}/../../../../libkern ${.CURDIR}/../../../../libkern/arm
|
||||
|
||||
__ixp425_boot_Makefile.inc__:
|
||||
|
||||
# Both Avila and Pronghorn Metro are supported by ixp425
|
||||
BOOT_FLAVOR=ixp425
|
||||
|
||||
CFLAGS+=-Os -ffreestanding \
|
||||
-I${.CURDIR}/../../../.. \
|
||||
-I${.CURDIR}/../../../../arm \
|
||||
-DCPU_XSCALE_IXP425 \
|
||||
-Wall -Waggregate-return \
|
||||
-Werror \
|
||||
-Wnested-externs \
|
||||
-Wpointer-arith -Wshadow -Wwrite-strings \
|
||||
-Wmissing-prototypes \
|
||||
-Wmissing-declarations
|
||||
|
||||
# -Wstrict-prototypes
|
||||
|
||||
CFLAGS+=-DBOOT_${BOOT_FLAVOR:tu}
|
||||
|
||||
LD ?= ld
|
||||
OBJCOPY ?= objcopy
|
||||
|
||||
.if defined(P)
|
||||
${P}: ${OBJS}
|
||||
${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS}
|
||||
|
||||
CLEANFILES+= ${P}
|
||||
.endif
|
||||
|
||||
.if defined(WITH_TAG_LIST)
|
||||
MK_TAG_LIST:=yes
|
||||
.else
|
||||
MK_TAG_LIST:=no
|
||||
.endif
|
||||
|
||||
.endif
|
@ -1,78 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
# We get a lot of the std lib functions from here.
|
||||
.PATH: ${.CURDIR}/../../at91/libat91
|
||||
|
||||
# Enable to get debug msgs
|
||||
#DEBUG=yes
|
||||
|
||||
# Hack to search through the kernel for ufs:ad0s1a and replace it with
|
||||
# the correct one for the active slice/partition.
|
||||
FIXUP_BOOT_DRV=yes
|
||||
|
||||
P=boot2
|
||||
FILES=${P}
|
||||
SRCS=arm_init.S boot2.c ${BOOT_FLAVOR:tl}_board.c
|
||||
SRCS+=memchr.c memcmp.c memcpy.c memmem.c memset.c printf.c strcmp.c strcpy.c
|
||||
SRCS+=strlen.c ashldi3.c divsi3.S muldi3.c
|
||||
SRCS+=aeabi_unwind.c
|
||||
MAN=
|
||||
|
||||
KERNPHYSADDR=0x180000
|
||||
KERNVIRTADDR=${KERNPHYSADDR}
|
||||
BOOT_STACK=0x200000-4
|
||||
M=${MACHINE}
|
||||
LDFLAGS=-e ${KERNPHYSADDR} -EB -T ldscript.${M}
|
||||
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
|
||||
S=${.CURDIR}/../../../..
|
||||
|
||||
CFLAGS+= \
|
||||
-DBOOT_STACK=${BOOT_STACK} \
|
||||
-I${.CURDIR}/../../../common \
|
||||
-I${.CURDIR}
|
||||
|
||||
.if defined(FIXUP_BOOT_DRV)
|
||||
CFLAGS+=-DFIXUP_BOOT_DRV
|
||||
.endif
|
||||
.if defined(DEBUG)
|
||||
CFLAGS+=-DDEBUG
|
||||
.endif
|
||||
|
||||
ldscript.$M: $S/conf/ldscript.$M
|
||||
cat $S/conf/ldscript.$M|sed s/KERNPHYSADDR/${KERNPHYSADDR}/g| \
|
||||
sed s/KERNVIRTADDR/${KERNVIRTADDR}/g | \
|
||||
sed s/" + SIZEOF_HEADERS"// > ldscript.$M
|
||||
|
||||
${P}: ldscript.$M
|
||||
|
||||
CLEANFILES+=ldscript.$M
|
||||
|
||||
memchr.c: $S/../lib/libc/string/memchr.c
|
||||
sed -e 's/string\.h/lib.h/' < $S/../lib/libc/string/memchr.c > \
|
||||
${.TARGET}
|
||||
|
||||
memmem.c: $S/../lib/libc/string/memmem.c
|
||||
sed -e 's/string\.h/lib.h/' < $S/../lib/libc/string/memmem.c > \
|
||||
${.TARGET}
|
||||
|
||||
CLEANFILES+=memchr.c memmem.c
|
||||
|
||||
ashldi3.o: $S/libkern/ashldi3.c
|
||||
${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC}
|
||||
|
||||
divsi3.o: $S/libkern/${M}/divsi3.S
|
||||
${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC}
|
||||
|
||||
muldi3.o: $S/libkern/${M}/muldi3.c
|
||||
${CC} -c ${CFLAGS} -D_KERNEL -o ${.TARGET} ${.IMPSRC}
|
||||
|
||||
inflate.c: $S/kern/inflate.c
|
||||
sed -e 's/extern void putstr (char/extern void putstr (const char/' < \
|
||||
$S/kern/inflate.c > ${.TARGET}
|
||||
|
||||
CLEANFILES+=inflate.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,58 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay. 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 <machine/asm.h>
|
||||
|
||||
ASENTRY_NP(start)
|
||||
/* Initialise bss and sp */
|
||||
nop
|
||||
adr r1, .Lstart
|
||||
ldmia r1, {r1, r2, sp} /* Set initial stack and */
|
||||
sub r2, r2, r1 /* get zero init data */
|
||||
mov r3, #0
|
||||
.L1:
|
||||
str r3, [r1], #0x0004 /* get zero init data */
|
||||
subs r2, r2, #4
|
||||
bgt .L1
|
||||
|
||||
.extern main
|
||||
bl main
|
||||
/* main should not return. If it does, spin forever */
|
||||
infiniteLoop:
|
||||
b infiniteLoop
|
||||
END(start)
|
||||
|
||||
.Lstart:
|
||||
.word _edata
|
||||
.word _end
|
||||
.word BOOT_STACK
|
||||
|
||||
ENTRY(cpu_id)
|
||||
mrc p15, 0, r0, c0, c0, 0
|
||||
RET
|
||||
END(cpu_id)
|
||||
|
||||
/* End */
|
@ -1,446 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are freely
|
||||
* permitted provided that the above copyright notice and this
|
||||
* paragraph and the following disclaimer are duplicated in all
|
||||
* such forms.
|
||||
*
|
||||
* This software is provided "AS IS" and without any express or
|
||||
* implied warranties, including, without limitation, the implied
|
||||
* warranties of merchantability and fitness for a particular
|
||||
* purpose.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <machine/elf.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lib.h"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
#define NOPT 6
|
||||
|
||||
static const char optstr[NOPT] = "agnrsv";
|
||||
static const unsigned char flags[NOPT] = {
|
||||
RBX_ASKNAME,
|
||||
RBX_GDB,
|
||||
RBX_NOINTR,
|
||||
RBX_DFLTROOT,
|
||||
RBX_SINGLE,
|
||||
RBX_VERBOSE
|
||||
};
|
||||
|
||||
static unsigned dsk_start;
|
||||
static char cmd[512];
|
||||
static char kname[1024];
|
||||
static uint32_t opts;
|
||||
static uint8_t dsk_meta;
|
||||
static int bootslice;
|
||||
static int bootpart;
|
||||
static int disk_layout;
|
||||
#define DL_UNKNOWN 0
|
||||
#define DL_RAW 1 /* Dangerously dedicated */
|
||||
#define DL_SLICE 2 /* Use only slices (DOS partitions) */
|
||||
#define DL_SLICEPART 3 /* Use slices and partitions */
|
||||
|
||||
static void load(void);
|
||||
static int parse(void);
|
||||
static int dskread(void *, unsigned, unsigned);
|
||||
static int drvread(void *, unsigned, unsigned);
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
static void fixup_boot_drv(caddr_t, int, int, int);
|
||||
#endif
|
||||
|
||||
#include "ufsread.c"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
|
||||
{
|
||||
if ((size_t)fsread(inode, buf, nbyte) != nbyte)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
getstr(int c)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = cmd;
|
||||
if (c == 0)
|
||||
c = getc(10000);
|
||||
for (;;) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case '\177':
|
||||
case '\b':
|
||||
if (s > cmd) {
|
||||
s--;
|
||||
printf("\b \b");
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
*s = 0;
|
||||
return;
|
||||
default:
|
||||
if (s - cmd < sizeof(cmd) - 1)
|
||||
*s++ = c;
|
||||
xputchar(c);
|
||||
}
|
||||
c = getc(10000);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
const char *bt;
|
||||
int autoboot, c = 0;
|
||||
ufs_ino_t ino;
|
||||
|
||||
dmadat = (void *)(0x1c0000);
|
||||
p_memset((char *)dmadat, 0, 32 * 1024);
|
||||
bt = board_init();
|
||||
|
||||
printf("FreeBSD ARM (%s) boot2 v%d.%d\n", bt, 0, 4);
|
||||
|
||||
autoboot = 1;
|
||||
|
||||
/* Process configuration file */
|
||||
if ((ino = lookup(PATH_CONFIG)) ||
|
||||
(ino = lookup(PATH_DOTCONFIG)))
|
||||
fsread(ino, cmd, sizeof(cmd));
|
||||
|
||||
if (*cmd) {
|
||||
if (parse())
|
||||
autoboot = 0;
|
||||
printf("%s: %s\n", PATH_CONFIG, cmd);
|
||||
/* Do not process this command twice */
|
||||
*cmd = 0;
|
||||
}
|
||||
|
||||
if (*kname == '\0')
|
||||
strcpy(kname, PATH_KERNEL);
|
||||
|
||||
/* Present the user with the boot2 prompt. */
|
||||
for (;;) {
|
||||
printf("\nDefault: %s\nboot: ", kname);
|
||||
if (!autoboot ||
|
||||
(OPT_CHECK(RBX_NOINTR) == 0 && (c = getc(2)) != 0))
|
||||
getstr(c);
|
||||
xputchar('\n');
|
||||
autoboot = 0;
|
||||
c = 0;
|
||||
DPRINTF("cmd is '%s'\n", cmd);
|
||||
if (parse())
|
||||
xputchar('\a');
|
||||
else
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
load(void)
|
||||
{
|
||||
Elf32_Ehdr eh;
|
||||
static Elf32_Phdr ep[2];
|
||||
caddr_t p;
|
||||
ufs_ino_t ino;
|
||||
uint32_t addr;
|
||||
int i, j;
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
caddr_t staddr;
|
||||
int klen;
|
||||
|
||||
staddr = (caddr_t)0xffffffff;
|
||||
klen = 0;
|
||||
#endif
|
||||
if (!(ino = lookup(kname))) {
|
||||
if (!ls)
|
||||
printf("No %s\n", kname);
|
||||
return;
|
||||
}
|
||||
DPRINTF("Found %s\n", kname);
|
||||
if (xfsread(ino, &eh, sizeof(eh)))
|
||||
return;
|
||||
if (!IS_ELF(eh)) {
|
||||
printf("Invalid %s\n", "format");
|
||||
return;
|
||||
}
|
||||
fs_off = eh.e_phoff;
|
||||
for (j = i = 0; i < eh.e_phnum && j < 2; i++) {
|
||||
if (xfsread(ino, ep + j, sizeof(ep[0])))
|
||||
return;
|
||||
if (ep[j].p_type == PT_LOAD)
|
||||
j++;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
p = (caddr_t)(ep[i].p_paddr & 0x0fffffff);
|
||||
fs_off = ep[i].p_offset;
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
if (staddr == (caddr_t)0xffffffff)
|
||||
staddr = p;
|
||||
klen += ep[i].p_filesz;
|
||||
#endif
|
||||
if (xfsread(ino, p, ep[i].p_filesz))
|
||||
return;
|
||||
}
|
||||
addr = eh.e_entry & 0x0fffffff;
|
||||
DPRINTF("Entry point %x for %s\n", addr, kname);
|
||||
clr_board();
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
fixup_boot_drv(staddr, klen, bootslice, bootpart);
|
||||
#endif
|
||||
((void(*)(int))addr)(RB_BOOTINFO /* XXX | (opts & RBX_MASK) */);
|
||||
}
|
||||
|
||||
static int
|
||||
parse()
|
||||
{
|
||||
char *arg = cmd;
|
||||
char *ep, *p;
|
||||
int c, i;
|
||||
|
||||
while ((c = *arg++)) {
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
continue;
|
||||
for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
|
||||
ep = p;
|
||||
if (*p)
|
||||
*p++ = 0;
|
||||
if (c == '-') {
|
||||
while ((c = *arg++)) {
|
||||
for (i = 0; c != optstr[i]; i++)
|
||||
if (i == NOPT - 1)
|
||||
return -1;
|
||||
opts ^= OPT_SET(flags[i]);
|
||||
}
|
||||
} else {
|
||||
arg--;
|
||||
/* look for ad0s1a:... | ad0s1:... */
|
||||
if (strlen(arg) > 6 && arg[0] == 'a' &&
|
||||
arg[1] == 'd' && arg[3] == 's' &&
|
||||
(arg[5] == ':' || arg[6] == ':')) {
|
||||
/* XXX Should also handle disk. */
|
||||
bootslice = arg[4] - '0';
|
||||
if (bootslice < 1 || bootslice > 4)
|
||||
return (-1);
|
||||
bootpart = 0;
|
||||
if (arg[5] != ':')
|
||||
bootpart = arg[5] - 'a';
|
||||
if (bootpart < 0 || bootpart > 7)
|
||||
return (-1);
|
||||
dsk_meta = 0;
|
||||
if (arg[5] == ':')
|
||||
arg += 6;
|
||||
else
|
||||
arg += 7;
|
||||
/* look for ad0a:... */
|
||||
} else if (strlen(arg) > 4 && arg[0] == 'a' &&
|
||||
arg[1] == 'd' && arg[2] == '0' && arg[4] == ':') {
|
||||
bootslice = 0;
|
||||
bootpart = arg[3] - 'a';
|
||||
if (bootpart < 0 || bootpart > 7)
|
||||
return (-1);
|
||||
dsk_meta = 0;
|
||||
arg += 5;
|
||||
}
|
||||
if ((i = ep - arg)) {
|
||||
if ((size_t)i >= sizeof(kname))
|
||||
return -1;
|
||||
memcpy(kname, arg, i + 1);
|
||||
}
|
||||
}
|
||||
arg = p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* dskread() will try to handle the disk layouts that are typically
|
||||
* encountered.
|
||||
* - raw or "Dangerously Dedicated" mode. No real slice table, just the
|
||||
* default one that is included with bsdlabel -B. Typically this is
|
||||
* used with ROOTDEVNAME=\"ufs:ad0a\".
|
||||
* - slice only. Only a slice table is installed with no bsd label or
|
||||
* bsd partition table. This is typically used with
|
||||
* ROOTDEVNAME=\"ufs:ad0s1\".
|
||||
* - slice + bsd label + partition table. This is typically done with
|
||||
* with fdisk + bsdlabel and is used with ROOTDEVNAME=\"ufs:ad0s1a\".
|
||||
*/
|
||||
static int
|
||||
dskread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
struct dos_partition *dp;
|
||||
struct disklabel *d;
|
||||
char *sec;
|
||||
int i;
|
||||
|
||||
if (!dsk_meta) {
|
||||
sec = dmadat->secbuf;
|
||||
dsk_start = 0;
|
||||
if (drvread(sec, DOSBBSECTOR, 1))
|
||||
return -1;
|
||||
dp = (void *)(sec + DOSPARTOFF);
|
||||
if (bootslice != 0) {
|
||||
i = bootslice - 1;
|
||||
if (dp[i].dp_typ != DOSPTYP_386BSD)
|
||||
return -1;
|
||||
} else {
|
||||
for (i = 0; i < NDOSPART; i++) {
|
||||
if ((dp[i].dp_typ == DOSPTYP_386BSD) &&
|
||||
(dp[i].dp_flag == 0x80))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != NDOSPART) {
|
||||
bootslice = i + 1;
|
||||
DPRINTF("Found an active fbsd slice. (%d)\n", i + 1);
|
||||
/*
|
||||
* Although dp_start is aligned within the disk
|
||||
* partition structure, DOSPARTOFF is 446, which
|
||||
* is only word (2) aligned, not longword (4)
|
||||
* aligned. Cope by using memcpy to fetch the
|
||||
* start of this partition.
|
||||
*/
|
||||
memcpy(&dsk_start, &dp[i].dp_start, 4);
|
||||
dsk_start = swap32(dsk_start);
|
||||
DPRINTF("dsk_start %x\n", dsk_start);
|
||||
if ((bootslice == 4) && (dsk_start == 0)) {
|
||||
disk_layout = DL_RAW;
|
||||
bootslice = 0;
|
||||
}
|
||||
}
|
||||
if (drvread(sec, dsk_start + LABELSECTOR, 1))
|
||||
return -1;
|
||||
d = (void *)(sec + LABELOFFSET);
|
||||
if ((d->d_magic == DISKMAGIC && d->d_magic2 == DISKMAGIC) ||
|
||||
(swap32(d->d_magic) == DISKMAGIC &&
|
||||
swap32(d->d_magic2) == DISKMAGIC)) {
|
||||
DPRINTF("p_size = %x\n",
|
||||
!d->d_partitions[bootpart].p_size);
|
||||
if (!d->d_partitions[bootpart].p_size) {
|
||||
printf("Invalid partition\n");
|
||||
return -1;
|
||||
}
|
||||
DPRINTF("p_offset %x, RAW %x\n",
|
||||
swap32(d->d_partitions[bootpart].p_offset),
|
||||
swap32(d->d_partitions[RAW_PART].p_offset));
|
||||
dsk_start += swap32(d->d_partitions[bootpart].p_offset);
|
||||
dsk_start -= swap32(d->d_partitions[RAW_PART].p_offset);
|
||||
if ((disk_layout == DL_UNKNOWN) && (bootslice == 0))
|
||||
disk_layout = DL_RAW;
|
||||
else if (disk_layout == DL_UNKNOWN)
|
||||
disk_layout = DL_SLICEPART;
|
||||
} else {
|
||||
disk_layout = DL_SLICE;
|
||||
DPRINTF("Invalid %s\n", "label");
|
||||
}
|
||||
DPRINTF("bootslice %d, bootpart %d, dsk_start %u\n", bootslice,
|
||||
bootpart, dsk_start);
|
||||
dsk_meta++;
|
||||
}
|
||||
return drvread(buf, dsk_start + lba, nblk);
|
||||
}
|
||||
|
||||
static int
|
||||
drvread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
static unsigned c = 0x2d5c7c2f;
|
||||
|
||||
printf("%c\b", c = c << 8 | c >> 24);
|
||||
return (avila_read((char *)buf, lba, nblk));
|
||||
}
|
||||
|
||||
#ifdef FIXUP_BOOT_DRV
|
||||
/*
|
||||
* fixup_boot_drv() will try to find the ROOTDEVNAME spec in the kernel
|
||||
* and change it to what was specified on the comandline or /boot.conf
|
||||
* file or to what was encountered on the disk. It will try to handle 3
|
||||
* different disk layouts, raw (dangerously dedicated), slice only and
|
||||
* slice + partition. It will look for the following strings in the
|
||||
* kernel, but if it is one of the first three, the string in the kernel
|
||||
* must use the correct form to match the actual disk layout:
|
||||
* - ufs:ad0a
|
||||
* - ufs:ad0s1
|
||||
* - ufs:ad0s1a
|
||||
* - ufs:ROOTDEVNAME
|
||||
* In the case of the first three strings, only the "a" at the end and
|
||||
* the "1" after the "s" will be modified, if they exist. The string
|
||||
* length will not be changed. In the case of the last string, the
|
||||
* whole string will be built up and nul, '\0' terminated.
|
||||
*/
|
||||
static void
|
||||
fixup_boot_drv(caddr_t addr, int klen, int bs, int bp)
|
||||
{
|
||||
const u_int8_t op[] = "ufs:ROOTDEVNAME";
|
||||
const u_int8_t op2[] = "ufs:ad0";
|
||||
u_int8_t *p, *ps;
|
||||
|
||||
DPRINTF("fixup_boot_drv: 0x%x, %d, slice %d, partition %d\n",
|
||||
(int)addr, klen, bs, bp);
|
||||
if (bs > 4)
|
||||
return;
|
||||
if (bp > 7)
|
||||
return;
|
||||
ps = memmem(addr, klen, op, sizeof(op));
|
||||
if (ps != NULL) {
|
||||
p = ps + 4; /* past ufs: */
|
||||
DPRINTF("Found it at 0x%x\n", (int)ps);
|
||||
p[0] = 'a'; p[1] = 'd'; p[2] = '0'; /* ad0 */
|
||||
p += 3;
|
||||
if (bs > 0) {
|
||||
/* append slice */
|
||||
*p++ = 's';
|
||||
*p++ = bs + '0';
|
||||
}
|
||||
if (disk_layout != DL_SLICE) {
|
||||
/* append partition */
|
||||
*p++ = bp + 'a';
|
||||
}
|
||||
*p = '\0';
|
||||
} else {
|
||||
ps = memmem(addr, klen, op2, sizeof(op2) - 1);
|
||||
if (ps != NULL) {
|
||||
p = ps + sizeof(op2) - 1;
|
||||
DPRINTF("Found it at 0x%x\n", (int)ps);
|
||||
if (*p == 's') {
|
||||
/* fix slice */
|
||||
p++;
|
||||
*p++ = bs + '0';
|
||||
}
|
||||
if (*p == 'a')
|
||||
*p = bp + 'a';
|
||||
}
|
||||
}
|
||||
if (ps == NULL) {
|
||||
printf("Could not locate \"%s\" to fix kernel boot device, "
|
||||
"check ROOTDEVNAME is set\n", op);
|
||||
return;
|
||||
}
|
||||
DPRINTF("Changed boot device to %s\n", ps);
|
||||
}
|
||||
#endif
|
@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay. 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_CF_ATA_H
|
||||
#define ARM_BOOT_CF_ATA_H
|
||||
|
||||
#define CF_DATA 0x00
|
||||
#define CF_ERROR 0x01
|
||||
#define CF_FEATURE 0x01
|
||||
#define CF_SECT_CNT 0x02
|
||||
#define CF_SECT_NUM 0x03
|
||||
#define CF_CYL_L 0x04
|
||||
#define CF_CYL_H 0x05
|
||||
#define CF_DRV_HEAD 0x06
|
||||
#define CF_D_MASTER 0x00
|
||||
#define CF_D_LBA 0x40
|
||||
#define CF_D_IBM 0xa0
|
||||
#define CF_STATUS 0x07
|
||||
#define CF_S_ERROR 0x01
|
||||
#define CF_S_INDEX 0x02
|
||||
#define CF_S_CORR 0x04
|
||||
#define CF_S_DRQ 0x08
|
||||
#define CF_S_DSC 0x10
|
||||
#define CF_S_DWF 0x20
|
||||
#define CF_S_READY 0x40
|
||||
#define CF_S_BUSY 0x80
|
||||
#define CF_COMMAND 0x07
|
||||
|
||||
/* This is according to the appnote, but Sam use 0x1e in avila_ata.c */
|
||||
#define CF_ALT_STATUS 0x16
|
||||
#define CF_ALT_DEV_CTR 0x16
|
||||
#define CF_ALT_DEV_CTR2 0x1e
|
||||
#define CF_A_IDS 0x02
|
||||
#define CF_A_RESET 0x04
|
||||
#define CF_A_4BIT 0x08
|
||||
|
||||
#define AVILA_IDE_GPIN 12
|
||||
|
||||
#endif /* !ARM_BOOT_CF_ATA_H */
|
@ -1,771 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/ata.h>
|
||||
#include <sys/linker_set.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lib.h"
|
||||
#include "cf_ata.h"
|
||||
|
||||
#include <machine/armreg.h>
|
||||
#include <arm/xscale/ixp425/ixp425reg.h>
|
||||
#include <dev/ic/ns16550.h>
|
||||
|
||||
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;
|
||||
|
||||
static u_int8_t uart_getreg(u_int8_t *, int);
|
||||
static void uart_setreg(u_int8_t *, int, u_int8_t);
|
||||
|
||||
static void cf_init(void);
|
||||
static void cf_clr(void);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
const char *
|
||||
board_init(void)
|
||||
{
|
||||
struct board_config **pbp;
|
||||
|
||||
cputype = cpu_id() & CPU_ID_CPU_MASK;
|
||||
|
||||
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 "???";
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be called just before starting the kernel. This is so
|
||||
* that one can undo incompatible hardware settings.
|
||||
*/
|
||||
void
|
||||
clr_board(void)
|
||||
{
|
||||
cf_clr();
|
||||
}
|
||||
|
||||
/*
|
||||
* General support functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DELAY should delay for the number of microseconds.
|
||||
* The idea is that the inner loop should take 1us, so val is the
|
||||
* number of usecs to delay.
|
||||
*/
|
||||
void
|
||||
DELAY(int val)
|
||||
{
|
||||
volatile int sub;
|
||||
volatile int subsub;
|
||||
|
||||
sub = val;
|
||||
while(sub) {
|
||||
subsub = 3;
|
||||
while(subsub)
|
||||
subsub--;
|
||||
sub--;
|
||||
}
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
swap32(u_int32_t a)
|
||||
{
|
||||
return (((a & 0xff) << 24) | ((a & 0xff00) << 8) |
|
||||
((a & 0xff0000) >> 8) | ((a & 0xff000000) >> 24));
|
||||
}
|
||||
|
||||
u_int16_t
|
||||
swap16(u_int16_t val)
|
||||
{
|
||||
return (val << 8) | (val >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* uart related funcs
|
||||
*/
|
||||
static u_int8_t
|
||||
uart_getreg(u_int8_t *bas, int off)
|
||||
{
|
||||
return *((volatile u_int32_t *)(bas + (off << 2))) & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
uart_setreg(u_int8_t *bas, int off, u_int8_t val)
|
||||
{
|
||||
*((volatile u_int32_t *)(bas + (off << 2))) = (u_int32_t)val;
|
||||
}
|
||||
|
||||
int
|
||||
getc(int seconds)
|
||||
{
|
||||
int c, delay, limit;
|
||||
|
||||
c = 0;
|
||||
delay = 10000;
|
||||
limit = seconds * 1000000/10000;
|
||||
while ((uart_getreg(ubase, REG_LSR) & LSR_RXRDY) == 0 && --limit)
|
||||
DELAY(delay);
|
||||
|
||||
if ((uart_getreg(ubase, REG_LSR) & LSR_RXRDY) == LSR_RXRDY)
|
||||
c = uart_getreg(ubase, REG_DATA);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
putchar(int ch)
|
||||
{
|
||||
int delay, limit;
|
||||
|
||||
delay = 500;
|
||||
limit = 20;
|
||||
while ((uart_getreg(ubase, REG_LSR) & LSR_THRE) == 0 && --limit)
|
||||
DELAY(delay);
|
||||
uart_setreg(ubase, REG_DATA, ch);
|
||||
|
||||
limit = 40;
|
||||
while ((uart_getreg(ubase, REG_LSR) & LSR_TEMT) == 0 && --limit)
|
||||
DELAY(delay);
|
||||
}
|
||||
|
||||
void
|
||||
xputchar(int ch)
|
||||
{
|
||||
if (ch == '\n')
|
||||
putchar('\r');
|
||||
putchar(ch);
|
||||
}
|
||||
|
||||
void
|
||||
putstr(const char *str)
|
||||
{
|
||||
while(*str)
|
||||
xputchar(*str++);
|
||||
}
|
||||
|
||||
void
|
||||
puthex8(u_int8_t ch)
|
||||
{
|
||||
const char *hex = "0123456789abcdef";
|
||||
|
||||
putchar(hex[ch >> 4]);
|
||||
putchar(hex[ch & 0xf]);
|
||||
}
|
||||
|
||||
void
|
||||
puthexlist(const u_int8_t *str, int length)
|
||||
{
|
||||
while(length) {
|
||||
puthex8(*str);
|
||||
putchar(' ');
|
||||
str++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* CF/IDE functions.
|
||||
*
|
||||
*/
|
||||
|
||||
struct {
|
||||
u_int64_t dsize;
|
||||
u_int64_t total_secs;
|
||||
u_int8_t heads;
|
||||
u_int8_t sectors;
|
||||
u_int32_t cylinders;
|
||||
|
||||
u_int32_t *cs1to;
|
||||
u_int32_t *cs2to;
|
||||
|
||||
u_int8_t *cs1;
|
||||
u_int8_t *cs2;
|
||||
|
||||
u_int32_t use_lba;
|
||||
u_int32_t use_stream8;
|
||||
u_int32_t debug;
|
||||
|
||||
u_int8_t status;
|
||||
u_int8_t error;
|
||||
} dskinf;
|
||||
|
||||
static void cfenable16(void);
|
||||
static void cfdisable16(void);
|
||||
static u_int8_t cfread8(u_int32_t off);
|
||||
static u_int16_t cfread16(u_int32_t off);
|
||||
static void cfreadstream8(void *buf, int length);
|
||||
static void cfreadstream16(void *buf, int length);
|
||||
static void cfwrite8(u_int32_t off, u_int8_t val);
|
||||
static u_int8_t cfaltread8(u_int32_t off);
|
||||
static void cfaltwrite8(u_int32_t off, u_int8_t val);
|
||||
static int cfwait(u_int8_t mask);
|
||||
static int cfaltwait(u_int8_t mask);
|
||||
static int cfcmd(u_int32_t cmd, u_int32_t cylinder, u_int32_t head,
|
||||
u_int32_t sector, u_int32_t count, u_int32_t feature);
|
||||
static void cfreset(void);
|
||||
#ifdef DEBUG
|
||||
static int cfgetparams(void);
|
||||
#endif
|
||||
static void cfprintregs(void);
|
||||
|
||||
static void
|
||||
cf_init(void)
|
||||
{
|
||||
u_int8_t status;
|
||||
#ifdef DEBUG
|
||||
int rval;
|
||||
#endif
|
||||
|
||||
/* NB: board init routines setup other parts of dskinf */
|
||||
dskinf.use_stream8 = 0;
|
||||
dskinf.use_lba = 0;
|
||||
dskinf.debug = 1;
|
||||
|
||||
DPRINTF("cs1 %x, cs2 %x\n", dskinf.cs1, dskinf.cs2);
|
||||
|
||||
/* Setup the CF window */
|
||||
*dskinf.cs1to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
|
||||
DPRINTF("t1 %x, ", *dskinf.cs1to);
|
||||
|
||||
*dskinf.cs2to |= (EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
|
||||
DPRINTF("t2 %x\n", *dskinf.cs2to);
|
||||
|
||||
/* Detect if there is a disk. */
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
DELAY(1000);
|
||||
status = cfread8(CF_STATUS);
|
||||
if (status != 0x50)
|
||||
printf("cf-ata0 %x\n", (u_int32_t)status);
|
||||
if (status == 0xff) {
|
||||
printf("cf_ata0: No disk!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cfreset();
|
||||
|
||||
if (dskinf.use_stream8) {
|
||||
DPRINTF("setting %d bit mode.\n", 8);
|
||||
cfwrite8(CF_FEATURE, 0x01); /* Enable 8 bit transfers */
|
||||
cfwrite8(CF_COMMAND, ATA_SETFEATURES);
|
||||
cfaltwait(CF_S_READY);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
rval = cfgetparams();
|
||||
if (rval)
|
||||
return;
|
||||
#endif
|
||||
dskinf.use_lba = 1;
|
||||
dskinf.debug = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cf_clr(void)
|
||||
{
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
cfaltwait(CF_S_READY);
|
||||
cfwrite8(CF_FEATURE, 0x81); /* Enable 8 bit transfers */
|
||||
cfwrite8(CF_COMMAND, ATA_SETFEATURES);
|
||||
cfaltwait(CF_S_READY);
|
||||
}
|
||||
|
||||
static void
|
||||
cfenable16(void)
|
||||
{
|
||||
u_int32_t val;
|
||||
|
||||
val = *dskinf.cs1to;
|
||||
*dskinf.cs1to = val &~ EXP_BYTE_EN;
|
||||
DELAY(100);
|
||||
#if 0
|
||||
DPRINTF("%s: cs1 timing reg %x\n", *dskinf.cs1to, __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
cfdisable16(void)
|
||||
{
|
||||
u_int32_t val;
|
||||
|
||||
DELAY(100);
|
||||
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
|
||||
cfread8(u_int32_t off)
|
||||
{
|
||||
volatile u_int8_t *vp;
|
||||
|
||||
vp = (volatile u_int8_t *)(dskinf.cs1 + off);
|
||||
return *vp;
|
||||
}
|
||||
|
||||
static void
|
||||
cfreadstream8(void *buf, int length)
|
||||
{
|
||||
u_int8_t *lbuf;
|
||||
u_int8_t tmp;
|
||||
|
||||
lbuf = buf;
|
||||
while (length) {
|
||||
tmp = cfread8(CF_DATA);
|
||||
*lbuf = tmp;
|
||||
#ifdef DEBUG
|
||||
if (dskinf.debug && (length > (512 - 32))) {
|
||||
if ((length % 16) == 0)
|
||||
xputchar('\n');
|
||||
puthex8(tmp);
|
||||
putchar(' ');
|
||||
}
|
||||
#endif
|
||||
lbuf++;
|
||||
length--;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (dskinf.debug)
|
||||
xputchar('\n');
|
||||
#endif
|
||||
}
|
||||
|
||||
static u_int16_t
|
||||
cfread16(u_int32_t off)
|
||||
{
|
||||
volatile u_int16_t *vp;
|
||||
|
||||
vp = (volatile u_int16_t *)(dskinf.cs1 + off);
|
||||
return swap16(*vp);
|
||||
}
|
||||
|
||||
static void
|
||||
cfreadstream16(void *buf, int length)
|
||||
{
|
||||
u_int16_t *lbuf;
|
||||
|
||||
length = length / 2;
|
||||
cfenable16();
|
||||
lbuf = buf;
|
||||
while (length--) {
|
||||
*lbuf = cfread16(CF_DATA);
|
||||
lbuf++;
|
||||
}
|
||||
cfdisable16();
|
||||
}
|
||||
|
||||
static void
|
||||
cfwrite8(u_int32_t off, u_int8_t val)
|
||||
{
|
||||
volatile u_int8_t *vp;
|
||||
|
||||
vp = (volatile u_int8_t *)(dskinf.cs1 + off);
|
||||
*vp = val;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
cfwrite16(u_int32_t off, u_int16_t val)
|
||||
{
|
||||
volatile u_int16_t *vp;
|
||||
|
||||
vp = (volatile u_int16_t *)(dskinf.cs1 + off);
|
||||
*vp = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static u_int8_t
|
||||
cfaltread8(u_int32_t off)
|
||||
{
|
||||
volatile u_int8_t *vp;
|
||||
|
||||
off &= 0x0f;
|
||||
vp = (volatile u_int8_t *)(dskinf.cs2 + off);
|
||||
return *vp;
|
||||
}
|
||||
|
||||
static void
|
||||
cfaltwrite8(u_int32_t off, u_int8_t val)
|
||||
{
|
||||
volatile u_int8_t *vp;
|
||||
|
||||
/*
|
||||
* This is documented in the Intel appnote 302456.
|
||||
*/
|
||||
off &= 0x0f;
|
||||
vp = (volatile u_int8_t *)(dskinf.cs2 + off);
|
||||
*vp = val;
|
||||
}
|
||||
|
||||
static int
|
||||
cfwait(u_int8_t mask)
|
||||
{
|
||||
u_int8_t status;
|
||||
u_int32_t tout;
|
||||
|
||||
tout = 0;
|
||||
while (tout <= 5000000) {
|
||||
status = cfread8(CF_STATUS);
|
||||
if (status == 0xff) {
|
||||
printf("%s: master: no status, reselecting\n",
|
||||
__func__);
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
DELAY(1);
|
||||
status = cfread8(CF_STATUS);
|
||||
}
|
||||
if (status == 0xff)
|
||||
return -1;
|
||||
dskinf.status = status;
|
||||
if (!(status & CF_S_BUSY)) {
|
||||
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("%s: status 0x%x mask 0x%x tout %u\n",
|
||||
__func__, status, mask, tout);
|
||||
return (status & CF_S_ERROR);
|
||||
}
|
||||
}
|
||||
if (tout > 1000) {
|
||||
tout += 1000;
|
||||
DELAY(1000);
|
||||
} else {
|
||||
tout += 10;
|
||||
DELAY(10);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
cfaltwait(u_int8_t mask)
|
||||
{
|
||||
u_int8_t status;
|
||||
u_int32_t tout;
|
||||
|
||||
tout = 0;
|
||||
while (tout <= 5000000) {
|
||||
status = cfaltread8(CF_ALT_STATUS);
|
||||
if (status == 0xff) {
|
||||
printf("cfaltwait: master: no status, reselecting\n");
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
DELAY(1);
|
||||
status = cfread8(CF_STATUS);
|
||||
}
|
||||
if (status == 0xff)
|
||||
return -1;
|
||||
dskinf.status = status;
|
||||
if (!(status & CF_S_BUSY)) {
|
||||
if (status & CF_S_ERROR)
|
||||
dskinf.error = cfread8(CF_ERROR);
|
||||
if ((status & mask) == mask) {
|
||||
DPRINTF("cfaltwait: tout %u\n", tout);
|
||||
return (status & CF_S_ERROR);
|
||||
}
|
||||
}
|
||||
if (tout > 1000) {
|
||||
tout += 1000;
|
||||
DELAY(1000);
|
||||
} else {
|
||||
tout += 10;
|
||||
DELAY(10);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
cfcmd(u_int32_t cmd, u_int32_t cylinder, u_int32_t head, u_int32_t sector,
|
||||
u_int32_t count, u_int32_t feature)
|
||||
{
|
||||
if (cfwait(0) < 0) {
|
||||
printf("cfcmd: timeout\n");
|
||||
return -1;
|
||||
}
|
||||
cfwrite8(CF_FEATURE, feature);
|
||||
cfwrite8(CF_CYL_L, cylinder);
|
||||
cfwrite8(CF_CYL_H, cylinder >> 8);
|
||||
if (dskinf.use_lba)
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM | CF_D_LBA | head);
|
||||
else
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM | head);
|
||||
cfwrite8(CF_SECT_NUM, sector);
|
||||
cfwrite8(CF_SECT_CNT, count);
|
||||
cfwrite8(CF_COMMAND, cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cfreset(void)
|
||||
{
|
||||
u_int8_t status;
|
||||
u_int32_t tout;
|
||||
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
DELAY(1);
|
||||
#ifdef DEBUG
|
||||
cfprintregs();
|
||||
#endif
|
||||
cfread8(CF_STATUS);
|
||||
cfaltwrite8(CF_ALT_DEV_CTR, CF_A_IDS | CF_A_RESET);
|
||||
DELAY(10000);
|
||||
cfaltwrite8(CF_ALT_DEV_CTR, CF_A_IDS);
|
||||
DELAY(10000);
|
||||
cfread8(CF_ERROR);
|
||||
DELAY(3000);
|
||||
|
||||
for (tout = 0; tout < 310000; tout++) {
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
DELAY(1);
|
||||
status = cfread8(CF_STATUS);
|
||||
if (!(status & CF_S_BUSY))
|
||||
break;
|
||||
DELAY(100);
|
||||
}
|
||||
DELAY(1);
|
||||
if (status & CF_S_BUSY) {
|
||||
cfprintregs();
|
||||
printf("cfreset: Status stayed busy after reset.\n");
|
||||
}
|
||||
DPRINTF("cfreset: finished, tout %u\n", tout);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static int
|
||||
cfgetparams(void)
|
||||
{
|
||||
u_int8_t *buf;
|
||||
|
||||
buf = (u_int8_t *)(0x170000);
|
||||
p_memset((char *)buf, 0, 1024);
|
||||
/* Select the drive. */
|
||||
cfwrite8(CF_DRV_HEAD, CF_D_IBM);
|
||||
DELAY(1);
|
||||
cfcmd(ATA_ATA_IDENTIFY, 0, 0, 0, 0, 0);
|
||||
if (cfaltwait(CF_S_READY | CF_S_DSC | CF_S_DRQ)) {
|
||||
printf("cfgetparams: ATA_IDENTIFY failed.\n");
|
||||
return -1;
|
||||
}
|
||||
if (dskinf.use_stream8)
|
||||
cfreadstream8(buf, 512);
|
||||
else
|
||||
cfreadstream16(buf, 512);
|
||||
if (dskinf.debug)
|
||||
cfprintregs();
|
||||
#if 0
|
||||
memcpy(&dskinf.ata_params, buf, sizeof(struct ata_params));
|
||||
dskinf.cylinders = dskinf.ata_params.cylinders;
|
||||
dskinf.heads = dskinf.ata_params.heads;
|
||||
dskinf.sectors = dskinf.ata_params.sectors;
|
||||
printf("dsk0: sec %x, hd %x, cyl %x, stat %x, err %x\n",
|
||||
(u_int32_t)dskinf.ata_params.sectors,
|
||||
(u_int32_t)dskinf.ata_params.heads,
|
||||
(u_int32_t)dskinf.ata_params.cylinders,
|
||||
(u_int32_t)dskinf.status,
|
||||
(u_int32_t)dskinf.error);
|
||||
#endif
|
||||
dskinf.status = cfread8(CF_STATUS);
|
||||
if (dskinf.debug)
|
||||
printf("cfgetparams: ata_params * %x, stat %x\n",
|
||||
(u_int32_t)buf, (u_int32_t)dskinf.status);
|
||||
return 0;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
static void
|
||||
cfprintregs(void)
|
||||
{
|
||||
u_int8_t rv;
|
||||
|
||||
putstr("cfprintregs: regs error ");
|
||||
rv = cfread8(CF_ERROR);
|
||||
puthex8(rv);
|
||||
putstr(", count ");
|
||||
rv = cfread8(CF_SECT_CNT);
|
||||
puthex8(rv);
|
||||
putstr(", sect ");
|
||||
rv = cfread8(CF_SECT_NUM);
|
||||
puthex8(rv);
|
||||
putstr(", cyl low ");
|
||||
rv = cfread8(CF_CYL_L);
|
||||
puthex8(rv);
|
||||
putstr(", cyl high ");
|
||||
rv = cfread8(CF_CYL_H);
|
||||
puthex8(rv);
|
||||
putstr(", drv head ");
|
||||
rv = cfread8(CF_DRV_HEAD);
|
||||
puthex8(rv);
|
||||
putstr(", status ");
|
||||
rv = cfread8(CF_STATUS);
|
||||
puthex8(rv);
|
||||
putstr("\n");
|
||||
}
|
||||
|
||||
int
|
||||
avila_read(char *dest, unsigned source, unsigned length)
|
||||
{
|
||||
if (dskinf.use_lba == 0 && source == 0)
|
||||
source++;
|
||||
if (dskinf.debug)
|
||||
printf("avila_read: 0x%x, sect %d num secs %d\n",
|
||||
(u_int32_t)dest, source, length);
|
||||
while (length) {
|
||||
cfwait(CF_S_READY);
|
||||
/* cmd, cyl, head, sect, count, feature */
|
||||
cfcmd(ATA_READ, (source >> 8) & 0xffff, source >> 24,
|
||||
source & 0xff, 1, 0);
|
||||
|
||||
cfwait(CF_S_READY | CF_S_DRQ | CF_S_DSC);
|
||||
if (dskinf.use_stream8)
|
||||
cfreadstream8(dest, 512);
|
||||
else
|
||||
cfreadstream16(dest, 512);
|
||||
length--;
|
||||
source++;
|
||||
dest += 512;
|
||||
}
|
||||
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");
|
@ -1,67 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay. 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
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
int main(void);
|
||||
|
||||
void DELAY(int);
|
||||
|
||||
int getc(int);
|
||||
void putchar(int);
|
||||
void xputchar(int);
|
||||
void putstr(const char *);
|
||||
void puthex8(u_int8_t);
|
||||
void puthexlist(const u_int8_t *, int);
|
||||
void printf(const char *fmt,...);
|
||||
|
||||
void bzero(void *, size_t);
|
||||
char *strcpy(char *to, const char *from);
|
||||
int strcmp(const char *to, const char *from);
|
||||
int p_strlen(const char *);
|
||||
int p_memcmp(const char *, const char *, unsigned);
|
||||
void *memchr(const void *, int, size_t);
|
||||
void memcpy(void *to, const void *from, unsigned size);
|
||||
void *memmem(const void *, size_t, const void *, size_t);
|
||||
void p_memset(char *buffer, char value, int size);
|
||||
|
||||
#define strlen p_strlen
|
||||
#define memcmp p_memcmp
|
||||
#define memset p_memset
|
||||
|
||||
u_int16_t swap16(u_int16_t);
|
||||
u_int32_t swap32(u_int32_t);
|
||||
|
||||
const char *board_init(void);
|
||||
void clr_board(void);
|
||||
int avila_read(char*, unsigned, unsigned);
|
||||
u_int cpu_id(void);
|
||||
|
||||
#endif /* !ARM_BOOT_LIB_H */
|
Loading…
Reference in New Issue
Block a user