]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - cpu/blackfin/initcode.c
Blackfin: recurse with early serial initcode
[karo-tx-uboot.git] / cpu / blackfin / initcode.c
index ffc8420f1a94cf5b93920fc171519dac1ad18243..c0fe2c65a6c6232398ea0ce328c85d4ce2fcd7e8 100644 (file)
@@ -12,6 +12,7 @@
 #include <config.h>
 #include <asm/blackfin.h>
 #include <asm/mach-common/bits/bootrom.h>
+#include <asm/mach-common/bits/core.h>
 #include <asm/mach-common/bits/ebiu.h>
 #include <asm/mach-common/bits/pll.h>
 #include <asm/mach-common/bits/uart.h>
@@ -20,7 +21,7 @@
 #include "serial.h"
 
 __attribute__((always_inline))
-static inline uint32_t serial_init(void)
+static inline void serial_init(void)
 {
 #ifdef __ADSPBF54x__
 # ifdef BFIN_BOOT_UART_USE_RTS
@@ -61,21 +62,16 @@ static inline uint32_t serial_init(void)
        }
 #endif
 
-       uint32_t old_baud = serial_early_get_baud();
-
        if (BFIN_DEBUG_EARLY_SERIAL) {
+               int ucen = *pUART_GCTL & UCEN;
                serial_early_init();
 
                /* If the UART is off, that means we need to program
                 * the baud rate ourselves initially.
                 */
-               if (!old_baud) {
-                       old_baud = CONFIG_BAUDRATE;
+               if (ucen != UCEN)
                        serial_early_set_baud(CONFIG_BAUDRATE);
-               }
        }
-
-       return old_baud;
 }
 
 __attribute__((always_inline))
@@ -89,30 +85,6 @@ static inline void serial_deinit(void)
 #endif
 }
 
-/* We need to reset the baud rate when we have early debug turned on
- * or when we are booting over the UART.
- * XXX: we should fix this to calc the old baud and restore it rather
- *      than hardcoding it via CONFIG_LDR_LOAD_BAUD ... but we have
- *      to figure out how to avoid the division in the baud calc ...
- */
-__attribute__((always_inline))
-static inline void serial_reset_baud(uint32_t baud)
-{
-       if (!BFIN_DEBUG_EARLY_SERIAL && CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART)
-               return;
-
-#ifndef CONFIG_LDR_LOAD_BAUD
-# define CONFIG_LDR_LOAD_BAUD 115200
-#endif
-
-       if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS)
-               serial_early_set_baud(baud);
-       else if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART)
-               serial_early_set_baud(CONFIG_LDR_LOAD_BAUD);
-       else
-               serial_early_set_baud(CONFIG_BAUDRATE);
-}
-
 __attribute__((always_inline))
 static inline void serial_putc(char c)
 {
@@ -120,7 +92,7 @@ static inline void serial_putc(char c)
                return;
 
        if (c == '\n')
-               *pUART_THR = '\r';
+               serial_putc('\r');
 
        *pUART_THR = c;
 
@@ -129,12 +101,22 @@ static inline void serial_putc(char c)
 }
 
 
-/* Max SCLK can be 133MHz ... dividing that by 4 gives
- * us a freq of 33MHz for SPI which should generally be
+/* Max SCLK can be 133MHz ... dividing that by (2*4) gives
+ * us a freq of 16MHz for SPI which should generally be
  * slow enough for the slow reads the bootrom uses.
  */
+#if !defined(CONFIG_SPI_FLASH_SLOW_READ) && \
+    ((defined(__ADSPBF52x__) && __SILICON_REVISION__ >= 2) || \
+     (defined(__ADSPBF54x__) && __SILICON_REVISION__ >= 1))
+# define BOOTROM_SUPPORTS_SPI_FAST_READ 1
+#else
+# define BOOTROM_SUPPORTS_SPI_FAST_READ 0
+#endif
 #ifndef CONFIG_SPI_BAUD_INITBLOCK
-# define CONFIG_SPI_BAUD_INITBLOCK 4
+# define CONFIG_SPI_BAUD_INITBLOCK (BOOTROM_SUPPORTS_SPI_FAST_READ ? 2 : 4)
+#endif
+#ifdef SPI0_BAUD
+# define bfin_write_SPI_BAUD bfin_write_SPI0_BAUD
 #endif
 
 /* PLL_DIV defines */
@@ -158,17 +140,24 @@ static inline void serial_putc(char c)
 #endif
 
 #ifndef CONFIG_PLL_CTL_VAL
-# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9))
+# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF)
 #endif
 
 #ifndef CONFIG_EBIU_RSTCTL_VAL
 # define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */
 #endif
+#if ((CONFIG_EBIU_RSTCTL_VAL & 0xFFFFFFC4) != 0)
+# error invalid EBIU_RSTCTL value: must not set reserved bits
+#endif
 
 #ifndef CONFIG_EBIU_MBSCTL_VAL
 # define CONFIG_EBIU_MBSCTL_VAL 0
 #endif
 
+#if defined(CONFIG_EBIU_DDRQUE_VAL) && ((CONFIG_EBIU_DDRQUE_VAL & 0xFFFF8000) != 0)
+# error invalid EBIU_DDRQUE value: must not set reserved bits
+#endif
+
 /* Make sure our voltage value is sane so we don't blow up! */
 #ifndef CONFIG_VR_CTL_VAL
 # define BFIN_CCLK ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_CCLK_DIV)
@@ -195,6 +184,9 @@ static inline void serial_putc(char c)
 # elif defined(__ADSPBF54x__)  /* TBD; use default */
 #  undef CONFIG_VR_CTL_VLEV
 #  define CONFIG_VR_CTL_VLEV VLEV_120
+# elif defined(__ADSPBF538__) || defined(__ADSPBF539__)        /* TBD; use default */
+#  undef CONFIG_VR_CTL_VLEV
+#  define CONFIG_VR_CTL_VLEV VLEV_125
 # endif
 
 # ifdef CONFIG_BFIN_MAC
@@ -212,10 +204,79 @@ static inline void serial_putc(char c)
 # define CONFIG_VR_CTL_VAL (CONFIG_VR_CTL_CLKBUF | CONFIG_VR_CTL_VLEV | CONFIG_VR_CTL_FREQ)
 #endif
 
-__attribute__((saveall))
+/* some parts do not have an on-chip voltage regulator */
+#if defined(__ADSPBF51x__)
+# define CONFIG_HAS_VR 0
+# undef CONFIG_VR_CTL_VAL
+# define CONFIG_VR_CTL_VAL 0
+#else
+# define CONFIG_HAS_VR 1
+#endif
+
+#ifndef EBIU_RSTCTL
+/* Blackfin with SDRAM */
+#ifndef CONFIG_EBIU_SDBCTL_VAL
+# if CONFIG_MEM_SIZE == 16
+#  define CONFIG_EBSZ_VAL EBSZ_16
+# elif CONFIG_MEM_SIZE == 32
+#  define CONFIG_EBSZ_VAL EBSZ_32
+# elif CONFIG_MEM_SIZE == 64
+#  define CONFIG_EBSZ_VAL EBSZ_64
+# elif CONFIG_MEM_SIZE == 128
+#  define CONFIG_EBSZ_VAL EBSZ_128
+# elif CONFIG_MEM_SIZE == 256
+#  define CONFIG_EBSZ_VAL EBSZ_256
+# elif CONFIG_MEM_SIZE == 512
+#  define CONFIG_EBSZ_VAL EBSZ_512
+# else
+#  error You need to define CONFIG_EBIU_SDBCTL_VAL or CONFIG_MEM_SIZE
+# endif
+# if CONFIG_MEM_ADD_WDTH == 8
+#  define CONFIG_EBCAW_VAL EBCAW_8
+# elif CONFIG_MEM_ADD_WDTH == 9
+#  define CONFIG_EBCAW_VAL EBCAW_9
+# elif CONFIG_MEM_ADD_WDTH == 10
+#  define CONFIG_EBCAW_VAL EBCAW_10
+# elif CONFIG_MEM_ADD_WDTH == 11
+#  define CONFIG_EBCAW_VAL EBCAW_11
+# else
+#  error You need to define CONFIG_EBIU_SDBCTL_VAL or CONFIG_MEM_ADD_WDTH
+# endif
+# define CONFIG_EBIU_SDBCTL_VAL (CONFIG_EBCAW_VAL | CONFIG_EBSZ_VAL | EBE)
+#endif
+#endif
+
+/* Conflicting Column Address Widths Causes SDRAM Errors:
+ * EB2CAW and EB3CAW must be the same
+ */
+#if ANOMALY_05000362
+# if ((CONFIG_EBIU_SDBCTL_VAL & 0x30000000) >> 8) != (CONFIG_EBIU_SDBCTL_VAL & 0x00300000)
+#  error "Anomaly 05000362: EB2CAW and EB3CAW must be the same"
+# endif
+#endif
+
+BOOTROM_CALLED_FUNC_ATTR
 void initcode(ADI_BOOT_DATA *bootstruct)
 {
-       uint32_t old_baud = serial_init();
+       ADI_BOOT_DATA bootstruct_scratch;
+
+       /* Save the clock pieces that are used in baud rate calculation */
+       unsigned int sdivB, divB, vcoB;
+       serial_init();
+       if (BFIN_DEBUG_EARLY_SERIAL || CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
+               sdivB = bfin_read_PLL_DIV() & 0xf;
+               vcoB = (bfin_read_PLL_CTL() >> 9) & 0x3f;
+               divB = serial_early_get_div();
+       }
+
+       serial_putc('A');
+
+       /* If the bootstruct is NULL, then it's because we're loading
+        * dynamically and not via LDR (bootrom).  So set the struct to
+        * some scratch space.
+        */
+       if (!bootstruct)
+               bootstruct = &bootstruct_scratch;
 
 #ifdef CONFIG_HW_WATCHDOG
 # ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
@@ -233,88 +294,192 @@ void initcode(ADI_BOOT_DATA *bootstruct)
        }
 #endif
 
