|
From: Erik M. <er...@us...> - 2001-08-06 22:44:55
|
Update of /cvsroot/blob/blob/src
In directory usw-pr-cvs1:/tmp/cvs-serv26030/src
Modified Files:
Makefile.am clock.c command.c flash.c led.c main.c serial.c
start.S time.c util.c uucodec.c
Added Files:
flashasm.S ledasm.S linux.c memory.c memsetup.S rest-ld-script
start-ld-script testmem.S testmem2.S trampoline.S
Removed Files:
ld-script
Log Message:
Here we go: merge the blob_1_0_9_hack branch back into the HEAD branch
Index: flashasm.S
===================================================================
RCS file: flashasm.S
diff -N flashasm.S
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsgmVRnq Mon Aug 6 15:44:54 2001
@@ -0,0 +1,190 @@
+/*
+ * flashasm.S: flash magic for LART
+ *
+ * Copyright (C) 1999 2000 2001 Jan-Derk bakker (J.D...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+.ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+.text
+
+
+.globl data_to_flash
+.globl data_from_flash
+ /* Subroutine that takes data in r0 and formats it so it will be in */
+ /* the correct order for the internal flash */
+ /* used for LART only */
+data_to_flash:
+#if defined LART
+ mov r1, #0x0
+
+ tst r0, #0x00000001
+ orrne r1, r1, #0x00001000
+ tst r0, #0x00000002
+ orrne r1, r1, #0x00004000
+ tst r0, #0x00000004
+ orrne r1, r1, #0x00000800
+ tst r0, #0x00000008
+ orrne r1, r1, #0x00000200
+ tst r0, #0x00000010
+ orrne r1, r1, #0x00000001
+ tst r0, #0x00000020
+ orrne r1, r1, #0x00000004
+ tst r0, #0x00000040
+ orrne r1, r1, #0x00000080
+ tst r0, #0x00000080
+ orrne r1, r1, #0x00000020
+
+ tst r0, #0x00000100
+ orrne r1, r1, #0x00002000
+ tst r0, #0x00000200
+ orrne r1, r1, #0x00008000
+ tst r0, #0x00000400
+ orrne r1, r1, #0x00000400
+ tst r0, #0x00000800
+ orrne r1, r1, #0x00000100
+ tst r0, #0x00001000
+ orrne r1, r1, #0x00000002
+ tst r0, #0x00002000
+ orrne r1, r1, #0x00000008
+ tst r0, #0x00004000
+ orrne r1, r1, #0x00000040
+ tst r0, #0x00008000
+ orrne r1, r1, #0x00000010
+
+ tst r0, #0x00010000
+ orrne r1, r1, #0x00100000
+ tst r0, #0x00020000
+ orrne r1, r1, #0x00400000
+ tst r0, #0x00040000
+ orrne r1, r1, #0x00080000
+ tst r0, #0x00080000
+ orrne r1, r1, #0x00020000
+ tst r0, #0x00100000
+ orrne r1, r1, #0x01000000
+ tst r0, #0x00200000
+ orrne r1, r1, #0x04000000
+ tst r0, #0x00400000
+ orrne r1, r1, #0x80000000
+ tst r0, #0x00800000
+ orrne r1, r1, #0x20000000
+
+ tst r0, #0x01000000
+ orrne r1, r1, #0x00200000
+ tst r0, #0x02000000
+ orrne r1, r1, #0x00800000
+ tst r0, #0x04000000
+ orrne r1, r1, #0x00040000
+ tst r0, #0x08000000
+ orrne r1, r1, #0x00010000
+ tst r0, #0x10000000
+ orrne r1, r1, #0x02000000
+ tst r0, #0x20000000
+ orrne r1, r1, #0x08000000
+ tst r0, #0x40000000
+ orrne r1, r1, #0x40000000
+ tst r0, #0x80000000
+ orrne r1, r1, #0x10000000
+
+ mov r0, r1
+#endif
+ mov pc, r14
+
+ /* Takes data received from the flash, and unshuffles it. */
+data_from_flash:
+#if defined LART
+ mov r1, #0x00
+
+ tst r0, #0x00000001
+ orrne r1, r1, #0x00000010
+ tst r0, #0x00000002
+ orrne r1, r1, #0x00001000
+ tst r0, #0x00000004
+ orrne r1, r1, #0x00000020
+ tst r0, #0x00000008
+ orrne r1, r1, #0x00002000
+ tst r0, #0x00000010
+ orrne r1, r1, #0x00008000
+ tst r0, #0x00000020
+ orrne r1, r1, #0x00000080
+ tst r0, #0x00000040
+ orrne r1, r1, #0x00004000
+ tst r0, #0x00000080
+ orrne r1, r1, #0x00000040
+
+ tst r0, #0x00000100
+ orrne r1, r1, #0x00000800
+ tst r0, #0x00000200
+ orrne r1, r1, #0x00000008
+ tst r0, #0x00000400
+ orrne r1, r1, #0x00000400
+ tst r0, #0x00000800
+ orrne r1, r1, #0x00000004
+ tst r0, #0x00001000
+ orrne r1, r1, #0x00000001
+ tst r0, #0x00002000
+ orrne r1, r1, #0x00000100
+ tst r0, #0x00004000
+ orrne r1, r1, #0x00000002
+ tst r0, #0x00008000
+ orrne r1, r1, #0x00000200
+
+ tst r0, #0x00010000
+ orrne r1, r1, #0x08000000
+ tst r0, #0x00020000
+ orrne r1, r1, #0x00080000
+ tst r0, #0x00040000
+ orrne r1, r1, #0x04000000
+ tst r0, #0x00080000
+ orrne r1, r1, #0x00040000
+ tst r0, #0x00100000
+ orrne r1, r1, #0x00010000
+ tst r0, #0x00200000
+ orrne r1, r1, #0x01000000
+ tst r0, #0x00400000
+ orrne r1, r1, #0x00020000
+ tst r0, #0x00800000
+ orrne r1, r1, #0x02000000
+
+ tst r0, #0x01000000
+ orrne r1, r1, #0x00100000
+ tst r0, #0x02000000
+ orrne r1, r1, #0x10000000
+ tst r0, #0x04000000
+ orrne r1, r1, #0x00200000
+ tst r0, #0x08000000
+ orrne r1, r1, #0x20000000
+ tst r0, #0x10000000
+ orrne r1, r1, #0x80000000
+ tst r0, #0x20000000
+ orrne r1, r1, #0x00800000
+ tst r0, #0x40000000
+ orrne r1, r1, #0x40000000
+ tst r0, #0x80000000
+ orrne r1, r1, #0x00400000
+
+ mov r0, r1
+#endif
+ mov pc, r14
+
+
+
Index: ledasm.S
===================================================================
RCS file: ledasm.S
diff -N ledasm.S
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsVaCKDr Mon Aug 6 15:44:54 2001
@@ -0,0 +1,82 @@
+/*
+ * ledasm.S: simple LED control code
+ *
+ * Copyright (C) 2001 Erik Mouw (J.A...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/*
+ * Documentation:
+ * [1] Intel Corporation, "Intel StrongARM SA-1100 Microprocessor
+ * Developer's Manual", April 1999
+ * [2] Intel Corporation, "Intel StrongARM SA-1110 Microprocessor
+ * Advanced Developer's manual, December 1999
+ */
+
+.ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define ASSEMBLY
+#include "led.h"
+
+
+
+.text
+
+LED: .long LED_GPIO
+GPIO_BASE: .long 0x90040000
+#define GPDR 0x00000004
+#define GPSR 0x00000008
+#define GPCR 0x0000000c
+
+
+
+
+.globl ledinit
+ /* initialise LED GPIO and turn LED on.
+ * clobbers r0 and r1
+ */
+ledinit:
+ ldr r0, GPIO_BASE
+ ldr r1, LED
+ str r1, [r0, #GPDR] /* LED GPIO is output */
+ str r1, [r0, #GPSR] /* turn LED on */
+ mov pc, lr
+
+
+
+
+.globl led_on
+ /* turn LED on. clobbers r0 and r1 */
+led_on:
+ ldr r0, GPIO_BASE
+ ldr r1, LED
+ str r1, [r0, #GPSR]
+ mov pc, lr
+
+
+
+
+.globl led_off
+ /* turn LED off. clobbers r0 and r1 */
+led_off:
+ ldr r0, GPIO_BASE
+ ldr r1, LED
+ str r1, [r0, #GPCR]
+ mov pc, lr
Index: linux.c
===================================================================
RCS file: linux.c
diff -N linux.c
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsmK81Iq Mon Aug 6 15:44:54 2001
@@ -0,0 +1,169 @@
+/*
+ * linux.c: support functions for booting a kernel
+ *
+ * Copyright (C) 2001 Erik Mouw (J.A...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "linux.h"
+#include "main.h"
+#include "flash.h"
+#include "memory.h"
+#include "serial.h"
+#include "util.h"
+
+#include <asm/setup.h>
+
+
+static void setup_start_tag(void);
+static void setup_memory_tags(void);
+static void setup_commandline_tag(char *commandline);
+static void setup_ramdisk_tag(void);
+static void setup_initrd_tag(void);
+static void setup_end_tag(void);
+
+
+static struct tag *params;
+
+
+void boot_linux(char *commandline)
+{
+ register u32 i;
+ void (*theKernel)(int zero, int arch) = (void (*)(int, int))KERNEL_RAM_BASE;
+
+ setup_start_tag();
+ setup_memory_tags();
+ setup_commandline_tag(commandline);
+ setup_initrd_tag();
+ setup_ramdisk_tag();
+ setup_end_tag();
+
+ /* we assume that the kernel is in place */
+ SerialOutputString("\nStarting kernel ...\n\n");
+
+ /* turn off I-cache */
+ asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));
+ i &= ~0x1000;
+ asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));
+
+ /* flush I-cache */
+ asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));
+
+ theKernel(0, ARCH_NUMBER);
+
+ SerialOutputString("Hey, the kernel returned! This should not happen.\n");
+}
+
+
+static void setup_start_tag(void)
+{
+ params = (struct tag *)BOOT_PARAMS;
+
+ params->hdr.tag = ATAG_CORE;
+ params->hdr.size = tag_size(tag_core);
+
+ params->u.core.flags = 0;
+ params->u.core.pagesize = 0;
+ params->u.core.rootdev = 0;
+
+ params = tag_next(params);
+}
+
+
+static void setup_memory_tags(void)
+{
+ int i;
+
+ for(i = 0; i < NUM_MEM_AREAS; i++) {
+ if(memory_map[i].used) {
+ params->hdr.tag = ATAG_MEM;
+ params->hdr.size = tag_size(tag_mem32);
+
+ params->u.mem.start = memory_map[i].start;
+ params->u.mem.size = memory_map[i].len;
+
+ params = tag_next(params);
+ }
+ }
+}
+
+
+static void setup_commandline_tag(char *commandline)
+{
+ char *p;
+
+ /* eat leading white space */
+ for(p = commandline; *p == ' '; p++)
+ ;
+
+ /* skip non-existent command lines so the kernel will still
+ * use its default command line.
+ */
+ if(*p == '\0')
+ return;
+
+ params->hdr.tag = ATAG_CMDLINE;
+ params->hdr.size = (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
+
+ strcpy(params->u.cmdline.cmdline, p);
+
+ params = tag_next(params);
+}
+
+
+static void setup_initrd_tag(void)
+{
+ /* an ATAG_INITRD node tells the kernel where the compressed
+ * ramdisk can be found. ATAG_RDIMG is a better name, actually.
+ */
+ params->hdr.tag = ATAG_INITRD;
+ params->hdr.size = tag_size(tag_initrd);
+
+ params->u.initrd.start = RAMDISK_RAM_BASE;
+ params->u.initrd.size = INITRD_LEN;
+
+ params = tag_next(params);
+}
+
+
+static void setup_ramdisk_tag(void)
+{
+ /* an ATAG_RAMDISK node tells the kernel how large the
+ * decompressed ramdisk will become.
+ */
+ params->hdr.tag = ATAG_RAMDISK;
+ params->hdr.size = tag_size(tag_ramdisk);
+
+ params->u.ramdisk.start = 0;
+ params->u.ramdisk.size = RAMDISK_SIZE;
+ params->u.ramdisk.flags = 1; /* automatically load ramdisk */
+
+ params = tag_next(params);
+}
+
+
+static void setup_end_tag(void)
+{
+ params->hdr.tag = ATAG_NONE;
+ params->hdr.size = 0;
+}
Index: memory.c
===================================================================
RCS file: memory.c
diff -N memory.c
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvswY83qs Mon Aug 6 15:44:54 2001
@@ -0,0 +1,115 @@
+/*
+ * memory.c: memory test routines for the blob bootloader
+ *
+ * Copyright (C) 2001 Erik Mouw (J.A...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "main.h"
+#include "memory.h"
+#include "serial.h"
+
+/* test in 1MB chunks */
+#define TEST_BLOCK_SIZE (1024 * 1024)
+
+
+
+
+/* from testmem2.S */
+extern int testram(u32 addr);
+
+
+
+
+memory_area_t memory_map[NUM_MEM_AREAS];
+
+
+
+
+void get_memory_map(void)
+{
+ u32 addr;
+ int i;
+
+ /* init */
+ for(i = 0; i < NUM_MEM_AREAS; i++)
+ memory_map[i].used = 0;
+
+ /* first write a 0 to all memory locations */
+ for(addr = MEMORY_START; addr < MEMORY_END; addr += TEST_BLOCK_SIZE)
+ * (u32 *)addr = 0;
+
+ /* scan memory in blocks */
+ i = 0;
+ for(addr = MEMORY_START; addr < MEMORY_END; addr += TEST_BLOCK_SIZE) {
+ if(testram(addr) == 0) {
+ /* yes, memory */
+ if(* (u32 *)addr != 0) { /* alias? */
+#ifdef BLOB_DEBUG
+ SerialOutputString("Detected alias at 0x");
+ SerialOutputHex(addr);
+ SerialOutputString(", aliased from 0x");
+ SerialOutputHex(* (u32 *)addr);
+ SerialOutputByte('\n');
+#endif
+ if(memory_map[i].used)
+ i++;
+
+ continue;
+ }
+
+ /* not an alias, write the current address */
+ * (u32 *)addr = addr;
+#ifdef BLOB_DEBUG
+ SerialOutputString("Detected memory at 0x");
+ SerialOutputHex(addr);
+ SerialOutputByte('\n');
+#endif
+ /* does this start a new block? */
+ if(memory_map[i].used == 0) {
+ memory_map[i].start = addr;
+ memory_map[i].len = TEST_BLOCK_SIZE;
+ memory_map[i].used = 1;
+ } else {
+ memory_map[i].len += TEST_BLOCK_SIZE;
+ }
+ } else {
+ /* no memory here */
+ if(memory_map[i].used == 1)
+ i++;
+ }
+ }
+
+ SerialOutputString("Memory map:\n");
+ for(i = 0; i < NUM_MEM_AREAS; i++) {
+ if(memory_map[i].used) {
+ SerialOutputString(" 0x");
+ SerialOutputHex(memory_map[i].len);
+ SerialOutputString(" @ 0x");
+ SerialOutputHex(memory_map[i].start);
+ SerialOutputString(" (");
+ SerialOutputDec(memory_map[i].len / (1024 * 1024));
+ SerialOutputString(" MB)\n");
+ }
+ }
+}
Index: memsetup.S
===================================================================
RCS file: memsetup.S
diff -N memsetup.S
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsjPbkQr Mon Aug 6 15:44:54 2001
@@ -0,0 +1,219 @@
+/*
+ * memsetup.S: memory setup for various architectures
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A...@it...) and
+ * Jan-Derk Bakker (J.D...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/*
+ * Documentation:
+ * [1] Intel Corporation, "Intel StrongARM SA-1100 Microprocessor
+ * Developer's Manual", April 1999
+ * [2] Intel Corporation, "Intel StrongARM SA-1110 Microprocessor
+ * Advanced Developer's manual, December 1999
+ */
+
+.ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+
+
+.text
+
+
+
+
+MEM_BASE: .long 0xa0000000
+MEM_START: .long 0xc0000000
+#define MDCNFG 0x0
+#define MDCAS0 0x04
+#define MDCAS1 0x08
+#define MDCAS2 0x0c
+#define MCS0 0x10
+
+
+
+
+#if (defined BRUTUS)
+mdcas0: .long 0xc71c703f
+mdcas1: .long 0xffc71c71
+mdcas2: .long 0xffffffff
+mdcnfg: .long 0x0334b22f
+mcs0: .long 0xfff8fff8
+#endif
+
+#if (defined NESA)
+mdcas0: .long 0xc71c703f
+mdcas1: .long 0xffc71c71
+mdcas2: .long 0xffffffff
+mdcnfg: .long 0x0334b22f
+mcs0: .long 0xfff84458
+#endif
+
+#if defined LART
+mdcas0: .long 0xc71c703f
+mdcas1: .long 0xffc71c71
+mdcas2: .long 0xffffffff
+mdcnfg: .long 0x0334b22f
+mcs0: .long 0xad8c4888
+#endif
+
+#if defined PLEB
+mdcas0: .long 0x1c71c01f
+mdcas1: .long 0xff1c71c7
+mdcas2: .long 0xffffffff
+mdcnfg: .long 0x0c7f3ca3
+mcs0: .long 0xfff8fff8
+#endif
+
+#if defined SHANNON
+mdcas0: .long 0xc71c703f
+mdcas1: .long 0xffc71c71
+mdcas2: .long 0xffffffff
+mdcnfg: .long 0x0334b21f
+mcs0: .long 0xfff84458
+#endif
+
+
+.globl memsetup
+memsetup:
+#if defined USE_SA1100
+ /* Setup the flash memory */
+ ldr r0, MEM_BASE
+
+ ldr r1, mcs0
+ str r1, [r0, #MCS0]
+
+ /* Set up the DRAM */
+
+ /* MDCAS0 */
+ ldr r1, mdcas0
+ str r1, [r0, #MDCAS0]
+
+ /* MDCAS1 */
+ ldr r1, mdcas1
+ str r1, [r0, #MDCAS1]
+
+ /* MDCAS2 */
+ ldr r1, mdcas2
+ str r1, [r0, #MDCAS2]
+
+ /* MDCNFG */
+ ldr r1, mdcnfg
+ str r1, [r0, #MDCNFG]
+
+ /* Issue read requests to disabled bank to start refresh */
+ /* this is required by the Micron memory on a TuxScreen */
+
+ /* Comment from JDB:
+ * This is not strictly necessary. As long as blob writes something to
+ * the serial port between enabling and accessing DRAM (as I think it
+ * does even on Shannon), you can pretty much guarantee that the
+ * required eight refreshes have occurred (as 1 refresh is ~16
+ * microseconds, so even writing two characters at 115k2 covers the
+ * refreshes).
+ *
+ * Comment (on comment) from Erik:
+ * We don't print anymore in the low level loader, so we need this
+ * on all architectures.
+ */
+ ldr r1, MEM_START
+
+.rept 8
+ ldr r0, [r1]
+.endr
+
+
+#elif defined USE_SA1110
+ /* This part is actually for the Assabet only. If your board
+ * uses other settings, you'll have to ifdef them here.
+ */
+ /* Set up the SDRAM */
+ mov r1, #0xA0000000 /* MDCNFG base address */
+
+ ldr r2, =0xAAAAAA7F
+ str r2, [r1, #0x04] /* MDCAS00 */
+ str r2, [r1, #0x20] /* MDCAS20 */
+
+ ldr r2, =0xAAAAAAAA
+ str r2, [r1, #0x08] /* MDCAS01 */
+ str r2, [r1, #0x24] /* MDCAS21 */
+
+ ldr r2, =0xAAAAAAAA
+ str r2, [r1, #0x0C] /* MDCAS02 */
+ str r2, [r1, #0x28] /* MDCAS22 */
+
+ ldr r2, =0x4dbc0327 /* MDREFR */
+ str r2, [r1, #0x1C]
+
+ ldr r2, =0x72547254 /* MDCNFG */
+ str r2, [r1, #0x00]
+
+ /* Issue read requests to disabled bank to start refresh */
+
+ ldr r1, =0xC0000000
+
+.rept 8
+ ldr r0, [r1]
+.endr
+
+ mov r1, #0xA0000000 /* MDCNFG base address */
+
+ ldr r2, =0x72547255 /* Enable the banks */
+ str r2, [r1, #0x00] /* MDCNFG */
+
+/* Static memory chip selects on Assabet: */
+
+ ldr r2, =0x4b90 /* MCS0 */
+ orr r2,r2,r2,lsl #16
+ str r2, [r1, #0x10]
+
+ ldr r2, =0x22212419 /* MCS1 */
+ str r2, [r1, #0x14]
+
+ ldr r2, =0x42196669 /* MCS2 */
+ str r2, [r1, #0x2C]
+
+ ldr r2, =0xafccafcc /* SMCNFG */
+ str r2, [r1, #0x30]
+
+/* Set up PCMCIA space */
+
+ ldr r2, =0x994a994a
+ str r2, [r1, #0x18]
+
+/* All SDRAM memory settings should be ready to go... */
+/* For best performance, should fill out remaining memory config regs: */
+
+
+ /* Testing ,Chester */
+ mov r3,#0x12000000
+ mov r2,#0x5000 /* D9_LED on and D8_LED off */
+ str r2,[r3]
+ mov r4, #0x20000
+gogogo2:
+ subs r4, r4, #1
+ bne gogogo2
+#else
+#error "Configuration error: CPU not defined!"
+#endif
+
+ mov pc, lr
Index: rest-ld-script
===================================================================
RCS file: rest-ld-script
diff -N rest-ld-script
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvs0UaYCt Mon Aug 6 15:44:54 2001
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------
+ * Filename: rest-ld-script
+ * Version: $Id$
+ * Copyright: Copyright (C) 1999, Erik Mouw
+ * Author: Erik Mouw <J.A...@it...>
+ * Description: ld (linker) script to make the blob bootlader.
+ * Heavily inspired by the Linux kernel linker scripts.
+ * Created at: Tue Aug 24 17:24:06 1999
+ * Modified by: Erik Mouw <J.A...@it...>
+ * Modified at: Sun Aug 29 14:45:54 1999
+ *-----------------------------------------------------------------------*/
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_trampoline)
+SECTIONS
+{
+ . = 0xc0000400;
+
+ . = ALIGN(4);
+ .text : { *(.text) }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+}
+
Index: start-ld-script
===================================================================
RCS file: start-ld-script
diff -N start-ld-script
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvs3NCYUs Mon Aug 6 15:44:54 2001
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------
+ * Filename: ld-script
+ * Version: $Id$
+ * Copyright: Copyright (C) 1999, Erik Mouw
+ * Author: Erik Mouw <J.A...@it...>
+ * Description: ld (linker) script to make the blob bootlader.
+ * Heavily inspired by the Linux kernel linker scripts.
+ * Created at: Tue Aug 24 17:24:06 1999
+ * Modified by: Erik Mouw <J.A...@it...>
+ * Modified at: Sun Aug 29 14:45:54 1999
+ *-----------------------------------------------------------------------*/
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text : { *(.text) }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = ALIGN(4);
+ .bss : { *(.bss) }
+}
+
Index: testmem.S
===================================================================
RCS file: testmem.S
diff -N testmem.S
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsgiOEHu Mon Aug 6 15:44:54 2001
@@ -0,0 +1,56 @@
+/*
+ * testmem.S: memory tester, test if there is RAM available at given location
+ *
+ * Copyright (C) 2001 Russell King (rm...@ar...)
+ *
+ * This version clobbers registers r1-r4, so be sure to store their contents
+ * in a safe position. This function is not APCS compliant, so only use it
+ * from assembly code.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+.ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+.text
+.globl testram
+ @ r0 = address to test
+ @ returns r0 = 0 - ram present, r0 = 1 - no ram
+ @ clobbers r1 - r4
+testram:
+ ldmia r0, {r1, r2} @ store current value in r1 and r2
+ mov r3, #0x55 @ write 0x55 to first word
+ mov r4, #0xaa @ 0xaa to second
+ stmia r0, {r3, r4}
+ ldmia r0, {r3, r4} @ read it back
+ teq r3, #0x55 @ do the values match
+ teqeq r4, #0xaa
+ bne bad @ oops, no
+ mov r3, #0xaa @ write 0xaa to first word
+ mov r4, #0x55 @ 0x55 to second
+ stmia r0, {r3, r4}
+ ldmia r0, {r3, r4} @ read it back
+ teq r3, #0xaa @ do the values match
+ teqeq r4, #0x55
+bad: stmia r0, {r1, r2} @ in any case, restore old data
+ moveq r0, #0 @ ok - all values matched
+ movne r0, #1 @ no ram at this location
+ mov pc, lr
Index: testmem2.S
===================================================================
RCS file: testmem2.S
diff -N testmem2.S
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsXfq68t Mon Aug 6 15:44:54 2001
@@ -0,0 +1,56 @@
+/*
+ * testmem2.S: memory tester, test if there is RAM available at given location
+ *
+ * Copyright (C) 2001 Russell King (rm...@ar...)
+ *
+ * This version doesn't clobber registers r1-r4, so it's safe to call it from
+ * C code (fits nicely into the APCS specs).
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+.ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+.text
+.globl testram
+ @ r0 = address to test
+ @ returns r0 = 0 - ram present, r0 = 1 - no ram
+ @ doesnt clobber r1 - r4
+testram:
+ stmdb sp!, {r1-r4, lr}
+ ldmia r0, {r1, r2}
+ mov r3, #0x55 @ write 0x55 to first word
+ mov r4, #0xaa @ 0xaa to second
+ stmia r0, {r3, r4}
+ ldmia r0, {r3, r4} @ read it back
+ teq r3, #0x55 @ do the values match
+ teqeq r4, #0xaa
+ bne bad @ oops, no
+ mov r3, #0xaa @ write 0xaa to first word
+ mov r4, #0x55 @ 0x55 to second
+ stmia r0, {r3, r4}
+ ldmia r0, {r3, r4} @ read it back
+ teq r3, #0xaa @ do the values match
+ teqeq r4, #0x55
+bad: stmia r0, {r1, r2} @ in any case, restore old data
+ moveq r0, #0 @ ok - all values matched
+ movne r0, #1 @ no ram at this location
+ ldmia sp!, {r1-r4, pc}
Index: trampoline.S
===================================================================
RCS file: trampoline.S
diff -N trampoline.S
--- /dev/null Thu May 24 22:33:05 2001
+++ /tmp/cvsOKfmKv Mon Aug 6 15:44:54 2001
@@ -0,0 +1,34 @@
+/*
+ * trampoline.S: start of second stage boot loader, jump from assembly to C
+ *
+ * Copyright (C) 2001 Erik Mouw (J.A...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+.ident "$Id$"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+.text
+
+.globl _trampoline
+_trampoline:
+ bl main
+ /* if main ever returns we just call it again */
+ b _trampoline
Index: Makefile.am
===================================================================
RCS file: /cvsroot/blob/blob/src/Makefile.am,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- Makefile.am 2001/06/27 19:47:42 1.1.1.1
+++ Makefile.am 2001/08/06 22:44:52 1.2
@@ -12,46 +12,94 @@
bin_PROGRAMS = \
- blob-elf32 \
+ blob-start-elf32 \
+ blob-start \
+ blob-rest-elf32 \
+ blob-rest \
blob
+# First specify how to build the first stage loader
+
# WARNING: start.S *must* be the first file, otherwise the target will
# be linked in the wrong order!
-blob_elf32_SOURCES = \
+blob_start_elf32_SOURCES = \
start.S \
+ memsetup.S \
+ ledasm.S \
+ testmem.S
+
+
+blob_start_elf32_LDFLAGS += \
+ -Wl,-T,${top_srcdir}/src/start-ld-script
+
+blob_start_elf32_LDADD += \
+ -lgcc
+
+
+blob_start_SOURCES =
+
+
+blob-start: blob-start-elf32
+ $(OBJCOPY) $(OCFLAGS) $< $@
+
+
+# Now specify how to build the second stage loader
+
+blob_rest_elf32_SOURCES = \
+ trampoline.S \
+ flashasm.S \
+ testmem2.S \
clock.c \
command.c \
- main.c \
flash.c \
+ led.c \
+ linux.c \
+ main.c \
+ memory.c \
serial.c \
time.c \
util.c \
uucodec.c
-blob_SOURCES =
+blob_rest_elf32_LDFLAGS += \
+ -Wl,-T,${top_srcdir}/src/rest-ld-script
-EXTRA_DIST = \
- ld-script
+blob_rest_elf32_LDADD += \
+ -lgcc
-blob_elf32_LDFLAGS += \
- -Wl,-T,${top_srcdir}/src/ld-script
+blob_rest_SOURCES =
-blob_elf32_LDADD += \
- -lgcc
+blob-rest: blob-rest-elf32
+ $(OBJCOPY) $(OCFLAGS) $< $@
+
+
+# Finally specify how to build the full binary
+
+blob_SOURCES =
+
+blob: blob-start blob-rest
+ rm -f $@
+ dd if=blob-start of=$@ bs=1k conv=sync
+ dd if=blob-rest of=$@ bs=1k seek=1
+ chmod +x blob
+
+# automake administrativia
+
+EXTRA_DIST = \
+ start-ld-script \
+ rest-ld-script
+
+
INCLUDES += \
-I${top_builddir}/include \
-I${top_srcdir}/include
-
-
-blob: blob-elf32
- $(OBJCOPY) $(OCFLAGS) $< $@
CLEANFILES = *~
Index: clock.c
===================================================================
RCS file: /cvsroot/blob/blob/src/clock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- clock.c 2001/06/27 19:47:42 1.1.1.1
+++ clock.c 2001/08/06 22:44:52 1.2
@@ -36,12 +36,11 @@
#endif
#include "types.h"
-#include "util.h"
+#include "sa1100.h"
#include "serial.h"
#include "time.h"
+#include "util.h"
-#define __ASM_ARCH_HARDWARE_H
-#include <asm/arch-sa1100/SA-1100.h>
/* It should be possible to improve this function */
/* Determine if the given character is a 0 to 9 or a to z,
Index: command.c
===================================================================
RCS file: /cvsroot/blob/blob/src/command.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- command.c 2001/06/27 19:47:42 1.1.1.1
+++ command.c 2001/08/06 22:44:52 1.2
@@ -65,6 +65,8 @@
int numRead;
int maxRead = len - 1;
+ TimerClearOverflow();
+
startTime = TimerGetTime();
for(numRead = 0, i = 0; numRead < maxRead;) {
@@ -85,7 +87,7 @@
command[i++] = '\0';
/* print newline */
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
return(numRead);
} else if(c == '\b') { /* FIXME: is this backspace? */
if(i > 0) {
Index: flash.c
===================================================================
RCS file: /cvsroot/blob/blob/src/flash.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- flash.c 2001/06/27 19:47:42 1.1.1.1
+++ flash.c 2001/08/06 22:44:52 1.2
@@ -35,6 +35,7 @@
# include "config.h"
#endif
+#include "led.h"
#include "main.h"
#include "util.h"
#include "serial.h"
@@ -114,6 +115,22 @@
u32 data_from_flash(u32 what);
u32 data_to_flash(u32 what);
+#if defined SHANNON || defined NESA
+#define READ_ARRAY 0x00F000F0
+#define UNLOCK1 0x00AA00AA
+#define UNLOCK2 0x00550055
+#define ERASE_SETUP 0x00800080
+#define ERASE_CONFIRM 0x00300030
+#define PGM_SETUP 0x00A000A0
+#define UNLOCK_BYPASS 0x00200020
+#define FLASH_ADDR1 (0x00000555 << 2)
+#define FLASH_ADDR2 (0x000002AA << 2)
+#define ERASE_DONE 0x00800080
+#define RDY_MASK 0x00800080
+#define STATUS_PGM_ERR 0x00200020
+#define STATUS_ERASE_ERR 0x00000001
+
+#else
#define READ_ARRAY 0x00FF00FF
#define ERASE_SETUP 0x00200020
#define ERASE_CONFIRM 0x00D000D0
@@ -123,34 +140,42 @@
#define STATUS_BUSY 0x00800080
#define STATUS_ERASE_ERR 0x00200020
#define STATUS_PGM_ERR 0x00100010
-
-
+#endif
void EraseBlocks(tBlockType which)
{
char *thisBlock;
int numBlocks, i;
- if(RunningFromInternal()) {
- SerialOutputString("*** Can't erase -- running from internal flash.\r");
- return;
- }
-
- if(which == blKernel) {
+ switch(which) {
+ case blBlob:
+ thisBlock = (char *)BLOB_START;
+ numBlocks = NUM_BLOB_BLOCKS;
+ break;
+
+ case blKernel:
thisBlock = (char *)KERNEL_START;
numBlocks = NUM_KERNEL_BLOCKS;
- } else {
+ break;
+
+ case blRamdisk:
thisBlock = (char *)INITRD_START;
numBlocks = NUM_INITRD_BLOCKS;
+ break;
+
+ default:
+ /* this should not happen */
+ return;
}
for(i = 0; i < numBlocks; i++, thisBlock += MAIN_BLOCK_SIZE) {
SerialOutputByte('.');
+ led_toggle();
if((EraseOne(thisBlock) & STATUS_ERASE_ERR) != 0) {
- SerialOutputString("\r*** Erase error at address 0x");
+ SerialOutputString("\n*** Erase error at address 0x");
SerialOutputHex((u32)thisBlock);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
return;
}
}
@@ -164,25 +189,42 @@
volatile u32 *flashBase;
u32 result;
int maxLength, i;
+#if defined SHANNON || defined NESA
+#define READY 1
+#define ERR 2
+ int chip1, chip2;
+#endif
if((u32)source & 0x03) {
SerialOutputString("*** Source is not on a word boundary: 0x");
SerialOutputHex((u32)source);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
return;
}
if(length & 0x03)
length += 0x04;
length &= ~((u32) 0x03);
-
- if(type == blKernel) {
+
+ switch(type) {
+ case blBlob:
+ flashBase = (u32 *)BLOB_START;
+ maxLength = BLOB_LEN;
+ break;
+
+ case blKernel:
flashBase = (u32 *)KERNEL_START;
maxLength = KERNEL_LEN;
- }
- else {
+ break;
+
+ case blRamdisk:
flashBase = (u32 *)INITRD_START;
maxLength = INITRD_LEN;
+ break;
+
+ default:
+ /* this should not happen */
+ return;
}
if(length > maxLength)
@@ -195,16 +237,53 @@
SerialOutputHex((u32)source);
SerialOutputString(" to 0x");
SerialOutputHex((u32)flashBase);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
#endif
+
+#if defined SHANNON || defined NESA
+ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1);
+ *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2);
+ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS);
+#endif
for(i = 0; i < length; i+= 4, flashBase++, source++) {
- if((i % MAIN_BLOCK_SIZE) == 0)
+ if((i % MAIN_BLOCK_SIZE) == 0) {
SerialOutputByte('.');
+ led_toggle();
+ }
*flashBase = data_to_flash(PGM_SETUP);
*flashBase = *source;
+#if defined SHANNON || defined NESA
+
+ /* This is a pretty similar situation to the erasing status below
+ * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5
+ * gets set before this happens, there is an error, but this could
+ * happen near the clock edge, and bit 5 could be the actual data
+ * before bit 7 changes, so we have to read again.
+ */
+ chip1 = chip2 = 0;
+ do {
+ result = data_from_flash(*flashBase);
+
+ if (!chip1 && ((result & 0x80) == (*source & 0x80))) chip1 = READY;
+ if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) {
+ result = data_from_flash(*flashBase);
+ if ((result & 0x80) == (*source & 0x80)) chip1 = READY;
+ else chip1 = ERR;
+ }
+ if (!chip2 && ((result & (0x80 << 16)) == (*source & (0x80 << 16)))) chip2 = READY;
+ if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) {
+ result = data_from_flash(*flashBase);
+ if ((result & (0x80 << 16)) == (*source & (0x80 << 16))) chip2 = READY;
+ else chip2 = ERR;
+ }
+
+ } while (!chip1 || !chip2);
+
+ if (chip1 == ERR || chip2 == ERR || *flashBase != *source) {
+#else
do {
*flashBase = data_to_flash(STATUS_READ);
result = data_from_flash(*flashBase);
@@ -213,17 +292,21 @@
*flashBase = data_to_flash(READ_ARRAY);
if((result & STATUS_PGM_ERR) != 0 || *flashBase != *source) {
- SerialOutputString("\r*** Write error at address 0x");
+#endif
+ SerialOutputString("\n*** Write error at address 0x");
SerialOutputHex((u32)flashBase);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
return;
}
}
+
+#if defined SHANNON || defined NESA
+ *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY);
+#endif
} /* WriteBlocksFromMem */
-
static u32 EraseOne(const char *whichOne)
{
/* Routine to erase one block of flash */
@@ -231,12 +314,45 @@
volatile u32 *writeMe = (u32 *)whichOne;
u32 result;
+#if defined SHANNON || defined NESA
+ int chip1, chip2;
+#endif
+
#ifdef BLOB_DEBUG
SerialOutputString(__FUNCTION__ "(): erasing block at address 0x");
SerialOutputHex((u32)whichOne);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
#endif
+#if defined SHANNON || defined NESA
+ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1);
+ *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2);
+ *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP);
+ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1);
+ *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2);
+ *writeMe = data_to_flash(ERASE_CONFIRM);
+
+ /* I just can't find clean ways of dealing with this flash...
+ * The error bit is a *set* bit, so if its read, and bit 7 is 0,
+ * but bit 5 is 1, its an error, however, after these status reads
+ * are done, erased flash goes to 0xff...sooo...each chip has to
+ * be caught where the bits are the status bits */
+ chip1 = chip2 = 0;
+ do {
+ result = data_from_flash(*writeMe);
+ if (!chip1 && (result & 0xFFFF) & ERASE_DONE) chip1 = READY;
+ if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) chip1 = ERR;
+ if (!chip2 && (result >> 16) & ERASE_DONE) chip2 = READY;
+ if (!chip2 && (result >> 16) & STATUS_PGM_ERR) chip2 = ERR;
+
+ } while(!chip1 || !chip2);
+
+ *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY);
+
+ if (chip1 == ERR || chip2 == ERR) return 1;
+ return 0;
+#else
+
*writeMe = data_to_flash(ERASE_SETUP);
*writeMe = data_to_flash(ERASE_CONFIRM);
@@ -247,8 +363,8 @@
*writeMe = data_to_flash(READ_ARRAY);
return result;
+#endif
} /* EraseOne */
-
Index: led.c
===================================================================
RCS file: /cvsroot/blob/blob/src/led.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- led.c 2001/06/27 19:47:42 1.1.1.1
+++ led.c 2001/08/06 22:44:52 1.2
@@ -8,72 +8,71 @@
* Modified by: Erik Mouw <J.A...@it...>
* Modified at: Mon Aug 16 16:55:21 1999
*-----------------------------------------------------------------------*/
+/*
+ * led.c: simple LED control functions
+ *
+ * Copyright (C) 1999 2001 Erik Mouw (J.A...@it...)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/*
+ * All functions assume that the LED is properly initialised by the code
+ * in ledasm.S.
+ *
+ */
#ident "$Id$"
-/* function prototypes */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-void blink_led(void);
+#include "led.h"
+#include "sa1100.h"
-static inline void init_gpio(void);
-static inline void led_on(void);
-static inline void led_off(void);
-static inline void waitloop(void);
-static inline void init_gpio(void)
-{
- /* GPIO Pin Direction Register */
- register unsigned int *gpdr = (unsigned int *)0x90040004;
-
- /* bit 23 is the LED */
- *gpdr = 0x00800000;
-}
-
-
-
+static int led_state;
-static inline void led_on(void)
-{
- register unsigned int *gpsr = (unsigned int *)0x90040008;
-
- *gpsr = 0x00800000;
-}
-
-static inline void led_off(void)
+void led_on(void)
{
- register unsigned int *gpcr = (unsigned int *)0x9004000c;
-
- *gpcr = 0x00800000;
+ GPSR = LED_GPIO;
+ led_state = 1;
}
-static inline void waitloop(void)
+void led_off(void)
{
- __asm__ __volatile__ (
- " mov r4, #0x8000\n"
- "0: subs r4, r4, #1\n"
- " bne 0b\n");
+ GPCR = LED_GPIO;
+ led_state = 0;
}
-void blink_led(void)
+void led_toggle(void)
{
- init_gpio();
-
- for(;;)
- {
- led_on();
- waitloop();
- led_off();
- waitloop();
- }
+ if(led_state)
+ led_off();
+ else
+ led_on();
}
Index: main.c
===================================================================
RCS file: /cvsroot/blob/blob/src/main.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- main.c 2001/06/27 19:47:42 1.1.1.1
+++ main.c 2001/08/06 22:44:52 1.2
@@ -12,8 +12,9 @@
/*
* main.c: main file for the blob bootloader
*
- * Copyright (C) 1999 Jan-Derk Bakker (J.D...@it...) and
- * Erik Mouw (J.A...@it...)
+ * Copyright (C) 1999 2000 2001
+ * Jan-Derk Bakker (J.D...@it...) and
+ * Erik Mouw (J.A...@it...)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,103 +41,100 @@
#include "clock.h"
#include "command.h"
#include "flash.h"
+#include "led.h"
+#include "linux.h"
+#include "main.h"
+#include "memory.h"
+#include "sa1100.h"
#include "serial.h"
#include "time.h"
-#include "main.h"
#include "util.h"
#include "uucodec.h"
-
-typedef enum {
- fromFlash = 0,
- fromDownload = 1
-} blockSource;
-
-
-
-
-typedef struct {
- int kernelSize;
- blockSource kernelType;
-
- int ramdiskSize;
- blockSource ramdiskType;
-
- u32 blockSize;
- eBauds downloadSpeed;
-} blobStatus;
+void Download(char *commandline);
+void Flash(char *commandline);
+void PrintHelp(void);
+void SetDownloadSpeed(char *commandline);
+void PrintStatus(void);
+void ResetTerminal(void);
+void Reload(char *commandline);
+void PrintSerialSpeed(eBauds speed);
+void Reboot(void);
+void Reblob(void);
-void BootKernel(char *commandline);
-void Download(char *commandline, blobStatus *status);
-void Flash(char *commandline, blobStatus *status);
-void PrintHelp(void);
-void SetDownloadSpeed(char *commandline, blobStatus *status);
-void PrintStatus(blobStatus *status);
-void ResetTerminal(void);
-void Reload(char *commandline, blobStatus *status);
-void PrintSerialSpeed(eBauds speed);
+blob_status_t blob_status;
-void c_main(char *blockBase, u32 blockSize)
+int main(void)
{
+ u32 blockSize = 0x00800000;
int numRead = 0;
char commandline[128];
- blobStatus status;
int i;
int retval = 0;
+
+ /* Turn the LED on again, so we can see that we safely made it
+ * into C code.
+ */
+ led_on();
/* We really want to be able to communicate, so initialise the
* serial port at 9k6 (which works good for terminals)
*/
SerialInit(baud9k6);
TimerInit();
-
- /* initialise status */
- status.kernelSize = 0;
- status.kernelType = fromFlash;
- status.ramdiskSize = 0;
- status.ramdiskType = fromFlash;
- status.blockSize = blockSize;
- status.downloadSpeed = baud115k2;
-
- /* Load kernel and ramdisk from flash to RAM */
- Reload("kernel", &status);
- Reload("ramdisk", &status);
/* Print the required GPL string */
- SerialOutputString("\r" PACKAGE " version " VERSION "\r"
- "Copyright (C) 1999 2000 "
- "Jan-Derk Bakker and Erik Mouw\r"
+ SerialOutputString("\nConsider yourself LARTed!\n\n");
+ SerialOutputString(PACKAGE " version " VERSION "\n"
+ "Copyright (C) 1999 2000 2001 "
+ "Jan-Derk Bakker and Erik Mouw\n"
"Copyright (C) 2000 "
- "Johan Pouwelse.\r");
+ "Johan Pouwelse\n");
SerialOutputString(PACKAGE " comes with ABSOLUTELY NO WARRANTY; "
- "read the GNU GPL for details.\r");
+ "read the GNU GPL for details.\n");
SerialOutputString("This is free software, and you are welcome "
- "to redistribute it\r");
+ "to redistribute it\n");
SerialOutputString("under certain conditions; "
- "read the GNU GPL for details.\r\r");
+ "read the GNU GPL for details.\n");
+
+
+ /* get the amount of memory */
+ get_memory_map();
+
+ /* initialise status */
+ blob_status.kernelSize = 0;
+ blob_status.kernelType = fromFlash;
+ blob_status.ramdiskSize = 0;
+ blob_status.ramdiskType = fromFlash;
+ blob_status.blockSize = blockSize;
+ blob_status.downloadSpeed = baud115k2;
+
- /* and some information */
+ /* Load kernel and ramdisk from flash to RAM */
+ Reload("blob");
+ Reload("kernel");
+ Reload("ramdisk");
+
#ifdef BLOB_DEBUG
+ /* print some information */
SerialOutputString("Running from ");
if(RunningFromInternal())
- SerialOutputString("internal flash\r");
+ SerialOutputString("internal flash\n");
else
- SerialOutputString("external flash\r");
+ SerialOutputString("external flash\n");
- SerialOutputString("blockBase = 0x");
- SerialOutputHex((int) blockBase);
SerialOutputString(", blockSize = 0x");
SerialOutputHex(blockSize);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
#endif
/* wait 10 seconds before starting autoboot */
SerialOutputString("Autoboot in progress, press any key to stop ");
@@ -152,132 +150,108 @@
/* no key was pressed, so proceed booting the kernel */
if(retval == 0) {
commandline[0] = '\0';
- BootKernel(commandline);
+ boot_linux(commandline);
}
- SerialOutputString("\rAutoboot aborted\r");
- SerialOutputString("Type \"help\" to get a list of commands\r");
+ SerialOutputString("\nAutoboot aborted\n");
+ SerialOutputString("Type \"help\" to get a list of commands\n");
/* the command loop. endless, of course */
for(;;) {
DisplayPrompt(NULL);
- /* wait an hour to get a command */
- numRead = GetCommand(commandline, 128, 3600);
+ /* wait 10 minutes for a command */
+ numRead = GetCommand(commandline, 128, 600);
if(numRead > 0) {
if(MyStrNCmp(commandline, "boot", 4) == 0) {
- BootKernel(commandline + 4);
+ boot_linux(commandline + 4);
} else if(MyStrNCmp(commandline, "clock", 5) == 0) {
SetClock(commandline + 5);
} else if(MyStrNCmp(commandline, "download ", 9) == 0) {
- Download(commandline + 9, &status);
+ Download(commandline + 9);
} else if(MyStrNCmp(commandline, "flash ", 6) == 0) {
- Flash(commandline + 6, &status);
+ Flash(commandline + 6);
} else if(MyStrNCmp(commandline, "help", 4) == 0) {
PrintHelp();
+ } else if(MyStrNCmp(commandline, "reblob", 6) == 0) {
+ Reblob();
+ } else if(MyStrNCmp(commandline, "reboot", 6) == 0) {
+ Reboot();
} else if(MyStrNCmp(commandline, "reload ", 7) == 0) {
- Reload(commandline + 7, &status);
+ Reload(commandline + 7);
} else if(MyStrNCmp(commandline, "reset", 5) == 0) {
ResetTerminal();
} else if(MyStrNCmp(commandline, "speed ", 6) == 0) {
- SetDownloadSpeed(commandline + 6, &status);
+ SetDownloadSpeed(commandline + 6);
}
else if(MyStrNCmp(commandline, "status", 6) == 0) {
- PrintStatus(&status);
+ PrintStatus();
} else {
SerialOutputString("*** Unknown command: ");
SerialOutputString(commandline);
- SerialOutputByte('\r');
+ SerialOutputByte('\n');
}
}
}
-} /* c_main */
-
-
-
-
-void BootKernel(char *commandline)
-{
- void (*theKernel)(int zero, int arch) = (void (*)(int, int))KERNEL_RAM_BASE;
-
-#warning "FIXME: should set kernel commandline parameters -- Erik"
-#ifdef BLOB_DEBUG
- SerialOutputString("\r*** Ignoring kernel parameters\r");
-#endif
+ return 0;
+} /* main */
- /* we assume that the kernel is in place */
- /* See linux/include/asm-arm/system.h for architecture numbers */
- SerialOutputString("\rStarting kernel ...\r\r");
-
-#if defined ASSABET
- theKernel(0, 25);
-#elif defined BRUTUS
- theKernel(0, 16);
-#elif defined LART
- theKernel(0, 27);
-#elif defined PLEB
-#warning "This is NOT the correct PLEB architecture number!"
- theKernel(0, 18);
-#else
- /* Be generic and just tell the kernel that we are an SA1100
- architecture */
-#warning "Calling the kernel with a generic SA1100 architecture code. YMMV!"
- theKernel(0,18);
-#endif
-
- SerialOutputString("Hey, the kernel returned! This should not happen.\r");
-}
-
-void Download(char *commandline, blobStatus *status)
+void Download(char *commandline)
{
u32 startAddress = 0;
int bufLen;
int *numRead = 0;
- if(MyStrNCmp(commandline, "kernel", 6) == 0) {
+ if(MyStrNCmp(commandline, "blob", 4) == 0) {
+ /* download blob */
+ startAddress = BLOB_RAM_BASE;
+ bufLen = blob_status.blockSize - BLOB_BLOCK_OFFSET;
+ numRead = &blob_status.blobSize;
+ blob_status.blobType = fromDownload;
+ } else if(MyStrNCmp(commandline, "kernel", 6) == 0) {
/* download kernel */
startAddress = KERNEL_RAM_BASE;
- bufLen = status->blockSize - KERNEL_BLOCK_OFFSET;
- numRead = &status->kernelSize;
- status->kernelType = fromDownload;
+ bufLen = blob_status.blockSize - KERNEL_BLOCK_OFFSET;
+ numRead = &blob_status.kernelSize;
+ blob_status.kernelType = fromDownload;
} else if(MyStrNCmp(commandline, "ramdisk", 7) == 0) {
/* download ramdisk */
startAddress = RAMDISK_RAM_BASE;
- bufLen = status->blockSize - RAMDISK_BLOCK_OFFSET;
- numRead = &status->ramdiskSize;
- status->ramdiskType = fromDownload;
+ bufLen = blob_status.blockSize - RAMDISK_BLOCK_OFFSET;
+ numRead = &blob_status.ramdiskSize;
+ blob_status.ramdiskType = fromDownload;
} else {
SerialOutputString("*** Don't know how to download \"");
SerialOutputString(commandline);
- SerialOutputString("\"\r");
+ SerialOutputString("\"\n");
return;
}
SerialOutputString("Switching to ");
- PrintSerialSpeed(status->downloadSpeed);
- SerialOutputString(" baud\r");
+ PrintSerialSpeed(blob_status.downloadSpeed);
+ SerialOutputString(" baud\n");
- SerialOutputString("You have 60 seconds to switch your terminal emulator to the same speed and\r");
- SerialOutputString("start downloading. After that " PACKAGE " will switch back to 9600 baud.\r");
+ SerialOutputString("You have 60 seconds to switch your terminal emulator to the same speed and\n");
+ SerialOutputString("start downloading. After that " PACKAGE " will switch back to 9600 baud.\n");
- SerialInit(status->downloadSpeed);
+ SerialInit(blob_status.downloadSpeed);
*numRead = UUDecode((char *)startAddress, bufLen);
- SerialOutputString("\r(Please switch your terminal emulator back to 9600 baud)\r");
+ SerialOutputString("\n(Please switch your terminal emulator back to 9600 baud)\n");
if(*numRead < 0) {
/* something went wrong */
- SerialOutputString("*** Uudecode receive failed\r");
+ SerialOutputString("*** Uudecode receive failed\n");
/* reload the correct memory */
- Reload(commandline, status);
+ Reload(commandline);
SerialInit(baud9k6);
return;
@@ -286,7 +260,7 @@
SerialOutputDec(*numRead);
SerialOutputString(" (0x");
SerialOutputHex(*numRead);
- SerialOutputString(") bytes.\r");
+ SerialOutputString(") bytes.\n");
SerialInit(baud9k6);
@@ -295,24 +269,33 @@
-void Flash(char *commandline, blobStatus *status)
+void Flash(char *commandline)
{
u32 startAddress = 0;
tBlockType block;
- int numBytes = 0;;
+ int numBytes = 0;
+ int maxSize = 0;
- if(RunningFromInternal()) {
- SerialOutputString("*** Flash not possible when using internal flash\r");
- return;
- }
+ if(MyStrNCmp(commandline, "blob", 4) == 0) {
+ startAddress = BLOB_RAM_BASE;
+ block = blBlob;
+ numBytes = blob_status.blobSize;
+ maxSize = BLOB_LEN;
- if(MyStrNCmp(commandline, "kernel", 6) == 0) {
+ if(blob_status.blobType == fromFlash) {
+ SerialOutputString("*** No blob downloaded\n");
+ return;
+ }
+
+ SerialOutputString("Saving blob to flash ");
+ } else if(MyStrNCmp(commandline, "kernel", 6) == 0) {
startAddress = KERNEL_RAM_BASE;
block = blKernel;
- numBytes = status->kernelSize;
+ numBytes = blob_status.kernelSize;
+ maxSize = KERNEL_LEN;
- if(status->kernelType == fromFlash) {
- SerialOutputString("*** No kernel downloaded\r");
+ if(blob_status.kernelType == fromFlash) {
+ SerialOutputString("*** No kernel downloaded\n");
return;
}
@@ -320,10 +303,11 @@
} else if(MyStrNCmp(commandline, "ramdisk", 7) == 0) {
startAddress = RAMDISK_RAM_BASE;
block = blRamdisk;
- numBytes = status->ramdiskSize;
+ numBytes = blob_status.ramdiskSize;
+ maxSize = INITRD_LEN;
- if(status->ramdiskType == fromFlash) {
- SerialOutputString("*** No ramdisk downloaded\r");
+ if(blob_status.ramdiskType == fromFlash) {
+ SerialOutputString("*** No ramdisk downloaded\n");
return;
}
@@ -331,14 +315,25 @@
} else {
SerialOutputString("*** Don't know how to flash \"");
SerialOutputString(commandline);
- SerialOutputString("\"\r");
+ SerialOutputString("\"\n");
+ return;
+ }
+
+ if(numBytes > maxSize) {
+ SerialOutputString("*** Downloaded image too large for flash area\n");
+ SerialOutputString("*** (0x");
+ SerialOutputHex(numBytes);
+ SerialOutputString(" downloaded, maximum size is 0x");
+ SerialOutputHex(maxSize);
+ SerialOutputString(" bytes)\n");
+
return;
}
EraseBlocks(block);
SerialOutputByte(' ');
WriteBlocksFromMem(block, (u32 *)startAddress, numBytes);
- SerialOutputString(" done\r");
+ SerialOutputString(" done\n");
}
@@ -346,70 +341,72 @@
void PrintHelp(void)
{
- SerialOutputString("Help for " PACKAGE " " VERSION ", the LART bootloader\r");
- SerialOutputString("The following commands are supported:\r");
- SerialOutputString("* boot [kernel options] Boot Linux with optional kernel options\r");
- SerialOutputString("* clock PPCR MDCNFG MDCAS0 MDCAS1 MDCAS2\r");
- SerialOutputString(" Set the SA1100 core clock and DRAM timings\r");
- SerialOutputString(" (WARNING: dangerous command!)\r");
- SerialOutputString("* download {kernel|ramdisk} Download kernel or ramdisk image to RAM\r");
- SerialOutputString("* flash {kernel|ramdisk} Copy kernel or ramdisk from RAM to flash\r");
- SerialOutputString("* help Get this help\r");
- SerialOutputString("* reload {kernel|ramdisk} Reload kernel or ramdisk from flash to RAM\r");
- SerialOutputString("* reset Reset terminal\r");
- SerialOutputString("* speed Set download speed\r");
- SerialOutputString("* status Display current status\r");
+ SerialOutputString("Help for " PACKAGE " " VERSION ", the LART bootloader\n");
+ SerialOutputString("The following commands are supported:\n");
+ SerialOutputString("* boot [kernel options] Boot Linux with optional kernel options\n");
+ SerialOutputString("* clock PPCR MDCNFG MDCAS0 MDCAS1 MDCAS2\n");
+ SerialOutputString(" Set the SA1100 core clock and DRAM timings\n");
+ SerialOutputString(" (WARNING: dangerous command!)\n");
+ SerialOutputString("* download {blob|kernel|ramdisk} Download kernel or ramdisk image to RAM\n");
+ SerialOutputString("* flash {blob|kernel|ramdisk} Copy kernel or ramdisk from RAM to flash\n");
+ SerialOutputString("* help Get this help\n");
+ SerialOutputString("* reblob Restart blob from RAM\n");
+ SerialOutputString("* reboot Reboot system\n");
+ SerialOutputString("* reload {blob|kernel|ramdisk} Reload kernel or ramdisk from flash to RAM\n");
+ SerialOutputString("* reset Reset terminal\n");
+ SerialOutputString("* speed Set download speed\n");
+ SerialOutputString("* status Display current status\n");
}
-void SetDownloadSpeed(char *commandline, blobStatus *status)
+void SetDownloadSpeed(char *commandline)
{
if(MyStrNCmp(commandline, "1200", 4) == 0) {
- status->downloadSpeed = baud1k2;
+ blob_status.downloadSpeed = baud1k2;
} else if(MyStrNCmp(commandline, "1k2", 3) == 0) {
- status->downloadSpeed = baud1k2;
+ blob_status.downloadSpeed = baud1k2;
} else if(MyStrNCmp(commandline, "9600", 4) == 0) {
- status->downloadSpeed = baud9k6;
+ blob_status.downloadSpeed = baud9k6;
} else if(MyStrNCmp(commandline, "9k6", 3) == 0) {
- status->downloadSpeed = baud9k6;
+ blob_status.downloadSpeed = baud9k6;
} else if(MyStrNCmp(commandline, "19200", 5) == 0) {
- status->downloadSpeed = baud19k2;
+ blob_status.downloadSpeed = baud19k2;
} else if(MyStrNCmp(commandline, "19k2", 4) == 0) {
- status->downloadSpeed = baud19k2;
+ blob_status.downloadSpeed = baud19k2;
} else if(MyStrNCmp(commandline, "38400", 5) == 0) {
- status->downloadSpeed = baud38k4;
+ blob_status.downloadSpeed = baud38k4;
} else if(MyStrNCmp(commandline, "38k4", 4) == 0) {
- status->downloadSpeed = baud38k4;
+ blob_status.downloadSpeed = baud38k4;
} else if(MyStrNCmp(commandline, "57600", 5) == 0) {
- status->downloadSpeed = baud57k6;
+ blob_status.downloadSpeed = baud57k6;
} else if(MyStrNCmp(commandline, "57k6", 4) == 0) {
- status->downloadSpeed = baud57k6;
+ blob_status.downloadSpeed = baud57k6;
} else if(MyStrNCmp(commandline, "115200", 6) == 0) {
- status->downloadSpeed = baud115k2;
+ blob_status.downloadSpeed = baud115k2;
} else if(MyStrNCmp(commandline, "115k2", 5) == 0) {
- status->downloadSpeed = baud115k2;
+ blob_status.downloadSpeed = baud115k2;
} else {
SerialOutputString("*** Invalid download speed value \"");
SerialOutputString(commandline);
- SerialOutputString("\"\r*** Valid values are:\r");
- SerialOutputString("*** 1200, 9600, 19200, 38400, 57600, 115200,\r");
- SerialOutputString("*** 1k2, 9k6, 19k2, 38k4, 57k6, and 115k2\r");
+ SerialOutputString("\"\n*** Valid values are:\n");
+ SerialOutputString("*** 1200, 9600, 19200, 38400, 57600, 115200,\n");
+ SerialOutputString("*** 1k2, 9k6, 19k2, 38k4, 57k6, and 115k2\n");
}
SerialOutputString("Download speed set to ");
- PrintSerialSpeed(status->downloadSpeed);
- SerialOutputString(" baud\r");
+ PrintSerialSpeed(blob_status.downloadSpeed);
+ SerialOutputString(" baud\n");
}
-void PrintStatus(blobStatus *status)
+void PrintStatus(void)
{
- SerialOutputString("Bootloader : " PACKAGE "\r");
- SerialOutputString("Version : " VERSION "\r");
+ SerialOutputString("Bootloader : " PACKAGE "\n");
+ SerialOutputString("Version : " VERSION "\n");
SerialOutputString("Running from : ");
if(RunningFromInternal())
@@ -417,29 +414,38 @@
else
SerialOutputString("external");
- SerialOutputString(" flash\rBlocksize : 0x");
- SerialOutputHex(status->blockSize);
+ SerialOutputString(" flash\nBlocksize : 0x");
+ SerialOutputHex(blob_status.blockSize);
- SerialOutputString("\rDownload speed: ");
- PrintSerialSpeed(status->downloadSpeed);
- SerialOutputString(" baud\r");
+ SerialOutputString("\nDownload speed: ");
+ PrintSerialSpeed(blob_status.downloadSpeed);
+ SerialOutputString(" baud\n");
+
+ SerialOutputString("Blob : ");
+ if(blob_status.blobType == fromFlash) {
+ SerialOutputString("from flash\n");
+ } else {
+ SerialOutputString("downloaded, ");
+ SerialOutputDec(blob_status.blobSize);
+ SerialOutputString(" bytes\n");
+ }
SerialOutputString("Kernel : ");
- if(status->kernelType == fromFlash) {
- SerialOutputString("from flash\r");
+ if(blob_status.kernelType == fromFlash) {
+ SerialOutputString("from flash\n");
} else {
SerialOutputString("downloaded, ");
- SerialOutputDec(status->kernelSize);
- SerialOutputString(" bytes\r");
+ SerialOutputDec(blob_status.kernelSize);
+ SerialOutputString(" by...
[truncated message content] |