Add lm32 cpu and milkymist port
authorMichael Walle <michael@walle.cc>
Thu, 6 May 2010 19:48:42 +0000 (21:48 +0200)
committerMichael Walle <michael@walle.cc>
Thu, 6 May 2010 19:59:00 +0000 (21:59 +0200)
The port is only working in qemu at the moment. At least the SDRAM
initializing code is missing.

22 files changed:
umon_main/target/cpu/lm32/except_lm32.c [new file with mode: 0644]
umon_main/target/cpu/lm32/lm32.h [new file with mode: 0644]
umon_main/target/cpu/lm32/regs_lm32.c [new file with mode: 0644]
umon_main/target/cpu/lm32/strace_lm32.c [new file with mode: 0644]
umon_ports/milkymist/MM_ONE_boot.ldt [new file with mode: 0644]
umon_ports/milkymist/MM_ONE_ramtst.ldt [new file with mode: 0644]
umon_ports/milkymist/bashrc [new file with mode: 0644]
umon_ports/milkymist/config.h [new file with mode: 0644]
umon_ports/milkymist/cpu.h [new file with mode: 0644]
umon_ports/milkymist/cpuio.c [new file with mode: 0644]
umon_ports/milkymist/cpuio.h [new file with mode: 0644]
umon_ports/milkymist/etherdev.c [new file with mode: 0644]
umon_ports/milkymist/flashtest.scr [new file with mode: 0755]
umon_ports/milkymist/flashtest.scr.ucon [new file with mode: 0755]
umon_ports/milkymist/makefile [new file with mode: 0644]
umon_ports/milkymist/regnames.c [new file with mode: 0644]
umon_ports/milkymist/reset.S [new file with mode: 0644]
umon_ports/milkymist/target_version.h [new file with mode: 0644]
umon_ports/milkymist/tfsdev.h [new file with mode: 0644]
umon_ports/milkymist/vgafb.c [new file with mode: 0644]
umon_ports/milkymist/xcmddcl.h [new file with mode: 0644]
umon_ports/milkymist/xcmdtbl.h [new file with mode: 0644]