-       serial_putc('S');
+       serial_putc('B');
+
+       /* If external memory is enabled, put it into self refresh first. */
+       bool put_into_srfs = false;
+#ifdef EBIU_RSTCTL
+       if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) {
+               bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | SRREQ);
+               put_into_srfs = true;
+       }
+#else
+       if (bfin_read_EBIU_SDBCTL() & EBE) {
+               bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS);
+               put_into_srfs = true;
+       }
+#endif
+
+       serial_putc('C');
 
        /* Blackfin bootroms use the SPI slow read opcode instead of the SPI
         * fast read, so we need to slow down the SPI clock a lot more during
         * boot.  Once we switch over to u-boot's SPI flash driver, we'll
         * increase the speed appropriately.
         */
-       if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER)
-#ifdef SPI0_BAUD
-               bfin_write_SPI0_BAUD(CONFIG_SPI_BAUD_INITBLOCK);
-#else
+       if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) {
+               if (BOOTROM_SUPPORTS_SPI_FAST_READ && CONFIG_SPI_BAUD_INITBLOCK < 4)
+                       bootstruct->dFlags |= BFLAG_FASTREAD;
                bfin_write_SPI_BAUD(CONFIG_SPI_BAUD_INITBLOCK);
+       }
+
+       serial_putc('D');
+
+       /* If we're entering self refresh, make sure it has happened. */
+       if (put_into_srfs)
+#ifdef EBIU_RSTCTL
+               while (!(bfin_read_EBIU_RSTCTL() & SRACK))
+#else
+               while (!(bfin_read_EBIU_SDSTAT() & SDSRA))
 #endif
+                       continue;
 
