summaryrefslogtreecommitdiffstats
path: root/flash/minimon
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2003-11-30 11:37:43 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2003-11-30 11:37:43 +0000
commit6a4e4c87c24455e18bbd77565cb3e993ee350618 (patch)
tree6f2ceac4da97aa63ff8deef939bd3cc2d56d3466 /flash/minimon
parent014c4fa1f8d56850cfd504a90221c293e4a158f6 (diff)
downloadrockbox-6a4e4c87c24455e18bbd77565cb3e993ee350618.tar.gz
rockbox-6a4e4c87c24455e18bbd77565cb3e993ee350618.tar.bz2
rockbox-6a4e4c87c24455e18bbd77565cb3e993ee350618.zip
source code for all my flash stuff, now finally in cvs
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4083 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'flash/minimon')
-rw-r--r--flash/minimon/Makefile53
-rw-r--r--flash/minimon/README6
-rw-r--r--flash/minimon/minimon.c156
-rw-r--r--flash/minimon/minimon.h24
-rw-r--r--flash/minimon/minimon.lds60
5 files changed, 299 insertions, 0 deletions
diff --git a/flash/minimon/Makefile b/flash/minimon/Makefile
new file mode 100644
index 0000000000..57ae13e940
--- /dev/null
+++ b/flash/minimon/Makefile
@@ -0,0 +1,53 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+CC = sh-elf-gcc
+LD = sh-elf-ld
+AR = sh-elf-ar
+AS = sh-elf-as
+OC = sh-elf-objcopy
+
+FIRMWARE := ../../firmware
+TOOLSDIR=../../tools
+
+TARGET = minimon
+LDS := $(TARGET).lds
+
+INCLUDES= -I$(FIRMWARE)/export -I. -I$(OBJDIR)
+OBJDIR := .
+
+CFLAGS = -fpic -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns $(INCLUDES) $(DEFINES)
+AFLAGS += -small -relax
+
+
+ifdef DEBUG
+ DEFINES := -DDEBUG
+ CFLAGS += -g
+endif
+
+SRC := $(wildcard *.c)
+
+OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
+
+LINKFILE = $(OBJDIR)/$(TARGET).lds
+
+
+$(OBJDIR)/$(TARGET).bin : $(OBJDIR)/$(TARGET).elf
+ $(OC) -O binary $(OBJDIR)/$(TARGET).elf $(OBJDIR)/$(TARGET).bin
+ $(TOOLSDIR)/sh2d $(OBJDIR)/$(TARGET).bin -o 0900000 > $(OBJDIR)/$(TARGET).asm
+
+$(OBJDIR)/$(TARGET).elf : $(OBJS)
+ $(CC) -Os -nostdlib -o $(OBJDIR)/$(TARGET).elf -L$(OBJDIR) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/$(TARGET).map
+
+
+clean:
+ -rm -f $(OBJS) $(OBJDIR)/$(TARGET).asm \
+ $(OBJDIR)/$(TARGET).bin \
+ $(OBJDIR)/$(TARGET).elf \
+ $(OBJDIR)/$(TARGET).map
diff --git a/flash/minimon/README b/flash/minimon/README
new file mode 100644
index 0000000000..b80edd9689
--- /dev/null
+++ b/flash/minimon/README
@@ -0,0 +1,6 @@
+(c) 2003 by Jrg Hohensohn
+
+MiniMon is the tiny but powerful-enough piece of code that can be loaded
+with the UART boot mod.
+It allows to read and write memory, flash program, execute code.
+This is suitable to reflash the box, load Rockbox or the gdb stub, etc.
diff --git a/flash/minimon/minimon.c b/flash/minimon/minimon.c
new file mode 100644
index 0000000000..e7981f2d09
--- /dev/null
+++ b/flash/minimon/minimon.c
@@ -0,0 +1,156 @@
+// minimalistic monitor
+// to be loaded with the UART boot feature
+// capable of reading and writing bytes, commanded by UART
+
+#include "sh7034.h"
+#include "minimon.h"
+
+// scalar types
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned long UINT32;
+
+typedef void(*tpFunc)(void); // type for exec
+typedef int(*tpMain)(void); // type for start vector to main()
+
+
+// prototypes
+int main(void);
+
+// our binary has to start with a vector to the entry point
+tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
+
+
+UINT8 uart_read(void)
+{
+ UINT8 byte;
+ while (!(SSR1 & SCI_RDRF)); // wait for char to be available
+ byte = RDR1;
+ SSR1 &= ~SCI_RDRF;
+ return byte;
+}
+
+
+void uart_write(UINT8 byte)
+{
+ while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty
+ TDR1 = byte;
+ SSR1 &= ~SCI_TDRE;
+}
+
+
+int main(void)
+{
+ UINT8 cmd;
+ UINT32 addr;
+ UINT32 size;
+ UINT32 content;
+ volatile UINT8* paddr = 0;
+ volatile UINT8* pflash; // flash base address
+
+ while (1)
+ {
+ cmd = uart_read();
+ switch (cmd)
+ {
+ case BAUDRATE:
+ content = uart_read();
+ uart_write(cmd); // acknowledge by returning the command value
+ while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate
+ BRR1 = content;
+ break;
+
+ case ADDRESS:
+ addr = (uart_read() << 24) | (uart_read() << 16) | (uart_read() << 8) | uart_read();
+ paddr = (UINT8*)addr;
+ pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align
+ uart_write(cmd); // acknowledge by returning the command value
+ break;
+
+ case BYTE_READ:
+ content = *paddr++;
+ uart_write(content); // the content is the ack
+ break;
+
+ case BYTE_WRITE:
+ content = uart_read();
+ *paddr++ = content;
+ uart_write(cmd); // acknowledge by returning the command value
+ break;
+
+ case BYTE_READ16:
+ size = 16;
+ while (size--)
+ {
+ content = *paddr++;
+ uart_write(content); // the content is the ack
+ }
+ break;
+
+ case BYTE_WRITE16:
+ size = 16;
+ while (size--)
+ {
+ content = uart_read();
+ *paddr++ = content;
+ }
+ uart_write(cmd); // acknowledge by returning the command value
+ break;
+
+ case BYTE_FLASH:
+ content = uart_read();
+ pflash[0x5555] = 0xAA; // set flash to command mode
+ pflash[0x2AAA] = 0x55;
+ pflash[0x5555] = 0xA0; // byte program command
+ *paddr++ = content;
+ uart_write(cmd); // acknowledge by returning the command value
+ break;
+
+ case BYTE_FLASH16:
+ size = 16;
+ while (size--)
+ {
+ content = uart_read();
+ pflash[0x5555] = 0xAA; // set flash to command mode
+ pflash[0x2AAA] = 0x55;
+ pflash[0x5555] = 0xA0; // byte program command
+ *paddr++ = content;
+ }
+ uart_write(cmd); // acknowledge by returning the command value
+ break;
+
+ case HALFWORD_READ:
+ content = *(UINT16*)paddr;
+ paddr += 2;
+ uart_write(content >> 8); // highbyte
+ uart_write(content & 0xFF); // lowbyte
+ break;
+
+ case HALFWORD_WRITE:
+ content = uart_read() << 8 | uart_read();
+ *(UINT16*)paddr = content;
+ paddr += 2;
+ uart_write(cmd); // acknowledge by returning the command value
+ break;
+
+ case EXECUTE:
+ {
+ tpFunc pFunc = (tpFunc)paddr;
+ pFunc();
+ uart_write(cmd); // acknowledge by returning the command value
+ }
+ break;
+
+
+ default:
+ {
+ volatile UINT16* pPortB = (UINT16*)0x05FFFFC2;
+ *pPortB |= 1 << 6; // bit 6 is red LED on
+ uart_write(~cmd); // error acknowledge
+ }
+
+ } // case
+ }
+
+ return 0;
+}
diff --git a/flash/minimon/minimon.h b/flash/minimon/minimon.h
new file mode 100644
index 0000000000..b6e9805ecf
--- /dev/null
+++ b/flash/minimon/minimon.h
@@ -0,0 +1,24 @@
+#ifndef _MINIMON_H
+#define _MINIMON_H
+
+
+// Commands
+// all multibyte values (address, halfwords) are passed as big endian
+// (most significant of the bytes first)
+
+// set the address (all read/write commands will auto-increment it)
+#define BAUDRATE 0x00 // followed by BRR value; response: command byte
+#define ADDRESS 0x01 // followed by 4 bytes address; response: command byte
+#define BYTE_READ 0x02 // response: 1 byte content
+#define BYTE_WRITE 0x03 // followed by 1 byte content; response: command byte
+#define BYTE_READ16 0x04 // response: 16 bytes content
+#define BYTE_WRITE16 0x05 // followed by 16 bytes; response: command byte
+#define BYTE_FLASH 0x06 // followed by 1 byte content; response: command byte
+#define BYTE_FLASH16 0x07 // followed by 16 bytes; response: command byte
+#define HALFWORD_READ 0x08 // response: 2 byte content
+#define HALFWORD_WRITE 0x09 // followed by 2 byte content; response: command byte
+#define EXECUTE 0x0A // response: command byte if call returns
+#define VERSION 0x0B // response: version
+
+
+#endif // _MINIMON_H
diff --git a/flash/minimon/minimon.lds b/flash/minimon/minimon.lds
new file mode 100644
index 0000000000..dbdbdc3faa
--- /dev/null
+++ b/flash/minimon/minimon.lds
@@ -0,0 +1,60 @@
+OUTPUT_FORMAT(elf32-sh)
+INPUT(minimon.o)
+
+MEMORY
+{
+ DRAM : ORIGIN = 0x09000000, LENGTH = 0x200000
+}
+
+SECTIONS
+{
+ .startvector :
+ {
+ *(.startvector)
+ . = ALIGN(0x4);
+ } > DRAM
+
+ .got :
+ {
+ *(.got)
+ } > DRAM
+
+ .got.plt :
+ {
+ *(.got.plt)
+ } > DRAM
+
+ .rela.got :
+ {
+ *(.rela.got)
+ } > DRAM
+
+ .text :
+ {
+ . = ALIGN(0x200);
+ *(.entry)
+ *(.text)
+ . = ALIGN(0x4);
+ } > DRAM
+
+ .data :
+ {
+ *(.data)
+ } > DRAM
+
+ .rodata :
+ {
+ *(.rodata)
+ . = ALIGN(0x4);
+ } > DRAM
+
+ .bss :
+ {
+ *(.bss)
+ } > DRAM
+
+ .stack :
+ {
+ *(.stack)
+ } > DRAM
+}