diff --git a/umon_main/target/cpu/lm32/except_lm32.c b/umon_main/target/cpu/lm32/except_lm32.c
new file mode 100644 (file)
index 0000000..fe271c1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Author: Michael Walle <michael@walle.cc>
+ * License: Lucent Public License 1.02
+ */
+#include "config.h"
+#include "cpu.h"
+#include "cpuio.h"
+#include "genlib.h"
+#include "stddefs.h"
+#include "warmstart.h"
+
+ulong  ExceptionAddr;
+int            ExceptionType;
+
+/* exception():
+ * This is the first 'C' function called out of a monitor-installed
+ * exception handler. 
+ */
+void
+exception(ulong addr, int type)
+{
+       ExceptionAddr = addr;
+       ExceptionType = type;
+
+       monrestart(EXCEPTION);
+}
+
+void
+vinit()
+{
+       /* nothing here. vector table is set up in reset.S */
+}
+
+char *
+ExceptionType2String(int type)
+{
+       char *string;
+
+       switch(type) {
+               case EXCP_BREAKPOINT:
+                       string = "BREAKPOINT";
+                       break;
+               case EXCP_I_BUS_ERROR:
+                       string = "INSTRUCTION BUS ERROR";
+                       break;
+               case EXCP_WATCHPOINT:
+                       string = "WATCHPOINT";
+                       break;
+               case EXCP_D_BUS_ERROR:
+                       string = "DATA BUS ERROR";
+                       break;
+               case EXCP_DIVIDE_BY_ZERO:
+                       string = "DIVIDE BY ZERO";
+                       break;
+               case EXCP_INTERRUPT:
+                       string = "INTERRUPT";
+                       break;
+               case EXCP_SYSTEM_CALL:
+                       string = "SYSTEM CALL";
+                       break;
+               default:
+                       string = "unknown";
+                       break;
+       }
+
+       return(string);
+}
+
diff --git a/umon_main/target/cpu/lm32/lm32.h b/umon_main/target/cpu/lm32/lm32.h
new file mode 100644 (file)
index 0000000..c45c4fa
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _CPU_LM32_H
+#define _CPU_LM32_H
+
+static inline unsigned int lm32_get_ie()
+{
+       unsigned int ret;
+       asm volatile("rcsr %0, IE" : "=r"(ret) : );
+       return ret;
+}
+
+static inline void lm32_set_ie(unsigned int ie)
+{
+       asm volatile("wcsr IE, %0" : : "r"(ie));
+}
+
+static inline unsigned int lm32_get_im()
+{
+       unsigned int ret;
+       asm volatile("rcsr %0, IM" : "=r"(ret) : );
+       return ret;
+}
+
+static inline void lm32_set_im(unsigned int im)
+{
+       asm volatile("wcsr IM, %0" : : "r"(im));
+}
+
+static inline unsigned int lm32_get_ip()
+{
+       unsigned int ret;
+       asm volatile("rcsr %0, IP" : "=r"(ret) : );
+       return ret;
+}
+
+static inline void lm32_set_ip(unsigned int ip)
+{
+       asm volatile("wcsr IP, %0" : : "r"(ip));
+}
+
+static inline void lm32_flush_icache()
+{
+       asm volatile(
+                       "wcsr ICC, r0\n"
+                       "nop\n"
+                       "nop\n"
+                       "nop\n"
+                       "nop\n"
+       );
+}
+
+static inline void lm32_flush_dcache()
+{
+       asm volatile(
+                       "wcsr DCC, r0\n"
+                       "nop\n"
+       );
+}
+
+#endif
+
diff --git a/umon_main/target/cpu/lm32/regs_lm32.c b/umon_main/target/cpu/lm32/regs_lm32.c
new file mode 100644 (file)
index 0000000..76795e7
--- /dev/null
@@ -0,0 +1,13 @@
+static char  *regnames[] = {
+       "R0",           "R1",           "R2",           "R3",
+       "R4",           "R5",           "R6",           "R7",
+       "R8",           "R9",           "R10",          "R11",
+       "R12",          "R13",          "R14",          "R15",
+       "R16",          "R17",          "R18",          "R19",
+       "R20",          "R21",          "R22",          "R23",
+       "R24",          "R25",          "R26",          "R27",
+       "R28",          "R29",          "R30",          "R31",
+       "PC",           "EID",          "EBA",          "DEBA",
+       "IE",           "IM",       "IP"
+};
+
diff --git a/umon_main/target/cpu/lm32/strace_lm32.c b/umon_main/target/cpu/lm32/strace_lm32.c
new file mode 100644 (file)
index 0000000..38a44c0
--- /dev/null
@@ -0,0 +1,116 @@
+/* strace.c:
+ *     General notice:
+ *     This code is part of a boot-monitor package developed as a generic base
+ *     platform for embedded system designs.  As such, it is likely to be
+ *     distributed to various projects beyond the control of the original
+ *     author.  Please notify the author of any enhancements made or bugs found
+ *     so that all may benefit from the changes.  In addition, notification back
+ *     to the author will allow the new user to pick up changes that may have
+ *     been made by other users after this version of the code was distributed.
+ *
+ *     Note1: the majority of this code was edited with 4-space tabs.
+ *     Note2: as more and more contributions are accepted, the term "author"
+ *                is becoming a mis-representation of credit.
+ *
+ *     Original author:        Ed Sutter
+ *     Email:                          esutter@lucent.com
+ *     Phone:                          908-582-2351
+ *
+ */
+#include "config.h"
+#if INCLUDE_STRACE
+#include "tfs.h"
+#include "tfsprivate.h"
+#include "ctype.h"
+#include "genlib.h"
+#include "stddefs.h"
+#include "cpu.h"
+
+char *StraceHelp[] = {
+    "Stack trace",
+    "-[d:F:P:rs:v]",
+    " -d #   max depth count (def=20)",
+    " -F #   specify frame-pointer (don't use content of A6)",
+    " -P #   specify PC (don't use content of PC)",
+    " -r     dump regs",
+    " -v     verbose",
+    0,
+};
+
+int
+Strace(int argc,char *argv[])
+{
+       char    *symfile, fname[64];
+       TFILE   *tfp;
+       ulong   *framepointer, pc, fp, offset;
+    int                tfd, opt, maxdepth, pass, verbose, bullseye;
+
+       tfd = fp = 0;
+       maxdepth = 20;
+       verbose = 0;
+       pc = ExceptionAddr;
+    while ((opt=getopt(argc,argv,"d:F:P:rs:v")) != -1) {
+               switch(opt) {
+               case 'd':
+                       maxdepth = atoi(optarg);
+                       break;
+               case 'F':
+                       fp = strtoul(optarg,0,0);
+                       break;
+               case 'P':
+                       pc = strtoul(optarg,0,0);
+                       break;
+               case 'r':
+                       showregs();
+                       break;
+               case 'v':
+                       verbose = 1;
+                       break;
+           default:
+                       return(0);
+               }
+       }
+       
+       if (!fp)
+               getreg("A6", (ulong *)&framepointer);
+       else
+               framepointer = (ulong *)fp;
+
+       /* Start by detecting the presence of a symbol table file... */
+       symfile = getenv("SYMFILE");
+       if (!symfile)
+               symfile = SYMFILE;
+
+       tfp = tfsstat(symfile);
+       if (tfp)  {
+               tfd = tfsopen(symfile,TFS_RDONLY,0);
+               if (tfd < 0)
+                       tfp = (TFILE *)0;
+       }
+
+       /* Show current position: */
+       printf("   0x%08lx",pc);
+       if (tfp) {
+               AddrToSym(tfd,pc,fname,&offset);
+               printf(": %s()",fname);
+               if (offset)
+                       printf(" + 0x%lx",offset);
+       }
+       putchar('\n');
+
+       /* Now step through the stack frame... */
+       bullseye = pass = 0;
+       while(maxdepth) {
+               /* ADD_CODE_HERE */
+       }
+
+       if (!maxdepth)
+               printf("Max depth termination\n");
+       
+       if (tfp) {
+               tfsclose(tfd,0);
+       }
+    return(0);
+}
+
+#endif
diff --git a/umon_ports/milkymist/MM_ONE_boot.ldt b/umon_ports/milkymist/MM_ONE_boot.ldt
new file mode 100644 (file)
index 0000000..cda955f
--- /dev/null
@@ -0,0 +1,69 @@
+/* Linker file for building monitor using GNU toolset on PC...
+
+       General notice:
+       This code is part of a boot-monitor package developed as a generic base
+       platform for embedded system designs.  As such, it is likely to be
+       distributed to various projects beyond the control of the original
+       author.  Please notify the author of any enhancements made or bugs found
+       so that all may benefit from the changes.  In addition, notification back
+       to the author will allow the new user to pick up changes that may have
+       been made by other users after this version of the code was distributed.
+
+       Author: Ed Sutter
+       email:  esutter@lucent.com
+       phone:  908-582-2351
+
+*/
+
+MEMORY 
+{
+       ram (RWX):              org = BOOTRAMBASE,      len = BOOTRAMLEN
+       rom (RWX):              org = BOOTROMBASE,      len = BOOTROMLEN
+       resetv (RWX):   org = 0xfffffff0,       len = 0x10
+}
+
+SECTIONS
+{
+       .bss    :
+       {
+               bss_start = .;
+               *(.bss) *(COMMON)
+       } >ram
+
+       .sbss   :
+       {
+               *(.sbss)
+               bss_end = .;
+       } >ram
+
+       .text   :
+       {
+               boot_base = .;
+               reset.o(.text)
+       } >rom
+
+       .data   :
+       {
+               *(.data)
+       } >rom
+
+       .sdata  :
+       {
+               *(.sdata)
+       } >rom
+
+       .sdata2 :
+       {
+               *(.sdata2)
+       } >rom
+
+       .rodata :
+       {
+               *(.rodata)
+       } >rom
+
+       .got    :
+       {
+               *(.got)
+       } >rom
+}
diff --git a/umon_ports/milkymist/MM_ONE_ramtst.ldt b/umon_ports/milkymist/MM_ONE_ramtst.ldt
new file mode 100644 (file)
index 0000000..34d4203
--- /dev/null
@@ -0,0 +1,69 @@
+/* Linker file for building monitor using GNU toolset on PC...
+
+       General notice:
+       This code is part of a boot-monitor package developed as a generic base
+       platform for embedded system designs.  As such, it is likely to be
+       distributed to various projects beyond the control of the original
+       author.  Please notify the author of any enhancements made or bugs found
+       so that all may benefit from the changes.  In addition, notification back
+       to the author will allow the new user to pick up changes that may have
+       been made by other users after this version of the code was distributed.
+
+       Author: Ed Sutter
+       email:  esutter@lucent.com
+       phone:  908-582-2351
+
+*/
+etheraddr              = MACADDRBASE;
+alt_tfsdevtbl_base     = ALTTFSDEVTBLBASE;
+
+MEMORY 
+{
+       ram (RWX):              org = RAMTSTBASE,       len = RAMTSTLEN
+}
+
+SECTIONS
+{
+       .text   :
+       {
+               boot_base = .;
+               reset.o(.text)
+       } >ram
+
+       .data   :
+       {
+               *(.data)
+       } >ram
+
+       .sdata  :
+       {
+               *(.sdata)
+       } >ram
+
+       .sdata2 :
+       {
+               *(.sdata2)
+       } >ram
+
+       .rodata :
+       {
+               *(.rodata)
+       } >ram
+
+       .got    :
+       {
+               *(.got)
+       } >ram
+
+       .bss    :
+       {
+               bss_start = .;
+               *(.bss) *(COMMON)
+       } >ram
+
+       .sbss   :
+       {
+               *(.sbss)
+               bss_end = .;
+       } >ram
+}
diff --git a/umon_ports/milkymist/bashrc b/umon_ports/milkymist/bashrc
new file mode 100644 (file)
index 0000000..16ded27
--- /dev/null
@@ -0,0 +1,16 @@
+# Set prompt to reflect the target:
+PS1=TEMPLATE:
+
+# TITLE may be used by the 'title' tool in umon_setup
+export TITLE="TEMPLATE Monitor Development"
+
+# If UMONTOP is not set, then set it to the default:
+if [ "$UMONTOP" == "" ]
+then
+       export UMONTOP=../../umon_main
+fi
+
+# The umon_setup script looks for the presence of the EXT_UMON_SETUP
+# as a shell variable.  If it is present it assumes it is the fullpath
+# of a user-defined script that will be run as part of the umon setup.
+. $UMONTOP/host/bin/umon_setup
diff --git a/umon_ports/milkymist/config.h b/umon_ports/milkymist/config.h
new file mode 100644 (file)
index 0000000..a6e0c95
--- /dev/null
@@ -0,0 +1,200 @@
+#define CPU_BE
+#define PLATFORM_NAME  "Milkymist One"
+#define CPU_NAME       "LatticeMico32"
+
+#define FREQUENCY_HZ (100*1000000)
+
+/* LOOPS_PER_SECOND:
+ * Approximately the size of a loop that will cause a 1-second delay.
+ * This value can be adjusted by using the "sleep -c" command.
+ */
+#define LOOPS_PER_SECOND       (FREQUENCY_HZ / 10)
+#define TIMER_TICKS_PER_MSEC (FREQUENCY_HZ / 1000)
+
+/* PRE_TFSAUTOBOOT_HOOK():
+ * This is a port-specific function that will be called just prior to
+ * uMon running any/each autobootable file (not including monrc).
+#define PRE_TFSAUTOBOOT_HOOK() func()
+ */
+
+/* PRE_COMMANDLOOP_HOOK():
+ * This is a port-specific function that will be called just before
+ * MicroMonitor turns over control to the endless command processing
+ * loop in start() (start.c).
+#define PRE_COMMANDLOOP_HOOK() func()
+ */
+
+/* If a watchdog macro is needed, this is how you do it
+ * (using target specific code in the macro of course)...
+ * The remoteWatchDog() call is only needed if your appliation
+ * will override the monitor's watchdog macro.  If that isn't
+ * needed, then that logic can be omitted from the macro.
+
+#define WATCHDOG_MACRO                                                                                 \
+       {                                                                                                               \
+               extern void (*remoteWatchDog)(void);                            \
+               if (remoteWatchDog) {                                                           \
+                       remoteWatchdog()                                                                \
+               }                                                                                                       \
+               else {                                                                                          \
+                       *(unsigned long *)0xff000000 |= 0x00100000;             \
+                       *(unsigned long *)0xff000000 &= ~0x00100000;    \
+               }
+       }
+ *
+ */
+
+/* If the ENET_LINK_IS_UP macro is defined as some function, then
+ * that function will be called every half second for some number of
+ * ticks.  The default tick count is set by the definition of
+ * LINKUP_TICK_MAX also defined in that file.  This can be overridden
+ * here if necessary.  Refer to the function EthernetWaitforLinkup() in
+ * ethernet.c (umon_main/target/common/ethernet.c) for complete details.
+ *
+ * The function defined by ENET_LINK_IS_UP (shown below as phy_linkup())
+ * is assumed to return 1 if the link is up; else 0. 
+ *
+#define ENET_LINK_IS_UP phy_linkup
+#define LINKUP_TICK_MAX 10
+ *
+ * The purpose of this is to provide a common way to wait for the up-state
+ * of the link prior to allowing other commands to execute from uMon at
+ * startup.
+ */
+
+
+/* Flash bank configuration:
+ * Basic information needed to configure the flash driver.
+ * Fill in port specific values here.
+ */
+#define SINGLE_FLASH_DEVICE
+#define FLASH_COPY_TO_RAM              1
+#define FLASH_BANK0_BASE_ADDR          0x00000000
+#define FLASH_PROTECT_RANGE    "0-2"
+#define FLASH_BANK0_WIDTH       2
+#define FLASH_BANK0_SIZE        0x2000000
+#define FLASH_LARGEST_SECTOR    0x20000
+#define FLASH_TIMEOUT           10000000
+#define FLASH_NUM_SECTORS       256
+
+/* If there is a need to have the range of protected sectors locked (and
+ * the flash device driver supports it), then enable this macro...
+#define LOCK_FLASH_PROTECT_RANGE
+ */
+//#define APPRAMBASE_OVERRIDE 0x40000000
+
+#define DEFAULT_ETHERADD "01:02:03:04:05:06"
+
+/* TFS definitions:
+ * Values that configure the flash space that is allocated to TFS.
+ * Fill in port specific values here.
+ */
+#define TFSSPARESIZE                   FLASH_LARGEST_SECTOR
+#define TFSSTART                       (FLASH_BANK0_BASE_ADDR+0x80000)
+#define TFSEND                         0x01FDFFFF
+#define TFSSPARE                       (TFSEND+1)
+#define TFSSECTORCOUNT                 ((TFSSPARE-TFSSTART)/0x20000)
+#define TFS_EBIN_ELF                   1
+#define TFS_VERBOSE_STARTUP            1
+#define TFS_ALTDEVTBL_BASE             &alt_tfsdevtbl_base
+
+/* FLASHRAM Parameters (not required):
+ * Primarily used for configuring TFS on battery-backed RAM.
+ * For a simple (volatile) RAM-based TFS device, use the
+ * "tfs ramdev" command.
+ *
+ * Define a block of RAM space to be used as a TFS-device.
+ * This is a block of RAM that TFS is fooled into treating like flash.
+ * It essentially provides a RAM-based file-storage area.
+ */
+//#define FLASHRAM_BASE                        0x380000
+
+#ifdef FLASHRAM_BASE
+# define FLASHRAM_END                  0x3fffff
+# define FLASHRAM_SECTORSIZE   0x010000
+# define FLASHRAM_SPARESIZE            FLASHRAM_SECTORSIZE
+# define FLASHRAM_SECTORCOUNT  8
+# define FLASHRAM_BANKNUM              1
+# define FLASHBANKS                            2
+#else
+# define FLASHBANKS                            1
+#endif
+
+/* ALLOCSIZE:
+ * Specify the size of the memory block (in monitor space) that
+ * is to be allocated to malloc in the monitor.  Note that this
+ * size can be dynamically increased using the heap command at
+ * runtime.
+ */
+#define ALLOCSIZE              (64*1024)
+
+/* MONSTACKSIZE:
+ * The amount of space allocated to the monitor's stack.
+ */
+#define MONSTACKSIZE   (8*1024)
+
+/* INCLUDE_XXX Macros:
+ * Set/clear the appropriate macros depending on what you want
+ * to configure in your system.  The sanity of this list is tested
+ * through the inclusion of "inc_check.h" at the bottom of this list...
+ * When starting a port, set all but INCLUDE_MALLOC, INCLUDE_SHELLVARS,
+ * INCLUDE_MEMCMDS and INCLUDE_XMODEM to zero.  Then in small steps
+ * enable the following major features in the following order:
+ *
+ *     INCLUDE_FLASH to test the flash device drivers.
+ *     INCLUDE_TFS* to overlay TFS onto the flash. 
+ *  INCLUDE_ETHERNET, INCLUDE_TFTP to turn the ethernet interface.
+ *
+ * All other INCLUDE_XXX macros can be enabled as needed and for the
+ * most part, they're hardware independent.
+ * Note that for building a very small footprint, INCLUDE_MALLOC and
+ * INCLUDE_SHELLVARS can be disabled.
+ */
+                                                               
+#define INCLUDE_MALLOC                 1
+#define INCLUDE_MEMCMDS         1
+#define INCLUDE_SHELLVARS              1
+#define INCLUDE_XMODEM          1
+#define INCLUDE_EDIT            1
+#define INCLUDE_DISASSEMBLER    0
+#define INCLUDE_UNZIP           1
+#define INCLUDE_ETHERNET        1
+#define INCLUDE_ICMP                   1
+#define INCLUDE_TFTP            1
+#define INCLUDE_TFS             1
+#define INCLUDE_FLASH           1
+#define INCLUDE_LINEEDIT        1
+#define INCLUDE_DHCPBOOT        1
+#define INCLUDE_TFSAPI          1
+#define INCLUDE_TFSSYMTBL       1
+#define INCLUDE_TFSSCRIPT       1
+#define INCLUDE_TFSCLI          1
+#define INCLUDE_EE              1
+#define INCLUDE_GDB             0
+#define INCLUDE_STRACE          0
+#define INCLUDE_CAST            0
+#define INCLUDE_STRUCT          0
+#define INCLUDE_REDIRECT        1
+#define INCLUDE_QUICKMEMCPY     0
+#define INCLUDE_PROFILER        0
+#define INCLUDE_BBC             0
+#define INCLUDE_MEMTRACE        0
+#define INCLUDE_STOREMAC        0
+#define INCLUDE_VERBOSEHELP     1
+#define INCLUDE_HWTMR              0
+#define INCLUDE_PORTCMD                    0
+#define INCLUDE_USRLVL             0
+#define INCLUDE_FBI             1
+#define INCLUDE_PS2KBD          1
+
+/* Some fine tuning (if needed)...
+ * If these #defines are not in config.h, they default to '1' in
+ * various other include files within uMon source; hence, they're
+ * really only useful if you need to turn off ('0') the specific
+ * facility or block of code.
+ */
+#define INCLUDE_TFTPSRVR               0
+#define INCLUDE_ETHERVERBOSE   1
+#define INCLUDE_MONCMD                 0
+
+#include "inc_check.h"
diff --git a/umon_ports/milkymist/cpu.h b/umon_ports/milkymist/cpu.h
new file mode 100644 (file)
index 0000000..3824dac
--- /dev/null
@@ -0,0 +1,15 @@
+/* cpu.h:
+ */
+#define MONARGV0 "umon"
+
+#define RESETFUNC()         ((void(*)())target_reset)
+
+#define EXCP_RESET          0
+#define EXCP_BREAKPOINT     1
+#define EXCP_I_BUS_ERROR    2
+#define EXCP_WATCHPOINT     3
+#define EXCP_D_BUS_ERROR    4
+#define EXCP_DIVIDE_BY_ZERO 5
+#define EXCP_INTERRUPT      6
+#define EXCP_SYSTEM_CALL    7
+
diff --git a/umon_ports/milkymist/cpuio.c b/umon_ports/milkymist/cpuio.c
new file mode 100644 (file)
index 0000000..71cd47f
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Author: Michael Walle <michael@walle.cc>
+ * License: Lucent Public License 1.02
+ */
+
+#include "config.h"
+#include "stddefs.h"
+#include "cpuio.h"
+#include "genlib.h"
+#include "cache.h"
+#include "warmstart.h"
+#include "timer.h"
+#include "lm32.h"
+#include "ps2_kbd.h"
+
+/* devInit():
+ * As a bare minimum, initialize the console UART here using the
+ * incoming 'baud' value as the baud rate.
+ */
+void
+devInit(int baud)
+{
+       ConsoleBaudSet(baud);
+
+#if INCLUDE_PS2KBD
+       ps2_kbd_init();
+#endif
+}
+
+/* ConsoleBaudSet():
+ * Provide a means to change the baud rate of the running
+ * console interface.  If the incoming value is not a valid
+ * baud rate, then default to 9600.
+ * In the early stages of a new port this can be left empty.
+ * Return 0 if successful; else -1.
+ */
+int
+ConsoleBaudSet(int baud)
+{
+       UART_DIVISOR = CPU_FREQUENCY/baud/16;
+
+       return(0);
+}
+
+ulong
+target_timer(void)
+{
+       return TIMER0_COUNTER;
+}
+
+/* target_console_empty():
+ * Target-specific portion of flush_console() in chario.c.
+ * This function returns 1 if there are no characters waiting to
+ * be put out on the UART; else return 0 indicating that the UART
+ * is still busy outputting characters from its FIFO.
+ * In the early stages of a new port this can simply return 1.
+ */
+int
+target_console_empty(void)
+{
+       return(1);
+}
+
+/* target_putchar():
+ * When buffer has space available, load the incoming character
+ * into the UART.
+ */
+int
+target_putchar(char c)
+{
+       UART_RXTX = c;
+
+    /* Wait for transmit ready bit */
+    while(1) {
+               if (lm32_get_ip() & (1 << UART_IRQ_TX))
+            break;
+    }
+       lm32_set_ip(1 << UART_IRQ_TX);
+
+    return((int)c);
+}
+
+int
+uart_gotachar(void)
+{
+       if (lm32_get_ip() & (1 << UART_IRQ_RX))
+        return(1);
+       return(0);
+}
+
+/* target_gotachar():
+ * Return 0 if no char is avaialable at UART rcv fifo; else 1.
+ * Do NOT pull character out of fifo, just return status. 
+ *
+ * Define INCLUDE_BLINKLED in config.h and add STATLED_ON()
+ * and STATLED_OFF() macros (or functions)  so that uMon will
+ * run and blink a target LED at a configured (or default 500msec)
+ * interval...
+ */
+int
+target_gotachar(void)
+{
+#if INCLUDE_BLINKLED
+       static uint8_t ledstate;
+       static struct elapsed_tmr tmr;
+
+#ifndef BLINKON_MSEC
+#define BLINKON_MSEC 500
+#define BLINKOFF_MSEC 500
+#endif
+
+       switch(ledstate) {
+               case 0:
+                       startElapsedTimer(&tmr,BLINKON_MSEC);
+                       ledstate = 1;
+                       STATLED_ON();
+                       break;
+               case 1:
+                       if(msecElapsed(&tmr)) {
+                               STATLED_OFF();
+                               ledstate = 2;
+                               startElapsedTimer(&tmr,BLINKOFF_MSEC);
+                       }
+                       break;
+               case 2:
+                       if(msecElapsed(&tmr)) {
+                               STATLED_ON();
+                               ledstate = 1;
+                               startElapsedTimer(&tmr,BLINKON_MSEC);
+                       }
+                       break;
+       }
+#endif
+       if (uart_gotachar())
+        return(1);
+#if INCLUDE_PS2KBD
+       if (ps2_gotachar())
+               return(1);
+#endif
+    return(0);
+}
+
+/* target_getchar():
+ * Assume there is a character in the UART's input buffer and just
+ * pull it out and return it.
+ */
+int 
+target_getchar(void)
+{
+    char    c;
+
+#if INCLUDE_PS2KBD
+       if (ps2_gotachar()) {
+               c = ps2_getchar();
+       } else
+#endif
+       {
+               lm32_set_ip(1 << UART_IRQ_RX);
+               c = UART_RXTX;
+       }
+
+    return((int)c);
+}
+
+/* intsoff():
+ * Disable all system interrupts here and return a value that can
+ * be used by intsrestore() (later) to restore the interrupt state.
+ */
+ulong
+intsoff(void)
+{
+       ulong status;
+
+       status = 0;
+       /* ADD_CODE_HERE */
+       return(status);
+}
+
+/* intsrestore():
+ * Re-establish system interrupts here by using the status value
+ * that was returned by an earlier call to intsoff().
+ */
+void
+intsrestore(ulong status)
+{
+       /* ADD_CODE_HERE */
+}
+
+/* cacheInitForTarget():
+ * Establish target specific function pointers and
+ * enable i-cache...
+ * Refer to $core/cache.c for a description of the function pointers.
+ * NOTE:
+ * If cache (either I or D or both) is enabled, then it is important
+ * that the appropriate cacheflush/invalidate function be established.
+ * This is very important because programs (i.e. cpu instructions) are
+ * transferred to memory using data memory accesses and could
+ * potentially result in cache coherency problems.
+ */
+void
+cacheInitForTarget(void)
+{
+       /* ADD_CODE_HERE */
+}
+
+/* target_reset():
+ * The default (absolute minimum) action to be taken by this function
+ * is to call monrestart(INITIALIZE).  It would be better if there was
+ * some target-specific function that would really cause the target
+ * to reset...
+ */
+void
+target_reset(void)
+{
+       flushDcache(0,0);
+       disableDcache();
+       invalidateIcache(0,0);
+       disableIcache();
+       monrestart(INITIALIZE);
+}
+
+void
+timer_init(void)
+{
+       TIMER0_COUNTER = 0;
+       TIMER0_CONTROL = TIMER_ENABLE;
+}
+
+/* If any CPU IO wasn't initialized in reset.S, do it here...
+ * This just provides a "C-level" IO init opportunity. 
+ */
+void
+initCPUio(void)
+{
+       /* ADD_CODE_HERE */
+}
diff --git a/umon_ports/milkymist/cpuio.h b/umon_ports/milkymist/cpuio.h
new file mode 100644 (file)
index 0000000..9f1c926
--- /dev/null
@@ -0,0 +1,83 @@
+#define MONARGV0 "umon"
+#define DEFAULT_BAUD_RATE 115200
+#define CPU_FREQUENCY 83333333
+
+#define MMPTR(x) (*((volatile unsigned int *)(x)))
+
+/* uart */
+#define UART_RXTX           MMPTR(0x80000000)
+#define UART_DIVISOR        MMPTR(0x80000004)
+
+/* timer */
+#define TIMER0_CONTROL      MMPTR(0x80001010)
+#define TIMER0_COMPARE      MMPTR(0x80001014)
+#define TIMER0_COUNTER      MMPTR(0x80001010)
+
+#define TIMER_ENABLE        (1 << 0)
+#define TIMER_AUTORESTART   (1 << 1)
+
+/* network */
+#define MINIMAC_SETUP       MMPTR(0x80009000)
+#define MINIMAC_MDIO        MMPTR(0x80009004)
+#define MINIMAC_STATE0      MMPTR(0x80009008)
+#define MINIMAC_ADDR0       MMPTR(0x8000900c)
+#define MINIMAC_COUNT0      MMPTR(0x80009010)
+#define MINIMAC_STATE1      MMPTR(0x80009014)
+#define MINIMAC_ADDR1       MMPTR(0x80009018)
+#define MINIMAC_COUNT1      MMPTR(0x8000901c)
+#define MINIMAC_STATE2      MMPTR(0x80009020)
+#define MINIMAC_ADDR2       MMPTR(0x80009024)
+#define MINIMAC_COUNT2      MMPTR(0x80009028)
+#define MINIMAC_STATE3      MMPTR(0x8000902c)
+#define MINIMAC_ADDR3       MMPTR(0x80009030)
+#define MINIMAC_COUNT3      MMPTR(0x80009034)
+#define MINIMAC_TXADDR      MMPTR(0x80009038)
+#define MINIMAC_TXREMAINING MMPTR(0x8000903c)
+
+#define MINIMAC_SETUP_RXRST   (1 << 0)
+#define MINIMAC_SETUP_TXRST   (1 << 0)
+
+#define MINIMAC_STATE_EMPTY   0
+#define MINIMAC_STATE_LOADED  1
+#define MINIMAC_STATE_PENDING 2
+
+#define MINIMAC_MDIO_DO       (1 << 0)
+#define MINIMAC_MDIO_DI       (1 << 1)
+#define MINIMAC_MDIO_OE       (1 << 2)
+#define MINIMAC_MDIO_CLK      (1 << 3)
+
+/* framebuffer */
+#define VGAFB_CONTROL         MMPTR(0x80003000)
+#define VGAFB_HRES            MMPTR(0x80003004)
+#define VGAFB_HSYNC_START     MMPTR(0x80003008)
+#define VGAFB_HSYNC_END       MMPTR(0x8000300C)
+#define VGAFB_HSCAN           MMPTR(0x80003010)
+#define VGAFB_VRES            MMPTR(0x80003014)
+#define VGAFB_VSYNC_START     MMPTR(0x80003018)
+#define VGAFB_VSYNC_END       MMPTR(0x8000301C)
+#define VGAFB_VSCAN           MMPTR(0x80003020)
+#define VGAFB_BASEADDRESS     MMPTR(0x80003024)
+#define VGAFB_BASEADDRESS_ACT MMPTR(0x80003028)
+#define VGAFB_BURST_COUNT     MMPTR(0x8000302C)
+
+#define VGAFB_CONTROL_RESET   (1 << 0)
+
+#define PIXFMT_IS_RGB565 1
+#define PIXFMT_IS_RGB555 0
+#define PIXELS_PER_ROW  640
+#define PIXELS_PER_COL  480
+
+#include "stddefs.h"
+extern uchar vgafb_framebuffer[];
+#define FRAME_BUFFER_BASE_ADDR vgafb_framebuffer
+#define FBDEV_SETSTART fbdev_setstart
+
+/* ps2 */
+#define PS2_REG(x)            MMPTR(0x80007000 + (x * 4))
+#define PS2_TIMEOUT           100000
+
+/* interrupts */
+#define TIMER0_IRQ          1
+#define UART_IRQ_RX         3
+#define UART_IRQ_TX         4
+
diff --git a/umon_ports/milkymist/etherdev.c b/umon_ports/milkymist/etherdev.c
new file mode 100644 (file)
index 0000000..13115e7
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Author: Michael Walle <michael@walle.cc>
+ * License: Lucent Public License 1.02
+ *
+ * Some parts are derived from the milkymist BIOS available at:
+ *   http://github.com/lekernel/milkymist
+ *
+ * The author, namely Sebastien Bourdeauducq, permitted these parts to be
+ * released under the Lucent Public License.
+ */
+
+#include "config.h"
+#include "genlib.h"
+#include "stddefs.h"
+#include "ether.h"
+#include "cpuio.h"
+#include "lm32.h"
+
+#if INCLUDE_ETHERNET
+
+#define PKT_BUF_LEN 1512
+
+static uchar *tx_buf;
+static uchar *rx_buf;
+static uchar *rx_buf_back;
+
+static uchar _buffers[3*PKT_BUF_LEN];
+
+static struct {
+       ulong tx_pkt;
+       ulong rx_pkt;
+} stats;
+
+static uchar preamble_sfd[8] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5};
+/*
+ * enreset():
+ *     Reset the PHY and MAC.
+ */
+void
+enreset(void)
+{
+       MINIMAC_STATE0 = MINIMAC_STATE_EMPTY;
+       MINIMAC_TXREMAINING = 0;
+       MINIMAC_SETUP = MINIMAC_SETUP_RXRST | MINIMAC_SETUP_TXRST;
+
+       /* TODO: reset phy */
+}
+
+/*
+ * eninit():
+ * Initialize the PHY and MAC.
+ * This would include establishing buffer descriptor tables and
+ * all the support code that will be used by the ethernet device.
+ *
+ * It can be assumed at this point that the array uchar BinEnetAddr[6]
+ * contains the 6-byte MAC address.
+ *
+ * Return 0 if successful; else -1.
+ */
+int
+eninit(void)
+{
+       /* Initialize the Phy */
+       /* TODO: init phy */
+
+       /* Query the PHY to determine if the link is up.
+        * If not just default to a 10Base-T, half-duplex interface config.
+        * If link is up, then attempt auto-negotiation.
+        */
+       /* ADD_CODE_HERE */
+
+       /* Init buffers */
+       tx_buf = _buffers;
+       rx_buf = _buffers + PKT_BUF_LEN;
+       rx_buf_back = _buffers + 2*PKT_BUF_LEN;
+
+       /* Set preamble and SFD for the TX buffer */
+       memset(tx_buf, preamble_sfd, sizeof(preamble_sfd));
+
+       /* Initialize the MAC */
+       MINIMAC_ADDR0 = (unsigned int)rx_buf_back;
+       MINIMAC_STATE0 = MINIMAC_STATE_LOADED;
+       MINIMAC_SETUP = 0;
+
+       return (0);
+}
+
+int
+EtherdevStartup(int verbose)
+{
+       /* Initialize local device error counts (if any) here. */
+       /* OPT_ADD_CODE_HERE */
+
+       /* Put ethernet controller in reset: */
+       enreset();
+
+       /* Initialize controller and return the value returned by
+        * eninit().
+        */
+       return(eninit());
+}
+
+/* disablePromiscuousReception():
+ * Provide the code that disables promiscuous reception.
+ */
+void
+disablePromiscuousReception(void)
+{
+       /* minimac doesn't have a mac filter */
+}
+
+/* enablePromiscuousReception():
+ * Provide the code that enables promiscuous reception.
+ */
+void
+enablePromiscuousReception(void)
+{
+       /* minimac doesn't have a mac filter */
+}
+
+/* disableBroadcastReception():
+ * Provide the code that disables broadcast reception.
+ */
+void
+disableBroadcastReception(void)
+{
+       /* minimac doesn't have a mac filter */
+}
+
+/* enableBroadcastReception():
+ * Provide the code that enables broadcast reception.
+ */
+void
+enableBroadcastReception(void)
+{
+       /* minimac doesn't have a mac filter */
+}
+
+/* 
+ * enselftest():
+ *     Run a self test of the ethernet device(s).  This can be stubbed
+ *     with a return(1).
+ *     Return 1 if success; else -1 if failure.
+ */
+int
+enselftest(int verbose)
+{
+       return(1);
+}
+
+/* ShowEtherdevStats():
+ * This function is used to display device-specific stats (error counts
+ * usually).
+ */
+void
+ShowEtherdevStats(void)
+{
+       /* OPT_ADD_CODE_HERE */
+}
+
+/* getXmitBuffer():
+ * Return a pointer to the buffer that is to be used for transmission of
+ * the next packet.  Since the monitor's driver is EXTREMELY basic,
+ * there will only be one packet ever being transmitted.  No need to queue
+ * up transmit packets.
+ */
+uchar *
+getXmitBuffer(void)
+{
+       return(tx_buf + sizeof(preamble_sfd));
+}
+
+/* sendBuffer():
+ * Send out the packet assumed to be built in the buffer returned by the
+ * previous call to getXmitBuffer() above.
+ */
+int
+sendBuffer(int length)
+{
+       ulong crc;
+
+       uchar *tx_pkt = tx_buf + sizeof(preamble_sfd);
+
+#if INCLUDE_ETHERVERBOSE
+       if (EtherVerbose & SHOW_OUTGOING)
+               printPkt((struct ether_header *)tx_pkt, length, ETHER_OUTGOING);
+#endif
+
+       /* Bump up the packet length to a minimum of 64 bytes.
+        */
+       if (length < 64)
+               length = 64;
+
+       /* Add the code that will tickle the device into sending out the
+        * buffer that was previously returned by getXmitBuffer() above...
+        */
+       crc = crc32(tx_pkt, length);
+       tx_pkt[length    ] = (crc & 0xff);
+       tx_pkt[length + 1] = (crc & 0xff00) >> 8;
+       tx_pkt[length + 2] = (crc & 0xff0000) >> 16;
+       tx_pkt[length + 3] = (crc & 0xff000000) >> 24;
+
+       length += 12;
+
+       MINIMAC_TXADDR = (unsigned int) tx_buf;
+       MINIMAC_TXREMAINING = length;
+
+       EtherXFRAMECnt++;
+       return(0);
+}
+
+/* DisableEtherdev():
+ * Fine as it is...
+ */
+void
+DisableEtherdev(void)
+{
+       enreset();
+}
+
+/* extGetIpAdd():
+ * If there was some external mechanism (other than just using the
+ * IPADD shell variable established in the monrc file) for retrieval of
+ * the board's IP address, then do it here...
+ */
+char *
+extGetIpAdd(void)
+{
+       return((char *)0);
+}
+
+/* extGetEtherAdd():
+ * If there was some external mechanism (other than just using the
+ * ETHERADD shell variable established in the monrc file) for retrieval of
+ * the board's MAC address, then do it here...
+ */
+char *
+extGetEtherAdd(void)
+{
+       return((char *)0);
+}
+
+/*
+ * polletherdev():
+ * Called continuously by the monitor (ethernet.c) to determine if there
+ * is any incoming ethernet packets.
+ *
+ * NOTES:
+ * 1. This function must be reentrant, because there are a few cases in
+ *    processPACKET() where pollethernet() may be called.
+ * 2. It should only process one packet per call.  This is important
+ *    because if allowed to stay here to flush all available packets,
+ *    it may starve the rest of the system (especially in cases of heavy
+ *    network traffic).
+ * 3. There are cases in the monitor's execution that may cause the
+ *    polling polletherdev() to cease for several seconds.  Depending on
+ *    network traffic, this may cause the input buffering mechanism on
+ *    the ethernet device to overflow.  A robust polletherdev() function
+ *    should support this gracefully (i.e. when the error is detected,
+ *    attempt to pass all queued packets to processPACKET(), then do what
+ *    is necessary to clear the error).
+ */
+int
+polletherdev(void)
+{
+       uchar *pktbuf = (uchar *)0;
+       uchar *buf;
+       int     pktlen = 0, pktcnt = 0;
+
+       if (MINIMAC_STATE0 == MINIMAC_STATE_PENDING) {
+               lm32_flush_dcache();
+                               
+               pktbuf = rx_buf_back + 8;
+               pktlen = MINIMAC_COUNT0 - 8;
+
+               /* switch rx buffers */
+               buf = rx_buf;
+               rx_buf = rx_buf_back;
+               rx_buf_back = buf;
+
+               MINIMAC_ADDR0 = (unsigned int)rx_buf_back;
+               MINIMAC_STATE0 = MINIMAC_STATE_LOADED;
+
+               printPkt((struct ether_header *)pktbuf, pktlen, ETHER_INCOMING);
+               
+               processPACKET((struct ether_header *)pktbuf, pktlen);
+               pktcnt++;
+               //MINIMAC_STATE0 = MINIMAC_STATE_LOADED;
+       }
+       return(pktcnt);
+}
+
+#endif
diff --git a/umon_ports/milkymist/flashtest.scr b/umon_ports/milkymist/flashtest.scr
new file mode 100755 (executable)
index 0000000..c45f8c5
--- /dev/null
@@ -0,0 +1,122 @@
+# flashtest.scr:
+# This script can be run after a port is completed to verify
+# that the flash driver can properly deal with various address
+# and data alignments.
+#
+# Required shell variables: SECTORBASE & SNUM ...
+#
+# SECTORBASE: set to the base address of some sector within
+#   TFS that can be erased during this test.
+# SNUM: the number of the sector whose base address is
+#   $SECTORBASE.
+# NOLOCK: set to TRUE if the flash driver doesn't support flash
+#   lock/unlock
+
+if $SECTORBASE seq \$SECTORBASE goto USAGE
+if $SNUM seq \$SNUM goto USAGE
+
+# Copy SECTORBASE to SBASE, and APPRAMBASE to SRC
+set SBASE $SECTORBASE
+set SRC $APPRAMBASE
+
+# TEST1:
+echo TEST1: 
+echo Verify pattern
+# Establish a few known bytes of source data:
+pm $SRC 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a
+set SRC=hex($SRC+8)
+pm $SRC 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a
+dm $APPRAMBASE 16
+set SRC $APPRAMBASE
+
+# Unlock and erase the sector and verify erasure
+# (should be all 0xff):
+gosub FLASH_UNLOCK
+flash erase $SNUM
+dm $SBASE 16
+set SIZE 16
+
+# LOOP:
+if $SIZE eq 0 goto NEXTLOOP
+gosub FLASHTEST
+set SBASE=hex($SBASE+1) 
+set SRC=hex($SRC+1)
+set SIZE=hex($SIZE-2)
+goto LOOP
+
+# NEXTLOOP:
+set SRC $APPRAMBASE
+set SBASE $SECTORBASE
+set SIZE 8
+# LOOP2:
+if $SIZE eq 0 goto TEST2
+gosub FLASHTEST
+set SIZE=hex($SIZE-1)
+goto LOOP2
+
+# FLASHTEST
+flash write $SBASE $SRC $SIZE
+dm $SECTORBASE 16
+flash erase $SNUM
+dm $SECTORBASE 16
+return
+
+# TEST2:
+# Write a few known initial bytes of data with 0xff's within
+# the data...
+echo TEST2:
+pm $APPRAMBASE 0x41 0xff 0xff 0x44 0x45 0xff 0x47 0x48
+flash write $SECTORBASE $APPRAMBASE 8
+
+# Then try to insert data into the fields that were
+# originally 0xff...
+pm $APPRAMBASE 0x42 0x43
+set ADDR=hex($SECTORBASE+1)
+flash write $ADDR $APPRAMBASE 2
+
+pm $APPRAMBASE 0x46
+set ADDR=hex($SECTORBASE+5)
+flash write $ADDR $APPRAMBASE 1
+
+# Now make sure the write worked...
+pm $APPRAMBASE 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48
+echo Next two lines of data should match...
+dm $SECTORBASE 8
+dm $APPRAMBASE 8
+cm -v $APPRAMBASE $SECTORBASE 8
+flash erase $SNUM
+
+#####################
+#
+# TEST 3:
+echo TEST3:
+if $NOLOCK seq TRUE exit
+echo Verify that a locked sector will not write or erase:
+set SCRIPT_IGNORE_ERROR TRUE
+flash write $SECTORBASE $APPRAMBASE 1
+flash lock $SNUM
+dm $SECTORBASE 16
+echo This line should generate a flash write error...
+flash write $SECTORBASE $APPRAMBASE 16
+dm $SECTORBASE 16
+echo This erase should fail...
+flash erase $SNUM
+gosub FLASH_UNLOCK
+echo This erase should succeed...
+flash erase $SNUM
+dm $SECTORBASE 16
+
+exit
+
+# FLASH_UNLOCK:
+if $NOLOCK seq TRUE return
+flash unlock $SNUM
+return 
+
+# FLASH_LOCK:
+if $NOLOCK seq TRUE return
+flash lock $SNUM
+return 
+
+# USAGE:
+echo Establish SECTORBASE and SNUM, then rerun.
diff --git a/umon_ports/milkymist/flashtest.scr.ucon b/umon_ports/milkymist/flashtest.scr.ucon
new file mode 100755 (executable)
index 0000000..621209d
--- /dev/null
@@ -0,0 +1,133 @@
+#####\r
+#\r
+# flashtest.scr:\r
+# This script is the uCon-equivalent of flashtest.scr as supplied\r
+# with uMon to run on a uMon based target.  The benefit of this script\r
+# is that TFS does not have to be installed on the system to run this\r
+# through uCon.\r
+#\r
+#####\r
+set PROMPT uMON>\r
+gosub GET_APPRAMBASE_FROM_TARGET\r
+\r
+# Ask the user for sector/flash information...\r
+dialog Q_AND_A "Enter the base address of a sector we can use to test:"\r
+set SECTORBASE $DIALOG\r
+dialog Q_AND_A "Enter that sector number:"\r
+set SNUM $DIALOG\r
+dialog DDLIST "Does this driver support flash lock?" YES NO\r
+set FLOCK $DIALOG\r
+\r
+# Copy SECTORBASE to SBASE, and APPRAMBASE to SRC\r
+set SBASE $SECTORBASE\r
+set SRC $APPRAMBASE\r
+\r
+# TEST1:\r
+echo TEST1: \r
+echo Verify pattern\r
+# Establish a few known bytes of source data:\r
+send "pm $SRC 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a"\r
+set SRC=hex($SRC+8)\r
+send "pm $SRC 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a"\r
+send "dm $APPRAMBASE 16"\r
+set SRC $APPRAMBASE\r
+\r
+# Unlock and erase the sector and verify erasure\r
+# (should be all 0xff):\r
+gosub FLASH_UNLOCK\r
+send "flash erase $SNUM"\r
+send "dm $SBASE 16"\r
+set SIZE 16\r
+\r
+# LOOP:\r
+if $SIZE eq 0 goto NEXTLOOP\r
+gosub FLASHTEST\r
+set SBASE=hex($SBASE+1) \r
+set SRC=hex($SRC+1)\r
+set SIZE=hex($SIZE-2)\r
+goto LOOP\r
+\r
+# NEXTLOOP:\r
+set SRC $APPRAMBASE\r
+set SBASE $SECTORBASE\r
+set SIZE 8\r
+# LOOP2:\r
+if $SIZE eq 0 goto TEST2\r
+gosub FLASHTEST\r
+set SIZE=hex($SIZE-1)\r
+goto LOOP2\r
+\r
+# FLASHTEST\r
+send "flash write $SBASE $SRC $SIZE"\r
+send "dm $SECTORBASE 16"\r
+send "flash erase $SNUM"\r
+send "dm $SECTORBASE 16"\r
+return\r
+\r
+# TEST2:\r
+# Write a few known initial bytes of data with 0xff's within\r
+# the data...\r
+echo TEST2:\r
+send "pm $APPRAMBASE 0x41 0xff 0xff 0x44 0x45 0xff 0x47 0x48"\r
+send "flash write $SECTORBASE $APPRAMBASE 8"\r
+\r
+# Then try to insert data into the fields that were\r
+# originally 0xff...\r
+send "pm $APPRAMBASE 0x42 0x43"\r
+set ADDR=hex($SECTORBASE+1)\r
+send "flash write $ADDR $APPRAMBASE 2"\r
+\r
+send "pm $APPRAMBASE 0x46"\r
+set ADDR=hex($SECTORBASE+5)\r
+send "flash write $ADDR $APPRAMBASE 1"\r
+\r
+# Now make sure the write worked...\r
+send "pm $APPRAMBASE 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48"\r
+echo Next two lines of data should match...\r
+send "dm $SECTORBASE 8"\r
+send "dm $APPRAMBASE 8"\r
+send "cm -v $APPRAMBASE $SECTORBASE 8"\r
+send "flash erase $SNUM"\r
+\r
+#####################\r
+#\r
+# TEST 3:\r
+if $FLOCK seq NO exit\r
+echo TEST3:\r
+echo Verify that a locked sector will not write or erase:\r
+send "flash write $SECTORBASE $APPRAMBASE 1"\r
+send "flash lock $SNUM"\r
+send "dm $SECTORBASE 16"\r
+echo This line should generate a flash write error...\r
+send "flash write $SECTORBASE $APPRAMBASE 16"\r
+send "dm $SECTORBASE 16"\r
+echo This erase should fail...\r
+send "flash erase $SNUM"\r
+gosub FLASH_UNLOCK\r
+echo This erase should succeed...\r
+send "flash erase $SNUM"\r
+send "dm $SECTORBASE 16"\r
+\r
+exit\r
+\r
+# FLASH_UNLOCK:\r
+if $FLOCK seq NO return\r
+send "flash unlock $SNUM"\r
+return \r
+\r
+# FLASH_LOCK:\r
+if $FLOCK seq NO return\r
+send "flash lock $SNUM"\r
+return \r
+\r
+# USAGE:\r
+echo Establish SECTORBASE and SNUM, then rerun.\r
+\r
+# GET_APPRAMBASE_FROM_TARGET:\r
+\r
+log on C:/log\r
+send "echo \$APPRAMBASE"\r
+log off\r
+file token C:/log 1 2\r
+set APPRAMBASE $FILE\r
+return\r
diff --git a/umon_ports/milkymist/makefile b/umon_ports/milkymist/makefile
new file mode 100644 (file)
index 0000000..dedf1d3
--- /dev/null
@@ -0,0 +1,195 @@
+###############################################################################
+#
+# MicroMonitor Release 1.0 milkymist board makefile.
+#
+###############################################################################
+#
+# Build Variables:
+# TOPDIR:
+#      Set to the content of UMONTOP, which is an externally defined
+#      shell variable assumed by this environment to be set to the full
+#      path of the umon_main directory.
+# PLATFORM:
+#      ASCII name of the target platform (e.g. "Cogent CSB472")
+# TGTDIR:
+#      The name of the working directory that this port is to be built in.
+# CPUTYPE/FILETYPE:
+#      This combination of variables builds the GCC prefix (and is used for
+#      a few other purposes.
+#      Typical values for CPUTYPE are arm, ppc, m68k, mips and xscale.
+#      Typical values for FILETYPE are elf, coff, rtems and aout.
+# CUSTOM_FLAGS:
+#      Establish the custom portion of the 'C' flags used for cross-compilation.
+#      Refer to the file $(UMONTOP)/target/make/common.make for the set of
+#      variables used (in addition to this one) to build the final CFLAGS
+#      variable.
+# CUSTOM_AFLAGS:
+#      Similar to CUSTOM_FLAGS, this is used for assembler files.
+# CUSTOM_INCLUDE:
+#      Used to specify port-specific additions to the INCLUDES list. 
+#
+PLATFORM               = MM_ONE
+TOPDIR                 = $(UMONTOP)
+TGTDIR                 = milkymist
+CPUTYPE                        = lm32
+FILETYPE               = elf
+CUSTOM_CFLAGS  = -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled
+CUSTOM_AFLAGS  =
+CUSTOM_INCLUDE =
+
+# If using something other than the Microcross model for the GNU
+# tools (i.e. CPUTYPE-FILETYPE-TOOL) then specify the tool prefix
+# here... (for example, powerpc-405-linux-gnu)
+#TOOL_PREFIX   =       powerpc-405-linux-gnu
+
+###############################################################################
+#
+# Memory map configuration:
+# The following variables are used to establish the system's memory map.
+# The values associated with these variables are substituted into
+# the .ldt (.ld template) files to generate the .ld files actually used
+# for the final linkage.  This allows the user to override these defaults
+# without touching a memory map file.  Adjust them appropriately based on
+# the target memory map.
+#
+# BOOTRAMBASE/BOOTRAMLEN: 
+# BOOTROMBASE/BOOTROMLEN: 
+#      Specify the base and length of RAM and ROM (i.e. flash) space used by
+#      the version of the monitor that will reside (and run out of) boot flash.
+# RAMTSTBASE/RAMTSTLEN:
+#      Specify the base and length of RAM to be used by the "test" version of
+#      the monitor that will reside entirely in RAM.
+#BOOTRAMBASE=0x47fe0000
+BOOTRAMBASE=0x40000000
+#BOOTRAMLEN=0x20000
+BOOTRAMLEN=0x8000000
+BOOTROMBASE=0x00000000
+BOOTROMLEN=0x2000000
+RAMTSTBASE=0x40000000
+RAMTSTLEN=0x8000000
+
+# These next two hard-coded values are used by ram-based versions of
+# uMon to allow them to know where these flash-based structures are located.
+# Obviously the addresses are port-specific and are specified here for
+# reference only.
+MACADDRBASE=0xfff80000
+ALTTFSDEVTBLBASE=0xfff80020
+
+
+include        $(TOPDIR)/target/make/common.make
+
+###############################################################################
+#
+# Build each variable from a list of individual filenames...
+#
+# LOCSSRC:
+#      Local (in this directory) assembler files.
+# LOCCSRC:
+#      Local (in this directory) 'C' files.
+#      Note regarding except_xxx.c and strace_xxx.c...
+#      Prior to writing your processor-specific except_xxx.c and strace_xxx.c
+#      check the target's cpu directory to make sure it isn't already available.
+#      If available, then change the filenames accordingly and move them to
+#      the CPUCSRC filelist.  If you need to develop them, build them in
+#      this port-specific directory, then upon completion they can be moved
+#      to the cpu-specific directory so that they can be used by other ports.
+# CPUSSRC:
+#      CPU-specific assembler files in the main/target/cpu/CPU directory.
+# CPUSSRC:
+#      CPU-specific 'C' files in the main/target/cpu/CPU directory.
+# COMCSRC:
+#      Core 'C' files found in the main/target/core directory.
+# IODEVSRC:
+#      Device-specific files found in main/target/dev directory.       
+# FLASHSRC:
+#      The flash driver file found in main/target/flash/devices directory.
+#
+LOCSSRC                = reset.S 
+CPUSSRC                = 
+LOCCSRC                = cpuio.c etherdev.c vgafb.c
+COMCSRC                = arp.c bbc.c cast.c cache.c chario.c cmdtbl.c crypt.c \
+                         docmd.c dhcp_00.c dhcpboot.c edit.c ee.c env.c ethernet.c \
+                         flash.c genlib.c icmp.c if.c ledit_vt100.c monprof.c \
+                         mprintf.c memcmds.c malloc.c moncom.c memtrace.c misccmds.c \
+                         misc.c password.c redirect.c reg_cache.c sbrk.c start.c \
+                         struct.c symtbl.c tcpstuff.c tfs.c tfsapi.c tfsclean1.c \
+                         tfscli.c \
+                         tfsloader.c tfslog.c tftp.c timestuff.c xmodem.c gdb.c \
+                         fbi.c font.c
+CPUCSRC                = except_lm32.c strace_lm32.c
+IODEVSRC       = ps2_kbd.c
+FLASHSRC       = intel28f256_16x1.c
+
+include $(TOPDIR)/target/make/objects.make
+
+OBJS   =       $(LOCSOBJ) $(CPUSOBJ) $(LOCCOBJ) $(CPUCOBJ) $(COMCOBJ) \
+                       $(FLASHOBJ) $(IODEVOBJ)
+
+#########################################################################
+#
+# Targets...
+
+# boot:
+# The default target is "boot", a shortcut to $(BUILDDIR)/boot.$(FILETYPE).
+# This builds the bootflash image that can be used by 'newmon' to 
+# load a new version onto an already running system.
+#
+boot:  $(BUILDDIR)/boot.$(FILETYPE)
+       @echo Boot version of uMon built under $(BUILDDIR) ...
+       @ls $(BUILDDIR)/boot*
+
+# ramtst:
+# A shortcut to $(BUILDDIR)/ramtst.$(FILETYPE).  This is a version of uMon
+# that resides strictly in RAM and is used for two main purposes:
+# 1. To test new monitor features prior to burning the boot flash.
+# 2. To be downloaded into the RAM space of a board that has no programmed
+#    boot flash.  This provides a running monitor that can then accept
+#    an incoming bootflash image using 'newmon'.
+#
+ramtst:        $(BUILDDIR)/ramtst.$(FILETYPE)
+       @echo Ram-resident test version of uMon built under $(BUILDDIR) ...
+       @ls $(BUILDDIR)/ramtst*
+
+$(BUILDDIR)/boot.$(FILETYPE): $(BUILDDIR) $(OBJS) libz.a libg.a makefile
+       $(MAKE_MONBUILT)
+       $(MAKE_LDFILE) \
+               BOOTRAMBASE=$(BOOTRAMBASE) BOOTRAMLEN=$(BOOTRAMLEN) \
+               BOOTROMBASE=$(BOOTROMBASE) BOOTROMLEN=$(BOOTROMLEN)
+       $(LINK) -e coldstart $(OBJS) monbuilt.o libz.a libg.a $(LIBGCC)
+       $(MAKE_BINARY)
+       $(MAKE_GNUSYMS)
+
+$(BUILDDIR)/ramtst.$(FILETYPE): $(BUILDDIR) $(OBJS) libz.a libg.a makefile
+       $(MAKE_MONBUILT)
+       $(MAKE_LDFILE) \
+               RAMTSTBASE=$(RAMTSTBASE) RAMTSTLEN=$(RAMTSTLEN) \
+               MACADDRBASE=$(MACADDRBASE) ALTTFSDEVTBLBASE=$(ALTTFSDEVTBLBASE)
+       $(LINK) -e coldstart $(OBJS) monbuilt.o libz.a libg.a $(LIBGCC)
+       $(MAKE_BINARY)
+       $(MAKE_GNUSYMS)
+
+include $(TOPDIR)/target/make/rules.make
+
+#########################################################################
+#
+# Miscellaneous...
+#
+######
+#
+# cscope_local:
+# Put additional files here that should be included in the cscope
+# files list.  This is called before the generic cscope file builder,
+# so it should create the cscope.files file.
+#
+cscope_local:
+       >cscope.files
+
+######
+#
+# help_local:
+# Add text here as needed by the port.
+#
+help_local:
+       @echo "This template defaults to using ppc-elf as the tool prefix."
+       @echo "To override this default modify CPU & FILETYPE variables."
+       @echo 
diff --git a/umon_ports/milkymist/regnames.c b/umon_ports/milkymist/regnames.c
new file mode 100644 (file)
index 0000000..fa075d4
--- /dev/null
@@ -0,0 +1,10 @@
+/* This file is included by the common file reg_cache.c.
+ * The file included below is the table of register names.
+ * The purpose behind this multiple level of file inclusion is to allow
+ * the common file "reg_cache.c" to include a file called "regnames.c"
+ * which will have a target-specific register table without the target-
+ * specific filename.
+ * If the file specified below isn't correct, then check main/cpu/CPU for
+ * others.
+ */
+#include "regs_lm32.c"
diff --git a/umon_ports/milkymist/reset.S b/umon_ports/milkymist/reset.S
new file mode 100644 (file)
index 0000000..931012d
--- /dev/null
@@ -0,0 +1,309 @@
+/* reset.S:
+ *
+ * First bit of boot code run by the processor.
+ *
+ */
+    .file   "reset.S"
+
+    .extern start
+    .extern MonStack
+    .extern exception
+    .global reset
+    .global warmstart
+    .global coldstart
+
+#include "config.h"
+#include "warmstart.h"
+#include "cpu.h"
+
+/*********************************************************************
+ *
+ * coldstart:
+ * The reset point.
+ */
+reset:
+_reset_handler:
+    /* set r0 to zero */
+    xor r0, r0, r0
+    /* disable and mask irq */
+    wcsr IE, r0
+    wcsr IM, r0
+    /* set exception base address */
+    mvhi r1, hi(_reset_handler)
+    ori r1, r1, lo(_reset_handler)
+    wcsr EBA, r1
+    /* do coldstart */
+    bi coldstart
+    nop
+
+_breakpoint_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ba, -4
+    mvi r2, EXCP_BREAKPOINT
+    bi exception_handler
+    nop
+    nop
+
+_instruction_bus_error_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ea, -4
+    mvi r2, EXCP_I_BUS_ERROR
+    bi exception_handler
+    nop
+    nop
+
+_watchpoint_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ba, -4
+    mvi r2, EXCP_WATCHPOINT
+    bi exception_handler
+    nop
+    nop
+
+_data_bus_error_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ea, -4
+    mvi r2, EXCP_D_BUS_ERROR
+    bi exception_handler
+    nop
+    nop
+
+_divide_by_zero_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ea, -4
+    mvi r2, EXCP_DIVIDE_BY_ZERO
+    bi exception_handler
+    nop
+    nop
+
+_interrupt_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ea, -4
+    mvi r2, EXCP_INTERRUPT
+    bi exception_handler
+    nop
+    nop
+
+_system_call_handler:
+    addi sp, sp, -16
+    sw (sp+0), r1
+    sw (sp+4), r2
+    addi r1, ea, -4
+    mvi r2, EXCP_SYSTEM_CALL
+    bi exception_handler
+    nop
+    nop
+
+coldstart:
+    mvi r1, 1
+
+    /* flush data cache */
+    wcsr DCC, r1
+    nop
+    nop
+    nop
+    nop
+
+    /* flush instruction cache */
+    wcsr ICC, r1
+    nop
+    nop
+    nop
+    nop
+
+    mvi r1, INITIALIZE
+    bi warmstart
+    
+/*********************************************************************
+ *
+ * moncomptr:
+ * Pointer to the moncom function, used to link application to monitor.
+ * Refer to umon_main/target/core/moncomptr.S
+ */
+#include "moncomptr.S"
+
+/*********************************************************************
+ *
+ * etheraddr:
+ * Location that could be used to store a fixed MAC address.
+ * Refer to umon_main/target/core/etheraddr.S.
+ * NOTE:
+ * This should only be included in flash-resident code, then
+ * the address in flash should be accessible to ram-based versions of
+ * uMon via tags in the linker map file.
+ */
+#include "etheraddr.S"
+
+/*********************************************************************
+ *
+ * alttfsdevtbl.S:
+ * Location that could be used to store an "alternate" TFS device
+ * table for use by the "tfs cfg" command.
+ * Refer to umon_main/target/core/alttfsdevtbl.S.
+ * NOTE:
+ * This should only be included in flash-resident code, then
+ * the address in flash should be accessible to ram-based versions of
+ * uMon via tags in the linker map file.
+ */
+#include "alttfsdevtbl.S"
+    
+/*********************************************************************
+ *
+ * warmstart:
+ * A point callable by C, as warmstart(int type), where
+ * 'type' is one of the values defined in warmstart.h.
+ */
+warmstart:
+    mv r11, r1
+    /* Minimal CPU/IO Initialization (i.e. chip selects) here.
+     * Stay in assembler here if possible.
+     */
+    
+/*********************************************************************
+ *
+ * SPInit:
+ * Establish a stack frame.
+ */
+SPInit:
+    /* First initialize stack to point to MonStack+MONSTACKSIZE+64
+     * (an address that is outside the MonStack array), and then
+     * call stkinit().  This loads the MonStack[] array with a known
+     * pattern that allows uMon to later analyze the running stack usage.
+     */
+    mvhi sp, hi(MonStack)
+    ori sp, sp, lo(MonStack)
+    addi sp, sp, MONSTACKSIZE+64
+    mvhi r1, hi(stkinit)
+    ori r1, r1, lo(stkinit)
+    call r1
+    
+    /* Next, re-initialize stack to point to MonStack+MONSTACKSIZE...
+     * This is important because other portions of the code
+     * assume this is where the stack resides.
+     */
+    mvhi sp, hi(MonStack)
+    ori sp, sp, lo(MonStack)
+    addi sp, sp, MONSTACKSIZE-4
+
+/*********************************************************************
+ *
+ * gotoC:
+ * This code jumps to the start() function in the monitor
+ * and should never return.
+ */
+gotoC:
+    /* - Retrieve the variable passed to warmstart and place it
+     *   whereever it needs to be so that the start() function in
+     *   'C' sees it as an argument.  Note that if FORCE_BSS_INIT
+     *   is defined, then start() will ignore this argument.
+     * - Branch to start().
+     */
+    mv r1, r11
+    mvhi r2, hi(start)
+    ori r2, r2, lo(start)
+    b r2
+
+exception_handler:
+    /* store registers we use here */
+    sw (sp+8), r3
+    sw (sp+12), r4
+
+    /* save registers to regtbl */
+    mvhi r3, hi(regtbl)
+    ori r3, r3, lo(regtbl)
+
+    sw (r3+0), r0
+
+    /* store r1 */
+    lw r4, (sp+0)
+    sw (r3+4), r4
+
+    /* store r2 */
+    lw r4, (sp+4)
+    sw (r3+8), r4
+
+    /* store r3 */
+    lw r4, (sp+8)
+    sw (r3+12), r4
+
+    /* r4 is stored at the end */
+
+    sw (r3+20), r5
+    sw (r3+24), r6
+    sw (r3+28), r7
+    sw (r3+32), r8
+    sw (r3+36), r9
+    sw (r3+40), r10
+    sw (r3+44), r11
+    sw (r3+48), r12
+    sw (r3+52), r13
+    sw (r3+56), r14
+    sw (r3+60), r15
+    sw (r3+64), r16
+    sw (r3+68), r17
+    sw (r3+72), r18
+    sw (r3+76), r19
+    sw (r3+80), r20
+    sw (r3+84), r21
+    sw (r3+88), r22
+    sw (r3+92), r23
+    sw (r3+96), r24
+    sw (r3+100), r25
+    sw (r3+104), r26   /* gp */
+    sw (r3+108), r27   /* fp */
+
+    /* store r28/sp */
+    addi r4, sp, 16
+    sw (r3+112), r4    /* sp */
+    sw (r3+116), r29   /* ra */
+    sw (r3+120), r30   /* ea */
+    sw (r3+124), r31   /* ba */
+
+    /* PC is exception address */
+    sw (r3+128), r1
+
+    /* EID is exception type */
+    sw (r3+132), r2
+
+    /* store eba */
+    rcsr r4, eba
+    sw (r3+136), r4
+
+    /* store deba */
+    rcsr r4, deba
+    sw (r3+140), r4
+
+    /* store ie */
+    rcsr r4, ie
+    sw (r3+144), r4
+
+    /* store im */
+    rcsr r4, im
+    sw (r3+148), r4
+
+    /* store ip */
+    rcsr r4, ip
+    sw (r3+152), r4
+
+    /* now we can store r4 */
+    lw r5, (sp+12)
+    sw (r3+16), r4
+
+    /* should never return */
+    calli exception
+
+dead_end:
+    bi dead_end
+
diff --git a/umon_ports/milkymist/target_version.h b/umon_ports/milkymist/target_version.h
new file mode 100644 (file)
index 0000000..fa728a7
--- /dev/null
@@ -0,0 +1,8 @@
+/* target_version.h:
+ * Initial version for all ports is zero.  As the TARGET_VERSION incrments
+ * as a result of changes made to the target-specific code, this file should
+ * be used as an informal log of those changes for easy reference by others.
+ *
+ * 1->2: Added 'struct' command.
+ */
+#define TARGET_VERSION 2
diff --git a/umon_ports/milkymist/tfsdev.h b/umon_ports/milkymist/tfsdev.h
new file mode 100644 (file)
index 0000000..541f3fb
--- /dev/null
@@ -0,0 +1,36 @@
+/* tfsdev.h:
+       This file is ONLY included by tfs.c.  It is seperate from tfs.h because
+       it is target-specific.  It is not part of config.h because it includes
+       the declaration of the tfsdevtbl[].
+       A prefix in the name of the file determines what device is used to store
+       that file.  If no prefix is found the the first device in the table is
+       used as a default.  The syntax of the prefix is "//STRING/" where STRING
+       is user-definable, but the initial // and final / are required by tfs
+       code.
+*/
+
+struct tfsdev tfsdevtbl[] = {
+       {
+               "//FLASH/",
+               TFSSTART,
+               TFSEND,
+               TFSSPARE,
+               TFSSPARESIZE,
+               TFSSECTORCOUNT,
+               TFS_DEVTYPE_FLASH },
+
+#ifdef FLASHRAM_BASE
+       {
+               "//RAM/",
+               FLASHRAM_BASE,
+               FLASHRAM_END - FLASHRAM_SPARESIZE,
+               FLASHRAM_END - FLASHRAM_SPARESIZE + 1,
+               FLASHRAM_SPARESIZE,
+               FLASHRAM_SECTORCOUNT-1,
+               TFS_DEVTYPE_RAM | TFS_DEVINFO_AUTOINIT },
+#endif
+
+       { 0, TFSEOT,0,0,0,0,0 }
+};
+
+#define TFSDEVTOT ((sizeof(tfsdevtbl))/(sizeof(struct tfsdev)))
diff --git a/umon_ports/milkymist/vgafb.c b/umon_ports/milkymist/vgafb.c
new file mode 100644 (file)
index 0000000..5d43b06
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Author: Michael Walle <michael@walle.cc>
+ * License: Lucent Public License 1.02
+ */
+
+#include "cpuio.h"
+#include "config.h"
+#include "stddefs.h"
+
+#if INCLUDE_FBI
+
+#define BPP 2
+#define FB_SIZE (PIXELS_PER_COL * PIXELS_PER_ROW * BPP)
+
+/* double buffering */
+uchar vgafb_framebuffer[FB_SIZE*2] __attribute__((aligned(32)));
+
+void fbdev_init(void) {
+       VGAFB_BASEADDRESS = (unsigned int)vgafb_framebuffer;
+       VGAFB_HRES = PIXELS_PER_ROW;
+       VGAFB_VRES = PIXELS_PER_COL;
+       VGAFB_CONTROL = 0;
+}
+
+void fbdev_setstart(long addr) {
+       /* The baseaddress has to be 32 byte aligned. For common screen
+        * resolutions this requirement is met if the addr points to the
+        * beginning of a row. */
+       VGAFB_BASEADDRESS = (unsigned int)addr;
+}
+
+#endif
diff --git a/umon_ports/milkymist/xcmddcl.h b/umon_ports/milkymist/xcmddcl.h
new file mode 100644 (file)
index 0000000..1057b07
--- /dev/null
@@ -0,0 +1,14 @@
+/* xcmdtbl.h:
+ * This file must exist even if it is empty because it is #included in the
+ * common file cmdtbl.c.  The purpose is to keep the common comand table
+ * file (common/cmdtbl.c) from being corrupted with non-generic commands
+ * that may be target specific.
+ * This is the declaration portion of the code that must be at the top of
+ * the cmdtbl[] array.
+ *
+ * For example...
+
+extern int date();
+extern char *dateHelp[];
+
+ */
diff --git a/umon_ports/milkymist/xcmdtbl.h b/umon_ports/milkymist/xcmdtbl.h
new file mode 100644 (file)
index 0000000..ad74e63
--- /dev/null
@@ -0,0 +1,12 @@
+/* xcmdtbl.c:
+ * This file must exist even if it is empty because it is #included in the
+ * common file cmdtbl.c.  The purpose is to keep the common comand table 
+ * file (common/cmdtbl.c) from being corrupted with non-generic commands
+ * that may be target specific.
+ * It is the entry in the command table representing the new command being
+ * added to the cmdtbl[] array.
+ * For example:
+
+{"date",               date,           dateHelp,       0},
+
+ */