-       serial_putc('B');
+       serial_putc('E');
+
+       /* With newer bootroms, we use the helper function to set up
+        * the memory controller.  Older bootroms lacks such helpers
+        * so we do it ourselves.
+        */
+       uint16_t vr_ctl = bfin_read_VR_CTL();
+       if (!ANOMALY_05000386) {
+               serial_putc('F');
+
+               /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */
+               ADI_SYSCTRL_VALUES memory_settings;
+               uint32_t actions = SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT;
+               if (CONFIG_HAS_VR) {
+                       actions |= SYSCTRL_VRCTL;
+                       if (CONFIG_VR_CTL_VAL & FREQ_MASK)
+                               actions |= SYSCTRL_INTVOLTAGE;
+                       else
+                               actions |= SYSCTRL_EXTVOLTAGE;
+                       memory_settings.uwVrCtl = CONFIG_VR_CTL_VAL;
+               } else
+                       actions |= SYSCTRL_EXTVOLTAGE;
+               memory_settings.uwPllCtl = CONFIG_PLL_CTL_VAL;
+               memory_settings.uwPllDiv = CONFIG_PLL_DIV_VAL;
+               memory_settings.uwPllLockCnt = CONFIG_PLL_LOCKCNT_VAL;
+#if ANOMALY_05000432
+               bfin_write_SIC_IWR1(0);
+#endif
+               bfrom_SysControl(actions, &memory_settings, NULL);
+#if ANOMALY_05000432
+               bfin_write_SIC_IWR1(-1);
+#endif
+#if ANOMALY_05000171
+               bfin_write_SICA_IWR0(-1);
+               bfin_write_SICA_IWR1(-1);
+#endif
+       } else {
+               serial_putc('G');
 
-       /* Disable all peripheral wakeups except for the PLL event. */
+               /* Disable all peripheral wakeups except for the PLL event. */
 #ifdef SIC_IWR0
-       bfin_write_SIC_IWR0(1);
-       bfin_write_SIC_IWR1(0);
+               bfin_write_SIC_IWR0(1);
+               bfin_write_SIC_IWR1(0);
 # ifdef SIC_IWR2
-       bfin_write_SIC_IWR2(0);
+               bfin_write_SIC_IWR2(0);
 # endif
 #elif defined(SICA_IWR0)
-       bfin_write_SICA_IWR0(1);
-       bfin_write_SICA_IWR1(0);
+               bfin_write_SICA_IWR0(1);
+               bfin_write_SICA_IWR1(0);
 #else
-       bfin_write_SIC_IWR(1);
+               bfin_write_SIC_IWR(1);
 #endif
 
-       serial_putc('L');
+               serial_putc('H');
 
-       bfin_write_PLL_LOCKCNT(CONFIG_PLL_LOCKCNT_VAL);
+               /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */
+               bfin_write_PLL_LOCKCNT(CONFIG_PLL_LOCKCNT_VAL);
 
-       serial_putc('A');
+               serial_putc('I');
 
-       /* Only reprogram when needed to avoid triggering unnecessary
-        * PLL relock sequences.
-        */
-       if (bfin_read_VR_CTL() != CONFIG_VR_CTL_VAL) {
-               serial_putc('!');
-               bfin_write_VR_CTL(CONFIG_VR_CTL_VAL);
-               asm("idle;");
-       }
+               /* Only reprogram when needed to avoid triggering unnecessary
+                * PLL relock sequences.
+                */
+               if (vr_ctl != CONFIG_VR_CTL_VAL) {
+                       serial_putc('!');
+                       bfin_write_VR_CTL(CONFIG_VR_CTL_VAL);
+                       asm("idle;");
+               }
 
-       serial_putc('C');
+               serial_putc('J');
 
-       bfin_write_PLL_DIV(CONFIG_PLL_DIV_VAL);
+               bfin_write_PLL_DIV(CONFIG_PLL_DIV_VAL);
 
-       serial_putc('K');
+               serial_putc('K');
 
-       /* Only reprogram when needed to avoid triggering unnecessary
-        * PLL relock sequences.
-        */
-       if (bfin_read_PLL_CTL() != CONFIG_PLL_CTL_VAL) {
-               serial_putc('!');
-               bfin_write_PLL_CTL(CONFIG_PLL_CTL_VAL);
-               asm("idle;");
+               /* Only reprogram when needed to avoid triggering unnecessary
+                * PLL relock sequences.
+                */
+               if (ANOMALY_05000242 || bfin_read_PLL_CTL() != CONFIG_PLL_CTL_VAL) {
+                       serial_putc('!');
+                       bfin_write_PLL_CTL(CONFIG_PLL_CTL_VAL);
+                       asm("idle;");
+               }
+
+               serial_putc('L');
+
+               /* Restore all peripheral wakeups. */
+#ifdef SIC_IWR0
+               bfin_write_SIC_IWR0(-1);
+               bfin_write_SIC_IWR1(-1);
+# ifdef SIC_IWR2
+               bfin_write_SIC_IWR2(-1);
+# endif
+#elif defined(SICA_IWR0)
+               bfin_write_SICA_IWR0(-1);
+               bfin_write_SICA_IWR1(-1);
+#else
+               bfin_write_SIC_IWR(-1);
+#endif
        }
 
+       serial_putc('M');
+
        /* Since we've changed the SCLK above, we may need to update
         * the UART divisors (UART baud rates are based on SCLK).
+        * Do the division by hand as there are no native instructions
+        * for dividing which means we'd generate a libgcc reference.
         */
-       serial_reset_baud(old_baud);
+       if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
+               unsigned int sdivR, vcoR;
+               sdivR = bfin_read_PLL_DIV() & 0xf;
+               vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f;
+               int dividend = sdivB * divB * vcoR;
+               int divisor = vcoB * sdivR;
+               unsigned int quotient;
+               for (quotient = 0; dividend > 0; ++quotient)
+                       dividend -= divisor;
+               serial_early_put_div(quotient - ANOMALY_05000230);
+       }
 
-       serial_putc('F');
+       serial_putc('N');
 
-       /* Program the async banks controller. */
-       bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
-       bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
-       bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
+       /* Program the external memory controller before we come out of
+        * self-refresh.  This only works with our SDRAM controller.
+        */
+#ifndef EBIU_RSTCTL
+       bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL);
+       bfin_write_EBIU_SDBCTL(CONFIG_EBIU_SDBCTL_VAL);
+       bfin_write_EBIU_SDGCTL(CONFIG_EBIU_SDGCTL_VAL);
+#endif
 
-#ifdef EBIU_MODE
-       /* Not all parts have these additional MMRs. */
-       bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
-       bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
-       bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
+       serial_putc('O');
+
+       /* Now that we've reprogrammed, take things out of self refresh. */
+       if (put_into_srfs)
+#ifdef EBIU_RSTCTL
+               bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
+#else
+               bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() & ~(SRFS));
 #endif
 
-       serial_putc('I');
+       serial_putc('P');
 
-       /* Program the external memory controller. */
+       /* Our DDR controller sucks and cannot be programmed while in
+        * self-refresh.  So we have to pull it out before programming.
+        */
 #ifdef EBIU_RSTCTL
        bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1 /*DDRSRESET*/ | CONFIG_EBIU_RSTCTL_VAL);
        bfin_write_EBIU_DDRCTL0(CONFIG_EBIU_DDRCTL0_VAL);
@@ -324,28 +489,64 @@ void initcode(ADI_BOOT_DATA *bootstruct)
        /* default is disable, so don't need to force this */
        bfin_write_EBIU_DDRCTL3(CONFIG_EBIU_DDRCTL3_VAL);
 # endif
-#else
-       bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL);
-       bfin_write_EBIU_SDBCTL(CONFIG_EBIU_SDBCTL_VAL);
-       bfin_write_EBIU_SDGCTL(CONFIG_EBIU_SDGCTL_VAL);
+# ifdef CONFIG_EBIU_DDRQUE_VAL
+       bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE() | CONFIG_EBIU_DDRQUE_VAL);
+# endif
 #endif
 
-       serial_putc('N');
+       serial_putc('Q');
 
-       /* Restore all peripheral wakeups. */
-#ifdef SIC_IWR0
-       bfin_write_SIC_IWR0(-1);
-       bfin_write_SIC_IWR1(-1);
-# ifdef SIC_IWR2
-       bfin_write_SIC_IWR2(-1);
-# endif
-#elif defined(SICA_IWR0)
-       bfin_write_SICA_IWR0(-1);
-       bfin_write_SICA_IWR1(-1);
-#else
-       bfin_write_SIC_IWR(-1);
+       /* Are we coming out of hibernate (suspend to memory) ?
+        * The memory layout is:
+        * 0x0: hibernate magic for anomaly 307 (0xDEADBEEF)
+        * 0x4: return address
+        * 0x8: stack pointer
+        *
+        * SCKELOW is unreliable on older parts (anomaly 307)
+        */
+       if (ANOMALY_05000307 || vr_ctl & 0x8000) {
+               uint32_t *hibernate_magic = 0;
+               __builtin_bfin_ssync(); /* make sure memory controller is done */
+               if (hibernate_magic[0] == 0xDEADBEEF) {
+                       serial_putc('R');
+                       bfin_write_EVT15(hibernate_magic[1]);
+                       bfin_write_IMASK(EVT_IVG15);
+                       __asm__ __volatile__ (
+                               /* load reti early to avoid anomaly 281 */
+                               "reti = %0;"
+                               /* clear hibernate magic */
+                               "[%0] = %1;"
+                               /* load stack pointer */
+                               "SP = [%0 + 8];"
+                               /* lower ourselves from reset ivg to ivg15 */
+                               "raise 15;"
+                               "rti;"
+                               :
+                               : "p"(hibernate_magic), "d"(0x2000 /* jump.s 0 */)
+                       );
+               }
+       }
+
+       serial_putc('S');
+
+       /* Program the async banks controller. */
+       bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
+       bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
+       bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
+
+#ifdef EBIU_MODE
+       /* Not all parts have these additional MMRs. */
+       bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
+       bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
+       bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
 #endif
 
+       serial_putc('T');
+
+       /* tell the bootrom where our entry point is */
+       if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS)
+               bfin_write_EVT1(CONFIG_SYS_MONITOR_BASE);
+
        serial_putc('>');
        serial_putc('\n');